#!/usr/bin/env python3

import sys
import json

class BorSyntaxException(Exception):
    pass

def parse(file):
    lines = Lookahead(iter(file.splitlines()))
    delay = .5

    # parse top of file for flags
    while lines.peek() is not None and lines.peek().startswith('#'):
        line = lines.next()
        if line.startswith('#delay '):
            try:
                delay = float(line[7:].strip())
            except ValueError:
                print('Syntax Error on line: "' + line + '"')
                print('Value cannot be converted to "float"')

    return build_sequence(interpret(file.splitlines()), delay)

def interpret(rows):
    lines = Lookahead(iter(rows))
    pattern = []
    delay = .5

    while lines.peek() is not None:
        line = lines.next()
        if line.startswith('#'):
            continue

        elements = line.split(' ')
        if len(elements) == 4 and elements[0] == 'set':
            pattern.append(build_color(elements[1], elements[2], elements[3]))
        elif elements[0].startswith('sequence') or elements[0].startswith('fade'):
            indented_lines = []
            while lines.peek() is not None and lines.peek().startswith("\t"):
                indented_lines.append(lines.next()[1:])

            if '(' in elements[0] and ')' in elements[0]:
                newdelay = elements[0][elements[0].index('(') + 1:elements[0].index(')')]
                delay = float(newdelay) if newdelay.replace('.', '', 1).isdigit() else delay

            if elements[0].startswith('sequence'):
                    new_elements = build_sequence(interpret(indented_lines), delay)
            else:
                new_elements = build_fade(interpret(indented_lines), delay)
            pattern.append(new_elements)
        else:
            print('Syntax Error on line: "' + line + '"')
            raise BorSyntaxException
    return pattern

def build_color(red, green, blue):
    return {
        'type': 'color',
        'red': int(red),
        'green': int(green),
        'blue': int(blue)
    }

def build_sequence(sequence, delay):
    return {
        "type": "sequence",
        "delay": delay,
        "sequence": sequence
    }

def build_fade(colors, delay):
    stripped = []
    for c in colors:
        stripped.append(c)
    return {
        'type': 'fade',
        'delay': delay,
        'colors': stripped
    }

class Lookahead:
    def __init__(self, iter):
        self.iter = iter
        self.buffer = []

    def __iter__(self):
        return self

    def next(self):
        if self.buffer:
            return self.buffer.pop(0)
        else:
            return next(self.iter)

    def peek(self):
        if len(self.buffer) < 1:
            try:
                self.buffer.append(next(self.iter))
            except StopIteration:
                return None
        return self.buffer[0]

    def lookahead(self, n):
        """Return an item n entries ahead in the iteration."""
        while n >= len(self.buffer):
            try:
                self.buffer.append(next(self.iter))
            except StopIteration:
                return None
        return self.buffer[n]

if __name__ == '__main__' and len(sys.argv) == 3:
    infile = open(sys.argv[1], 'r')
    outfile = open(sys.argv[2], 'w')
    try:
        outfile.write(json.dumps(parse(infile.read())))
    except BorSyntaxException:
        print('Syntax incorrect file not saved.')


from django.shortcuts import render
from rest_framework import generics
from people import models, serializers
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework import status
from biblio import models as biblio_models
from biblio import serializers as biblio_serializers
from redlist import serializers as redlist_serializers
from redlist import models as redlist_models
from rest_framework.renderers import TemplateHTMLRenderer, BrowsableAPIRenderer, JSONRenderer

@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'people': reverse('people_list', request=request, format=format),
    })

