def unit5_count():
    try:
        with open('unit5.txt', 'w+') as unit5_file:
            unit5_file.write(input("Введите числа через пробел: "))
            count = map(int, unit5_file.read().split())

    except:
        print("К сожалению, неверно указан файл")

unit5_count()
sum_all = 0
with open('unit5.txt', 'r+', encoding="utf-8") as unit5_file_ch2:
    for i in unit5_file_ch2.read().split():
        sum_all += int(i)
if sum_all > 0:
    print(f"Сумма всех чисел, находящихся в unit5.txt, равна: {sum_all}")
else:
    print("В файле unit5.txt либо нет значений, либо они нулевые! ")


# To get the input from the user and count the number of even and odd
lst_size=int(input("Enter the number of elements to be added in the list:"))
lst=[]
count=1
even_count=0
odd_count=0
for i in range(lst_size):
    value=int(input("Enter the value: "))
    lst.append(value)
    count+=1
    if value%2==0:
        even_count+=1
    else:
        odd_count+=1
print("Count of even numbers:", even_count,"\nCount of odd numbers:", odd_count)


#this is the server file

from flask import Flask, render_template, request, redirect, session
import random
from datetime import datetime

app = Flask(__name__)
app.secret_key = 'keep it secret, keep it safe' # set a secret key for security purposes

@app.route('/', methods=['get']) #per instructions:  Have the root route render this [the wireframe] page..an that is about all it does
def start():

    new_time=datetime.now().strftime('%Y-%m-%d %H:%M:%S%f')

    if 'total_gold' not in session:
        session['total_gold'] = 0
    if 'activity_list' not in session:
        session['activity_list'] = []

    return render_template("ninjagold.html", activity_results=session['activity_list'], gold_count=session['total_gold']) #these extra values are just for testing and will move to the other route

@app.route('/process_money', methods=['POST'])  #per video, html form key-values will be sent to this route per instructions:  Have the "/process_money" POST route increase/decrease the user's gold by an appropriate amount and redirect to the root route.  I think this means the html page's form sends its results to this /process money route
def process_money():
    new_time=datetime.now().strftime('%Y-%m-%d %H:%M:%S%f')
    location_visited=request.form['locationclick'] #possible values:  farm, cave, house, casino
    print("location visited:  " + location_visited)
    if (location_visited=="farm"):
        new_gold=random.randint(10,20)
        new_activity_text="
Earned "+ str(new_gold) + " golds from the farm! (" + new_time + ")
"
    elif (location_visited=="cave"):
        new_gold=random.randint(5,10)
        new_activity_text="
Earned "+ str(new_gold) + " golds from the cave! (" + new_time + ")
"
    elif (location_visited=="house"):
        new_gold=random.randint(2,5)
        new_activity_text="
Earned "+ str(new_gold) + " golds from the house! (" + new_time + ")
"
    else:
        new_gold=random.randint(-50,50)
        if (new_gold>0):
            new_activity_text="
Entered a casino and won "+ str(new_gold) + " golds ! (" + new_time + ")
"
        elif (new_gold == 0):
            new_activity_text="
Entered a casino and won "+ str(1) + " golds  ! (" + new_time + ")
"
        else:
            new_activity_text="
Entered a casino and lost "+ str(new_gold*-1) + " golds  Ouch! (" + new_time + ")
"

    print("new activity string:  " + new_activity_text)

    session['total_gold'] = str(int(session['total_gold']) + new_gold)
    #session['activity_list'] = [new_activity_text,new_activity_text,'erer','4545t']
    session['activity_list'].insert(0,new_activity_text)
    print(session['activity_list'])

    return redirect("/")

if __name__ == "__main__":
    app.run(debug=True)


import sys

from api.hh_api import HeadHunterAPI
from config import EMPLOYEERS_VACANCY_ID
from database.db_manager import DBManager
from app.mixin_menu_app import MixinMenuAPP
from utils.сurrency_сonverter import get_currency_data
from app.job_search_meta import JobSearchAppMeta
from utils.loading_progress import show_loading_progress
from utils.generate_unique import generate_unique_four_letter_value

class JobSearchApp(MixinMenuAPP, metaclass=JobSearchAppMeta):
    """
        Главное приложение для поиска работы.

        Класс наследуется от миксина MixinMenuAPP и использует метакласс JobSearchAppMeta.

        Атрибуты:
            hh_api (HeadHunterAPI): Экземпляр класса HeadHunterAPI для работы с HeadHunter API.
            db_manager (DBManager): Экземпляр класса DBManager для работы с базой данных.
            existing_values (list): Список существующих значений для генерации уникальных идентификаторов.
    """
    hh_api = HeadHunterAPI()
    db_manager = DBManager()
    existing_values = []

    @classmethod
    def _interact_with_user(cls) -> None:
        """
            Взаимодействие с пользователем.

            Метод запускает взаимодействие с пользователем, предоставляя главное меню приложения и обрабатывая выбор
            пользователя.
        """
        cls.db_manager.connect()
        cls.db_manager.clear_tables()
        cls.__get_for_database_all_vacancies()
        cls.main_menu()
        cls.db_manager.disconnect()

    @classmethod
    def __get_for_database_all_vacancies(cls):
        """ Получение всех вакансий из API и запись в базу данных.

            Метод получает список всех вакансий от API, обрабатывает их и записывает в базу данных.
        """
        total_employers = len(EMPLOYEERS_VACANCY_ID)
        completed_employers = 0
        for employeer_name, employeer_id in EMPLOYEERS_VACANCY_ID.items():
            company_name = employeer_name
            company_vacancies = cls.hh_api.get_vacancies(employeer_id)
            for vacancy in company_vacancies:
                vacancy_name = vacancy["name"]
                vacancy_url = vacancy["alternate_url"]
                vacancy_from = int(vacancy["salary"]["from"]) if vacancy.get("salary") is not None and vacancy[
                    "salary"].get("from") is not None else 0
                vacancy_to = int(vacancy["salary"]["to"]) if vacancy.get("salary") is not None and vacancy[
                    "salary"].get("to") is not None else 0
                if vacancy.get("salary") and vacancy["salary"]["currency"] not in ["RUR", "RUB"]:
                    vacancy_from *= get_currency_data(vacancy["salary"]["currency"])
                    vacancy_to *= get_currency_data(vacancy["salary"]["currency"])
                vacancy_currency = "RUR"
                vacancy_id = generate_unique_four_letter_value(cls.existing_values)
                cls.db_manager.insert_vacancy_to_all(vacancy_id, company_name, vacancy_name, vacancy_from,
                                                     vacancy_to,
                                                     vacancy_currency,
                                                     vacancy_url)

                cls.db_manager.insert_vacancy_company(vacancy_id, company_name, vacancy_name, vacancy_from,
                                                      vacancy_to,
                                                      vacancy_currency,
                                                      vacancy_url)
            completed_employers += 1
            show_loading_progress(completed_employers, total_employers)
        sys.stdout.write("\rЗагрузка завершена!\n")

    @classmethod
    def _get_vacancies_with_keyword(cls, keyword):
        """ Получение списка вакансий с заданным ключевым словом.

           Метод получает список вакансий, в названии которых содержится заданное ключевое слово, из базы данных и
           выводит его на экран.

           Аргументы:
               keyword (str): Ключевое слово для поиска вакансий.
        """
        result_df = cls.db_manager.get_vacancies_with_keyword(keyword)
        result_str = result_df.to_string(index=False)
        print(result_str)

    @classmethod
    def _get_avg_salary(cls):
        """ Получение средней зарплаты по вакансиям.

            Метод получает среднюю зарплату по всем вакансиям из базы данных и выводит ее на экран.
        """
        print(cls.db_manager.get_avg_salary())

    @classmethod
    def _get_vacancies_with_higher_salary(cls):
        """ Получение списка вакансий с зарплатой выше средней.

           Метод получает список вакансий, у которых зарплата выше средней по всем вакансиям из базы данных и выводит
           его на экран.
        """
        result_df = cls.db_manager.get_vacancies_with_higher_salary()
        result_str = result_df.to_string(index=False)
        print(result_str)

    @classmethod
    def _get_companies_and_vacancies_count(cls):
        """ Получение списка всех компаний и количества вакансий у каждой компании.

            Метод получает список всех компаний и количество вакансий у каждой компании из базы данных и выводит его на
            экран.
        """
        result_df = cls.db_manager.get_companies_and_vacancies_count()
        result_str = result_df.to_string(index=False)
        print(result_str)

    @classmethod
    def _get_top_vacancies(cls):
        """ Получение списка топ-300 вакансий.

            Метод получает список топ-300 вакансий с указанием названия компании, названия вакансии и зарплаты, а также
            ссылки на вакансию из базы данных и выводит его на экран.
        """
        result_df = cls.db_manager.get_top_vacancies()
        result_str = result_df.to_string(index=False)
        print(result_str)


import itertools
digits = [ x for x in range(10) ]

i = 0
for x in itertools.permutations(digits):
    i += 1
    if i == 1000000:
        print(x)
        break

for c in x:
    print(c,end="")


import csv
import numpy as np
from pymc import Gamma, Normal, NoncentralT, Binomial, Uniform, invlogit, logit, deterministic, stochastic

### SETUP
# counts_pos, counts_total, batch_id, plate_id, row, col, treatment
rows = [tuple(row) for row in csv.reader(open('nephrine_fracs.csv'))]
pos_counts, total_counts, batch_ids, plate_ids, row_ids, col_ids, treatment_ids = [np.array(v) for v in zip(*rows)]
pos_counts = pos_counts.astype(int)
total_counts = total_counts.astype(int)
num_wells = len(pos_counts)

# batches
batch_names, batch_idxs = np.unique(batch_ids, return_inverse=True)
num_batches = len(batch_names)

# plates
plate_names, plate_idxs = np.unique(plate_ids, return_inverse=True)
num_plates = len(plate_names)

# batchrows, batchcols
batchrow_names, batchrow_idxs = np.unique(['batchrow_%s_%s'%(b, r) for b, r in zip(batch_ids, row_ids)], return_inverse=True)
batchcol_names, batchcol_idxs = np.unique(['batchcol_%s_%s'%(b, c) for b, c in zip(batch_ids, col_ids)], return_inverse=True)
num_batchrows = len(batchrow_names)
num_batchcols = len(batchcol_names)

# treatments
treatment_names, treatment_idxs = np.unique(treatment_ids, return_inverse=True)
num_treatments = len(treatment_names)

### MODEL
# base effect, uninformative prior
base_fx = Normal('base', mu=0, tau=0.001, size=1, value=np.zeros(1))

# batch effect, somewhat informative prior
batch_fx = Normal('batch_fx', mu=0, tau=0.1, size=num_batches, value=np.zeros(num_batches))

# plate effect, two-level prior, somewhat informative
plate_prec = Gamma('plate_prec', alpha=0.1, beta=0.1)
plate_fx = np.array([Normal('plate_fx_%s'%(name), mu=0, tau=plate_prec, value=0) for name in plate_names])

# batch row and column effects, two-level prior
batchrowcol_prec_base = Gamma('batchrowcol_prec_prior', alpha=0.01, beta=0.01)
batchrow_fx = np.array([Normal('batchrow_fx_%s'%(name), mu=0, tau=batchrowcol_prec_base, value=0) for name in batchrow_names])
batchcol_fx = np.array([Normal('batchcol_fx_%s'%(name), mu=0, tau=batchrowcol_prec_base, value=0) for name in batchcol_names])

def initial_guess(treatment):
    return np.median(logit((pos_counts[treatment_ids == treatment] + 1).astype(float) / (total_counts[treatment_ids == treatment] + 2)))

# treatment effect - individual precisions
# NB: these are the values we are interested in capturing.
treatment_prec = [Gamma('treatment_prec_%s'%(name), alpha=0.01, beta=0.01, value=0.5) for name in treatment_names]
treatment_fx = np.array([Normal('treatment_fx_%s'%(name), mu=0, tau=treatment_prec[idx], value=initial_guess(name)) for idx, name in enumerate(treatment_names)])

# # well effects - we want to allow outliers, so use a 3-parameter
# # Student's t distribution (see ARM, pg. 384, Gelman & Hill)
# # nu = degrees of freedom
# well_df_inv = Uniform('well_df_inv', lower=0.0, upper=0.5, value=0.25)
# @deterministic(plot=False)
# def well_df(well_df_inv=well_df_inv):
#     return 1.0 / well_df_inv
#
# #lam = scale
# @deterministic(plot=False)
# def well_lam(well_df=well_df):
#     return (well_df - 2) / well_df
#
# well_fx = np.array([NoncentralT('well_fx_%d'%(wellidx), mu=0, lam=well_lam, nu=well_df, value=0) for wellidx in range(num_wells)])

# Unnobserved probabilities per well
@deterministic(plot=False)
def p_wells(base_fx=base_fx,
            batch_fx=batch_fx,
            plate_fx=plate_fx,
            batchrow_fx=batchrow_fx,
            batchcol_fx=batchcol_fx,
            treatment_fx=treatment_fx):
    # use this ordering to make everything turn into an ArrayContainer
    return invlogit(treatment_fx[treatment_idxs] +
                    base_fx +
                    batch_fx[batch_idxs] +
                    plate_fx[plate_idxs] +
                    batchrow_fx[batchrow_idxs] +
                    batchcol_fx[batchcol_idxs])

# Likelihood
pos_counts_likelihood = Binomial('pos_counts', value=pos_counts, n=total_counts, p=p_wells, observed=True, verbose=0)


n = int(input())
i = 2

while n != 1:
    if n % i == 0:
        n /= i
        print(i)
    else:
        i += 1

# 시간초과
# import math

# n = int(input())
# a = []
# b = []

# # 소수 판별
# def prime(x):
#     for i in range(2, int(math.sqrt(x)) + 1):
#         if x % i == 0:
#             return False
#     return True

# # 소인수분해
# for i in range(2, n):
#     if prime(i):
#         while n % i == 0:
#             n /= i
#             print(i)


from random import choice

from faker import Faker

bank_names_fr = [
    "Banque CIBC",
    "BMO Banque de Montréal",
    "Banque Desjardins",
    "Banque HSBC Canada",
    "Banque Laurentienne du Canada",
    "Banque Nationale du Canada",
    "Banque Royale du Canada",
    "Banque Scotia",
    "Banque TD Canada Trust",
]

bank_names_en = [
    "CIBC Bank",
    "BMO Montreal Bank",
    "Desjardins Bank",
    "HSBC Canada Bank",
    "Laurentian Bank of Canada",
    "National Bank of Canada",
    "Royal Bank of Canada",
    "Scotia Bank",
    "TD Canada Trust Bank",
]

class FinancingFaker:
    def __init__(self, locale: str) -> None:
        """
        A faker to fake a financing institution.

                locale (str): The locale language setting to use for simulation. Can either be `'fr_CA'` or `'en_CA'`.
        """
        self.locale = locale

        self.address_faker = Faker(locale=self.locale)

        if self.locale == "fr_CA":
            self.bank_name = bank_names_fr
        elif self.locale == "en_CA":
            self.bank_name = bank_names_en
        else:
            raise ValueError(f"The locale {locale} is not supporter. It can either be 'fr_CA' or 'en_CA'.")

    def financing(self) -> str:
        """
        Method to fake a financing details information. Namely, is name and address.

        Return:
            A string of the bank name and address in capitalize characters.
        """
        bank = choice(self.bank_name)
        address = self.address_faker.address()

        return f"{bank} {address}"


import argparse
import numpy as np
import pandas as pd

import io_tools

BASE_TIMESTEP = 10
MAX_TIMESTEP = 120

parser = argparse.ArgumentParser(description="Reduce displacement data for remote processing.")

parser.add_argument("disp_file", help="displacements file")
parser.add_argument("outfile", help="output file")

args = parser.parse_args()

df = pd.read_csv(args.disp_file, dtype=io_tools.DTYPE_DICT)

df = io_tools.filter_displacement_data(df, remove_zeros=False, base_timestep=BASE_TIMESTEP)

df = df[df[io_tools.TIMESTEP] <= MAX_TIMESTEP]

df.to_csv(args.outfile)


import weibull

# fail times include no censored data
fail_times = [
    9402.7,
    6082.4,
    13367.2,
    10644.6,
    8632.0,
    3043.4,
    12860.2,
    1034.5,
    2550.9,
    3637.1
]

# this is where the actual analysis and curve fitting occur
analysis = weibull.Analysis(fail_times, unit='hour')
analysis.fit()

analysis.probplot()

print(f'beta: {analysis.beta}\teta: {analysis.eta}')
print(f'B2 life: {analysis.b(2):.02f}\nB10 life: {analysis.b(10):.02f}\nB50 life: {analysis.b(50):.02f}')
print(f'median: {analysis.median}')
print(f'mean: {analysis.mean}')
print(f'mttf: {analysis.mttf}')


#!/usr/bin/env python3
import yaml
import rospy
import os
from uav_abstraction_layer.srv import TakeOff, GoToWaypoint, Land
from geometry_msgs.msg import PoseStamped

class WayPointTracker:
    def __init__(self):
        self.uav_namespace = rospy.get_param("~uav_namespace", "")
        self.file_path = rospy.get_param("~flight_plan_path", "")
	# Create the servies
        self.take_off_service_name = os.path.join("/", self.uav_namespace, "ual/take_off")
        self.go_to_service_name = os.path.join("/", self.uav_namespace, "ual/go_to_waypoint")
        self.land_service_name = os.path.join("/", self.uav_namespace, "ual/land")
        self.take_off_service = self.registerService(self.take_off_service_name, TakeOff)
        self.go_to_service = self.registerService(self.go_to_service_name, GoToWaypoint)
        self.land_service = self.registerService(self.land_service_name, Land)
        # Load flight plan
        self.raw_flight_plan = None
        self.flight_plan = None
        self.loop_waypoints = None
        self.loadFlightPlan()
        self.parseFlightPlan()
        # Exectute flight plan
        self.takeOff(self.take_off_service, self.flight_plan['TakeOff'])
        self.followPoints(self.go_to_service, self.flight_plan['Waypoints'])
        self.goToWaypoint(self.go_to_service, self.flight_plan['LandingPosition'])
        self.land(self.land_service)

    def loadFlightPlan(self):
        # Check file exists
        if not os.path.exists(self.file_path):
            raise ValueError("The file does not exist, please check the provided path.")

        with open(self.file_path, 'r') as wp_file:
            self.raw_flight_plan = yaml.safe_load(wp_file)

    def makeStampedPose(self, data, frame):
        waypoint = PoseStamped()
        waypoint.header.frame_id = frame
        waypoint.pose.position.x =    data[0]
        waypoint.pose.position.y =    data[1]
        waypoint.pose.position.z =    data[2]
        waypoint.pose.orientation.x = data[3]
        waypoint.pose.orientation.y = data[4]
        waypoint.pose.orientation.z = data[5]
        waypoint.pose.orientation.w = data[6]
        return waypoint

    def parseFlightPlan(self):
        self.loop_waypoints = self.raw_flight_plan['loop_waypoints']
        self.flight_plan = {}
        self.flight_plan['TakeOff'] = self.raw_flight_plan['take_off_altitude']
        self.flight_plan['LandingPosition'] = self.makeStampedPose(self.raw_flight_plan['landing_position'],
                                                              self.raw_flight_plan['frame_id'])
        self.flight_plan['Waypoints'] = []
        for i in self.raw_flight_plan['waypoints']:
            waypoint = self.makeStampedPose(i, self.raw_flight_plan['frame_id'])
            self.flight_plan['Waypoints'].append(waypoint)

    def followPoints(self, go_to_service, waypoints):
        if self.loop_waypoints:
            while (not rospy.is_shutdown()):
                for waypoint in waypoints:
                    self.goToWaypoint(go_to_service, waypoint)
        else:
            for waypoint in waypoints:
                self.goToWaypoint(go_to_service, waypoint)

    def registerService(self, service_path, service_type):
        rospy.wait_for_service(service_path)
        try:
            service = rospy.ServiceProxy(service_path, service_type)
        except rospy.ServiceException as e:
            print("Service registration failed: %s", e)
        return service

    def goToWaypoint(self, go_to_service, waypoint):
        try:
            go_to_service(waypoint, True)
        except rospy.ServiceException as e:
            print("Service call failed: %s", e)

    def takeOff(self, take_off_service, height):
        try:
            take_off_service(height, True)
        except rospy.ServiceException as e:
            print("Service call failed: %s", e)

    def land(self, land_service):
        try:
            land_service(True)
        except rospy.ServiceException as e:
            print("Service call failed: %s", e)

if __name__ == "__main__":
    rospy.init_node('waypoint_tracker')
    WPT = WayPointTracker()


# -*- coding: utf-8 -*-
from __future__ import absolute_import

from enigma import eInputDeviceManager, eTimer
from Screens.Screen import Screen
from Screens.Rc import Rc
from Components.Sources.List import List
from Components.ActionMap import ActionMap
from Components.config import config
from Components.Sources.StaticText import StaticText
from Tools.Directories import pathExists, resolveFilename, SCOPE_CURRENT_SKIN
from Tools.LoadPixmap import LoadPixmap
from Tools.Log import Log

from os import path as os_path

import six

from .CharJump import CharJump
from .InputDeviceIRDatabase import irdb
from .IrProtocols.ProtocolMaster import ProtocolMaster
from .KeyBindingList import KeyBindingList