class PeopleList(generics.ListCreateAPIView):
    queryset=models.Person.objects.all()
    serializer_class = serializers.PersonSerializer

    # Overriding super method to use .get_or_create() instead of .save()
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid(): # raise_exception=True
            try:
                person = models.Person.objects.get(**serializer.validated_data)
                person = serializers.PersonSerializer(person)
                return Response(person.data, status=status.HTTP_202_ACCEPTED)
            except models.Person.DoesNotExist:
                # Try and get all possible people in the database first
                if serializer.validated_data['initials']:
                    person = models.Person.objects.filter(surname=serializer.validated_data['surname'].strip(),
                                                          initials=serializer.validated_data['initials'].strip(),
                                                          first__startswith=serializer.validated_data['first'][0].strip()).first()
                    if person is None:
                        person = models.Person.objects.filter(surname=serializer.validated_data['surname'].strip(),
                                                              initials=serializer.validated_data['initials'].strip()).first()
                else:
                    person = models.Person.objects.filter(surname=serializer.validated_data['surname'].strip(),
                                                          initials__isnull=True).first()

                # If they cannot be found then create them
                if person is None:
                    self.perform_create(serializer)
                    headers = self.get_success_headers(serializer.data)
                    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
                else:
                    person = serializers.PersonSerializer(person)
                    return Response(person.data, status=status.HTTP_202_ACCEPTED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@renderer_classes((TemplateHTMLRenderer, JSONRenderer, BrowsableAPIRenderer))
def person(request, slug):
    if request.method == 'GET':
        person = models.Person.objects.get(slug=slug)

        # References
        references = biblio_models.Reference.objects.filter(authors=person, bibtex__isnull=False)
        references = biblio_serializers.ReferenceSerializer(references, many=True)

        # Assessment contributors
        contributions = redlist_models.Contribution.objects.filter(person=person)
        contributions = redlist_serializers.ContributionAssessmentSerializer(contributions, many=True)

        response = {'references': references.data, 'contributions': contributions.data, 'person': str(person)}
        return Response(response, status=status.HTTP_202_ACCEPTED, template_name='website/person.html')


import collections

import six
import shapely.geometry
import geojson

def polygon_from_bounds(bounds):
    "Return a GeoJSON Polygon dict from a (minx, miny, maxx, maxy) tuple"
    return {
        "type": "Polygon",
        "coordinates": ((
            (bounds[2], bounds[1]),
            (bounds[2], bounds[3]),
            (bounds[0], bounds[3]),
            (bounds[0], bounds[1]),
            (bounds[2], bounds[1]),
        ),)
    }

def test_valid_bounds(bounds):
    """
    Test given bounds are in correct order and are valid WGS84 lat-lon values

    Raises TypeError or ValueError if bounds are invalid, otherwise returns None
    """
    try:
        if not isinstance(bounds, (list, tuple)):
            raise TypeError("Bounds must be a list or tuple, instead got type {}".format(type(bounds)))

        if len(bounds) != 4:
            raise ValueError(
                "Bounds must a sequence of (minx, miny, maxx, maxy), "
                "got sequence of length {}".format(len(bounds))
            )
    except TypeError:
        six.raise_from(
            TypeError("Bounds must a sequence of (minx, miny, maxx, maxy), got {}".format(type(bounds))),
            None
        )
    if not (-180 < bounds[0] < 180 and
            -90 < bounds[1] < 90 and
            -180 < bounds[2] < 180 and
            -90 < bounds[3] < 90):
        raise ValueError("Bounds must be in EPSG:4326 (WGS84 lat-lon) coordinates")

    if bounds[0] >= bounds[2]:
        raise ValueError("minx >= maxx in given bounds, should be (minx, miny, maxx, maxy)")
    if bounds[1] >= bounds[3]:
        raise ValueError("miny >= maxy in given bounds, should be (minx, miny, maxx, maxy)")

def geometry_like_to_shapely(geometry):
    """
    Convert a GeoJSON dict, or __geo_interface__ object, to a Shapely geometry.

    Handles Features and FeatureCollections (FeatureCollections become GeometryCollections).
    """
    if isinstance(geometry, shapely.geometry.base.BaseGeometry):
        return geometry

    if not isinstance(geometry, collections.Mapping):
        try:
            geometry = geometry.__geo_interface__
        except AttributeError:
            six.raise_from(
                TypeError("geometry object is not a GeoJSON dict, nor has a `__geo_interface__`: {}".format(geometry)),
                None
            )

    geoj = as_geojson_geometry(geometry)
    try:
        shape = shapely.geometry.shape(geoj)
    except Exception:
        raise ValueError("Could not interpret this geometry as a Shapely shape: {}".format(geometry))

    # test that geometry is in WGS84
    test_valid_bounds(shape.bounds)
    return shape

def as_geojson_geometry(geojson_dict):
    """
    Return a mapping as a GeoJSON instance, converting Feature types to Geometry types.
    """
    try:
        geoj = geojson.GeoJSON.to_instance(geojson_dict, strict=True)
    except (TypeError, KeyError, UnicodeEncodeError) as ex:
        raise ValueError("geometry not recognized as valid GeoJSON ({}): {}".format(str(ex), geojson_dict))
    # Shapely cannot handle GeoJSON Features or FeatureCollections
    if isinstance(geoj, geojson.Feature):
        geoj = geoj.geometry
    elif isinstance(geoj, geojson.FeatureCollection):
        features = []
        for feature in geoj.features:
            try:
                features.append(geojson.GeoJSON.to_instance(feature, strict=True).geometry)
            except (TypeError, KeyError, UnicodeEncodeError) as ex:
                raise ValueError(
                    "feature in FeatureCollection not recognized as valid ({}): {}".format(str(ex), feature))
        geoj = geojson.GeometryCollection(features)
    return geoj


import cv2
import numpy as np
import face_recognition
import os
import datetime
import sqlite3
database=sqlite3.connect('face_recognizer')
cursor=database.cursor()

path = 'Training_images'
images = []
classNames = []
myList = os.listdir(path)
print(myList)
for cl in myList:
    curImg = cv2.imread(f'{path}/{cl}')
    images.append(curImg)
    classNames.append(os.path.splitext(cl)[0])
print(classNames)
dict=dict()
for i in classNames:
    dict['{}'.format(i)]='absent'

def findEncodings(images):
    encodeList = []

    for img in images:
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        encode = face_recognition.face_encodings(img)[0]
        encodeList.append(encode)
    return encodeList

encodeListKnown = findEncodings(images)
print('Encoding Complete')

cap = cv2.VideoCapture(0)

while True:
    success, img = cap.read()

    imgS = cv2.resize(img, (0, 0), None, 0.25, 0.25)
    imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)

    facesCurFrame = face_recognition.face_locations(imgS)
    encodesCurFrame = face_recognition.face_encodings(imgS, facesCurFrame)

    for encodeFace, faceLoc in zip(encodesCurFrame, facesCurFrame):
        matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
        faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)

        matchIndex = np.argmin(faceDis)

        if matches[matchIndex]:
            name = classNames[matchIndex].upper()
            #print(name)
            if dict[classNames[matchIndex]]=='absent':
                dict[classNames[matchIndex]]='present'
            for i in dict:
                if dict[i] == 'present':
                    date = "".format(datetime.datetime.now().date())
                    time = "{}:{}:{}".format(datetime.datetime.now().hour, datetime.datetime.now().minute,
                                             datetime.datetime.now().second)
                    query = "select * from attendance where name='{}' and attendance='present'".format(i)
                    d = cursor.execute(query)
                    data_new = d.fetchall()
                    if len(data_new) >= 1:
                        pass
                    else:
                        cursor.execute("insert into attendance values('{}','{}','{}','{}')".format(i, dict[i],
                                                                                datetime.datetime.now().date(),
                                                                                time))
                        database.commit()
                        print("successfully stored")
            y1, x2, y2, x1 = faceLoc
            y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4
            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.rectangle(img, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
            cv2.putText(img, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
    cv2.imshow('Webcam', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
print(dict)

cv2.destroyAllWindows()


# SVM model with 4 classes first 10 time bins trimmed dataset
# 10-fold CV of CNN on the dataset with 4 classes
# PVHA, PVLA, NVHA, NVLA,
from __future__ import print_function

import matplotlib

matplotlib.rcParams.update({'font.size': 16})
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report

import pandas as pd
import matplotlib.pyplot as plt
import seaborn.apionly as sns
import numpy as np
from loadData import loadData
from sklearn.svm import SVC
from sklearn.decomposition import PCA
from sklearn.model_selection import KFold
from sklearn.metrics import r2_score, accuracy_score
from sklearn.preprocessing import StandardScaler
import pickle

# Importing the data files
numClasses = 4
if numClasses == 12:
    classNames = ['PVHA_i1', 'PVHA_i2', 'PVHA_i3', 'PVLA_i1', 'PVLA_i2', 'PVLA_i3', 'NVHA_i1', 'NVHA_i2', 'NVHA_i3',
                  'NVLA_i1', 'NVLA_i2', 'NVLA_i3']
else:
    classNames = ['PVHA', 'PVLA', 'NVHA', 'NVLA']

path = 'DATA/DATA_' + str(numClasses) + '/'

(X, y) = loadData(path, numClasses)

X = np.transpose(X, [3, 0, 1, 2])
X.shape

# average over trimmed time
X1 = np.mean(X[:, :, 10:, :], axis=2)

# Extracting beta, lower gamma and higher gamma bands and averaging each separately
temp1 = np.mean(X1[:, 13:30, :], axis=1)
temp2 = np.mean(X1[:, 31:50, :], axis=1)
temp3 = np.mean(X1[:, 51:79, :], axis=1)

X = np.concatenate((temp1, temp2, temp2), axis=1)
print(X.shape)

# parameters
n_classes = 4
nfold = 10
npc = 25
gam = 0.1
C = 100

## 10 fold cross validation with optimal parameters npcs = 25 gamma = 0.1
# Create cross-validation object
kf = KFold(nfold, shuffle=True)

# Create the scaler objects
xscal = StandardScaler()
yscal = StandardScaler()

# Run the cross-validation
rsq = np.zeros(nfold)
acc = np.zeros(nfold)
yhatPerFold = []
ytsPerFold = []
accuracyTrain = []
accuracyVal = []
confusionMatrices = []
reports = []
for ifold, ind in enumerate(kf.split(X)):
    print('Fold = %d' % ifold)
    # Get the training data in the split
    Itr, Its = ind
    Xtr = X[Itr, :]
    ytr = y[Itr]
    Xts = X[Its, :]
    yts = y[Its]

    # Fit and transform the data
    Xtr1 = xscal.fit_transform(Xtr)
    Xts1 = xscal.transform(Xts)

    # Fit PCA on the training data
    pca = PCA(n_components=npc, svd_solver='randomized', whiten=True)
    pca.fit(Xtr1)

    # Transform the training and test
    Ztr = pca.transform(Xtr1)
    Zts = pca.transform(Xts1)

    # Fiting on the transformed training data
    svc = SVC(C=C, kernel='rbf', gamma=gam)
    svc.fit(Ztr, ytr)

    # Predict on the test data
    yhat = svc.predict(Zts)
    yhatPerFold.append(yhat)
    rsq[ifold] = r2_score(yts, yhat)
    acc[ifold] = accuracy_score(yts, yhat)

    print('R^2     = %12.4e' % rsq[ifold])
    print('acc     = %12.4e' % acc[ifold])

    a = classification_report(yts, yhat, target_names=classNames, output_dict=True)
    reports.append(a)
    print("Confusion matrix on the test data")
    cm = confusion_matrix(yts, yhat, labels=range(n_classes))
    print(cm)
    confusionMatrices.append(cm)

acc_mean = []
# Compute mean accuracy
for i in range(nfold):
    acc_mean.append(reports[i]['accuracy'])

# Save history
accSVM_4_fn = ('REPORTS/accuracySVM_4_time_trimmed.p')
with open(accSVM_4_fn, 'wb') as fp:
    pickle.dump(acc_mean, fp)

reports_4_fn = ('REPORTS/reportsSVM_4_time_trimmed.p')
with open(reports_4_fn, 'wb') as fp:
    pickle.dump(reports, fp)

confusionMatrices_4_fn = ('REPORTS/confusionMatricesSVM_4_time_trimmed.p')
with open(confusionMatrices_4_fn, 'wb') as fp:
    pickle.dump(confusionMatrices, fp)

with plt.style.context("default"):
    plt.figure(figsize=(8, 6))
    plt.plot(np.linspace(1, 10, 10), acc_mean, label='accuracy')
    plt.xlabel('folds')
    plt.ylabel('accuracy')
    plt.title("Accuracy for each fold", fontsize=18)
    plt.legend()
    plt.xlim([0.5, 10.5])
    plt.ylim([0.4, 1.0])
    plt.xticks(np.arange(1, 10.5, step=1))
    plt.grid()
    plt.savefig('FIGURES/accuracy_svm_10fold_4_classes_time_trimmed.pdf')

# normalize confusion matrices
normalizedAvgCM = np.zeros((n_classes, n_classes))
for i in range(len(confusionMatrices)):
    cm = confusionMatrices[i]
    normalizedAvgCM += cm / cm.astype(np.float).sum(axis=1)

normalizedAvgCM = normalizedAvgCM / nfold

# plot one time prediction confusion matrix
df_cm = pd.DataFrame(normalizedAvgCM, index=classNames, columns=classNames)
plt.figure(figsize=(9.6, 4.1))  # 5.7
sns.set(font_scale=1.4)  # for label size
ax = sns.heatmap(df_cm, cbar_kws={'ticks': [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]}, vmin=0, vmax=1.0,
                 annot=True, annot_kws={"size": 18}, fmt='2.2f', cmap="Blues")  # font size
bottom, top = ax.get_ylim()
ax.set_ylim(bottom + 0.5, top - 0.5)
ax.set_ylim(sorted(ax.get_xlim(), reverse=True))
ax.set_yticklabels(classNames, rotation=0, fontsize="16", va="center")
ax.set_xticklabels(classNames, rotation=0, fontsize="16", ha="center")
plt.tight_layout()
plt.savefig('FIGURES/normCM_svm_10fold_4_classes_time_trimmed.pdf')

# print performance metrics after 10 fold CV
avgPrecision = np.zeros(numClasses)
avgRecall = np.zeros(numClasses)
avgF1 = np.zeros(numClasses)
classes = list(reports[0].keys())[0:numClasses]
for clIdx in range(len(classes)):
    tmpPrecision = []
    tmpRecall = []
    tmpF1 = []

    for f in range(nfold):
        tmpPrecision.append(reports[f][classes[clIdx]]['precision'])
        tmpRecall.append(reports[f][classes[clIdx]]['recall'])
        tmpF1.append(reports[f][classes[clIdx]]['f1-score'])

    avgPrecision[clIdx] = np.mean(tmpPrecision)
    avgRecall[clIdx] = np.mean(tmpRecall)
    avgF1[clIdx] = np.mean(tmpF1)
print(np.mean(acc_mean))
print(np.mean(avgPrecision))
print(np.mean(avgRecall))
print(np.mean(avgF1))


import discord
from discord.ext import commands

class Edit:

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

    @commands.command()
    async def edit(self, ctx, *, username: str):
        await self.bot.user.edit(username=username)
        await ctx.send(f'Changed username to {username}.')

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


"""
old_api.py: adapter for nengo_theano and [Jython] nengo-1.4

The purpose of this emulation layer is to run scripts and tests that were
written for nengo-1.4 and theano_nengo. Authors are encouraged to use
`nengo.Model` directly instead of this file for their current work.

"""

import logging
import random

import numpy as np

from . import Model
from . import LIF
from .templates.ensemble_array import EnsembleArray

logger = logging.getLogger(__name__)

class Network(object):
    def __init__(self, *args, **kwargs):
        self.model = Model(*args, **kwargs)

    @property
    def dt(self):
        return self.model.dt

    def make_input(self, name, value):
        return self.model.make_node(name, value)

    def make_array(self, name, neurons, array_size, dimensions=1, **kwargs):
        """Generate a network array specifically.

        This function is deprecated; use for legacy code
        or non-theano API compatibility.

        """
        return self.make(
            name=name, neurons=neurons, dimensions=dimensions,
            array_size=array_size, **kwargs)

    def make(self, name, neurons, array_size, dimensions=1, **kwargs):
        if 'neuron_type' in kwargs:
            if kwargs['neuron_type'].lower() == 'lif':
                neurons = LIF(neurons)
            else:
                raise ValueError("Only LIF supported")
            del kwargs['neuron_type']
        else:
            neurons = LIF(neurons)
        return self.model.add(EnsembleArray(
            name, neurons, array_size, dimensions, **kwargs))

    def connect(self, name1, name2, func=None, pstc=0.005, **kwargs):
        if func is not None:
            kwargs['function'] = func
        return self.model.connect(name1, name2, filter=pstc, **kwargs)

    def make_probe(self, name, dt_sample, pstc):
        return self.model.probe(name, dt_sample, pstc)

    def run(self, simtime, **kwargs):
        netcopy = Network()
        netcopy.model = self.model.run(simtime, **kwargs)
        return netcopy


from . import Simulate
from ..Controls import VehicleClosedLoopControl
from ..Containers.Controls import referenceCommands
from ece163.Controls.VehicleTrim import VehicleTrim
from ..Constants import VehiclePhysicalConstants

class Chapter6Simulate(Simulate.Simulate):
	def __init__(self):
		super().__init__()
		self.inputNames.extend(['commandedCourse', 'commandedAltitude', 'commandedAirspeed'])
		self.underlyingModel = VehicleClosedLoopControl.VehicleClosedLoopControl()

		# self.variableList.append((self.underlyingModel.getForcesMoments, 'ForceMoments',
		# 							['Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz']))

		self.variableList.append((self.underlyingModel.getVehicleState, 'state',
									['pn', 'pe', 'pd', 'yaw', 'pitch', 'roll', 'u', 'v', 'w', 'p', 'q', 'r', 'Va', 'alpha', 'beta', 'chi']))
		# self.dT = 1/50

		self.referenceInput = referenceCommands()

	def getVehicleState(self):
		return self.underlyingModel.getVehicleState()

	def takeStep(self, referenceInput=None):
		self.time += VehiclePhysicalConstants.dT
		if referenceInput is None:
			referenceInput = self.referenceInput
		self.underlyingModel.Update(referenceInput)
		self.recordData([referenceInput.commandedCourse, referenceInput.commandedAltitude, referenceInput.commandedAirspeed])
		return

	def reset(self):
		self.time = 0
		self.underlyingModel.reset()
		self.takenData.clear()


import numpy as np

def svenn(f, x0, S0, delta_param):
    x = np.array([x0])
    S = np.array([S0])

    lambd = [0]
    delta =  delta_param * np.linalg.norm(x[0]) / np.linalg.norm(S[0])

    #choose direction and find first value
    f1 = f(x[0] + (lambd[0] - delta) * S[0])
    f2 = f(x[0] + lambd[0] * S[0])
    f3 = f(x[0] + (lambd[0] + delta) * S[0])

    f_values = [f2]

    if f1 >= f2 >= f3:
        delta = delta
        lambd.append(lambd[0] + delta)
        f_values.append(f3)
    elif f1 <= f2 <= f3:
        delta = - delta
        lambd.append(lambd[0] + delta)
        f_values.append(f1)
    elif f1 >= f2 <= f3:
        a = lambd[0] - delta
        b = lambd[0] + delta
        f_values.append(f1)
        f_values.append(f3)
        return a, b
    else:
        print('Function is not unimodal')

    x = np.append(x, [x[0] + lambd[1] * S[0]], axis=0)

    #find all other values except first and last
    i = 1
    while f_values[i] <= f_values[i - 1]:
        lambd.append(lambd[i] + (2 ** i) * delta)
        x = np.append(x, [x[0] + lambd[i + 1] * S[0]], axis=0)
        f_values.append(f(x[0] + lambd[i + 1] * S[0]))
        i += 1

    #find last value
    lambd.append(lambd[i - 1] + (lambd[i] - lambd[i - 1]) / 2)
    x = np.append(x, [x[0] + lambd[i + 1] * S[0]], axis=0)
    f_values.append(f(x[0] + lambd[i + 1] * S[0]))

    #sort lambdas
    lambda_and_f = dict(zip(lambd, f_values))
    lambda_sorted = sorted(lambda_and_f)
    f_values_sorted = []
    for key in lambda_sorted:
        f_values_sorted.append(lambda_and_f[key])

    m = min(f_values_sorted)
    a = lambda_sorted[f_values_sorted.index(m) - 1]
    b = lambda_sorted[f_values_sorted.index(m) + 1]

    return a, b

def golden_ratio(f, a, b, x0, S0, epsilon):

    x = np.array([x0])
    S = np.array([S0])
    L = b - a

    x1 = a + 0.382 * L
    x2 = a + 0.618 * L

    f1 = f(x[0] + x1 * S[0])
    f2 = f(x[0] + x2 * S[0])

    while L >= epsilon:
        if f1 <= f2:
            a = a
            b = x2
            L = b - a
            x2 = x1
            f2 = f1
            x1 = a + 0.382 * L
            f1 = f(x[0] + x1 * S[0])
        elif f1 >= f2:
            a = x1
            b = b
            L = b - a
            x1 = x2
            f1 = f2
            x2 = a + 0.618 * L
            f2 = f(x[0] + x2 * S[0])

    lambda_top = (a + b) / 2
    return lambda_top

def dsk_powell(f, a, b, xw, S0, epsilon):
    xq = np.array([xw])
    S = np.array([S0])
    x1 = a
    x2 = (a + b) / 2
    x3 = b

    f1 = f(xq[0] + x1 * S[0])
    f2 = f(xq[0] + x2 * S[0])
    f3 = f(xq[0] + x3 * S[0])

    x_star = x2 + (abs(x2 - x1) * (f1 - f3) / (2 * (f1 - 2 * f2 + f3)))
    f_star = f(xq[0] + x_star * S[0])

    x = [x1, x2, x_star, x3]
    f_values = [f1, f2, f_star, f3]

    x_and_f = dict(zip(x, f_values))
    x_sorted = sorted(x_and_f)
    f_values_sorted = []
    for key in x_sorted:
        f_values_sorted.append(x_and_f[key])

    x_min = x2
    f_min = f_values_sorted[x_sorted.index(x2)]
    f_star = f_values_sorted[x_sorted.index(x_star)]

    while abs(x_min - x_star) >= epsilon and abs(f_min - f_star) >= epsilon:

        f_min = min(f_values_sorted)

        x1 = x_sorted[f_values_sorted.index(f_min) - 1]
        x2 = x_sorted[f_values_sorted.index(f_min)]
        x3 = x_sorted[f_values_sorted.index(f_min) + 1]
        x_min = x2
        f1 = f_values_sorted[f_values_sorted.index(f_min) - 1]
        f2 = f_min
        f3 = f_values_sorted[f_values_sorted.index(f_min) + 1]

        if abs(x3 - x2) == abs(x2 - x1):
            x_star = x2 + (abs(x2 - x1) * (f3 - f1)) / (2 * (f1 - 2 * f2 + f3))
        else:
            a1 = (f2 - f1) / (x2 - x1)
            a2 = (1 / (x3 - x2)) * ((f3 - f1) / (x3 - x1) - (f2 - f1) / (x2 - x1))
            x_star = ((x1 + x2) / 2) - (a1 / (2 * a2))

        if abs(x_min - x_star) >= epsilon:
            f_star = f(xq[0] + x_star * S[0])
        else: f_star = f2

        x = [x1, x2, x_star, x3]
        f_values = [f1, f2, f_star, f3]

        x_and_f = dict(zip(x, f_values))
        x_sorted = sorted(x_and_f)
        f_values_sorted = []
        for key in x_sorted:
            f_values_sorted.append(x_and_f[key])

    return x_star


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import networkx as nx
from parse import *
from utils  import *
from pulp import *
from math import comb

graph, budget = read_input_file("inputs/small/small-1.in")
pos = nx.kamada_kawai_layout(graph)  # positions for all nodes
nx.draw(graph, pos, with_labels=True)
prob = LpProblem("proj",LpMaximize)

inputs = pd.read_csv("inputs/small/small-1.in", header = None)
n = int(list(inputs[0])[0])
s_max = float(list(inputs[0])[1])
K = 3

# Parsing input data
df = inputs
df = pd.DataFrame([x.split() for x in df[0].tolist() ])
df = df.loc[2:,:]
df["i"] = df.loc[:,0]
df["j"] = df.loc[:,1]
df["sadness"] = df.loc[:,3]
df["happiness"] = df.loc[:,2]
df = df[["i", "j", "sadness", "happiness"]]
i_id = [int(i) for i in list(df["i"])]
j_id = [int(i) for i in list(df["j"])]
sadness = [float(i) for i in list(df["sadness"])]*K
happiness = [float(i) for i in list(df["happiness"])]*K

sadness_1 = [float(i) for i in list(df["sadness"])]
happiness_1 = [float(i) for i in list(df["happiness"])]
len(sadness) == len(happiness)

prob = LpProblem("solver",LpMaximize)

# edges
d_e = {}
for k in range(K):
    for i in range(comb(n,2)):
        d_e["e_{0}_{1}_{2}".format(i_id[i],j_id[i],k)] = LpVariable("e_{0}_{1}_{2}".format(i_id[i],j_id[i],k), cat="Binary")
edges_1 = list(d_e.values())

# Create another edge array with different sort
edges_2 = [d_e.get(i) for i in sorted(d_e.keys(), key=lambda x: (x[2], x[4]))]

# Create another edge array for constraint 4
edges_3 = [d_e.get(i) for i in sorted(d_e.keys(), key=lambda x: (x[2], x[6]))]

# Check
len(edges_1) == comb(n,2)*K

# vertices
d_v = {}
for j in range(K):
    for i in range(n):
        d_v["v_{0}_{1}".format(i,j)] = LpVariable("v_{0}_{1}".format(i,j), cat="Binary")
vertices_1 = list(d_v.values())

# Create another edge array with different sort
vertices_2 = [d_v.get(i) for i in sorted(d_v.keys(), key=lambda x: x[2])]

# Check
len(vertices_1) == n*K

# Linearization of quadratic variables 1
v_list = np.array(np.array_split(vertices_1, K)).tolist()
v_big = []
for i in range(K):
    j = 0
    while j != n:
        for _ in range(j,n-1):
            v_big.append(v_list[i][j])
        j += 1

print(len(edges_1) == len(v_big))

# Linearization of quadratic variables 2
v_list_2 = [i[1:] for i in v_list]
v_big_2 = []
for h in range(K):
    j = 0
    while j != n:
        for i in range(j,n-1):
            v_big_2.append(v_list_2[h][i])
        j += 1
        i = j
print(len(edges_1) == len(v_big_2))

##LP Solver
# Objective function
prob += sum(edges_1[i] * happiness[i] for i in range(len(happiness)))

# Constraint 1
# Each rooms has sadness levels <= s_max / K
aa = []
h = 0
for i in range(K):
    for j in range(comb(n,2)):
        aa.append(edges_1[h] * sadness_1[j])
        h += 1
constraint_2 = [sum(aa[i:i+ comb(n,2)]) for i in range(0, len(aa), comb(n,2))]
for i in range(len(constraint_2)):
    prob += constraint_2[i] <= s_max / K
# Constraint 2
# Each person belongs to only one room
constraint_3 = [sum(vertices_2[i:i + K]) for i in range(0, len(vertices_2), K)]
for i in range(len(constraint_3)):
    prob += constraint_3[i] == 1
# Linearization of quadratic variables
# Constraint 3.1
for i in range(len(edges_1)):
    prob += edges_1[i] <= v_big[i]
# Constraint 3.2
for i in range(len(edges_1)):
    prob += edges_1[i] <= v_big_2[i]
# Constraint 3.3
for i in range(len(edges_1)):
    prob += edges_1[i] >= v_big[i] + v_big_2[i] - 1

prob.solve()

variables = [v.varValue for v in prob.variables()[len(prob.variables()) - n*K : len(prob.variables())]]
locations = list(np.mod(np.nonzero(variables)[0], K))
output_dict = dict(list(enumerate(locations)))
print(output_dict)
print(is_valid_solution(output_dict, graph, s_max, K))
# write_output_file(output_dict, "path")


import socket
# Simple Strings are printed by using ord() -> ordinal
# It tells the numeric value of of a ASCII character
# ASCII is a type of number reference to a single character

# print(ord('G'))

# Everything in Python is Unicode

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80))
cmd = 'GET http://data.pr4e.org/intro-short.txt HTTP/1.0\r\n\r\n'.encode()  # Encodes everything (unicode) to bytes
# or UTF8 and sends
mysock.send(cmd)

while True:
    data = mysock.recv(512)
    if len(data) < 1:
        break
    print(data.decode())  # Decodes the bytes/UTF8 into UTF8
mysock.close()


from . import main
from flask import current_app, make_response, request, render_template, flash, redirect, url_for, session
from datetime import datetime
from .forms import NameForm, EditProfileForm, EditProfileAdminForm, PostForm, CommentForm
from .. import db
from flask.ext.sqlalchemy import get_debug_queries
from ..models import Permission, Role, User, Post, Comment, Blog
from flask.ext.login import login_required, current_user
# Requiring permissions
from ..decorators import admin_required, permission_required

# Routes
@main.route('/', methods=['GET', 'POST'])
def index():
    if current_user.is_authenticated():
        form = PostForm()
        if current_user.can(Permission.WRITE_ARTICLES) and \
           form.validate_on_submit():
            post = Post(body=form.body.data,
                        author=current_user._get_current_object())
            db.session.add(post)
            return redirect(url_for('.index'))
        page = request.args.get('page', 1, type=int)
        show_followed = False
        if current_user.is_authenticated():
            show_followed = bool(request.cookies.get('show_followed', ''))
        if show_followed:
            query = current_user.followed_posts
        else:
            query = Post.query
        pagination = query.order_by(Post.timestamp.desc()).paginate(
            page, per_page=current_app.config['NETWORK_POSTS_PER_PAGE'],
            error_out=False)
        posts = pagination.items
        return render_template('main/index.html', user=user, form=form, posts=posts,
                           show_followed=show_followed, pagination=pagination)
    else:
        return redirect(url_for('auth.login'))

# Example 10-4. app/main/views.py: Profile page route
# Example 11-5. app/main/views.py: Profile page route with blog posts

@main.route('/user/<username>')
def user(username):
    user = User.query.filter_by(username=username).first_or_404()
    posts = user.posts.order_by(Post.timestamp.desc()).all()
    blogs = user.blogs.order_by(Blog.timestamp.desc()).all()
    return render_template('main/user.html', user=user, posts=posts ,blogs=blogs)

# Example 10-8. app/main/views.py: Profile edit route
@main.route('/edit-profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
    form = EditProfileForm()
    if form.validate_on_submit():
        current_user.name = form.name.data
        current_user.location = form.location.data
        current_user.about_me = form.about_me.data
        db.session.add(current_user)
        flash('Your profile has been updated.')
        return redirect(url_for('.user', username=current_user.username))
    form.name.data = current_user.name
    form.location.data = current_user.location
    form.about_me.data = current_user.about_me
    return render_template('main/edit_profile.html', form=form)

# Example 10-11. app/main/views.py: Profile edit route for administrators
@main.route('/edit-profile/<int:id>', methods=['GET', 'POST'])
@login_required
@admin_required
def edit_profile_admin(id):
    user = User.query.get_or_404(id)
    form = EditProfileAdminForm(user=user)
    if form.validate_on_submit():
        user.email = form.email.data
        user.username = form.username.data
        user.confirmed = form.confirmed.data
        user.role = Role.query.get(form.role.data)
        user.name = form.name.data
        user.location = form.location.data
        user.about_me = form.about_me.data
        db.session.add(user)
        flash('The profile has been updated.')
        return redirect(url_for('.user', username=user.username))
    form.email.data = user.email
    form.username.data = user.username
    form.confirmed.data = user.confirmed
    form.role.data = user.role_id
    form.name.data = user.name
    form.location.data = user.location
    form.about_me.data = user.about_me
    return render_template('main/edit_profile.html', form=form, user=user)

@main.route('/post/<int:id>', methods=['GET', 'POST'])
def post(id):
    post = Post.query.get_or_404(id)
    form = CommentForm()
    if form.validate_on_submit():
        comment = Comment(body=form.body.data,
                          post=post,
                          author=current_user._get_current_object())
        db.session.add(comment)
        flash('Your comment has been published.')
        return redirect(url_for('.post', id=post.id, page=-1))
    page = request.args.get('page', 1, type=int)
    if page == -1:
        page = (post.comments.count() - 1) / \
            current_app.config['NETWORK_COMMENTS_PER_PAGE'] + 1
    pagination = post.comments.order_by(Comment.timestamp.asc()).paginate(
        page, per_page=current_app.config['NETWORK_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('main/posts.html', posts=[post], form=form,
                           comments=comments, pagination=pagination)

@main.route('/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit(id):
    post = Post.query.get_or_404(id)
    if current_user != post.author and \
            not current_user.can(Permission.ADMINISTER):
        abort(403)
    form = PostForm()
    if form.validate_on_submit():
        post.body = form.body.data
        db.session.add(post)
        flash('The post has been updated.')
        return redirect(url_for('.post', id=post.id))
    form.body.data = post.body
    return render_template('main/edit_post.html', form=form)

@main.route('/follow/<username>')
@login_required
@permission_required(Permission.FOLLOW)
def follow(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    if current_user.is_following(user):
        flash('You are already following this user.')
        return redirect(url_for('.user', username=username))
    current_user.follow(user)
    flash('You are now following %s.' % username)
    return redirect(url_for('.user', username=username))

@main.route('/unfollow/<username>')
@login_required
@permission_required(Permission.FOLLOW)
def unfollow(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    if not current_user.is_following(user):
        flash('You are not following this user.')
        return redirect(url_for('.user', username=username))
    current_user.unfollow(user)
    flash('You are not following %s anymore.' % username)
    return redirect(url_for('.user', username=username))

@main.route('/followers/<username>')
def followers(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    page = request.args.get('page', 1, type=int)
    pagination = user.followers.paginate(
        page, per_page=current_app.config['NETWORK_FOLLOWERS_PER_PAGE'],
        error_out=False)
    follows = [{'user': item.follower, 'timestamp': item.timestamp}
               for item in pagination.items]
    return render_template('_includes/followers.html', user=user, title="Followers of",
                           endpoint='.followers', pagination=pagination,
                           follows=follows)

@main.route('/followed-by/<username>')
def followed_by(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        flash('Invalid user.')
        return redirect(url_for('.index'))
    page = request.args.get('page', 1, type=int)
    pagination = user.followed.paginate(
        page, per_page=current_app.config['NETWORK_FOLLOWERS_PER_PAGE'],
        error_out=False)
    follows = [{'user': item.followed, 'timestamp': item.timestamp}
               for item in pagination.items]
    return render_template('_includes/followers.html', user=user, title="Followed by",
                           endpoint='.followed_by', pagination=pagination,
                           follows=follows)
@main.route('/all')
@login_required
def show_all():
    resp = make_response(redirect(url_for('.index')))
    resp.set_cookie('show_followed', '', max_age=30*24*60*60)
    return resp

@main.route('/followed')
@login_required
def show_followed():
    resp = make_response(redirect(url_for('.index')))
    resp.set_cookie('show_followed', '1', max_age=30*24*60*60)
    return resp

@main.route('/moderate')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate():
    page = request.args.get('page', 1, type=int)
    pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate(
        page, per_page=current_app.config['NETWORK_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('main/moderate.html', comments=comments,
                           pagination=pagination, page=page)

@main.route('/moderate/enable/<int:id>')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate_enable(id):
    comment = Comment.query.get_or_404(id)
    comment.disabled = False
    db.session.add(comment)
    return redirect(url_for('.moderate',
                            page=request.args.get('page', 1, type=int)))

@main.route('/moderate/disable/<int:id>')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate_disable(id):
    comment = Comment.query.get_or_404(id)
    comment.disabled = True
    db.session.add(comment)
    return redirect(url_for('.moderate',
                            page=request.args.get('page', 1, type=int)))

# Adding method to delete a comment
@main.route('/comment/delete/<int:id>')
@login_required
def delete_comment(id):
    comment = Comment.query.get_or_404(id)
    comment_post_id = comment.post_id
    if current_user.id != comment.author_id and \
            not current_user.can(Permission.ADMINISTER):
        abort(403)
    db.session.delete(comment)
    flash('Your comment has been deleted.')
    return redirect(url_for('.post', id=comment_post_id, page=1))

# Method for editing a comment
@main.route('/comment/edit/<int:id>', methods=['GET', 'POST'])
@login_required
def edit_comment(id):
    comment = Comment.query.get_or_404(id)
    comment_post_id = comment.post_id
    post = Post.query.filter_by(id=comment_post_id).first_or_404()
    if current_user.id != comment.author_id and \
            not current_user.can(Permission.ADMINISTER):
        abort(403)
    form = CommentForm()
    if form.validate_on_submit():
        comment = Comment(body=form.body.data,
                          post_id=post.id,
                          author=current_user._get_current_object())
        db.session.add(comment)
        flash('Your comment has been updated.')
        return redirect(url_for('.post', id=comment_post_id, page=1))
    form.body.data = comment.body
    return render_template('main/posts.html', form=form)


import numpy as np
import cv2

train_path = "D:/github/MachineLearning/Supervised/training_set/"
test_path = "D:/github/MachineLearning/Supervised/testing_set/"

def LoadTxtData(path, file_name):
    data = np.loadtxt(path + file_name + ".txt")
    return data

def ResizeImg(img, row_size, col_size):
    img = cv2.resize(img, (row_size, col_size))
    return img

def ComputeAccuracy(est_out, true_out):
    return (100 - np.mean(np.abs(true_out - est_out))*100)

class LogisticRegression:

    def GetNNInput(self, img):

        img_flatten = img.reshape(img.shape[0], -1).T
        img_flatten = img_flatten/255.

        return img_flatten

    def InitializeParams(self, nn_in_size, nn_out_size):
        w = np.random.randn(nn_out_size, nn_in_size)*0.01
        b = np.zeros((nn_out_size, 1))

        return w, b

    def PropagateForward(self, input, w, b):

        #linear output
        z = np.matmul(w, input) + b

        #non - linear output
        out = self.Sigmoid(z)

        return out

    def ComputeCost(self, nn_out, true_result, nn_train_size):

        cost = -(1/nn_train_size)*np.sum(true_result*np.log(nn_out) + (1 - true_result)*np.log(1 - nn_out))
        return cost

    def PropagateBackward(self, nn_in, nn_out, true_result, nn_train_size):

        dw = (1/nn_train_size)*np.matmul(nn_in, (nn_out - true_result).T).T
        db = (1/nn_train_size)*np.sum(nn_out - true_result, axis = 1, keepdims = True)
        db = np.squeeze(db)

        return dw, db

    def Sigmoid(self, input):
        out = 1/(1 + np.exp(-input))
        return out

    def Optimize(self, nn_in, y_train, learning_rate, num_of_iteration, nn_in_size, nn_train_size, nn_out_size):

        w, b = self.InitializeParams(nn_in.shape[0], nn_out_size)
        if __debug__:
            assert(w.shape == (nn_out_size, nn_in_size))
            assert(b.shape == (nn_out_size, 1))

        for i in range(num_of_iteration):
            nn_out = self.PropagateForward(nn_in, w, b)

            if __debug__:
                assert(nn_out.shape == (1, nn_train_size))

            cost = self.ComputeCost(nn_out, y_train, nn_train_size)

            dw, db = self.PropagateBackward(nn_in, nn_out, y_train, nn_train_size)

            if __debug__:
                assert(dw.shape == w.shape)
                assert(db.dtype == float)

            w = w - learning_rate*dw
            b = b - learning_rate*db

            if (i % 10 == 0):
                print("iteration " + str(i) + ": " + "cost: ", cost)

        return w, b, cost

    def Predict(self, nn_in, w, b, sample_size, binary_threshold):

        z = np.matmul(w, nn_in) + b
        nn_out = self.Sigmoid(z)

        prediction = np.zeros((1, sample_size))

        for i in range(sample_size):
            if (nn_out[0, i] > binary_threshold):
                prediction[0, i] = 1
            else:
                prediction[0, i] = 0

        return prediction

def main():

    #hyper parameter setting
    nn_in_size = 64*64*3
    nn_out_size = 1
    nn_train_size = 19
    nn_test_size = 19
    num_of_iteration = 500
    learning_rate = 0.009
    img_rows = 64
    img_cols = 64
    img_channels = 3
    binary_threshold = 0.5

    lrg = LogisticRegression()

    #load training and testing output
    y_train = LoadTxtData(train_path, "y_train")
    y_test = LoadTxtData(test_path, "y_test")

    #load training image and resize to be 64, 64, 3
    standard_img = np.zeros((nn_train_size, img_rows, img_cols, img_channels))
    for i in range(1, 20):
        file_path = train_path + str(i) + ".jpg"
        raw_img = cv2.imread(file_path)
        standard_img[i - 1,:,:,:] = ResizeImg(raw_img, img_rows, img_cols)

    #start training
    nn_train_in = lrg.GetNNInput(standard_img)
    if __debug__:
        assert(nn_train_in.shape == (nn_in_size, nn_train_size))

    w, b, cost = lrg.Optimize(nn_train_in, y_train, learning_rate, num_of_iteration, nn_in_size, nn_train_size, nn_out_size)

    #check training accuracy
    nn_train_predict = lrg.Predict(nn_train_in, w, b, nn_train_size, binary_threshold)
    print("train prediction: ", nn_train_predict)
    print("train ground truth: ", y_train)
    print("accuracy: ", ComputeAccuracy(nn_train_predict, y_train))

    #load testing image and resize to be 64, 64, 3
    standard_img = np.zeros((nn_test_size, img_rows, img_cols, img_channels))
    for i in range(1, 20):
        file_path = test_path + str(i) + ".jpg"
        raw_img = cv2.imread(file_path)
        standard_img[i - 1,:,:,:] = ResizeImg(raw_img, img_rows, img_cols)

    nn_test_in = lrg.GetNNInput(standard_img)
    if __debug__:
        assert(nn_test_in.shape == (nn_in_size, nn_test_size))

    #check testing accuracy
    nn_test_predict = lrg.Predict(nn_test_in, w, b, nn_test_size, binary_threshold)
    print("test prediction: ", nn_test_predict)
    print("test ground truth: ", y_test)
    print("accuracy: ", ComputeAccuracy(nn_test_predict, y_test))

if __name__ == '__main__':
    main()


#
# Copyright (c) 2017, Prometheus Research, LLC
#

from rex.asynctask import WorkerConfigVal
from rex.core import Initialize, get_settings

from .workers import JobExecutorWorker

__all__ = (
    'JobInitialize',
)

class JobInitialize(Initialize):
    @classmethod
    def signature(cls):  # pragma: no cover
        return 'job'

    def __call__(self):
        # Set up however many queues we're configured to use.
        config = WorkerConfigVal([JobExecutorWorker.name])
        for i in range(get_settings().job_queues):
            get_settings().asynctask_workers['rex_job_%s' % i] = config(
                JobExecutorWorker.name
            )


from SPARQLWrapper import SPARQLWrapper, JSON
from requests import get
import numpy as np
import math
import json

__data_file_path = '/Users/timoon/Projects/spbstu-is/simple-recommendation-system/data.csv'
__day_context_file_path = '/Users/timoon/Projects/spbstu-is/simple-recommendation-system/context_day.csv'
__place_context_file_path = '/Users/timoon/Projects/spbstu-is/simple-recommendation-system/context_place.csv'

def getUserMovieMarkData():
    return np.genfromtxt(__data_file_path, delimiter=',', dtype=int, skip_header=1, usecols=(np.arange(1, 31, 1)))

def getUserMovieDayContextData():
    return np.genfromtxt(__day_context_file_path, delimiter=',', dtype=str, skip_header=1, usecols=(np.arange(1, 31, 1)))

def getUserMoviePlaceContextData():
    return np.genfromtxt(__place_context_file_path, delimiter=',', dtype=str, skip_header=1, usecols=(np.arange(1, 31, 1)))

def findCompareapleUsers(target_user_id):
    data = getUserMovieMarkData()

    target_user_marks = data[target_user_id]
    similarity = []

    for user_id, user_marks in enumerate(data):
        if user_id != target_user_id:
            target_user_sqr_sum = 0
            current_user_sqr_sum = 0
            compared_users_sum = 0

            for mark_id, mark in enumerate(user_marks):
                if target_user_marks[mark_id] != -1 and mark != -1:
                    target_user_sqr_sum += target_user_marks[mark_id] * target_user_marks[mark_id]
                    current_user_sqr_sum += mark * mark
                    compared_users_sum += target_user_marks[mark_id] * mark

            similarity_value = compared_users_sum / (math.sqrt(current_user_sqr_sum) * math.sqrt(target_user_sqr_sum))
            similarity.append((user_id, similarity_value))

    dtype = [('user_id', int), ('similarity_value', float)]
    arr_sim = np.array(similarity, dtype=dtype)
    sorted_sim = np.sort(arr_sim, order='similarity_value')
    return sorted_sim[-7:]

def processUserRatings(target_user_id):
    real_target_id = target_user_id - 1
    relevant_users = findCompareapleUsers(real_target_id)
    data = getUserMovieMarkData()

    target_user_avg_mark = my_avg(data[real_target_id])

    relevant_users_avg_mark = []

    for user in relevant_users:
        relevant_users_avg_mark.append(my_avg(data[user[0]]))

    processed_target_user_marks = []

    for movie_id in np.arange(0, 30, 1):
        if data[real_target_id][movie_id] == -1:
            sim_sum = 0
            pure_sim_sum = 0

            for relevant_id, user in enumerate(relevant_users):
                if data[user[0]][movie_id] != -1:
                    sim_sum += user[1] * (data[user[0]][movie_id] - relevant_users_avg_mark[relevant_id])
                    pure_sim_sum += user[1]

            processed_target_user_marks.append((movie_id + 1, target_user_avg_mark + (sim_sum / pure_sim_sum)))

    return np.round(processed_target_user_marks, 3)

def dayContextValue(movie_ids):
    mark_data = getUserMovieMarkData()
    day_context_data = getUserMovieDayContextData()

    movie_day_param = []

    for movie in movie_ids:
        movie_marks = np.array([], dtype=int)
        movie_holiday_marks = np.array([], dtype=int)

        for user_id, user_marks in enumerate(mark_data):
            if user_marks[int(movie[0]) - 1] != -1:
                movie_marks = np.append(movie_marks, user_marks[int(movie[0]) - 1])
                if day_context_data[user_id][int(movie[0]) - 1].lstrip() == 'Sat' or day_context_data[user_id][int(movie[0]) - 1].lstrip() == 'Sun':
                    movie_holiday_marks = np.append(movie_holiday_marks, user_marks[int(movie[0]) - 1])

        movie_day_param.append((int(movie[0]), np.divide(np.average(movie_marks), np.average(movie_holiday_marks))))

    return movie_day_param

def placeContextValue(movie_ids):
    mark_data = getUserMovieMarkData()
    place_context_data = getUserMoviePlaceContextData()

    movie_place_param = []

    for movie in movie_ids:
        movie_marks = np.array([], dtype=int)
        movie_home_marks = np.array([], dtype=int)

        for user_id, user_marks in enumerate(mark_data):
            if user_marks[int(movie[0]) - 1] != -1:
                movie_marks = np.append(movie_marks, user_marks[int(movie[0]) - 1])
                if place_context_data[user_id][int(movie[0]) - 1].lstrip() == 'h' or place_context_data[user_id][int(movie[0]) - 1].lstrip() == 'v':
                    movie_home_marks = np.append(movie_home_marks, user_marks[int(movie[0]) - 1])

        movie_place_param.append((int(movie[0]), np.divide(np.average(movie_marks), np.average(movie_home_marks))))

    return movie_place_param

def my_avg(lst):
    sumer = 0
    cnt = 0
    for val in lst:
        if val != -1:
            sumer += val
            cnt += 1

    return sumer / cnt

def personalRecommendation(target_user):
    unseen_movie_processed_ratings = processUserRatings(target_user)
    movie_place_val = placeContextValue(unseen_movie_processed_ratings)
    movie_holiday_val = dayContextValue(unseen_movie_processed_ratings)

    recommendation_ratings = []
    for rating_id, val in enumerate(unseen_movie_processed_ratings):
        recommendation_ratings.append((int(val[0]), val[1] * movie_place_val[rating_id][1] * movie_holiday_val[rating_id][1]))

    recommendations = np.array(recommendation_ratings, dtype=[('movie_id', int), ('similarity_value', float)])
    sorted = np.sort(recommendations, order='similarity_value')

    return sorted[-1]

def saveAnsvers(target_user):
    user_id = target_user
    recommendation = personalRecommendation(target_user)

    res_obj = {
        'user': target_user,
        '1': {

        }
    }

    for val in processUserRatings(target_user):
        res_obj['1']['movie ' + str(int(val[0]))] = val[1]

    res_obj['2'] = {
        'movie ' + str(recommendation[0]): np.round(recommendation[1], 3)
    }

    with open('/Users/timoon/Projects/spbstu-is/simple-recommendation-system/results.json', 'w') as file:
        json.dump(res_obj, file)
        file.close()

# My film 'id'
movie_id = 'Movie ' + str(personalRecommendation(1)[0])

# I get film name by id from file
__data_file_path = 'movie_names.csv'
movie_names = np.genfromtxt(__data_file_path, delimiter=',', dtype=str, skip_header=0, usecols=(np.arange(1, 1, 1)))
movie_name = movie_names[np.where(movie_names[:,0]==movie_id)][0][1].strip()

# Ask api for Q by provided name
resp = get('https://www.wikidata.org/w/api.php', {
        'action': 'wbgetentities',
        'titles': movie_name,
        'sites': 'enwiki',
        'props': '',
        'format': 'json'
    }).json()

wikiMovieCode = list(resp['entities'])[0]

# Prepare request to wikidata
sparql = SPARQLWrapper("https://query.wikidata.org/sparql")
sparql.setQuery(
"""
SELECT DISTINCT ?human ?humanLabel ?picture

WHERE {
?human wdt:P31 wd:Q5.
?human wdt:P106 wd:Q33999.

?human wdt:P18 ?picture.

wd:""" + wikiMovieCode + """ wdt:P161 ?human.

?human wdt:P569 ?date.
wd:""" + wikiMovieCode + """ wdt:P577 ?dateFilm.

FILTER (YEAR(?dateFilm) - YEAR(?date) > 40)

SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
"""
)

# Send it and get the response in json format
sparql.setReturnFormat(JSON)
results = sparql.query().convert()

# My result data container
res = {}

# Put results into it
for res_id, result in enumerate(results['results']['bindings']):
    res[res_id] = {'name': result['humanLabel']['value'], 'picture':result['picture']['value'] }

# Then create file based on this data
# ?????
# PROFIT!
with open('results.json', 'w') as file:
    json.dump(res, file)
    file.close()


import sys
K = int(input())
A,B = map(int,input().split())

if not ( 1 <= K <= 1000 ): sys.exit()
if not ( 1 <= A <= 1000 and A <= B <= 1000 ): sys.exit()

for I in range(A,B+1):
    if I % K == 0:
        print('OK')
        sys.exit()
print('NG')


# sersopiws - A weather station for Raspberry Pi
# https://github.com/sersope/sersopiws
# Sergio Soriano Peiro - sersope@gmail.com
"""Basic program for testing module 'sensors.py'.

Run as root.
"""
from __future__ import division,absolute_import,print_function,unicode_literals
import curses
import time
import sensors as s
import pprint

s.start()

tecla = None
pantalla = curses.initscr()
curses.noecho()
pantalla.nodelay(1)
pantalla.addstr(0,1,'sersopiws v0.1')
pantalla.addstr(2,1,"(Type 'q' to exit, 'r' to reset rain ticks.)")
pp = pprint.PrettyPrinter(indent=4)

while tecla != ord('q') and tecla != ord('Q'):
    c = s.current
    d = s.daily
    pantalla.addstr(4, 1, pp.pformat(c))
    pantalla.addstr(13, 1, pp.pformat(d))
    pantalla.addstr(26, 1, 'Llueve? {}'.format(s._isRaining))
    pantalla.addstr(27, 1, 'Pulsos de lluvia= {:5.0f}'.format(s._rain_ticks))
    pantalla.addstr(28, 1, 'Intensidad actual de lluvia= {:4.1f} mm/h'.format(s._rain_rate))
    pantalla.addstr(29, 1, 'Intensidad del episodio= {:4.1f} mm/h'.format(s._rain_evar))
    pantalla.addstr(30, 1, 'Duracion del episodio= {:5.2f} min.'.format(s._rain_evle))
    pantalla.refresh()

    if tecla == ord('r'):
        s._rain_ticks = 0.0
        s._isRaining = False
    time.sleep(0.25)
    tecla = pantalla.getch()

s.stop()
curses.endwin()


from protein_network import *
from graph_tool.centrality import *
from pathlib import Path
import argparse

class centrality_metrics(protein_network):

    def __init__(self, file, mode, score):
        super().__init__(file, mode, score)

    @property
    def metric_calculator(self):
        metrics = []
        self.creating_network()
        if self.mode == "up_genes":
            metrics.append(self.up_genes)
        else:
            metrics.append(self.down_genes)
        metrics.append([gene for gene in pagerank(self.graph)])
        metrics.append([gene for gene in betweenness(self.graph)[0]])
        #metrics.append([gene for gene in eigenvector(self.graph)[1]])
        #metrics.append(central_point_dominance(self.graph, metrics[1][0]))
        metrics.append([gene for gene in closeness(self.graph)])
        metrics.append([gene for gene in katz(self.graph)])
        try:
            metrics.append([gene for gene in hits(self.graph, max_iter=1e6)[2]])
        except ZeroDivisionError:
            print("Cannot calculate Hits metrics because of a float division by zero")
        metrics = pd.DataFrame(metrics)
        metrics = metrics.fillna(1.0)
        return metrics

parser = argparse.ArgumentParser()
parser.add_argument('mode', nargs="?", help="Either up_genes or down_genes", default=["down_genes"])
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=Path("~/Downloads"
                                                                                "/DE_heart_fb_deseq2_edger.txt"))
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'))
args = parser.parse_args()


# Lattice Description of FRIB Front End
# Notes:
#  * Use coordinates in FRIB lattice file. These are set so the start of the RFQ is at coordinate 200 meters.
#    This is large enough where source coordinates are all positive.
#    - Use of this may create some confusion (simulations start at some odd z-value), but hopefully make it
#      simpler to understand coordinates of elements consistently with the construction specification.

# Lattice periodicity
top.zlatperi  = largepos # periodicity length [m]
top.zlatstrt  = 0.       # z of lattice start; added to element z's [m]
                         #   (can use to change lattice phase)

# Energy and Bias of Source High Voltage Platform

ekin_per_u = 12.*keV                             # target kinetic energy/u for LEBT post ES gap

StandBias  = A_ref*ekin_per_u/Q_ref - SourceBias # Conistent Bias of Injector Column
Bias       = StandBias + SourceBias              # Total bias to achieve ekin_per_u

ref_gamma_post_gap = 1. + ekin_per_u*jperev/(amu*clight**2)
ref_vel_post_gap = clight*sqrt(1. - 1./ref_gamma_post_gap**2)
ref_brho_post_gap = ref_gamma_post_gap*ref_vel_post_gap*A_ref*amu/(Q_ref*jperev)

# Venus ECR Source Fields
# Comment: Must have same z-grids for linear and nonlinear forms.

# --- element specification

ecr_shift  = 11.*cm                 # shift of ecr from lattice file spec to make room for s4p1
ecr_z_extr = 66.650938 - ecr_shift  # z-location of beam extraction aperture in simulation coordinates
ecr_sc     = 1.0                    # scale factor to muliply field data by
ecr_typ    = "lin"                  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

# --- linear element data
#fi = PRpickle.PR("lat_ecr_venus/lat_ecr_venus.lin.20140602.pkl")  old data file which does not include fringe field extension
fi = PRpickle.PR("lat_ecr_venus/lat_ecr_venus.lin.20160218.pkl")
ecr_bz_extr = fi.ecr_venus_bz_extr
ecr_dz = fi.ecr_venus_dz
ecr_nz = fi.ecr_venus_nz
ecr_z_m     = fi.ecr_venus_z_m
ecr_zm_extr = fi.ecr_venus_z_extr  # extraction location on z_m mesh field
ecr_bz0_m   = fi.ecr_venus_bz0_m
ecr_bz0p_m  = fi.ecr_venus_bz0p_m
fi.close()

ecr_zlen  = ecr_z_m.max() - ecr_z_m.min()                 # length ecr field mesh
ecr_zmmin = ecr_z_extr - (ecr_zm_extr - ecr_z_m.min())    # start point of ecr field mesh in sim coordinates
ecr_zmmax = ecr_z_extr + (ecr_z_m.max() - ecr_zm_extr)    # end   point of ecr field mesh in sim coordinates

ecr_lin_id = addnewmmltdataset(zlen=ecr_zlen,ms=ecr_bz0_m,msp=ecr_bz0p_m,nn=0,vv=0)

# --- define venus ecr fields
if ecr_typ == "lin":
  ecr = addnewmmlt(zs=ecr_zmmin,ze=ecr_zmmax,id=ecr_lin_id,sc=ecr_sc)
elif ecr_typ == "nl":
  #addnewbgrd(xs=0.,zs=s41_zc-s4_zlen/2.,ze=s41_zc+s4_zlen/2.,id=s4_nl_id,func=s41_scale)
  raise Exception("No ECR Venus Nonlinear Applied Fields Defined")
  ecr = None
else:
  print("Warning: No ECR Applied Fields Defined")
  ecr = None

# S4 solenoids
# Comment: linear and nonlinear variants must have same z-grid.

# --- element specification

s4p1_zc  = 66.956900   # S4 1: z-center
#s4p1_str = 0.6 # 0.754 # S4 1: peak on-axis B_z field strength [Tesla]
s4p1_typ = "nl"        # S4 1: type: "lin" = linear optics fields or "nl" = nonlinear r-z field

s4p2_zc  = 68.306900   # S4 2: z-center
#s4p2_str = 0.5 # 0.617 # s4 2: peak on-axis B_z field strength [Tesla]
s4p2_typ = "nl"        # S4 1: type: "lin" = linear optics fields or "nl" = nonlinear r-z field

# --- linear element data
#fi = PRpickle.PR("lat_s4/lat_s4.lin.20140603.pkl")
fi = PRpickle.PR("lat_s4/lat_s4.lin.20141031.pkl")
s4_dz  = fi.s4_dz
s4_nz  = fi.s4_nz
s4_z_m = fi.s4_z_m
s4_bz0_m   = fi.s4_bz0_m
s4_bz0p_m  = fi.s4_bz0p_m
fi.close()

s4_zlen = s4_z_m.max() - s4_z_m.min()
s4_lin_id = addnewmmltdataset(zlen=s4_zlen,ms=s4_bz0_m,msp=s4_bz0p_m,nn=0,vv=0)

# --- nonlinear element field data
#fi = PRpickle.PR('lat_s4/lat_s4.rz.20140603.pkl')
fi = PRpickle.PR('lat_s4/lat_s4.rz.20141031.pkl')
#
s4_len_coil   = fi.s4_len_coil
s4_len_magnet = fi.s4_len_magnet
s4_r_coil_i   = fi.s4_r_coil_i
s4_r_coil_o   = fi.s4_r_coil_o
#
if fi.s4_nz != s4_nz: raise Exception("S4: Nonlinear field model nz not equal to linear field model nz")
s4_dr   = fi.s4_dr
s4_nr   = fi.s4_nr
s4_r_m  = fi.s4_r_m
s4_br_m_in = fi.s4_br_m
s4_bz_m_in = fi.s4_bz_m
fi.close()

# --- nonlinear element vector potential data
#fi = PRpickle.PR('lat_s4/lat_s4.at.20140603.pkl')
fi = PRpickle.PR('lat_s4/lat_s4.at.20141031.pkl')
#
if fi.s4_nz != s4_nz: raise Exception("S4: Nonlin Vector potential model nz not equal to nonlinear/linear model nz")
if fi.s4_nr != s4_nr: raise Exception("S4: Nonlin Vector potential model nr not equal to nonlinear model nr")
s4_at_m  = fi.s4_at_m
fi.close()

# --- Axisymmetric b-field arrays must be 3d shape (nr+1,arb,nz+1) to load into Warp
s4_br_m = fzeros((s4_nr+1,1,s4_nz+1))
s4_br_m[:,0,:] = s4_br_m_in
s4_bz_m = fzeros((s4_nr+1,1,s4_nz+1))
s4_bz_m[:,0,:] = s4_bz_m_in

s4_nl_id = addnewbgrddataset(dx=s4_dr,dy=1.,zlength=s4_zlen,bx=s4_br_m,bz=s4_bz_m,rz = true)  # pass arb dy to avoid error trap

s4_aspect = s4_r_coil_i/s4_len_coil

# --- define solenoid s4 1
if s4p1_typ == "lin":
  s4p1 = addnewmmlt(zs=s4p1_zc-s4_zlen/2.,ze=s4p1_zc+s4_zlen/2.,id=s4_lin_id,sc=s4p1_str)
elif s4p1_typ == "nl":
  s4p1 = addnewbgrd(xs=0.,zs=s4p1_zc-s4_zlen/2.,ze=s4p1_zc+s4_zlen/2.,id=s4_nl_id,sc=s4p1_str)
else:
  print("Warning: No S4 1st Solenoid Applied Fields Defined")
  s4p1 = None

# --- define solenoid s4 2
if s4p2_typ == "lin":
  s4p2 = addnewmmlt(zs=s4p2_zc-s4_zlen/2.,ze=s4p2_zc+s4_zlen/2.,id=s4_lin_id,sc=s4p2_str)
elif s4p2_typ == "nl":
  s4p2 = addnewbgrd(xs=0.,zs=s4p2_zc-s4_zlen/2.,ze=s4p2_zc+s4_zlen/2.,id=s4_nl_id,sc=s4p2_str)
else:
  print("Warning: No S4 2nd Solenoid Applied Fields Defined")
  s4p2 = None

# --- Define vector potential function for both linear and nonlinear solenoid magnetic fields
def getatheta(r):
  # --- gather vector potential
  n = len(r)
  at = zeros(n)
  at_scratch = zeros(n)
  z  = top.zbeam*ones(n)
  if   top.zbeam >= ecr_zmmin and top.zbeam <= ecr_zmmax:
    # --- contribution in venus
    if ecr_typ == "lin":
      getgrid1d(n,z,at_scratch,ecr_nz,ecr_sc*ecr_bz0_m,ecr_zmmin,ecr_zmmax)
      at_scratch = at_scratch*r/2.
    elif ecr_typ == "nl":
       raise Exception("Vector Potential: ECR Nonlinear not defined")
    else:
       raise Exception("Vector Potential: ECR not defined")
    at += at_scratch
  if top.zbeam >= s4p1_zc-s4_zlen/2. and top.zbeam <= s4p1_zc+s4_zlen/2.:
    # --- contribution from 1st s4
    if s4p1_typ == "lin":
      getgrid1d(n,z,at_scratch,s4_nz,s4p1_str*s4_bz0_m,s4p1_zc-s4_zlen/2.,s4p1_zc+s4_zlen/2.)
      at_scratch = at_scratch*r/2.
    elif s4p1_typ == "nl":
      getgrid2d(n,r,z,at_scratch,s4_nr,s4_nz,s4p1_str*s4_at_m,s4_r_m.min(),s4_r_m.max(),
                s4p1_zc-s4_zlen/2.,s4p1_zc+s4_zlen/2.)
    else:
      raise Exception("Vector Potential: S4.1 not defined")
    at += at_scratch
  if top.zbeam >= s4p2_zc-s4_zlen/2. and top.zbeam <= s4p2_zc+s4_zlen/2.:
    # --- contribution from 2nd s4
    if s4p2_typ == "lin":
      getgrid1d(n,z,at_scratch,s4_nz,s4p2_str*s4_bz0_m,s4p2_zc-s4_zlen/2.,s4p2_zc+s4_zlen/2.)
      at_scratch = at_scratch*r/2.
    elif s4p2_typ == "nl":
      getgrid2d(n,r,z,at_scratch,s4_nr,s4_nz,s4p2_str*s4_at_m,s4_r_m.min(),s4_r_m.max(),
                s4p2_zc-s4_zlen/2.,s4p2_zc+s4_zlen/2.)
    else:
      raise Exception("Vector Potential: S4.2 not defined")
    at += at_scratch
  return at

# Grated Acceleration Gap
#  Note: for ideal zero-length gap:  top.lacclzl=true for zero length gap.  Accel given given by acclez*(accelze-acclzs)
#   see dave grote email on caution on setting top.acclsw for gaps.
#   Comment: Linear and nonlinear forms must have same axial grid.

# --- element specification
gag_zc  = 67.811564  # Grated Accel Gap: z-center
gag_typ = "nl"       # Grated Accel Gap: type: "ideal" = Short gap kick, "lin" = linear r-z field imported, "nl" = nonlinear r-z field imported

# --- linear element data
# fi = PRpickle.PR("lat_gag/lat_gag.lin.20140624.pkl")  # Original Warp model with simplified geometry
fi = PRpickle.PR("lat_gag/lat_gag.lin.20141029.pkl")    # Poisson model with high detail
gag_dz = fi.gag_dz0
gag_nz = fi.gag_nz0
gag_z_m     = fi.gag_z0_m
gag_ez0_m   = fi.gag_ez0_m
gag_ez0p_m  = fi.gag_ez0p_m
fi.close()

gag_zlen = gag_z_m.max() - gag_z_m.min()

gag_lin_id = addnewemltdataset(zlen=gag_zlen,es=gag_ez0_m,esp=gag_ez0p_m,nn=0,vv=0)

# --- nonlinear element data
#fi = PRpickle.PR('lat_gag/lat_gag.rz.20140624.pkl')  # Original Warp model with simplified geometry
fi = PRpickle.PR('lat_gag/lat_gag.rz.20141029.pkl')   # Poisson model with high detail
if fi.gag_nz != gag_nz: raise Exception("GAG: Nonlinear and linear field model nz not equal")
gag_nr = fi.gag_nr
gag_dr = fi.gag_dr
gag_r_m = fi.gag_r_m
gag_z_m_cen = fi.gag_z_m_cen
gag_phi_m    = fi.gag_phi_m
gag_er_m_in  = fi.gag_er_m
gag_ez_m_in  = fi.gag_ez_m
fi.close()

gag_zlen = gag_z_m.max()-gag_z_m.min()          # axial length nonlin/lin structure on mesh

gag_zs   = gag_zc - (gag_z_m_cen-gag_z_m.min()) # z_start of nonlin/lin mesh structure
gag_ze   = gag_zc + (gag_z_m.max()-gag_z_m_cen) # z_end   of nonlin/lin mesh structure

# Geometry parameters ?? Read these in grated gap file to be safe .. ** must be consistent with input data ** ??
gag_rp = 7.3*cm                  # pipe radius of inner extent of rings in grated gap
gag_col_zs = gag_zc - 11.989*cm  # z-start (at end   of biased upstream pipe)     of grated gap mechanical structure
gag_col_ze = gag_zc + 15.611*cm  # z-end   (at start of grounded downstream pipe) of grated gap mechanical structure

gag_er_m = fzeros((gag_nr+1,1,gag_nz+1)) # Axisymmetric e-field arrays must be 3d shape (nr+1,arb,nz+1) to load into Warp
gag_er_m[:,0,:] = gag_er_m_in
gag_ez_m = fzeros((gag_nr+1,1,gag_nz+1))
gag_ez_m[:,0,:] = gag_ez_m_in

gag_nl_id = addnewegrddataset(dx=gag_dr,dy=1.,zlength=gag_zlen,ex=gag_er_m,ez =gag_ez_m,rz = true)

# --- define grated acceleration gap
if gag_typ == "ideal":
  print("Warning: No Ideal Acceleration Gap model yet implemented")
  gag = None
elif gag_typ == "lin":
  gag = addnewemlt(zs=gag_zs,ze=gag_ze,id=gag_lin_id,sc=StandBias)
elif gag_typ == "nl":
  gag = addnewegrd(xs=0.,zs=gag_zs,ze=gag_ze,id=gag_nl_id,sc=StandBias)
else:
  print("Warning: No Grated Acceleration Gap Applied Fields Defined")
  gag = None

## D5 Bending Dipole

## --- element specification

#d5p1_zc  = 69.587759   # D5 1: z-center
#d5p1_str = 1.0         # D5 1: Input field scale factor
#d5p1_typ = "nl"        # D5 1: type: "ideal" = uniform By, "lin" = linear optics fields, "3d" = 3d field
#d5p1_ideal_len = 1.0

#d5p2_zc  = 73.248371   # D5 2: z-center
#d5p2_str = 1.0         # D5 2: Input field scale factor
#d5p2_typ = "nl"        # D5 2: type: "ideal" = uniform By, "lin" = linear optics fields, "3d" = 3d field
#d5p2_ideal_len = 1.0

## --- nonlinear element data
#if False: # OLD VERSION
  #fi = PRpickle.PR('lat_d5/lat_d5.3d.20140527.pkl')
  #d5_3d_nx = fi.d5_nx
  #d5_3d_ny = fi.d5_ny
  #d5_3d_nz = fi.d5_nz
  #d5_3d_dx = fi.d5_dx
  #d5_3d_dy = fi.d5_dy
  #d5_3d_dz = fi.d5_dz
  #d5_3d_x_m = fi.d5_x_m
  #d5_3d_y_m = fi.d5_y_m
  #d5_3d_z_m = fi.d5_z_m
  #d5_3d_z_m_cen = fi.d5_z_m_cen
  #d5_3d_bx_m = fi.d5_bx_m
  #d5_3d_by_m = fi.d5_by_m
  #d5_3d_bz_m = fi.d5_bz_m
  #fi.close()
  #d5_3d_zlen = d5_3d_z_m.max() - d5_3d_z_m.min()

  #d5_3d_id = addnewbgrddataset(dx=d5_3d_dx,dy=d5_3d_dy,zlength=d5_3d_zlen,
                               #bx=d5_3d_bx_m,by=d5_3d_by_m,bz =d5_3d_bz_m)

#if d5p1_typ == "nl":
  ##Bend magnet grid data info
  #d5_3d_cond_in = 43.0*cm                       # Conductor inner radius
  #d5_3d_cond_out = 84.0*cm                      # Conductor outer radius
  ##d5_3d_x_ap = (d5_3d_cond_out - d5__3dcond_in)/2.0  # x aperture size
  ##d5_3d_y_ap = 5.0*cm                          # y aperture size
  #d5_3d_rc = (d5_3d_cond_out + d5_3d_cond_in)/2.0     # Magnet center radius
  #d5_3d_core_l = d5_3d_rc*0.5*pi                # Magnet core length
  #d5_3d_s = 69.2                                # Magnet core start point
  #d5_3d_e = d5_3d_s + d5_3d_core_l              # Magnet core end point

  #d5_3d_frng_l = 53.0*cm                        # Fringe field length
  #d5_3d_xw = 42.0*cm                            # B grid data X width
  #d5_3d_yw = 10.0*cm                            # B grid data Y width
  #d5_3d_zlen = d5_3d_frng_l*2.0 + d5_3d_core_l  # B grid data Z length
  #d5_3d_str = d5_3d_s - d5_3d_frng_l            # B grid data start point
  #d5_3d_end = d5_3d_str+d5_3d_zlen              # B grid data end point

  #d5_3d_scl = 0.6015157305571277 * 1.00132179   # B grid scaling factor (center_line_By *correction_factor)

  #d5_3d_nx = 105   # Number of X grid
  #d5_3d_ny = 25    # Number of Y grid
  #d5_3d_nz = 500   # Number of Z grid

  #d5_3d_dx = d5_3d_xw/float64(d5_3d_nx)     # X grid size
  #d5_3d_dy = d5_3d_yw/float64(d5_3d_ny)     # Y grid size
  #d5_3d_dz = d5_3d_zlen/float64(d5_3d_nz)   # Z grid size

  #bgdata = getdatafromtextfile("lat_d5/bend_trans.table",dims=[3,None],)
  #if len(bgdata[0]) != (d5_3d_nx+1)*(d5_3d_ny+1)*(d5_3d_nz+1): raise Exception("bend grid data is invalid.")

  #d5_3d_bx = resize(bgdata[0],(d5_3d_nx+1,d5_3d_ny+1,d5_3d_nz+1))*gauss
  #d5_3d_by = resize(bgdata[1],(d5_3d_nx+1,d5_3d_ny+1,d5_3d_nz+1))*gauss
  #d5_3d_bz = resize(bgdata[2],(d5_3d_nx+1,d5_3d_ny+1,d5_3d_nz+1))*gauss

  #d5_3d_id = addnewbgrddataset(dx=d5_3d_dx ,dy=d5_3d_dx ,zlength=d5_3d_zlen ,bx=d5_3d_bx, by=d5_3d_by ,bz=d5_3d_bz)

## Starting and ending position of first ideal D5 dipole.
## Also used to define the lattice bend

##d5p1_zs = 69.2 # may need to be revised upon obtaining lattice design data
##d5p1_ze = d5p1_zc + (d5p1_zc - d5p1_zs)

## Define starting and ending position of 1st ideal D5 dipole using ideal length and centre position
## Makes the bend less tight than when the starting position is set to be 69.2 m

## --- define dipole d5

## --- ideal (uniform) field
#if d5p1_typ == "ideal":
  #d5p1_zs = d5p1_zc - d5p1_ideal_len / 2.
  #d5p1_ze = d5p1_zc + d5p1_ideal_len / 2.
  #bending_R = (d5p1_ze - d5p1_zs)/(pi/2.)
  #bending_B = sqrt( A_ref*ekin_per_u*jperev*2.*A_ref*amu)/(Q_ref*jperev)/bending_R
  #d5p1 = addnewdipo(zs = d5p1_zs, ze = d5p1_ze, by = bending_B)
  #equivalent_G = 0.9/bending_R**2 * ref_brho_post_gap	#focusing effect from slanted poles
  #d5p1_equiv_quad = addnewquad(zs = d5p1_zs, ze = d5p1_ze, db = -equivalent_G)
## --- linear optic approximation field
#elif d5p1_typ == "lin":
  #print("Warning: No D5 1st Dipole Linear Applied Fields Defined")
  #d5p1 = None
## --- 3D field from magnet design code
#elif d5p1_typ == "nl":
  ##d5p1 = addnewbgrd(dx=d5_3d_dx,dy=d5_3d_dy,xs=d5_3d_x_m.min(),ys=d5_3d_y_m.min(),
  ##  zs=d5p1_zc-d5_3d_zlen/2.,ze=d5p1_zc+d5_3d_zlen/2.,id=d5_3d_id,sc=d5p1_str)

  #d5p1_zs = d5p1_zc - d5_3d_core_l/2. # core starts
  #d5p1_ze = d5p1_zc + d5_3d_core_l/2. # core ends
  #d5p1_str = d5p1_zs - d5_3d_frng_l   # fringe starts
  #d5p1_end = d5p1_ze + d5_3d_frng_l   # fringe ends

  #d5p1 = addnewbgrd(dx=d5_3d_dx, dy=d5_3d_dy, xs=-d5_3d_xw/2., ys=-d5_3d_yw/2.,
    #zs=d5p1_str, ze=d5p1_end, id=d5_3d_id, sc=d5_3d_scl)

#else:
  #print("Warning: No D5 1st Dipole Applied Fields Defined")
  #d5p1 = None

## --- ideal (uniform) field
#if d5p2_typ == "ideal":
  #d5p2_zs = d5p2_zc - d5p2_ideal_len / 2.
  #d5p2_ze = d5p2_zc + d5p2_ideal_len / 2.
  #bending_R = (d5p2_ze - d5p2_zs)/(pi/2.)
  #bending_B = sqrt( A_ref*ekin_per_u*jperev*2.*A_ref*amu)/(Q_ref*jperev)/bending_R
  #d5p2 = addnewdipo(zs = d5p2_zs, ze = d5p2_ze, by = bending_B)
  #equivalent_G = 0.9/bending_R**2 * ref_brho_post_gap	#focusing effect from slanted poles
  #d5p2_equiv_quad = addnewquad(zs = d5p2_zs, ze = d5p2_ze, db = -equivalent_G)
## --- linear optic approximation field
#elif d5p2_typ == "lin":
  #print("Warning: No D5 2nd Dipole Linear Applied Fields Defined")
  #d5p2 = None
## --- 3D field from magnet design code
#elif d5p2_typ == "nl":
  ##d5p1 = addnewbgrd(dx=d5_3d_dx,dy=d5_3d_dy,xs=d5_3d_x_m.min(),ys=d5_3d_y_m.min(),
  ##  zs=d5p1_zc-d5_3d_zlen/2.,ze=d5p1_zc+d5_3d_zlen/2.,id=d5_3d_id,sc=d5p1_str)

  #d5p2_zs = d5p2_zc - d5_3d_core_l/2.  # core starts
  #d5p2_ze = d5p2_zc + d5_3d_core_l/2.  # core ends
  #d5p2_str = d5p2_zs - d5_3d_frng_l    # fringe starts
  #d5p2_end = d5p2_ze + d5_3d_frng_l    # fringe ends

  #d5p2 = addnewbgrd(dx=d5_3d_dx, dy=d5_3d_dy, xs=-d5_3d_xw/2., ys=-d5_3d_yw/2.,
    #zs=d5p2_str, ze=d5p2_end, id=d5_3d_id, sc=d5_3d_scl)

#else:
  #print("Warning: No D5 2nd Dipole Applied Fields Defined")
  #d5p2 = None

##
## Lattice bends for D5 Bending Dipole
##
##  Comments:
##   * Use ideal bends on lattice whether dipole field is ideal (uniform) or not.

#d5p1_bend = True  # True or False: Add ideal bend to lattice
#d5p2_bend = True  # True or False: Add ideal bend to lattice

#if d5p1_bend:
  #top.diposet = False     # turn off By that automatically generated with addnewbend()
  #equivalent_ideal_R = (d5p1_ze - d5p1_zs)/(pi/2.)
  #equivalent_ideal_B = sqrt( A_ref*ekin_per_u*jperev*2.*A_ref*amu)/(Q_ref*jperev)/equivalent_ideal_R
  #addnewbend(zs = d5p1_zs, ze = d5p1_ze, rc = equivalent_ideal_R)

#if d5p2_bend:
  #top.diposet = False     # turn off By that automatically generated with addnewbend()
  #equivalent_ideal_R = (d5p2_ze - d5p2_zs)/(pi/2.)
  #equivalent_ideal_B = sqrt( A_ref*ekin_per_u*jperev*2.*A_ref*amu)/(Q_ref*jperev)/equivalent_ideal_R
  #addnewbend(zs = d5p2_zs, ze = d5p2_ze, rc = equivalent_ideal_R)

#dipole_exit = [[0.,0.],[0.,0.]]
#cccounter = 0

#for ii in sp_target:
	#s = sp[ii]
	#species_R = sqrt( s.charge*Bias*2.*s.mass)/(s.charge)/ equivalent_ideal_B
	#offset = sqrt( species_R**2 - (species_R - equivalent_ideal_R)**2 ) - equivalent_ideal_R
	#centroid_angle = arccos( 1 - equivalent_ideal_R / species_R ) - pi/2

	#dipole_exit[cccounter][0] = offset
	#dipole_exit[cccounter][1] = centroid_angle*sign(offset)

	#cccounter += 1

## Q7 Electrostatic Quads
## Comment: linear and nonlinear variants must have same z-grid.

## --- calculate esq strength from k1 in DIMAD lattice design
## values used in Dr. Ren's model: 4.6kV, -8.3kV, 3.7kV

#amu_eV = 931.4941e6

#q7t1p1_k1 = 8.2957122
#q7t1p2_k1 = -15.6040684
#q7t1p3_k1 = 7.51275015

#q7_design_len = 0.2068

#q7_aper_r = 7.5*cm

##gamma_ref = (ekin_per_u + amu_eV) / amu_eV
##v_ref = sqrt(1. - 1./gamma_ref**2)*clight
##brho_ref = (A_ref * sqrt((ekin_per_u + amu_eV)**2 - (amu_eV)**2)/clight) / Q_ref

#q7_str_mode = 1    # 0: electrode potential corresponds to kappa ; 1: equivalent focusing
                   ## must be 0 for ideal q7

#inter_quad_distance = 0.335 # centroid distance between two quads in a triplet

## --- element specification

### 1st triplet
#q7t1p1_zc = 70.537759 # (q7: Q7 device type; t1: 1st triplet; p1: part 1)
##q7t1p1_str = 10000 # [V]
#q7t1p1_sign = 1    # +1 for x_quad, -1 for y_quad
#q7t1p1_typ = "nl"  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

#q7t1p2_zc = q7t1p1_zc + inter_quad_distance
##q7t1p2_str = 10000 # [V]
#q7t1p2_sign = -1   # +1 for x_quad, -1 for y_quad
#q7t1p2_typ = "nl"  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

#q7t1p3_zc = q7t1p2_zc + inter_quad_distance
##q7t1p3_str = 10000 # [V]
#q7t1p3_sign = 1    # +1 for x_quad, -1 for y_quad
#q7t1p3_typ = "nl"  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

### 2nd triplet
#q7t2p1_zc = 72.161896 # (q7: Q7 device type; t2: 2nd triplet; p1: part 1)
##q7t1p1_str = 10000 # [V]
#q7t2p1_sign = 1    # +1 for x_quad, -1 for y_quad
#q7t2p1_typ = "nl"  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

#q7t2p2_zc = q7t2p1_zc + inter_quad_distance
##q7t1p2_str = 10000 # [V]
#q7t2p2_sign = -1   # +1 for x_quad, -1 for y_quad
#q7t2p2_typ = "nl"  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

#q7t2p3_zc = q7t2p2_zc + inter_quad_distance
##q7t1p3_str = 10000 # [V]
#q7t2p3_sign = 1    # +1 for x_quad, -1 for y_quad
#q7t2p3_typ = "nl"  # type: "lin" = linear optics fields or "nl" = nonlinear r-z field

### --- linear element data
###fi = PRpickle.PR("lat_q7/lat_q7.lin.????.pkl")
##fi = PRpickle.PR("lat_q7/lat_q7.lin.????.pkl")
##s4_dz  = fi.s4_dz
##s4_nz  = fi.s4_nz
##s4_z_m = fi.s4_z_m
##s4_bz0_m   = fi.s4_bz0_m
##s4_bz0p_m  = fi.s4_bz0p_m
##fi.close()

##s4_zlen = s4_z_m.max() - s4_z_m.min()
##s4_lin_id = addnewmmltdataset(zlen=s4_zlen,ms=s4_bz0_m,msp=s4_bz0p_m,nn=0,vv=0)

## --- nonlinear element field data
#fi = PRpickle.PR('lat_q7/lat_q7.3d.20160607.pkl')
###
##s4_len_coil   = fi.s4_len_coil
##s4_len_magnet = fi.s4_len_magnet
##s4_r_coil_i   = fi.s4_r_coil_i
##s4_r_coil_o   = fi.s4_r_coil_o
##
##if fi.s4_nz != s4_nz: raise Exception("S4: Nonlinear field model nz not equal to linear field model nz")

#q7_dx   = fi.q7_dx
#q7_dy   = fi.q7_dy
#q7_dz   = fi.q7_dz
#q7_nx   = fi.q7_nx
#q7_ny   = fi.q7_ny
#q7_nz   = fi.q7_nz
#q7_x_m  = fi.q7_x_m
#q7_y_m  = fi.q7_y_m
#q7_z_m  = fi.q7_z_m
#q7_ex_m  = fi.q7_ex_m
#q7_ey_m  = fi.q7_ey_m
#q7_ez_m  = fi.q7_ez_m
#fi.close()

#q7_zlen = q7_z_m.max() - q7_z_m.min()
#q7_x_m_min = q7_x_m.min()
#q7_y_m_min = q7_y_m.min()

#q7_nl_id = addnewegrddataset(dx=q7_dx,dy=q7_dy,zlength=q7_zlen,ex=q7_ex_m,ey=q7_ey_m,ez=q7_ez_m)  # pass arb dy to avoid error trap

#if q7_str_mode == 0:
    #q7t1p1_str = abs(q7t1p1_k1)*ref_brho_post_gap*ref_vel_post_gap*q7_aper_r**2/2
    #q7t1p2_str = abs(q7t1p2_k1)*ref_brho_post_gap*ref_vel_post_gap*q7_aper_r**2/2
    #q7t1p3_str = abs(q7t1p3_k1)*ref_brho_post_gap*ref_vel_post_gap*q7_aper_r**2/2

#if q7_str_mode == 1:
	#dEx_array = q7_ex_m[51][50] - q7_ex_m[49][50]  # difference of E at two sets of mesh points along z
	#dExdx_array = dEx_array / (2*q7_dx)            # approximate dExdx at the centre
	#normalized_sum = sum(dExdx_array)*q7_dz
	#design_Gl_p1 = q7t1p1_k1*ref_brho_post_gap*ref_vel_post_gap*q7_design_len
	#design_Gl_p2 = q7t1p2_k1*ref_brho_post_gap*ref_vel_post_gap*q7_design_len
	#design_Gl_p3 = q7t1p3_k1*ref_brho_post_gap*ref_vel_post_gap*q7_design_len
	#q7t1p1_str = abs(design_Gl_p1/normalized_sum)
	#q7t1p2_str = abs(design_Gl_p2/normalized_sum)
	#q7t1p3_str = abs(design_Gl_p3/normalized_sum)

#q7t2p1_str = q7t1p3_str
#q7t2p2_str = q7t1p2_str
#q7t2p3_str = q7t1p1_str

## --- define esq q7 1st triplet part 1
#if q7t1p1_typ == "lin":
  #q7t1p1 = addnewmmlt(zs=q7t1p1_zc-q7_zlen/2.,ze=q7t1p1_zc+q7_zlen/2.,id=q7_lin_id,sc=q7t1p1_str*q7t1p1_sign)
#elif q7t1p1_typ == "nl":
  #q7t1p1 = addnewegrd(xs=q7_x_m_min,ys=q7_y_m_min,zs=q7t1p1_zc-q7_zlen/2.,ze=q7t1p1_zc+q7_zlen/2.,id=q7_nl_id,sc=q7t1p1_str*q7t1p1_sign)
#elif q7t1p1_typ == "ideal":
  #q7t1p1 = addnewequad(zs = q7t1p1_zc-q7_design_len/2., ze = q7t1p1_zc+q7_design_len/2., de = q7t1p1_str*q7t1p1_sign)
#else:
  #print("Warning: No S4 1st Solenoid Applied Fields Defined")
  #q7t1p1 = None

## --- define esq q7 1st triplet part 2
#if q7t1p2_typ == "lin":
  #q7t1p2 = addnewmmlt(zs=q7t1p2_zc-q7_zlen/2.,ze=q7t1p2_zc+q7_zlen/2.,id=q7_lin_id,sc=q7t1p2_str*q7t1p2_sign)
#elif q7t1p2_typ == "nl":
  #q7t1p2 = addnewegrd(xs=q7_x_m_min,ys=q7_y_m_min,zs=q7t1p2_zc-q7_zlen/2.,ze=q7t1p2_zc+q7_zlen/2.,id=q7_nl_id,sc=q7t1p2_str*q7t1p2_sign)
#elif q7t1p2_typ == "ideal":
  #q7t1p2 = addnewequad(zs = q7t1p2_zc-q7_design_len/2., ze = q7t1p2_zc+q7_design_len/2., de = q7t1p2_str*q7t1p2_sign)
#else:
  #print("Warning: No S4 1st Solenoid Applied Fields Defined")
  #q7t1p2 = None

## --- define esq q7 1st triplet part 3
#if q7t1p3_typ == "lin":
  #q7t1p3 = addnewmmlt(zs=q7t1p3_zc-q7_zlen/2.,ze=q7t1p3_zc+q7_zlen/2.,id=q7_lin_id,sc=q7t1p3_str*q7t1p3_sign)
#elif q7t1p3_typ == "nl":
  #q7t1p3 = addnewegrd(xs=q7_x_m_min,ys=q7_y_m_min,zs=q7t1p3_zc-q7_zlen/2.,ze=q7t1p3_zc+q7_zlen/2.,id=q7_nl_id,sc=q7t1p3_str*q7t1p3_sign)
#elif q7t1p3_typ == "ideal":
  #q7t1p3 = addnewequad(zs = q7t1p3_zc-q7_design_len/2., ze = q7t1p3_zc+q7_design_len/2., de = q7t1p3_str*q7t1p3_sign)
#else:
  #print("Warning: No S4 1st Solenoid Applied Fields Defined")
  #q7t1p3 = None

## --- define esq q7 2nd triplet part 1
#if q7t2p1_typ == "lin":
  #q7t2p1 = addnewmmlt(zs=q7t2p1_zc-q7_zlen/2.,ze=q7t2p1_zc+q7_zlen/2.,id=q7_lin_id,sc=q7t2p1_str*q7t2p1_sign)
#elif q7t2p1_typ == "nl":
  #q7t2p1 = addnewegrd(xs=q7_x_m_min,ys=q7_y_m_min,zs=q7t2p1_zc-q7_zlen/2.,ze=q7t2p1_zc+q7_zlen/2.,id=q7_nl_id,sc=q7t2p1_str*q7t2p1_sign)
#elif q7t2p1_typ == "ideal":
  #q7t2p1 = addnewequad(zs = q7t2p1_zc-q7_design_len/2., ze = q7t2p1_zc+q7_design_len/2., de = q7t2p1_str*q7t2p1_sign)
#else:
  #print("Warning: No S4 1st Solenoid Applied Fields Defined")
  #q7t2p1 = None

## --- define esq q7 2nd triplet part 2
#if q7t2p2_typ == "lin":
  #q7t2p2 = addnewmmlt(zs=q7t2p2_zc-q7_zlen/2.,ze=q7t2p2_zc+q7_zlen/2.,id=q7_lin_id,sc=q7t2p2_str*q7t2p2_sign)
#elif q7t2p2_typ == "nl":
  #q7t2p2 = addnewegrd(xs=q7_x_m_min,ys=q7_y_m_min,zs=q7t2p2_zc-q7_zlen/2.,ze=q7t2p2_zc+q7_zlen/2.,id=q7_nl_id,sc=q7t2p2_str*q7t2p2_sign)
#elif q7t2p2_typ == "ideal":
  #q7t2p2 = addnewequad(zs = q7t2p2_zc-q7_design_len/2., ze = q7t2p2_zc+q7_design_len/2., de = q7t2p2_str*q7t2p2_sign)
#else:
  #print("Warning: No S4 1st Solenoid Applied Fields Defined")
  #q7t2p2 = None

## --- define esq q7 2nd triplet part 3
#if q7t2p3_typ == "lin":
  #q7t2p3 = addnewmmlt(zs=q7t2p3_zc-q7_zlen/2.,ze=q7t2p3_zc+q7_zlen/2.,id=q7_lin_id,sc=q7t2p3_str*q7t2p3_sign)
#elif q7t2p3_typ == "nl":
  #q7t2p3 = addnewegrd(xs=q7_x_m_min,ys=q7_y_m_min,zs=q7t2p3_zc-q7_zlen/2.,ze=q7t2p3_zc+q7_zlen/2.,id=q7_nl_id,sc=q7t2p3_str*q7t2p3_sign)
#elif q7t2p3_typ == "ideal":
  #q7t2p3 = addnewequad(zs = q7t2p3_zc-q7_design_len/2., ze = q7t2p3_zc+q7_design_len/2., de = q7t2p3_str*q7t2p3_sign)
#else:
  #print("Warning: No S4 1st Solenoid Applied Fields Defined")
  #q7t2p3 = None

#### Scrapers ###

### Particles are not scraped if scraper is too thin w.r.t. simulation step size ##
## From trial and error: use 4mm-thick slits, 10mm-thick walls for 2mm step size

### Beam pipe (where the aperture is circular)

#r_p_up   = 8.00*cm  # aperture   upstream of grated gap [m]
#r_p_down = 7.62*cm  # aperture downstream of grated gap [m]

#post_d5p1_pipe_r = 7.5*cm
#post_d5p1_pipe_zs = d5p1_ze + 8*cm
#post_d5p1_pipe_ze = d5p1_ze + 8*cm +  229*mm

#q7t1_pipe_r = 12.4*cm
#q7t1_pipe_zs = post_d5p1_pipe_ze
#q7t1_pipe_ze = q7t1_pipe_zs + 952*mm

#r_ap   = array([r_p_up,               gag_rp,       r_p_down,   post_d5p1_pipe_r,     12.4*cm,       7.5*cm  ])
#v_ap   = array([SourceBias+StandBias, StandBias/2., 0.,         0.,                   0.,            0.])
#z_ap_l = array([ecr_z_extr,           gag_col_zs,   gag_col_ze, post_d5p1_pipe_zs,    q7t1_pipe_zs,  q7t1_pipe_ze])
#z_ap_u = array([gag_col_zs,           gag_col_ze,   d5p1_zs,    post_d5p1_pipe_ze,    q7t1_pipe_ze,  d5p2_ze + 0.4])

#beampipe = []
#for i in range(len(r_ap)):
  #rp = r_ap[i]
  #v  = v_ap[i]
  #zl = z_ap_l[i]
  #zu = z_ap_u[i]
  ##
  #beampipe.append( ZCylinderOut(radius=rp,zlower=zl,zupper=zu,voltage=v,condid="next") )

#r_p = max(r_ap)   # Max aperture in simulations

### Rectangular aperture in D5 Dipole:

## Include an additional 8cm of rectangular aperture after 1m long D5 Dipole

#added_len = 8*cm

#d5p1_aperture_out = Box(xsize = 180*mm, ysize = 150*mm, zsize = d5p1_ideal_len + added_len, xcent = 0*mm, ycent = 0., zcent = d5p1_zc + added_len/2)
#d5p1_aperture_in = Box(xsize = 150*mm, ysize = 120*mm, zsize = d5p1_ideal_len + added_len, xcent = 0*mm, ycent = 0., zcent = d5p1_zc + added_len/2)

#d5p1_aperture = [d5p1_aperture_out - d5p1_aperture_in]

##d5p1_aperture_xplus = Box(xsize = 10*mm, ysize = 120*mm, zsize = d5p1_ideal_len + added_len, xcent = 80*mm, ycent = 0, zcent = d5p1_zc + added_len/2)
##d5p1_aperture_xminus = Box(xsize = 10*mm, ysize = 120*mm, zsize = d5p1_ideal_len + added_len, xcent = -80*mm, ycent = 0, zcent = d5p1_zc + added_len/2)
##d5p1_aperture_yplus = Box(xsize = 150*mm, ysize = 10*mm, zsize = d5p1_ideal_len + added_len, xcent = 0, ycent = 65*mm, zcent = d5p1_zc + added_len/2)
##d5p1_aperture_yminus = Box(xsize = 150*mm, ysize = 10*mm, zsize = d5p1_ideal_len + added_len, xcent = 0, ycent = -65*mm, zcent = d5p1_zc + added_len/2)

##d5p1_aperture = [d5p1_aperture_xplus, d5p1_aperture_xminus, d5p1_aperture_yplus, d5p1_aperture_yminus]

### Gate valve

#valve_x_opening = 7*cm
#valve_y_opening = 10*cm
#valve_len = 4*mm
#valve_zc = q7t1p1_zc - 140*mm

## These sizes are arbitrary,
#valve_xsize = 7*cm
#valve_ysize = 10*cm

#valve_x_plus = Box(xsize = valve_xsize, ysize = valve_ysize, zsize = valve_len, xcent = (valve_x_opening + valve_xsize)/2, ycent = 0, zcent = valve_zc)
#valve_x_minus = Box(xsize = valve_xsize, ysize = valve_ysize, zsize = valve_len, xcent = -(valve_x_opening + valve_xsize)/2, ycent = 0, zcent = valve_zc)
#valve_y_plus = Box(xsize = valve_xsize, ysize = valve_ysize, zsize = valve_len, xcent = 0, ycent = (valve_y_opening + valve_ysize)/2, zcent = valve_zc)
#valve_y_minus = Box(xsize = valve_xsize, ysize = valve_ysize, zsize = valve_len, xcent = 0, ycent = -(valve_y_opening + valve_ysize)/2, zcent = valve_zc)

#gate_valve = [valve_x_plus, valve_x_minus, valve_y_plus, valve_y_minus]

### End plates of the ESQs in the 1st triplet

#endplate_len = 4*mm
#endplate_aperture = 65*mm

#q7t1_endplate_1 = ZCylinderOut(endplate_aperture, endplate_len, zcent= q7t1p1_zc - 19.5*mm)
#q7t1_endplate_2 = ZCylinderOut(endplate_aperture, endplate_len, zcent= q7t1p1_zc + 19.5*mm)
#q7t1_endplate_3 = ZCylinderOut(endplate_aperture, endplate_len, zcent= q7t1p2_zc - 19.5*mm)
#q7t1_endplate_4 = ZCylinderOut(endplate_aperture, endplate_len, zcent= q7t1p2_zc + 19.5*mm)
#q7t1_endplate_5 = ZCylinderOut(endplate_aperture, endplate_len, zcent= q7t1p3_zc - 19.5*mm)
#q7t1_endplate_6 = ZCylinderOut(endplate_aperture, endplate_len, zcent= q7t1p3_zc + 19.5*mm)

#q7t1_endplates = [q7t1_endplate_1,q7t1_endplate_2,q7t1_endplate_3,q7t1_endplate_4,q7t1_endplate_5,q7t1_endplate_6]

### Slits between ESQ in the 1st triplet

## Slit sizes are arbitrarily chosen at present, only making sure they extend into the beam tube in transverse directions
## The opening size in x is based on drawings

#q7t1_mid_12 = (q7t1p1_zc+q7t1p2_zc)/2  # mid-point between 1st and 2nd ESQ
#q7t1_mid_23 = (q7t1p2_zc+q7t1p3_zc)/2  # mid-point between 2nd and 3rd ESQ

#slits1_x_opening = 7*cm
#slits2_x_opening = 9*cm
#slit_xsize = 8*cm
#slit_ysize = 15*cm
#slit_len = 4*mm

#q7t1_slits1_xplus = Box(xsize = slit_xsize, ysize = slit_ysize, zsize = slit_len, xcent = (slits1_x_opening + slit_xsize)/2, ycent = 0, zcent = q7t1_mid_12)
#q7t1_slits1_xminus = Box(xsize = slit_xsize, ysize = slit_ysize, zsize = slit_len, xcent = -(slits1_x_opening + slit_xsize)/2, ycent = 0, zcent = q7t1_mid_12)
#q7t1_slits2_xplus = Box(xsize = slit_xsize, ysize = slit_ysize, zsize = slit_len, xcent = (slits2_x_opening + slit_xsize)/2, ycent = 0, zcent = q7t1_mid_23)
#q7t1_slits2_xminus = Box(xsize = slit_xsize, ysize = slit_ysize, zsize = slit_len, xcent = -(slits2_x_opening + slit_xsize)/2, ycent = 0, zcent = q7t1_mid_23)

#q7t1_slits = [q7t1_slits1_xplus,q7t1_slits1_xminus,q7t1_slits2_xplus,q7t1_slits2_xminus]

## Q7 Electrodes

## function returns a list of 4 cylinders that approximate the q7 electrodes
## required input: center position of the electrode

#def q7_electrodes_conductor(zcenter):
	#q7_electrode_len = 200*mm

	## approximate each electrode by a cylinder
	#cylinder_offset = 170*mm
	#cylinder_radius = 95*mm

	#electrode_xplus = ZCylinder(cylinder_radius, q7_electrode_len, xcent = cylinder_offset, zcent= zcenter)
	#electrode_xminus = ZCylinder(cylinder_radius, q7_electrode_len, xcent = -cylinder_offset, zcent= zcenter)
	#electrode_yplus = ZCylinder(cylinder_radius, q7_electrode_len, ycent = cylinder_offset, zcent= zcenter)
	#electrode_yminus = ZCylinder(cylinder_radius, q7_electrode_len, ycent = -cylinder_offset, zcent= zcenter)

	#return [electrode_xplus, electrode_xminus, electrode_yplus, electrode_yminus]

##scraper = ParticleScraper([q7t1_endplate_1,q7t1_endplate_2,q7t1_endplate_3,q7t1_endplate_4,q7t1_endplate_5,q7t1_endplate_6])

#scraperlist = beampipe + d5p1_aperture + gate_valve + q7t1_endplates + q7t1_slits + q7_electrodes_conductor(q7t1p1_zc) + q7_electrodes_conductor(q7t1p2_zc) + q7_electrodes_conductor(q7t1p3_zc)

#scraper = ParticleScraper(scraperlist)

##scraper.registerconductor(scaperlist)

# Neutralization specifications
#
#    Define neutralization fraction function
#       rho_neut_f(z,s)
#    that returns the neutralization fraction based on axial location z within the lattice for the named
#    species "s". Values of rho_neut_f() are set by dictionary named arrays specified
#    by species with:
#
#       neut_z    = []   Break points in lattice with neutralization fraction [m]
#       neut_frac = []   Neutralization fraction to the right of corresponding break point:
#                         0 = no neut, 1 = full neut
#
#    * neut_z values must be in numerical order.
#    * neut_frac should be the same dimension as neut_z
#    * Comment: Should generalize this structure to allow for different neutralization factors
#      by species.
#

sp_neut_z = \
array(
[ecr_z_extr - 10.*cm, # z to the left of ECR extraction point ... beam should be launched to right
 gag_zc - 20.90*cm,   # z of neut stop before grated gap, set where 1% of gap E_z field reached
 gag_zc + 22.28*cm   # z of neut stop after  grated gap, set where 1% of gap E_z field reached
]    )

sp_neut_frac = \
array(
[0.75,
 0.,
 0.75
]    )

neut_z    = {key: sp_neut_z    for key in sp.keys()}
neut_frac = {key: sp_neut_frac for key in sp.keys()}

def rho_neut_f(z,s):
  # --- Find index giving location in neutralization fraction array
  index = sum(where(z/neut_z[s] >= 1., 1, 0)) - 1
  if index < 0: index = 0
  # --- Return neutralization fraction with no error checking to allow flexability
  f = neut_frac[s][index]
  return(f)

# Aperture specfications
#
#   r_ap   = array of aperture radii
#   v_ap   = array of aperture bias voltages
#   z_ap_l = array of aperture extent lower ranges
#   z_ap_u = array of aperture extent upper ranges
#
#   aperture_r(z):  function returning aperture at value of z
#
#   * Arrays should be same dimension.
#   * Aperture is loaded into the xy simulation for fieldsolves.
#   * Aperture and bias does not matter in xy simulations, but try to use the right values for
#     consistent reference potential.
#

#r_p_up   = 8.00*cm  # aperture   upstream of grated gap [m]
#r_p_down = 7.62*cm  # aperture downstream of grated gap [m]

#r_ap   = array([r_p_up,               gag_rp,       r_p_down  ])
#v_ap   = array([SourceBias+StandBias, StandBias/2., 0.        ])
#z_ap_l = array([ecr_z_extr,           gag_col_zs,   gag_col_ze])
#z_ap_u = array([gag_col_zs,           gag_col_ze,   d5p1_zc   ])

#r_p = max(r_ap)   # Max aperture in simulations

#def aperture_r(z):
  #index = sum(where(z/z_ap_l >= 1.,1,0))-1
  #if index < 0: index = 0
  ##
  #return(r_ap[index])

#aperture = []
#for i in range(len(r_ap)):
  #rp = r_ap[i]
  #v  = v_ap[i]
  #zl = z_ap_l[i]
  #zu = z_ap_u[i]
  ##
  #aperture.append( ZCylinderOut(radius=rp,zlower=zl,zupper=zu,condid="next") )

## --- Add a circular aperture particle scraper at pipe radius aperture.
##       Could also use ParticleScraper(conductors=aperture) but
##       setting prwall is faster for a simple cylinder.
top.prwall = 7.5*cm    # reset this later consistent with actual aperture in range simulated in advances


# this script is used to do the detailed analysis of the eigenfunction
#deploypath='/home/task1/xiangjian/temp'
deploypath=root['SETTINGS']['REMOTE_SETUP']['workDir']
plots=root['SETTINGS']['PLOTS']
effnum=plots['effnum']
Para_x=plots['2d']['Para_x']
Para_y=plots['2d']['Para_y']
para_x_eigen=plots['2d']['para_x_eigen']
para_y_eigen=plots['2d']['para_y_eigen']
ky_eigen=plots['ky_eigen']
if root['SETTINGS']['PLOTS']['idimplt']==0:
    datanode=root['OUTPUTScan'][Para_x][str(para_x_eigen)[0:effnum]][Para_y][str(para_y_eigen)[0:effnum]]['lin'][str(ky_eigen)[0:effnum]]
else:
    datanode=root['OUTPUTScan'][Para_x][str(para_y_eigen)[0:effnum]][Para_y][str(para_x_eigen)[0:effnum]]['lin'][str(ky_eigen)[0:effnum]]
datanode.deploy(deploypath)
tag=str(plots['paraval_eigen'])+'_'+str(plots['ky_eigen'])
root['OUTPUTS'][tag]=OMFITcgyro(deploypath)
# transform from theta space to r space
output=root['OUTPUTS'][tag]
ball=output['balloon']
phi=ball['balloon_phi'].T[-1]
apar=ball['balloon_apar'].T[-1]
bpar=ball['balloon_bpar'].T[-1]
theta=ball['theta_b_over_pi']*pi
ky=output['input.cgyro.gen']['KY']
kys=ky*output['input.cgyro.gen']['S']
kr=theta*kys
# get the b_theta and j_par ,function of kr and ky
btheta=kr*apar
jpar=(kr**2+ky**2)*apar
# do the fourier transform
nr=output['input.cgyro.gen']['N_RADIAL']
ntheta=len(theta)
#n_rarr=2*ntheta+1
n_rarr=2*(ntheta/4)+1
r_arr=linspace(-4*nr,4*nr,n_rarr)  # a good start from nr and ntheta
phi_r_arr=zeros(n_rarr)+1j*zeros(n_rarr)
apar_r_arr=zeros(n_rarr)+1j*zeros(n_rarr)
btheta_r_arr=zeros(n_rarr)+1j*zeros(n_rarr)
jpar_r_arr=zeros(n_rarr)+1j*zeros(n_rarr)
bpar_r_arr=zeros(n_rarr)+1j*zeros(n_rarr)
for k in range(n_rarr):
    phi_r_arr[k]=sum([complex(real(phi[p]+phi[p+1])/2.,imag(phi[p]+phi[p+1])/2.)*exp(1j*(kr[p]+kr[p+1])/2.*r_arr[k])*(kr[k+1]-kr[k]) for p in range(ntheta-1)])
    apar_r_arr[k]=sum([complex(real(apar[p]+apar[p+1])/2.,imag(apar[p]+apar[p+1])/2.)*exp(1j*(kr[p]+kr[p+1])/2.*r_arr[k])*(kr[k+1]-kr[k]) for p in range(ntheta-1)])
    btheta_r_arr[k]=sum([complex(real(btheta[p]+btheta[p+1])/2.,imag(btheta[p]+btheta[p+1])/2.)*exp(1j*(kr[p]+kr[p+1])/2.*r_arr[k])*(kr[k+1]-kr[k]) for p in range(ntheta-1)])
    jpar_r_arr[k]=sum([complex(real(jpar[p]+jpar[p+1])/2.,imag(jpar[p]+jpar[p+1])/2.)*exp(1j*(kr[p]+kr[p+1])/2.*r_arr[k])*(kr[k+1]-kr[k]) for p in range(ntheta-1)])
#bpar_r_arr[k]=sum([complex(real(bpar[p]+bpar[p+1])/2.,imag(bpar[p]+bpar[p+1])/2.)*exp(1j*(kr[p]+kr[p+1])/2.*r_arr[k])*dkr for p in range(ntheta)])
# so we store the data
output['kr']=kr
output['kys']=kys
output['nr']=nr
output['theta']=theta
output['phi']=phi
output['apar']=apar
output['btheta']=btheta
output['jpar']=jpar
output['r_arr']=r_arr
output['phi_r_arr']=phi_r_arr
output['apar_r_arr']=apar_r_arr
output['btheta_r_arr']=btheta_r_arr
output['jpar_r_arr']=jpar_r_arr


def unikati(s):
    seznam = []
    for i in s:
        if i not in seznam:
            seznam.append(i)
    return seznam

def avtor(tvit):
    author, x = tvit.split(":", 1)
    return author

def vsi_avtorji(tviti):
    seznam = []
    for i in tviti:
        x = avtor(i)
        if x not in seznam:
            seznam.append(x)
    return seznam

def izloci_besedo(beseda):
    if not beseda.isalnum():
        for znak in beseda:
            if znak.isalnum():
                break
            else:
                beseda = beseda.replace(znak, '')

        for znak2 in reversed(beseda):
            if znak2.isalnum():
                break
            else:
                beseda = beseda.replace(znak2, '')
    return beseda

def se_zacne_z(tvit, c):
    s = []
    tvit = izloci_besedo(tvit)

    spliti = tvit.split(" ")
    for i in spliti:
        if i.startswith(c):
            s.append(i.replace(c, '').replace(",", '').replace("?", ''))

    return s

def zberi_se_zacne_z(tviti, c):
    s = []
    for i in tviti:
        i = se_zacne_z(i, c)
        if i not in s:
            s.append(i)
    return s

def zberi_se_zacne_z(tviti, c):
    s = []
    for tvit in tviti:
        tvit = se_zacne_z(tvit, c)          #dobim nazaj seznam besed iz funkcije se_zacne_z(tvit, c)
        for beseda in tvit:                 #grem cez ta seznam da dobim ven vse besede
            if beseda not in s:             #ce posamezna beseda ni v MAIN seznamu, jo dodam
                s.append(beseda)
    return s

def vse_afne(tviti):
    return zberi_se_zacne_z(tviti, '@')

def vsi_hashtagi(tviti):
    return zberi_se_zacne_z(tviti, '#')

def vse_osebe(tviti):
    s = []
    for i in vsi_avtorji(tviti):
        s.append(i)
    for i in vse_afne(tviti):
        if i not in s:
            s.append(i)

    return sorted(s)