class InputDeviceIRProg(Screen, CharJump):
	PLUGIN_IMAGES_PATH = "%s/images/" % (os_path.dirname(__file__))
	SKIN_IMAGES_PATH = resolveFilename(SCOPE_CURRENT_SKIN, config.skin.primary_skin.value.replace("/skin.xml", "/images/"))
	MAJOR_CODELIST_ITEMS = [ "amp", "av ", "tv", "vcr", "sat"]

	def __init__(self, session, remote):
		Screen.__init__(self, session)
		CharJump.__init__(self, session)
		self._remote = remote

		self["actions"] = ActionMap(["ListboxActions", "OkCancelActions", "EPGSelectActions"],
		{
			"ok": self._onKeyOK,
			"cancel": self._onKeyExit,
			"info" : self._onKeyInfo
		}, -1)

		self["list"] = List()
		self["list"].onSelectionChanged.append(self._onSelectionChanged)
		self._status = StaticText()
		self["status"] = self._status

		self._vendorPixmap = self._loadPixmap("vendor.svg")
		self._seperatorPixmap = self._loadPixmap("div-h.svg")
		self._level = 0
		self._lastLevel = 0
		self._lastVendor = ""
		self._keysAcknowledged = 0
		self._keysAckTimer = eTimer()
		self.__keysAckTimer_connection = self._keysAckTimer.timeout.connect(self._onKeysAckTimeout)
		self.__onIrKeycount_connection = eInputDeviceManager.getInstance().irKeyCount.connect(self._onIrKeyCount)
		self.onLayoutFinish.append(self._reload)

	def _onIrKeyCount(self, address, count):
		if address == self._remote.address():
			self._keysAcknowledged = count
			self._keysAckTimer.startLongTimer(2)

	def _onKeysAckTimeout(self):
		self.session.toastManager.showToast(_("%s IR codes acknowledged!") %(self._keysAcknowledged))
		self._keysAcknowledged = 0

	def _loadPixmap(self, filename, desktop=None):
		picfile = None
		if filename[0] == "/" and pathExists(filename):
			picfile = filename
		else:
			for p in (self.SKIN_IMAGES_PATH, self.PLUGIN_IMAGES_PATH):
				imagepath = "%s%s" % (p, filename)
				if pathExists(imagepath):
					picfile = "%s%s" % (p, filename)
					break
		if picfile:
			return LoadPixmap(path=picfile, desktop=desktop, cached=False)
		return None

	def _onKeyExit(self):
		if self._level == 1:
			self._level = 0
			self._reload()
			return
		self.close()

	def _getFirstForChar(self, char):#CharJump
		idx = 0
		for x in self["list"].list:
			val = x[0][0]
			Log.w(val)
			if val and val[0].upper() == char: # and not val.lower() in self.MAJOR_VENDORS:
				self["list"].setIndex(idx)
				break
			idx += 1

	def _onKey0(self, unused):#CharJump
		if self["list"].count():
			self["list"].setIndex(0)

	def _reload(self, dlist={}):
		if self._level == 0:
			dlist = irdb.data
		mlist = []
		for x, y in dlist.items():
			x = six.ensure_str(x)
			title = x
			subtitle = ""
			pic = self._seperatorPixmap
			if self._level == 0:
				lendev = len(y)
				if lendev == 1:
					subtitle = "%s" % (six.ensure_str(y.keys()[0]))
				else:
					subtitle = _("%s devices") % (lendev,)
			else:
				models = y.get("models", [])
				sorted_models = []
				if models:
					for dev in models:
						dev = six.ensure_str(dev)
						append = True
						for item in self.MAJOR_CODELIST_ITEMS:
							if dev.lower().startswith(item):
								append = False
						if append:
							sorted_models.append(dev)
						else:
							sorted_models.insert(0, dev)
					title = " / ".join(sorted_models)
				if title == "":
					title = _("Unknown")
				if not len(y["keys"]):
					Log.w("No known automap-keys for %s" % (title,))
				subtitle = _("%s mapped keys") % (len(y["keys"]))
			mlist.append(((x, y), self._vendorPixmap, subtitle, title, pic))
		if self._level != 0:
			def sortCodelist(x):
				x = x[0][0]
				val = "000000"
				items = self.MAJOR_CODELIST_ITEMS[:]
				items.reverse()
				for key in items:
					if x.lower().startswith(key):
						return val + x
					val = "{}{}".format(val, "000000")
				return x

			mlist = sorted(mlist, key=sortCodelist)
		self["list"].setList(mlist)
		if self._level == 0:
			self["list"].setIndex(self._lastLevel)
			self.setTitle(_("Vendors"))
			self["status"].setText("%s entries" % (len(mlist),))
		else:
			self.setTitle(self._lastVendor)
			self._onSelectionChanged()

	def _onKeyOK(self):
		sel = self["list"].getCurrent()
		entry = sel and sel[0]
		if not len(entry):
			return
		if self._level == 0:
			self._level = 1
			self._lastLevel = self["list"].getIndex()
			self._lastVendor = six.ensure_str(entry[0])
			self._reload(entry[1])
		else:
			self._send(entry[1])

	def _onKeyInfo(self):
		if self._level == 0:
			return
		sel = self["list"].getCurrent()
		entry = sel and sel[0]
		if not len(entry):
			return
		device, data = entry[0:2]
		title = six.ensure_str("%s - %s (%s - %s:%s)" %(self._lastVendor, device, data["protocol"], data["device"], data["subdevice"]))
		self.session.open(InputDeviceKeyInfo, title, data["keys"].keys())

	def _send(self, data):
		protocolData = ProtocolMaster.buildProtocol(data)
		self._remote.resetIr()
		for d in protocolData: #initial / repeat
			protocol, isRepeat, keys = d
			if protocol:
				self._remote.setIrProtocol(isRepeat, protocol)
			for irKey in keys:
				self._remote.setIrKey(irKey)
		self._remote.getIrKeyCount()
		self.session.toastManager.showToast(_("%s IR codes sent!") %(len(keys)), 3)

	def _onSelectionChanged(self):
		if self._level == 0:
			return
		entry = self["list"].getCurrent()
		entry = entry and entry[0]
		if not entry:
			return
		device, data = entry
		count = len(data["keys"])
		self["status"].setText(_("Press OK to apply assign %s keys of '%s'") %(count, device))

class InputDeviceKeyInfo(Screen, Rc):
	def __init__(self, session, title, boundKeys):
		Screen.__init__(self, session, windowTitle=title)
		Rc.__init__(self, 3)
		keys = sorted([six.ensure_str(x) for x in boundKeys])
		self["list"] = KeyBindingList(3, keys)
		self["list"].onSelectionChanged.append(self._onSelectionChanged)
		self["actions"] = ActionMap(["OkCancelActions"],
		{
			"cancel": self.close,
		}, -1)
		self.onLayoutFinish.append(self._onSelectionChanged)

	def _onSelectionChanged(self):
		self.clearSelectedKeys()
		selection = self["list"].getCurrent()
		Log.w(selection)
		selection = selection and selection[0]
		if not selection:
			return
		self.selectKey(selection)


#!/usr/bin/env python3.6

import os, sys
import yaml

from lmfit import Model
from lmfit.models import GaussianModel
from lmfit.model import save_modelresult
from lmfit.model import load_modelresult

from reproject import reproject_exact

from astropy.io import ascii, fits
from astropy.table import Table, Column
import numpy as np
#import numpy.ma as ma

import tPlay,cvPlay,bptPlot,momPlot

tP = tPlay.tplay()
cvP = cvPlay.convert()
bpt = bptPlot.BPTplot()
mPl = momPlot.MOMplot()

class momplay:
    '''Modules to create moment maps, residual maps, line ratios maps
    - makeMoments
        load line list, datacube and create loop for moments module
    - makeSigmaCentroidMap
        load line list, datacube and create loop for momSigmaCentroid module
    - makeMomPlots
        load line list, call momPlot for each line for mom0, mom1 maps from gaussian components
    - momSigmaCentroid
        mom0, mom1 from centroid and sigma of fitted line
    - moments
        mom0, mom1, mom2 of the fitted gaussian components of the line
    - resCube
        cube of residuals of fit
    - resLines
        for each line residuals are computed as the standard deviation of line-fit
        within vrange and as the sum of the absolute value of line-fit
    - makeLineRatioMaps
        load line list, and create loop for momLineRatio
    - momLineRatio
        maps of the line ratios (OIII/Hbeta, NII/Halpha, SII/Halpha)
    - momCDist
        map of the eta-parameter (distance from Kauffmann and Kewley SF curves)
    '''

    def makeMoments(self,cfg_par):

        workDir = cfg_par['general']['cubeDir']

        f = fits.open(cfg_par['general']['dataCubeName'])
        dd = f[0].header

        lineInfo = tP.openLineList(cfg_par)
        for ii in range(0,len(lineInfo['ID'])):
        #for ii in range(0,1):

            lineNameStr = str(lineInfo['Name'][ii])

            if '[' in lineNameStr:
                lineName = lineNameStr.replace("[", "")
                lineName = lineName.replace("]", "")
                lineName = lineName+str(int(lineInfo['Wave'][ii]))
            else:
                lineName = lineNameStr+str(int(lineInfo['Wave'][ii]))

            lineNameStr=lineNameStr+str(int(lineInfo['Wave'][ii]))
            lineThresh = float(lineInfo['SNThresh'][ii])
            cenRange = float(lineInfo['cenRange'][ii])

            print('\n\t         +++\t\t    '+lineName+'\t\t +++')

            if ii==0:
                doBinMap=True
            else:
                doBinMap=True

            self.moments(cfg_par,lineName,lineNameStr,dd,cfg_par['general']['outTableName'],lineThresh,doBinMap,cenRange)

        return

    def makeSigmaCentroidMaps(self,cfg_par):

        workDir = cfg_par['general']['cubeDir']

        f = fits.open(cfg_par['general']['dataCubeName'])
        dd = f[0].header

        lineInfo = tP.openLineList(cfg_par)
        for ii in range(0,len(lineInfo['ID'])):
        #for ii in range(0,1):

            lineNameStr = str(lineInfo['Name'][ii])

            if '[' in lineNameStr:
                lineName = lineNameStr.replace("[", "")
                lineName = lineName.replace("]", "")
                lineName = lineName+str(int(lineInfo['Wave'][ii]))
            else:
                lineName = lineNameStr+str(int(lineInfo['Wave'][ii]))

            lineNameStr=lineNameStr+str(int(lineInfo['Wave'][ii]))
            lineThresh = float(lineInfo['SNThresh'][ii])
            cenRange = float(lineInfo['cenRange'][ii])

            print('\t         +++\t\t'+lineName+'\t\t+++')

            self.momSigmaCentroid(cfg_par,lineName,lineNameStr,dd,lineThresh,cenRange)

        return

    def makeMomPlots(self,cfg_par):

        workDir = cfg_par['general']['cubeDir']
        modName = cfg_par['gFit']['modName']
        momModDir = cfg_par['general']['momDir']+modName+'/'

        lineInfo = tP.openLineList(cfg_par)
        for ii in range(0,len(lineInfo['ID'])):
        #for ii in range(0,1):

            lineNameStr = str(lineInfo['Name'][ii])

            if '[' in lineName:
                lineName = lineNameStr.replace("[", "")
                lineName = lineName.replace("]", "")

            lineName = lineName+str(int(lineInfo['Wave'][ii]))
            lineThresh = float(lineInfo['SNThresh'][ii])
            cenRange = float(lineInfo['cenRange'][ii])

            print('\n\t *********** --- Plot Moms: '+lineName+' --- ***********\n')

            mom0Name = momModDir+'mom0_g1-'+lineName+'.fits'
            mom1Name = momModDir+'mom1_g1-'+lineName+'.fits'

            mPl.mom0Plot(cfg_par, mom0Name,lineName,lineNameStr,lineThresh)
            mPl.mom1Plot(cfg_par, mom1Name,lineName,lineThresh,lineNameStr, 'moments',vRange=[-cenRange,cenRange])

        return

    def momSigmaCentroid(self,cfg_par,lineName,lineNameStr,header,lineThresh,cenRange):

        modName = cfg_par['gFit']['modName']
        momModDir = cfg_par['general']['momDir']+modName+'/'

        if not os.path.exists(momModDir):
            os.mkdir(momModDir)

        if 'CUNIT3' in header:
            del header['CUNIT3']
        if 'CTYPE3' in header:
            del header['CTYPE3']
        if 'CDELT3' in header:
            del header['CDELT3']
        if 'CRVAL3' in header:
            del header['CRVAL3']
        if 'CRPIX3' in header:
            del header['CRPIX3']
        if 'NAXIS3' in header:
            del header['NAXIS3']
        if 'CRDER3' in header:
            del header['CRDER3']

        momSigmaHead = header.copy()
        momCentroidHead = header.copy()
        momW80Head = header.copy()

        hdul = fits.open(cfg_par['general']['outTableName'])
        lines = hdul['Ancels'+cfg_par['gFit']['modName']].data
        if cfg_par['gFit']['modName'] == 'BF':
            cfg_par['gFit']['modName'] = 'g2'

        residuals = hdul['Residuals_'+cfg_par['gFit']['modName']].data
        #esiduals = hdul['Residuals_G1'].data

        linesG1 = hdul['LineRes_G1'].data

        #hduGen = fits.open(cfg_par['general']['outVorLineTableName'])
        tabGen = hdul['BININFO'].data

        momSigma = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
        momCentroid = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
        momW80 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
        momDisp = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        for i in range(0,len(lines['BIN_ID'])):

            match_bin = np.where(tabGen['BIN_ID']==lines['BIN_ID'][i])[0]

            for index in match_bin:

                thresHold = residuals['SN_NII6583'][index]
                sigmaThresh = linesG1['g1_SigIntr_NII6583'][index]

                if thresHold >= lineThresh and sigmaThresh < cfg_par['moments']['sigmaThresh']:

#                if thresHold >= lineThresh :

                    momW80[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['w80_'+lineName][i]
                    momSigma[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['sigma_'+lineName][i]
                    momCentroid[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['centroid_'+lineName][i]
                    momDisp[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['dispIntr_'+lineName][i]

        momSigmaHead['WCSAXES'] = 2
        momSigmaHead['SPECSYS'] = 'topocent'
        momSigmaHead['BUNIT'] = 'km/s'

        fits.writeto(momModDir+'momSigma-'+lineName+'.fits',momSigma,momSigmaHead,overwrite=True)

        mPl.mom2Plot(cfg_par, momModDir+'momSigma-'+lineName+'.fits',lineName,lineThresh,lineNameStr,'ancillary')

        fits.writeto(momModDir+'momDisp-'+lineName+'.fits',momDisp,momSigmaHead,overwrite=True)
        mPl.mom2Plot(cfg_par, momModDir+'momDisp-'+lineName+'.fits',lineName,lineThresh,lineNameStr,'ancillary')

        momCentroidHead['WCSAXES'] = 2
        momCentroidHead['SPECSYS'] = 'topocent'
        momCentroidHead['BUNIT'] = 'km/s'

        fits.writeto(momModDir+'momCentroid-'+lineName+'.fits',momCentroid,momCentroidHead,overwrite=True)
        mPl.mom1Plot(cfg_par, momModDir+'momCentroid-'+lineName+'.fits',lineName,lineThresh,
            lineNameStr,'ancillary',vRange=[-cenRange,cenRange],modName=cfg_par['gFit']['modName'])

        momW80Head['WCSAXES'] = 2
        momW80Head['SPECSYS'] = 'topocent'
        momW80Head['BUNIT'] = 'km/s'
        fits.writeto(momModDir+'momW80-'+lineName+'.fits',momW80,momW80Head,overwrite=True)
        mPl.mom2Plot(cfg_par, momModDir+'momW80-'+lineName+'.fits',lineName,lineThresh,lineNameStr,'ancillary')

        return

    def moments(self,cfg_par,lineName,lineNameStr,header,outTableName,lineThresh,doBinMap,cenRange):

        modName = cfg_par['gFit']['modName']
        momModDir = cfg_par['general']['momDir']+modName+'/'

        if not os.path.exists(momModDir):
            os.mkdir(momModDir)

        if 'CUNIT3' in header:
            del header['CUNIT3']
        if 'CTYPE3' in header:
            del header['CTYPE3']
        if 'CDELT3' in header:
            del header['CDELT3']
        if 'CRVAL3' in header:
            del header['CRVAL3']
        if 'CRPIX3' in header:
            del header['CRPIX3']
        if 'NAXIS3' in header:
            del header['NAXIS3']

        mom0Head = header.copy()
        mom1Head = header.copy()
        mom2Head = header.copy()
        binHead  = header.copy()

        hdul = fits.open(cfg_par['general']['outTableName'])

        lines = hdul['LineRes_'+cfg_par['gFit']['modName']].data

#        lines['BIN_ID'] = hdul['BININFO'].data['ID']
        residuals = hdul['Residuals_'+cfg_par['gFit']['modName']].data
        #residuals = hdul['Residuals_G1'].data

        linesG1 = hdul['LineRes_G1'].data

        hduGen = fits.open(cfg_par['general']['outVorLineTableName'])

        tabGen = hduGen[1].data

        ampSpax = np.empty(len(tabGen['BIN_ID']))

        mom0G1 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
        mom1G1 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
        mom2G1 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
        heightG1 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        if doBinMap==True:
            binMap = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        if modName != 'g1':
            #ancels = hdul['Ancels_'+cfg_par['gFit']['modName']].data
            mom0Tot = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
            mom0G2 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
            mom1G2 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
            mom2G2 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
            if modName == 'g3':
                mom0G3 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
                mom1G3 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
                mom2G3 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        for i in range(0,len(lines['BIN_ID'])):
            #if lines['BIN_ID'][i]< 0:
            #    continue
            #else:

            match_bin = np.where(tabGen['BIN_ID']==lines['BIN_ID'][i])[0]

            for index in match_bin:

                thresHold = residuals['SN_NII6583'][i]
                sigmaThresh = linesG1['g1_SigIntr_NII6583'][i]

                if cfg_par['gFit']['method'] == 'pixel':
                    tabGen['NSPAX'][index] = 1.

                #if modName=='g2':
                #    ampSpax[index] = (lines['g1_Amp_'+lineName][i]+lines['g2_Amp_'+lineName][i])/tabGen['NSPAX'][index]
                #elif modName=='g3':
                #    ampSpax[index] = (lines['g1_Amp_'+lineName][i]+lines['g2_Amp_'+lineName][i]+lines['g3_Amp_'+lineName][i])/tabGen['NSPAX'][index]

                #thresHold = lines['g1_Height_'+lineName][i]/0.3989423*lines['g1_Sigma_'+lineName][i]/noise[0,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])]
                #print(lines['g1_Height_'+lineName][i]/0.3989423*lines['g1_Sigma_'+lineName][i],lines['g1_Sigma_'+lineName][i],lines['g1_Height_'+lineName][i])
                #print(thresHold,lineThresh)

                if thresHold >= lineThresh and sigmaThresh < cfg_par['moments']['sigmaThresh']:
#                if thresHold >= lineThresh:

                    mom0G1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g1_Amp_'+lineName][i]/tabGen['NSPAX'][index]
#                        mom0G1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g1_Height_'+lineName][i]/tabGen['NSPAX'][index]
                    mom1G1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g1_Centre_'+lineName][i]
                    mom2G1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g1_SigIntr_'+lineName][i]
                    heightG1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g1_Height_'+lineName][i]

                    if doBinMap==True:
                        binMap[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['BIN_ID'][i]

                    if modName != 'g1':
                        mom0G2[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g2_Amp_'+lineName][i]/tabGen['NSPAX'][index]
                        if lines['g2_Amp_'+lineName][i]!=0.0:
                                mom1G2[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g2_Centre_'+lineName][i]
                                mom2G2[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g2_SigIntr_'+lineName][i]

                        if modName == 'g3':
                            mom0G3[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g3_Amp_'+lineName][i]/tabGen['NSPAX'][index]
                            if lines['g2_Amp_'+lineName][i]!=0.0:
                                mom1G3[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g3_Centre_'+lineName][i]
                                mom2G3[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lines['g3_SigIntr_'+lineName][i]

                        #mom0Tot[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = ampSpax[i]

                    #else#:
                    #    print(mom1G1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])])
                    #    print(int(tabGen['PixY'][index]),int(tabGen['PixX'][index]))

        if doBinMap==True:

            binHead['SPECSYS'] = 'topocent'
            binHead['BUNIT'] = 'Flux'
            fits.writeto(momModDir+'binMapMom0_'+lineName+'.fits',binMap, binHead,overwrite=True)

        del mom0Head['CRDER3']
        del mom1Head['CRDER3']
        del mom2Head['CRDER3']

        mom0Head['WCSAXES'] = 2

        mom0Head['SPECSYS'] = 'topocent'
        mom0Head['BUNIT'] = 'Jy/beam.km/s'
        fits.writeto(momModDir+'mom0_g1-'+lineName+'.fits',mom0G1,mom0Head,overwrite=True)
        fits.writeto(momModDir+'height_g1-'+lineName+'.fits',heightG1,mom0Head,overwrite=True)

        #mPl.mom0Plot(cfg_par, momModDir+'mom0_g1-'+lineName+'.fits',lineName,lineNameStr,lineThresh)

        mom1Head['WCSAXES'] = 2
        mom1Head['SPECSYS'] = 'topocent'
        mom1Head['BUNIT'] = 'km/s'
        fits.writeto(momModDir+'mom1_g1-'+lineName+'.fits',mom1G1,mom1Head,overwrite=True)
        #mPl.mom1Plot(cfg_par, momModDir+'mom1_g1-'+lineName+'.fits',lineName,
        #    lineThresh, lineNameStr,'moments', vRange=[-cenRange,cenRange],modName='g1')

        mom2Head['WCSAXES'] = 2
        mom2Head['SPECSYS'] = 'topocent'
        mom2Head['BUNIT'] = 'km/s'
        fits.writeto(momModDir+'mom2_g1-'+lineName+'.fits',mom2G1,mom2Head,overwrite=True)
        #mPl.mom2Plot(cfg_par, momModDir+'mom2_g1-'+lineName+'.fits',lineName,lineThresh,lineNameStr,'moments')

        if modName != 'g1':
            fits.writeto(momModDir+'mom0_g2-'+lineName+'.fits',mom0G2,mom0Head,overwrite=True)
            fits.writeto(momModDir+'mom1_g2-'+lineName+'.fits',mom1G2,mom1Head,overwrite=True)
            fits.writeto(momModDir+'mom2_g2-'+lineName+'.fits',mom2G2,mom2Head,overwrite=True)

            mPl.mom0Plot(cfg_par, momModDir+'mom0_g2-'+lineName+'.fits',lineName,lineNameStr,lineThresh)
            mPl.mom1Plot(cfg_par, momModDir+'mom1_g2-'+lineName+'.fits',lineName,
                lineNameStr,lineThresh,'moments',vRange=[-cenRange,cenRange],
                modName='g2')
            mPl.mom2Plot(cfg_par, momModDir+'mom2_g2-'+lineName+'.fits',lineName,lineThresh,lineNameStr,'moments')

            if modName == 'g2':
                fits.writeto(momModDir+'mom0_tot-'+lineName+'.fits', mom0G1+mom0G2,mom0Head,overwrite=True)

                mPl.mom0Plot(cfg_par, momModDir+'mom0_tot-'+lineName+'.fits',lineName,lineNameStr,lineThresh)

            if modName == 'g3':
                fits.writeto(momModDir+'mom0_g3-'+lineName+'.fits',mom0G3,mom0Head,overwrite=True)
                fits.writeto(momModDir+'mom1_g3-'+lineName+'.fits',mom1G3,mom1Head,overwrite=True)
                fits.writeto(momModDir+'mom2_g3-'+lineName+'.fits',mom2G3,mom2Head,overwrite=True)
                fits.writeto(momModDir+'mom0_tot-'+lineName+'.fits',mom0G1+mom0G2+mom0G3,mom0Head,overwrite=True)

        t=Table(tabGen)
        if modName+'-AmpSpax_'+lineName not in tabGen.dtype.names:
            t.add_column(Column(ampSpax,name=modName+'-AmpSpax_'+lineName))
        else:
            t.replace_column(modName+'-AmpSpax_'+lineName,Column(ampSpax,name=modName+'-AmpSpax_'+lineName))

        #try:
        #    tt = Table(hduGen['VORBININFO'].data)
        hduGen['VORBININFO'] = fits.BinTableHDU(t.as_array(),name='VORBININFO')

        #except KeyError as e:
        #    tt=fits.BinTableHDU(t.as_array(),name='VORBININFO')
        #    hdul.append(tt)

        hduGen.writeto(cfg_par['general']['outVorLineTableName'],overwrite=True)

        return

    def resCube(self,cfg_par):

        key = 'general'
        cubeDir = cfg_par['general']['cubeDir']
        workDir = cfg_par['general']['workdir']

        modName = cfg_par['gFit']['modName']

        resModDir = cfg_par['general']['resDir']+modName+'/'

        # if not os.path.exists(resModDir):
        #     os.mkdir(momModDir)

        f = fits.open(cfg_par['general']['dataCubeName'])
        dd = f[0].data
        resHead = f[0].header

        hdul = fits.open(cfg_par['general']['outTableName'])
        lines = hdul['LineRes_'+cfg_par['gFit']['modName']].data
        residuals = hdul['Residuals_'+cfg_par['gFit']['modName']].data

        bF = np.array(residuals['bestFit'],dtype=int)

        hduGen = fits.open(cfg_par['general']['outVorLineTableName'])
        tabGen = hduGen[1].data

        resG1 = np.zeros([resHead['NAXIS3'],resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
        fitCube = np.zeros([resHead['NAXIS3'],resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

        wave,xAxis,yAxis,pxSize,noiseBin, vorBinInfo,dataSpec = tP.openVorLineOutput(cfg_par,cfg_par['general']['outVorLineTableName'],
            cfg_par['general']['outVorSpectra'])

        #hdul = fits.open(cfg_par['general']['outTableName'])
        #tabGen = hdul['BinInfo'].data

        lambdaMin = np.log(cfg_par['gFit']['lambdaMin'])
        lambdaMax = np.log(cfg_par['gFit']['lambdaMax'])
        idxMin = int(np.where(abs(wave-lambdaMin)==abs(wave-lambdaMin).min())[0])
        idxMax = int(np.where(abs(wave-lambdaMax)==abs(wave-lambdaMax).min())[0])

        # if modName != 'g1':
        #     resTot = np.zeros([resHead['NAXIS3'],resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
        #     resG2 = np.zeros([resHead['NAXIS3'],resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
        #     if modName == 'g3':
        #         res0G3 = np.zeros([resHead['NAXIS3'],resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

        for i in range(0,len(lines['BIN_ID'])):
            match_bin = np.where(tabGen['BIN_ID']==lines['BIN_ID'][i])[0]

            if cfg_par['residuals']['BFcube'] == True:

                if bF[i] == 0:
                    modName = 'g1'
                elif bF[i] == 1:
                    modName = 'g2'
            else:
                modName = cfg_par['gFit']['modName']

            result = load_modelresult(cfg_par['general']['runNameDir']+'models/'+modName+'/'+str(lines['BIN_ID'][i])+'_'+modName+'.sav')

            for index in match_bin:
                yy = dd[idxMin:idxMax,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])]
                fit = result.best_fit
                residuals = result.best_fit-yy
                resG1[idxMin:idxMax,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = residuals
                fitCube[idxMin:idxMax,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = fit

        resHead['SPECSYS'] = 'topocent'
        resHead['BUNIT'] = 'Flux'
        if cfg_par['residuals']['BFcube'] == True:
            modName = 'BF'
        fits.writeto(cubeDir+'resCube_'+modName+'.fits',resG1,resHead,overwrite=True)
        fits.writeto(cubeDir+'fitCube_'+modName+'.fits',fitCube,resHead,overwrite=True)

        return

    def resLinesFromTable(self,cfg_par):
        '''
        Computes for each the residuals of the fit. Within which velocity range?
            At the moment is within 6*sigmaG1 and 3*sigmaG2

        Parameters:
            cfg_par: parameter file
                gFit_modName: specifies # of gaussian components used for the fit

        Uses:
            - voroni binned line subtracted datacube
            - table of voronoi binned datacube and spectra
            -
        Returns (located in /residuals/modName/):
            - res_linename: residuals computed as the standard deviation of line-fit
                            within a velocity range given by cenRange centred at the peak of the observed line
            - resSTDPeak_linename:  residuals computed as the standard deviation of line-fit
                            within a velocity range given by cenRange centred at the peak of the observed line multiplied by the peak of the line
            - snRes_linename: residuals divided by the noise
        '''

        modName = cfg_par['gFit']['modName']
        resModDir = cfg_par['general']['resDir']+modName+'/'

        lineInfo = tP.openLineList(cfg_par)

        cubeDir = cfg_par['general']['cubeDir']
        resName = cubeDir+'resCube_'+modName+'.fits'

        f = fits.open(resName)
        resHead = f[0].header
        if 'CUNIT3' in resHead:
            del resHead['CUNIT3']
        if 'CTYPE3' in resHead:
            del resHead['CTYPE3']
        if 'CDELT3' in resHead:
            del resHead['CDELT3']
        if 'CRVAL3' in resHead:
            del resHead['CRVAL3']
        if 'CRPIX3' in resHead:
            del resHead['CRPIX3']
        if 'NAXIS3' in resHead:
            del resHead['NAXIS3']
        if 'CRDER3'in resHead:
            del resHead['CRDER3']

        hdul = fits.open(cfg_par['general']['outTableName'])
        binInfo = hdul['BININFO'].data

        res = hdul['residuals_'+modName].data

        for ii in range(0,len(lineInfo['ID'])):

            lineName = str(lineInfo['Name'][ii])
            if '[' in lineName:
                lineName = lineName.replace("[", "")
                lineName = lineName.replace("]", "")

            lineName = lineName+str(int(lineInfo['Wave'][ii]))
            lineThresh = float(lineInfo['SNThresh'][ii])
            print('\n\t         +++\t\t    '+lineName+'\t\t +++')

            rmsRes = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            rmsResPeak = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            stdRes = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            stdResPeak = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            chiSq = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

            SNResLineMap = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

            rmsName =resModDir+'rms_'+lineName+'.fits'
            rmsPeakName =resModDir+'rmsPeak_'+lineName+'.fits'
            stdName =resModDir+'std_'+lineName+'.fits'
            stdPeakName =resModDir+'stdPeak_'+lineName+'.fits'
            chiSqName = resModDir+'chiRes_'+lineName+'.fits'
            SNResNameOut =resModDir+'SN_rms-noise'+lineName+'.fits'

            for i in range(0,len(res['BIN_ID'])):

                match_bin = np.where(binInfo['BIN_ID']==res['BIN_ID'][i])[0]

                for index in match_bin:

                    rmsRes[int(binInfo['PixY'][index]),int(binInfo['PixX'][index])] = res['rms_'+lineName][i]
                    rmsResPeak[int(binInfo['PixY'][index]),int(binInfo['PixX'][index])] = res['rmsPeak_'+lineName][i]
                    stdRes[int(binInfo['PixY'][index]),int(binInfo['PixX'][index])] = res['std_'+lineName][i]
                    stdResPeak[int(binInfo['PixY'][index]),int(binInfo['PixX'][index])] = res['stdPeak_'+lineName][i]
                    chiSq[int(binInfo['PixY'][index]),int(binInfo['PixX'][index])] = res['chiSq_'+lineName][i]
                    SNResLineMap[int(binInfo['PixY'][index]),int(binInfo['PixX'][index])] = res['SN_rms-noise'+lineName][i]

            resHead['WCSAXES'] = 2

            fits.writeto(rmsName,rmsRes,resHead,overwrite=True)
            fits.writeto(rmsPeakName,rmsResPeak,resHead,overwrite=True)
            fits.writeto(stdName,stdRes,resHead,overwrite=True)
            fits.writeto(stdPeakName,stdResPeak,resHead,overwrite=True)
            fits.writeto(chiSqName,chiSq,resHead,overwrite=True)

            fits.writeto(SNResNameOut,SNResLineMap,resHead,overwrite=True)

        return

    def resLines(self,cfg_par):

        '''
        Makes the residual maps from the residual table

        Parameters:
            cfg_par: parameter file
                gFit_modName: specifies # of gaussian components used for the fit

        Uses:
            - voroni binned line subtracted datacube
            - table of voronoi binned datacube and spectra

        Returns (located in /residuals/modName/):

            - resSTD_linename:  residuals computed as the standard deviation of line-fit
                                within a velocity range given by 6*sigmag1 weighted on the fitted amplitude of the line
            - resSTDPeak_linename:  residuals computed as the standard deviation of line-fit
                                within a velocity range given by 6*sigmag1 weighted on the observed amplitude of the line
        Options:
            - compute noise:
                when set to True in the parameter file, it computes the noise as the rms in within [-80,-60]AA and [+60,+80]AA with respect to the
                rest wavelenght of each line
                computes the S/N of each line as the peak/noise in each pixel
            Returns:
                - SN_linename: S/N map of each line
                - noise_linename: noise map of each line

        '''

        key = 'general'
        workDir = cfg_par[key]['workdir']
        cubeDir = cfg_par[key]['cubeDir']
        modName = cfg_par['gFit']['modName']
        resModDir = cfg_par['general']['resDir']+modName+'/'
        noiseDir = cfg_par['general']['noiseDir']
        resName = cubeDir+'resCube_'+modName+'.fits'
        fitCubeName = cubeDir+'fitCube_'+modName+'.fits'

        if not os.path.exists(resName):
            self.resCube(cfg_par)
        else:
            pass

        f = fits.open(resName)
        resCube = f[0].data
        resHead = f[0].header
        if 'CUNIT3' in resHead:
            del resHead['CUNIT3']
        if 'CTYPE3' in resHead:
            del resHead['CTYPE3']
        if 'CDELT3' in resHead:
            del resHead['CDELT3']
        if 'CRVAL3' in resHead:
            del resHead['CRVAL3']
        if 'CRPIX3' in resHead:
            del resHead['CRPIX3']
        if 'NAXIS3' in resHead:
            del resHead['NAXIS3']
        if 'CRDER3'in resHead:
            del resHead['CRDER3']

        f = fits.open(cfg_par['general']['outVorLines'])
        dd = f[0].data

        #to load Voronoi Bin noise : noiseBin
        wave,xAxis,yAxis,pxSize,noiseBin, vorBinInfo,dataSpec = tP.openVorLineOutput(cfg_par,cfg_par['general']['outVorLineTableName'],
            cfg_par['general']['outVorSpectra'])
        #print(noiseBin.shape)
        #print(cfg_par['general']['outVorLineTableName'])
        #sys.exit(0)
        f = fits.open(cfg_par['general']['dataCubeName'])
        dd = f[0].data
        header = f[0].header

        hdul = fits.open(cfg_par['general']['outTableName'])
        lines = hdul['LineRes_'+cfg_par['gFit']['modName']].data
        linesG1 = hdul['LineRes_g1'].data

        #lines['BIN_ID'] = hdul['BININFO'].data['ID']
        resNameList=['BIN_ID']
        frmList=['i4']
        tot = lines['BIN_ID']

        hduGen = fits.open(cfg_par['general']['outVorLineTableName'])
        tabGen = hduGen[1].data

        lineInfo = tP.openLineList(cfg_par)

        tableSpec = workDir+cfg_par[key]['tableSpecName']
        tab = fits.open(tableSpec)
        dataSpec = tab[1].data
        specExp = tab[2].data
        wave = [item for t in specExp for item in t]

        noiseMapName =noiseDir+'noiseMap.fits'
        noiseMap = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

        for ii in range(0,len(lineInfo['ID'])):

            stdArr = np.empty(len(lines['BIN_ID']))
            stdPeakArr = np.empty(len(lines['BIN_ID']))
            rmsArr = np.empty(len(lines['BIN_ID']))
            rmsPeakArr = np.empty(len(lines['BIN_ID']))
            peakArr = np.empty(len(lines['BIN_ID']))

            chiSqArr = np.empty(len(lines['BIN_ID']))

            noiseArr = np.empty(len(lines['BIN_ID']))
            SNValues = np.empty(len(lines['BIN_ID']))
            SNStdValues = np.empty(len(lines['BIN_ID']))

            lineName = str(lineInfo['Name'][ii])
            if '[' in lineName:
                lineName = lineName.replace("[", "")
                lineName = lineName.replace("]", "")

            lineName = lineName+str(int(lineInfo['Wave'][ii]))
            lineThresh = float(lineInfo['SNThresh'][ii])
            print('\n\t         +++\t\t    '+lineName+'\t\t +++')

            stdRes = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            stdResPeak = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            rmsRes = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            rmsResPeak = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

            chiRes = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

            noiseLine = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan
            SNLineMap = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

            SNRes = np.empty([resHead['NAXIS2'],resHead['NAXIS1']])*np.nan

            stdResName =resModDir+'std_'+lineName+'.fits'
            stdResPeakName =resModDir+'stdPeak_'+lineName+'.fits'

            rmsResName =resModDir+'rms_'+lineName+'.fits'
            rmsResPeakName =resModDir+'rmsPeak_'+lineName+'.fits'

            chiResName = resModDir+'chiRes_'+lineName+'.fits'

            noiseNameLine =noiseDir+'noise_'+lineName+'.fits'
            SNMapName =noiseDir+'SN_'+lineName+'.fits'

            SNResName =resModDir+'SN_rms-noise'+lineName+'.fits'

            for i in range(0,len(lines['BIN_ID'])):

                #lineHeigth = np.max(y[indexMin:indexMax])

                amp = lines['g1_Amp_'+lineName][i]

                cenKmsG1 = linesG1['g1_Centre_'+lineName][i]
                #sigKmsG1 = linesG1['g1_SigIntr_'+lineName][i]

                #if sigKmsG1 >=2.e3:
                #    sigKmsG1=2.e3

                cenG1 = np.log(cvP.vRadLambda(cenKmsG1,lineInfo['Wave'][ii]))
                leftG1 = np.log(cvP.vRadLambda(cenKmsG1-lineInfo['cenRange'][ii],lineInfo['Wave'][ii]))
                rightG1 = np.log(cvP.vRadLambda(cenKmsG1+lineInfo['cenRange'][ii],lineInfo['Wave'][ii]))

                idxLeft = int(np.where(abs(wave-leftG1)==abs(wave-leftG1).min())[0])
                idxRight = int(np.where(abs(wave-rightG1)==abs(wave-rightG1).min())[0])

                #define interval where to measure maximum of real line from centroid of 1G-fit
                peakLeft = np.log(cvP.vRadLambda(cenKmsG1-140.,lineInfo['Wave'][ii]))
                peakRight = np.log(cvP.vRadLambda(cenKmsG1+140.,lineInfo['Wave'][ii]))

                idxPeakLeft = int(np.where(abs(wave-peakLeft)==abs(wave-peakLeft).min())[0])
                idxPeakRight = int(np.where(abs(wave-peakRight)==abs(wave-peakRight).min())[0])

                if cfg_par['residuals']['computeNoise']==True:

                    leftNoise = np.log(lineInfo['Wave'][ii]-60.)
                    leftleftNoise = np.log(lineInfo['Wave'][ii]-80.)
                    rightNoise = np.log(lineInfo['Wave'][ii]+60.)
                    rightrightNoise = np.log(lineInfo['Wave'][ii]+80.)
                    idxLeftLeftNoise = int(np.where(abs(wave-leftleftNoise)==abs(wave-leftleftNoise).min())[0])
                    idxLeftNoise = int(np.where(abs(wave-leftNoise)==abs(wave-leftNoise).min())[0])

                    idxRightRightNoise = int(np.where(abs(wave-rightrightNoise)==abs(wave-rightrightNoise).min())[0])
                    idxRightNoise = int(np.where(abs(wave-rightNoise)==abs(wave-rightNoise).min())[0])

                    # noiseMinRed = cfg_par['general']['redshift']*cfg_par['gFit']['noiseMin']+cfg_par['gFit']['noiseMin']
                    # noiseMaxRed = cfg_par['general']['redshift']*cfg_par['gFit']['noiseMax']+cfg_par['gFit']['noiseMax']
                    # idxLeftNoise = int(np.where(abs(np.exp(wave)-noiseMinRed)==abs(np.exp(wave)-noiseMinRed).min())[0])
                    # idxRightNoise = int(np.where(abs(np.exp(wave)-noiseMaxRed)==abs(np.exp(wave)-noiseMaxRed).min())[0])

                    a = np.where(tabGen['BIN_ID'] == int(lines['BIN_ID'][i]))[0]
                    #if not  a.size == 0:

                    idxTable = a[0]
                    y = dd[:,int(tabGen['PixY'][idxTable]),int(tabGen['PixX'][idxTable])]
                    #else:
                    #    y = np.zeros((dd.shape[0]))

                if modName == 'g2':
                    amp = lines['g1_Amp_'+lineName][i]+lines['g2_Amp_'+lineName][i]
                    cenKmsG2 = lines['g2_Centre_'+lineName][i]
                    sigKmsG2 = lines['g2_SigMeas_'+lineName][i]

                    cenG2 = np.log(cvP.vRadLambda(cenKmsG2,lineInfo['Wave'][ii]))
                    leftG2 = np.log(cvP.vRadLambda(cenKmsG2-lineInfo['cenRange'][ii],lineInfo['Wave'][ii]))
                    rightG2 = np.log(cvP.vRadLambda(cenKmsG2+lineInfo['cenRange'][ii],lineInfo['Wave'][ii]))

                    idxLeftG2 = int(np.where(abs(wave-leftG2)==abs(wave-leftG2).min())[0])
                    idxRightG2 = int(np.where(abs(wave-rightG2)==abs(wave-rightG2).min())[0])

                    idxLeft = np.min([idxLeft,idxLeftG2])
                    idxRight = np.max([idxRight,idxRightG2])

                #     if modName =='g3':

                #         cenKmsG3 = lines['g3_Centre_'+lineName][i]
                #         sigKmsG3 = lines['g3_SigMeas_'+lineName][i]

                #         cenG2 = np.log(cvP.vRadLambda(cenKmsG1,lineInfo['Wave'][ii]))
                #         leftG2 = np.log(cvP.vRadLambda(cenKmsG1-3.*sigKmsG3,lineInfo['Wave'][ii]))
                #         rightG2 = np.log(cvP.vRadLambda(cenKmsG1+3.*sigKmsG3,lineInfo['Wave'][ii]))

                #         idxLeftG3 = int(np.where(abs(wave-leftG3)==abs(wave-leftG3).min())[0])
                #         idxRightG3 = int(np.where(abs(wave-rightG3)==abs(wave-rightG3).min())[0])

                        #idxLeft = np.min([idxLeft,idxLeftG3])
                        #idxRight = np.max([idxRight,idxRightG3])

                #if ii==0 and cfg_par['residuals']['computeNoise']==True:
                #    noiseValue = noiseBin[idxLeft][lines['BIN_ID'][i]][idxLeft]*amp

                match_bin = np.where(tabGen['BIN_ID']==lines['BIN_ID'][i])[0]
                #print(match_bin,lines['BIN_ID'][i])

                #result = load_modelresult(cfg_par[key]['modNameDir']+str(lines['BIN_ID'][i])+'_'+cfg_par['gFit']['modName']+'.sav')
                if idxRight-idxLeft <2.:
                    idxLeft-=4
                    idxRight+=4
                for index in match_bin:

                    # if modName=='g1':
                    #     thresHold = lines['g1_Amp_Hb4861'][i]/tabGen['NSPAX'][index]
                    # elif modName=='g2':
                    #     thresHold = (lines['g1_Amp_Hb4861'][i]+lines['g2_Amp_Hb4861'][i])/tabGen['NSPAX'][index]
                    # elif modName=='g3':
                    #     thresHold = (lines['g1_Amp_Hb4861'][i]+lines['g2_Amp_Hb4861'][i]+lines['g3_Amp_Hb4861'][i])/tabGen['NSPAX'][index]

                    # if thresHold >= lineThresh:
                    linePeak = np.max(y[idxPeakLeft:idxPeakRight])

                    stdValue = np.nanstd(resCube[idxLeft:idxRight,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])])
                    stdValuePeak = np.multiply(stdValue,linePeak)

                    rmsValue = np.sqrt(np.power(stdValue,2)+np.power(np.nanmean(resCube[idxLeft:idxRight,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])]),2))
                    rmsValuePeak = np.multiply(rmsValue,linePeak)

                    stdResPeak[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = stdValuePeak
                    stdRes[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = stdValue

                    rmsResPeak[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = rmsValuePeak
                    rmsRes[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = rmsValue

                    if cfg_par['residuals']['computeNoise']==True:

                        noise = np.nanstd(np.concatenate([y[idxLeftLeftNoise:idxLeftNoise],y[idxRightNoise:idxRightRightNoise]]))
                        sn = np.divide(linePeak,noise)
                        snStd = np.divide(stdValue,noise)

                        noiseLine[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = noise
                        SNLineMap[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = sn
                        SNRes[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = snStd

                        if modName =='g1':
                            nvar = 3
                        elif modName =='g2':
                            nvar = 6

                        chiSq=np.divide(np.divide(np.nansum(np.power(resCube[idxLeft:idxRight,int(tabGen['PixY'][index]),int(tabGen['PixX'][index])]-y[idxLeft:idxRight],2)),
                        np.power(noise,2)),idxRight-idxLeft-nvar)
                        chiRes[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = chiSq

                        #if ii==0:
                        #    noiseMap[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = noiseValue

                peakArr[i] = linePeak
                chiSqArr[i] = chiSq
                stdArr[i] = stdValue
                stdPeakArr[i] = stdValuePeak
                rmsArr[i] = rmsValue
                rmsPeakArr[i] = rmsValuePeak
                noiseArr[i] = noise
                SNValues[i] = sn
                SNStdValues[i] = snStd

            tot = np.column_stack((tot,stdArr))
            resNameList.append('std_'+lineName)
            frmList.append('f8')

            tot = np.column_stack((tot,stdPeakArr))
            resNameList.append('stdPeak_'+lineName)
            frmList.append('f8')

            tot = np.column_stack((tot,rmsArr))
            resNameList.append('rms_'+lineName)
            frmList.append('f8')

            tot = np.column_stack((tot,rmsPeakArr))
            resNameList.append('rmsPeak_'+lineName)
            frmList.append('f8')

            tot = np.column_stack((tot,rmsArr))
            resNameList.append('peak_'+lineName)
            frmList.append('f8')

            resHead['WCSAXES'] = 2

            fits.writeto(stdResName,stdRes,resHead,overwrite=True)
            fits.writeto(stdResPeakName,stdResPeak,resHead,overwrite=True)

            fits.writeto(rmsResName,rmsRes,resHead,overwrite=True)
            fits.writeto(rmsResPeakName,rmsResPeak,resHead,overwrite=True)

            if cfg_par['residuals']['computeNoise']==True:

                fits.writeto(noiseNameLine,noiseLine,resHead,overwrite=True)
                fits.writeto(SNMapName,SNLineMap,resHead,overwrite=True)
                fits.writeto(SNResName,SNRes,resHead,overwrite=True)

                fits.writeto(chiResName,chiRes,resHead,overwrite=True)

                tot = np.column_stack((tot,noiseArr))
                resNameList.append('noise_'+lineName)
                frmList.append('f8')

                tot = np.column_stack((tot,SNValues))
                resNameList.append('SN_'+lineName)
                frmList.append('f8')

                tot = np.column_stack((tot,SNStdValues))
                resNameList.append('SN_rms-noise'+lineName)
                frmList.append('f8')

                tot = np.column_stack((tot,chiSqArr))
                resNameList.append('chiSq_'+lineName)
                frmList.append('f8')
                #if ii==0:
                #    fits.writeto(noiseMapName,noiseMap,resHead,overwrite=True)

        t = Table(tot, names=(resNameList))
#        hdul.append(fits.BinTableHDU(t.as_array(), name='Residuals_'+modName))

        try:
            tt = Table(hdul['Residuals_'+modName].data)
            hdul['Residuals_'+modName] = fits.BinTableHDU(t.as_array(),name='Residuals_'+modName)
        except KeyError as e:
            tt=fits.BinTableHDU.from_columns(t.as_array(),name='Residuals_'+modName)
            hdul.append(tt)

        hdul.writeto(cfg_par['general']['outTableName'],overwrite=True)

        # try:
        #     tt = Table(hdul['Ancels'+modName].data)
        #     hdul['Ancels'+modName] = fits.BinTableHDU.from_columns(sigmaCenArr,name='Ancels'+modName)

        # except KeyError as e:
        #     tt=fits.BinTableHDU.from_columns(sigmaCenArr,name='Ancels'+modName)
        #     hdul.append(tt)

        return 0

    def makeLineRatioMaps(self,cfg_par):

        workDir = cfg_par['general']['cubeDir']

        f = fits.open(cfg_par['general']['dataCubeName'])
        dd = f[0].header

        #lineInfo = self.openLineList()

        #for ii in range(0,len(lineInfo['ID'])):
        #    lineName = str(lineInfo['Name'][ii])
        #    if '[' in lineName:
        #        lineName = lineName.replace("[", "")
        #        lineName = lineName.replace("]", "")

            #lineName = lineName+str(int(lineInfo['Wave'][ii]))

        self.momLineRatio(cfg_par,dd,cfg_par['general']['outTableName'])

        return

    def momLineRatio(self,cfg_par,header,outTableName):

        modName = cfg_par['gFit']['modName']
        bptDir = cfg_par['general']['bptDir']+'/'
        momModDir = cfg_par['general']['momDir']+modName+'/'

        if 'CUNIT3' in header:
            del header['CUNIT3']
        if 'CTYPE3' in header:
            del header['CTYPE3']
        if 'CDELT3' in header:
            del header['CDELT3']
        if 'CRVAL3' in header:
            del header['CRVAL3']
        if 'CRPIX3' in header:
            del header['CRPIX3']
        if 'NAXIS3' in header:
            del header['NAXIS3']
        if 'WCSAXES' in header:
            del header['WCSAXES']
        if 'CRDER3' in header:
            del header['CRDER3']

        lineMapHead = header.copy()

        hdul = fits.open(cfg_par['general']['outTableName'])
        lineBPT = hdul['BPT_'+cfg_par['gFit']['modName']].data

        hduGen = fits.open(cfg_par['general']['outVorLineTableName'])
        tabGen = hduGen[1].data

        hbetaMap = fits.open(momModDir+'mom0_'+modName+'-OIII5006.fits')
        hbetaData = hbetaMap[0].data

        numCols = len(lineBPT.dtype.names)

        if modName == 'g2':
            numCols = int((numCols-1)/3)
            numCols +=1
        if modName == 'g3':
            numCols = int((numCols-1)/4)
            numCols +=1

        for i in range(1,numCols):
            lineMapG1 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

            if modName != 'g1':
                lineMapToT = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
                lineMapG2 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

            if modName == 'g3':

                lineMapG3 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

            for j in range(0,len(lineBPT['BIN_ID'])):
                match_bin = np.where(tabGen['BIN_ID']==lineBPT['BIN_ID'][j])[0]

                for index in match_bin:
                    if ~np.isnan(hbetaData[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])]):
                        lineMapG1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j][i]

                    if modName != 'g1':

                        lineMapToT[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j][i+numCols*2-2]
                        lineMapG2[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j][i+numCols-1]

                        if modName == 'g3':
                            lineMapG3[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j][i+numCols+2] #TOREVIEW!!!!

            lineMapHead['BUNIT'] = 'Flux'
            outBPT = bptDir+'BPT-'+str(lineBPT.dtype.names[i])+'.fits'
            fits.writeto(bptDir+'BPT-'+str(lineBPT.dtype.names[i])+'.fits',lineMapG1,lineMapHead,overwrite=True)

            if modName != 'g1':
                outBPTg2 = bptDir+'BPT-'+str(lineBPT.dtype.names[i+numCols-1])+'.fits'
                outBPTtot = bptDir+'BPT-'+str(lineBPT.dtype.names[i+numCols*2-2])+'.fits'

                fits.writeto(outBPTg2,lineMapG2,lineMapHead,overwrite=True)
                fits.writeto(outBPTtot,lineMapToT,lineMapHead,overwrite=True)

                if modName == 'g3':
                    outBPTg3 = bptDir+'BPT-'+str(lineBPT.dtype.names[i+numCols+2])+'.fits'
                    fits.writeto(bptDir+'BPT-'+str(lineBPT.dtype.names[i+numCols+2])+'.fits',lineMapG3,lineMapHead,overwrite=True)

            if cfg_par['lineRatios']['bptMap'] == True:
                bpt.bptIM(cfg_par,outBPT)
                if modName != 'g1':
                    bpt.bptIM(cfg_par,outBPTg2)
                    bpt.bptIM(cfg_par,outBPTtot)
                elif modName=='g3':
                    bpt.bptIM(cfg_par,outBPTg3)

        return

    def momCDist(self,cfg_par):

        f = fits.open(cfg_par['general']['dataCubeName'])
        header = f[0].header
        f.close()
        modName = cfg_par['gFit']['modName']
        bptDir = cfg_par['general']['bptDir']+'/'
        momModDir = cfg_par['general']['momDir']+modName+'/'

        if 'CUNIT3' in header:
            del header['CUNIT3']
        if 'CTYPE3' in header:
            del header['CTYPE3']
        if 'CDELT3' in header:
            del header['CDELT3']
        if 'CRVAL3' in header:
            del header['CRVAL3']
        if 'CRPIX3' in header:
            del header['CRPIX3']
        if 'NAXIS3' in header:
            del header['NAXIS3']
        if 'WCSAXES' in header:
            del header['WCSAXES']
        if 'CRDER3' in header:
            del header['CRDER3']

        lineMapHead = header.copy()

        hdul = fits.open(cfg_par['general']['outTableName'])
        lineBPT = hdul['BPT_'+cfg_par['gFit']['modName']].data
        hbetaMap = fits.open(momModDir+'mom0_'+modName+'-Hb4861.fits')
        hbetaData = hbetaMap[0].data

        hduGen = fits.open(cfg_par['general']['outVorLineTableName'])
        tabGen = hduGen[1].data

        numCols = len(lineBPT.dtype.names)

        if modName == 'g2':
            numCols = int((numCols-1)/3)
            numCols +=1
        if modName == 'g3':
            numCols = int((numCols-1)/4)
            numCols +=1

        lineMapG1 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        if modName != 'g1':
            lineMapToT = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan
            lineMapG2 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        if modName == 'g3':

            lineMapG3 = np.zeros([header['NAXIS2'],header['NAXIS1']])*np.nan

        for j in range(0,len(lineBPT['BIN_ID'])):
            match_bin = np.where(tabGen['BIN_ID']==lineBPT['BIN_ID'][j])[0]

            for index in match_bin:
                if ~np.isnan(hbetaData[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])]):

                    lineMapG1[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j]['cDist-OIIIG1']

                    if modName != 'g1':

                        lineMapG2[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j]['cDist-OIIIG2']
                        lineMapToT[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j]['cDist-OIIIToT']

                        if modName == 'g3':
                            lineMapG3[int(tabGen['PixY'][index]),int(tabGen['PixX'][index])] = lineBPT[j]['cDist-OIIIG3'] #TOREVIEW!!!!

        lineMapHead['BUNIT'] = 'cDistance'
        outBPT = bptDir+'cDist-OIIIG1.fits'
        fits.writeto(outBPT,lineMapG1,lineMapHead,overwrite=True)

        if modName != 'g1':

            #print('\n\t************* --- GuFo : ERROR --- **************\n')
            #outBPTg2 = bptDir+'BPT-'+str(lineBPT.dtype.names[i+numCols-1])+'.fits'
            outBPTG2 = bptDir+'BPT-cDist-OIIIG2.fits'
            outBPTToT = bptDir+'BPT-cDist-OIIIToT.fits'

            fits.writeto(outBPTG2,lineMapG2,lineMapHead,overwrite=True)
            fits.writeto(outBPTToT,lineMapToT,lineMapHead,overwrite=True)

            if modName == 'g3':
                outBPTG3 = bptDir+'BPT-cDist-OIIIG3.fits'
                fits.writeto(outBPTG3,lineMapG3,lineMapHead,overwrite=True)

        if cfg_par['lineRatios']['cDistPlot'] == True:

            bpt.cDistIM(cfg_par,outBPT)

            if modName != 'g1':
                bpt.cDistIM(cfg_par,outBPTG2)
                bpt.cDistIM(cfg_par,outBPTToT)
            elif modName=='g3':

                bpt.cDistIM(cfg_par,outBPTG3)

        return

    def regridMoms(self,basename,slavename):

        outName = slavename.split('.fits')[0]
        outName = outName+'_rg.fits'

        base = fits.open(basename)
        bheader = base[0].header

        if 'WCSAXES' in bheader:
            bheader['WCSAXES'] = 2
        bheader['NAXIS'] = 2

        slave = fits.open(slavename)
        sheader = slave[0].header
        if 'WCSAXES' in sheader:
            sheader['WCSAXES'] = 2
        slave = fits.open(slavename)[0]
        sheader['NAXIS'] = 2

        bheader['BMIN'] = sheader['BMIN']
        bheader['BMAJ'] = sheader['BMAJ']
        # if 'FREQ' in slave.header:
        #     bheader['FREQ'] = sheader['FREQ']
        # elif 'CRVAL3' in sheader:
        #     bheader['FREQ'] = sheader['CRVAL3']

        #print basename
        #for i in base.header.keys():
        #    print i,'\t',base.header[i]
        #print slavename
        #for i in slave.header.keys():
        #    print i,'\t',slave.header[i]

        newslave, footprint = reproject_exact(slave, bheader)
        fits.writeto(outName, newslave, bheader, overwrite=True)

        return outName


import numpy as np

def sensitivity_specificity():

    output_matrix = np.loadtxt(open("Outcome/outcome_CT_clinical_BMD.csv", "rb"), delimiter=",", skiprows=0)
    threshold = 0.5

    TP = FN = TN = FP = 0
    for i in range(output_matrix.shape[0]): # output_matrix: participant ID, fracture probability, label
        score = output_matrix[i][1]
        label = output_matrix[i][-1]
        if score >= threshold:
            predict = 1
        else:
            predict = 0
        if predict == 1 and label == 1:
            TP = TP + 1
        if predict == 0 and label == 1:
            FN = FN + 1
        if predict == 0 and label == 0:
            TN = TN + 1
        if predict == 1 and label == 0:
            FP = FP + 1
    sensitivity = TP / (TP + FN)
    specificity = TN / (TN + FP)
    print("sensitivity, specificity", sensitivity, specificity)

    '''
    # choose the point on the ROC curve
    fpr, tpr, thresholds = metrics.roc_curve(output_matrix[:, 2], output_matrix[:, 1], pos_label=1)
    index = np.where(thresholds == point)
    print("sensitivity, specificity", tpr[index], 1 - fpr[index])
    '''

def ROC(): # calculate the set of (FPR, TPR) points for model outputs

    output_matrix = np.loadtxt(open("Outcome/outcome_CT_clinical_BMD.csv", "rb"), delimiter=",", skiprows=0)
    print("shape:", output_matrix.shape)
    score = output_matrix[:, 1]
    label = output_matrix[:, -1]  # output_matrix: participant ID, fracture probability, label

    prob_pos = np.array(score).reshape([output_matrix.shape[0], 1])
    test_label = np.array(label).reshape([output_matrix.shape[0], 1])
    threshold = np.arange(0, 1, 0.01)
    fpr = []
    tpr = []
    for i in range(len(threshold)):
        TP = TN = FP = FN = 0
        for j in range(len(test_label)):
            if prob_pos[j] > threshold[i]:
                predict = 1
            else:
                predict = 0
            if predict == 1 and test_label[j] == 1:
                TP = TP + 1
            if predict == 0 and test_label[j] == 1:
                FN = FN + 1
            if predict == 0 and test_label[j] == 0:
                TN = TN + 1
            if predict == 1 and test_label[j] == 0:
                FP = FP + 1
        FPR = FP / (FP + TN)
        TPR = TP / (TP + FN)
        fpr.append(FPR)
        tpr.append(TPR)
    fpr = np.array(fpr)
    tpr = np.array(tpr)
    set = np.vstack((fpr, tpr))

    np.savetxt("ROC_CT_clinical_BMD.csv", set, delimiter=",")


"""
    Created by: Rafal Uzarowicz
    Date of creation: 27.03.2020
    Github: https://github.com/RafalUzarowicz
"""

import unittest
from src.path_search_algo import dijkstra, brute_force
from src.graph import Graph

class TestPathSearchAlgorithms(unittest.TestCase):

    def test_dijkstra(self):
        graph = Graph()
        graph.add_edge("A", "B", 1)
        graph.add_edge("A", "C", 1)
        graph.add_edge("B", "D", 9)
        graph.add_edge("C", "D", 1)
        path, distance = dijkstra(graph,"A", "D")
        self.assertListEqual(path, ["A", "C", "D"])
        self.assertEqual(distance, 2)
        self.assertRaises(ValueError, dijkstra, graph, "A", "X")
        self.assertRaises(TypeError, dijkstra, "A", 7)

    def test_brute_force(self):
        graph1 = Graph()
        graph1.add_edge("A", "B", 1)
        graph1.add_edge("A", "C", 1)
        graph1.add_edge("B", "D", 9)
        graph1.add_edge("C", "D", 1)
        graph1.end = "D"
        graph1.start = "A"
        path = brute_force(graph1)
        self.assertListEqual(path[0], ["A", "C", "D"])
        self.assertEqual(path[1], 2)

if __name__ == '__main__':
    unittest.main()


import threading

class KeyboardThread(threading.Thread):
	def __init__(self, on_input, name = 'keyboard-input-thread'):
		self._on_input = on_input
		super(KeyboardThread, self).__init__(name=name)
		self.setDaemon(True)
		self.start()

	def run(self):
		while not self._on_input(input()):
			True


import scrapy

# TF-IDF
# import StemmerFactory class
from Sastrawi.Stemmer.StemmerFactory import StemmerFactory
from math import log10

# create stemmer
factory = StemmerFactory()
stemmer = factory.create_stemmer()

class QuotesSpider(scrapy.Spider):
    name = "tubes_novel5"

    def start_requests(self):
        main_Url = 'https://www.worldnovel.online/'
        Novel = 'the-first-order/'

        # list 10 url tiap chapter di novel the first order
        urls = [
            '{}{}chapter-1-a-sickness-in-the-head/'.format(main_Url, Novel),
            '{}{}chapter-2-this-world-has-never-trusted-tears/'.format(main_Url, Novel),
            '{}{}chapter-3-a-palace/'.format(main_Url, Novel),
            '{}{}chapter-4-luck-is-a-type-of-skill-too/'.format(main_Url, Novel),
            '{}{}chapter-5-the-school/'.format(main_Url, Novel),
            '{}{}chapter-6-walls-and-science/'.format(main_Url, Novel),
            '{}{}chapter-7-substitute-teacher/'.format(main_Url, Novel),
            '{}{}chapter-8-something-really-is-wrong-with-his-head/'.format(main_Url, Novel),
            '{}{}chapter-9-ask-me-if-theres-anything-you-dont-understand/'.format(main_Url, Novel),
            '{}{}chapter-10-side-quest/'.format(main_Url, Novel)
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse) # metode Scrapy meminta request ke web url

    def parse(self, response):
    #    print(response.url)
        yield {
             'jdlChap' : response.css('#outer-wrapper > div > h3::text').extract(), # mengambil data Judul Chapter
             'textNovel' : response.css('#soop > p ::text').extract(), # mengambil data berupaa seluruh isi teks novel yang terdapat dalam tag p
        }

    # block untuk proses TF-IDF function
    def get_list_of_word(list_of_chapNovel):
        list_of_word = []

        for sentence in list_of_chapNovel:
            for word in stemmer.stem(sentence).split(' '):
                if word not in list_of_chapNovel:
                    list_of_word.append(word)

        return list_of_word

    # membuka file yang berupa store data dari hasil ouput Scrapy tadi yang dimasukkan ke dalam sebuah file berformat json
    # yang mana untuk store data ke berupa file itu dilakukkan command Scrapy tertentu ke cmd, lalu akan tebentuklah file tersebut

    # List yang berisi kumpulan teks chapter novel dan ukuran dari list tersebut
    list_of_chapNovel = [open('novel_the_first_order.json', encoding='utf-8').read()]
    length_of_chapNovel = len(list_of_chapNovel)

    # berisi kata-kata yang berasal dari list text chapNovel
    list_of_word = get_list_of_word(list_of_chapNovel)
    # print(list_of_word)
    print(list_of_word[25])
    print(list_of_word[688])
    print(list_of_word[702])
    print(list_of_word[899])
    print(list_of_word[917])
    print(list_of_word[918])
    print(list_of_word[1200])
    print(list_of_word[1400])
    print(list_of_word[1539])
    print(list_of_word[1993])


#website compile

doctype = "html"
lang = "en-US"
author = "Angelo Carrabba"
self.keywords = []
spacing = 0

class webPage():
    def __init__(self):
        self.pageName = ""
        self.title = ""
        self.styleSheets = []
        self.scripts = []
        self.description = ""
        self.menu = ""
    def pl(s,*elements):
        for ele in elements:
            s += str(ele)
        s +=  "\n"
    def toString(self):
        s = ""
        pl(s, "<!DOCTYPE ", doctype, ">")
        pl(s, "html lang=\"", lang, "\">")
        pl(s, "<head>")
        pl(s, "<title>", self.title, "</title>")
        pl(s, "")

    def write(self):
        if len(self.pageName) == 0:
            self.printer()

index = webPage()
index.pageName = "index.html"
index.title = "home"


# 1. Реализовать функцию, принимающую два числа (позиционные аргументы) и выполняющую их деление.
# Числа запрашивать у пользователя, предусмотреть обработку ситуации деления на ноль.

def division(a, b):
    try:
        a, b = float(a), float(b)
        result = a / b
    except ZeroDivisionError:
        print("Значение делителя не должно быть нулевым!")
        return
    except ValueError:
        print("Вы ввели не число!")
        return
    if (result % 1) == 0:  # Если в результате целое число, то визуально отсечём у него 0 превращением в int
        result = int(result)
    return result

devidend, devisor = str(input("Введите числа через пробел (делимое, делитель): ")).split()
result_div = division(devidend, devisor)
if result_div is not None:
    print(f"{devidend} : {devisor} = {result_div}")


import torch
import numpy as np

from ml.modules.losses.ordinal_regression_loss import OrdinalRegressionLoss

config_path = '../config/config_files/kitti_base.yaml'

ord_num = 90
gamma = -0.97
beta = 90
config = load_config(config_path)
config['model']['params']['discretization'] = "SID"

ordinal_regression_loss = OrdinalRegressionLoss(ord_num, beta)

val_loader, niter_val = build_loader(config, is_train=False)

rmses = []

for i, data in enumerate(val_loader):
    gt = data['target'].unsqueeze(0)

    _, gt_mask = ordinal_regression_loss._create_ord_label(gt)

    label = ord_num - torch.sum(gt_mask, dim=1)
    t0 = torch.exp(np.log(beta) * label.float() / ord_num)
    t1 = torch.exp(np.log(beta) * (label.float() + 1) / ord_num)

    depth_gt = (t0 + t1) / 2 - gamma

    depth_gt = np.squeeze(depth_gt.numpy())
    gt = np.squeeze(gt.numpy())

    gt_mask = gt > 0
    gt = gt[gt_mask]
    depth_gt = depth_gt[gt_mask]

    rmse = np.sqrt(np.mean((depth_gt - gt) ** 2)) * 1000

    rmses.append(rmse)
    print(f'{i + 1} / {len(val_loader)}, RMSE: {rmse}')

mean_rmse = np.mean(rmses)
print(f'Mean minimum RMSE: {mean_rmse}')


from sqlalchemy import Column, ForeignKey, String, DateTime, Boolean, Enum
from sqlalchemy import func, exc
from sqlalchemy.dialects.postgresql import UUID
from uuid import uuid4
from .. import db
from enum import Enum
from datetime import datetime

#? https://stackoverflow.com/questions/33612625/how-to-model-enums-backed-by-integers-with-sqlachemy
#? https://docs.sqlalchemy.org/en/14/core/type_basics.html#sqlalchemy.types.Enum
class CategoryEnum(Enum):
  tollBooth = "toll booth"
  passage   = "passage"
  food      = "food"
  others    = "others"

class ExtraExpenses(db.Model):

    __tablename__ = "extra_expenses"
    id          = Column(UUID(as_uuid=True), primary_key=True, default=uuid4())
    id_move     = Column(UUID(as_uuid=True), ForeignKey("moves.id", ondelete="CASCADE", name="id_move"))
    description = Column(String(255), nullable=False)
    #* Opción 1
    category    = Column(Enum(CategoryEnum), nullable=False)
    #* Opción 2, no tengo pruebas, pero tampoco dudas
    #! category      = Column(Enum(["toll booth", "passage", "food", "others" ]), nullable=False)
    amount    = Column(String(18), nullable=False)
    #? https://stackoverflow.com/questions/13370317/sqlalchemy-default-datetime
    startedAt = Column(DateTime(timezone=True), nullable=False, server_default=func.now())
    updatedAt = Column(DateTime(timezone=True), nullable=True, onupdate=func.now())
    deletedAt = Column(DateTime(timezone=True), nullable=True)
    active    = Column(Boolean(), nullable=False, default=True)

    def save(**kwargs):
      try:
        expense = ExtraExpenses(**kwargs)
        db.session.add(expense)
        db.session.commit()
        return expense
      except Exception as error:
        print(error)
        return {}
      finally:
        pass

    def find():
      try:
        return ExtraExpenses.query.filter_by().all()
      except:
        return {}
      finally:
        pass

    def find_one(**kwargs):
      try:
        return db.session.query(ExtraExpenses).filter_by(**kwargs).first()
      except exc.SQLAlchemyError as err:
        print(err)
        return {}
      finally:
        db.session.close()

    def update(**update):
      try:
        update["updatedAt"] = datetime.now()
        updated = (
          db.session.query(ExtraExpenses)
          .filter_by(id=str(update["id"]))
          .update(update, synchronize_session="fetch")
        )
        db.session.commit()
        return updated
      except Exception as error:
        print(error)
        return {}

    def delete(**kwargs) -> int:
      try:
        updated = (
          db.session.query(ExtraExpenses)
          .filter_by(**kwargs)
          .update(
            {"active": False, "deletedAt": datetime.now()},
            synchronize_session="fetch",
          )
        )
        db.session.commit()
        return updated
      except exc.SQLAlchemyError as err:
        print(err)
        db.session.rollback()
        return {}


import time

import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

from datetime import datetime # Config file purpose

options = Options()
options.add_argument("--incognito")
options.add_argument("--window-size=1920x1080")

# Driver path
driver = webdriver.Chrome(options=options, executable_path="../chromedriver_win32/chromedriver.exe")

def layer_three(layer_two_file):
    print("Layer three is starting")
    '''

    This layer will retrieve layer_two.csv.
    Layer one contains author name and its profile url
    Layer two contains paper name and its url.

    The objective of layer three is retrieve paper title, description, paperlink, authors and date.
    This is the final layer to obtain the data.

    '''

    # Define dataframe for third layer
    layer_three_data = pd.DataFrame(
        columns=["df_paper_title", "df_paper_url", "df_paper_abstract", "df_paper_author", "df_paper_date"])
    data = {}

    df_layer_two_file = pd.read_csv(layer_two_file)
    print("Loading dataframe")
    print(df_layer_two_file)
    print("dataframe loaded")

    for i in range(len(df_layer_two_file["df_title_url"])):
        time.sleep(2)
        print("Moving to " + (df_layer_two_file["df_title_url"][i]))
        driver.get(df_layer_two_file["df_title_url"][i])  # Moves to unique paper page
        print("No of paper accessed", i)

        # columns = ["df_paper_title", "df_paper_doi", "df_paper_abstract", "df_paper_author", "df_paper_date"])

        # Obtain title
        paperTitle = driver.find_elements_by_css_selector(".container > div > div > div:nth-child(1) > h1")
        paperTitles = [el.text for el in paperTitle]
        print("Pasting paper title")
        data['df_paper_title'] = paperTitles

        # Obtain link
        paper_title_links = driver.find_elements_by_css_selector(
            ".rendering_contributiontojournal_publicationaccessrenderer > ul.dois > li > div > a")
        paperlink = [el.get_attribute("href") for el in paper_title_links]
        print("Pasting paper url")
        data['df_paper_url'] = paperlink

        # Obtain Abstract
        paper_abstract = driver.find_elements_by_css_selector(
            ".rendering_abstractportal.rendering_contributiontojournal_abstractportal > div")
        paper_abstracts = [el.text for el in paper_abstract]
        print("Pasting paper abstract")
        data['df_paper_abstract'] = paper_abstracts

        # Obtain authors
        paper_authors = driver.find_elements_by_css_selector(
            ".rendering_contributiontojournal_associatespersonsclassifiedportal > p > a:nth-child(1) > span")
        paper_author = [el.text for el in paper_authors]
        print("Pasting paper authors")
        data['df_paper_author'] = paper_author

        # Obtain publication date
        paper_publication_dates = driver.find_elements_by_css_selector(
            ".rendering_contributiontojournal_detailsportal > div > table > tbody > tr.status > td > span.date")
        paper_publication_date = [el.text for el in paper_publication_dates]
        print("Pasting paper publication date")
        data['df_paper_date'] = paper_publication_date

        layer_three_data = layer_three_data.append(data, ignore_index=True)

        layer_three_data.to_csv("./layer_three_data.csv", index=False)
        print("CSV saved, number of paper", i)

    df_layer_three_file = pd.read_csv(layer_three_data)

    df_layer_three_file['df_paper_title'] = df_layer_three_file['df_paper_title'].str.strip('[]')
    df_layer_three_file['df_paper_title'] = df_layer_three_file['df_paper_title'].str.strip("''")

    df_layer_three_file['df_paper_url'] = df_layer_three_file['df_paper_url'].str.strip('[]')
    df_layer_three_file['df_paper_url'] = df_layer_three_file['df_paper_url'].str.strip("''")

    df_layer_three_file['df_paper_abstract'] = df_layer_three_file['df_paper_abstract'].str.strip('[]')
    df_layer_three_file['df_paper_abstract'] = df_layer_three_file['df_paper_abstract'].str.strip("''")

    df_layer_three_file['df_paper_author'] = df_layer_three_file['df_paper_author'].str.strip('[]')
    df_layer_three_file['df_paper_author'] = df_layer_three_file['df_paper_author'].str.strip("''")

    df_layer_three_file['df_paper_date'] = df_layer_three_file['df_paper_date'].str.strip('[]')
    df_layer_three_file['df_paper_date'] = df_layer_three_file['df_paper_date'].str.strip("''")

    df_layer_three_file.to_csv("./layer_three_data.csv", index=False)
    print("CSV saved")

    print("End of layer three")

    f = open("version.cfg", "x")

    # datetime object containing current date and time
    now = datetime.now()

    # dd/mm/YY H:M:S
    dt = now.strftime("%d/%m/%Y %H:%M:%S")
    print("Saved version: ", dt)

    f.write(dt)
    f.close()

    driver.close()
    return True

# layer_three("layer_two_data.csv")