#!/usr/bin/python3

############################################################################################################################
# Setting up the program
############################################################################################################################

# These are the generic imports that are imported for a cgi file. Not sure if they're all relevant here

import numpy as np
import json
import sqlite3
from globalSettings import *
import pandas as pd
import math
import random
import csv
import os
import matplotlib.pyplot as plt
import sys
import time as time
import cgi
import cgitb
cgitb.enable()

# These are the imports necessary for this file

#import instrs as ins

# Connect to the Database

conn = sqlite3.connect(DBPath)
conn.text_factory = str
c = conn.cursor()

# Path to where the csv file will be saved

#path = r"/home/lg-pilot/Desktop/Ongoing/NGP2PilotGraphsTask/results/"
# path = r"pilot/demographs/ngp/"   #windows path

path = r"/var/www/pilot/demographs/ngp/"
filename = path + "NGP2graph_"

# Decide whether the script will be run using the GUI, CCM, or neither

true = 0
false = 1

GUI = true
CCM = false

device = DeviceName

# Choose a function for the script to perform

if(GUI == true):
    form = cgi.FieldStorage()
    request_Type = form.getvalue('requestType')

else:
    print("1. Create actual data ModeMap .csv files (requires a chip and instruments)")
    print("2. Create arbitrary data ModeMap .csv files")
    print("3. Create spectrum, using point on heatmap")
    print("4. Create spectrum, by choosing values of Wavelength, Power, SMSR")
    print("5. Print heatmaps")
    choice = int(eval(input("select cgi Function===>")))

    if choice == 1:
        request_Type = 'create_real_modemap_csv'

    elif choice == 2:
        request_Type = 'create_fake_modemap_csv'

    elif choice == 3:
        request_Type = 'select_point_on_graph'

    elif choice == 4:
        request_Type = 'select_values'

    elif choice == 5:
        request_Type = 'print_heatmaps'

    else:
        print("Enter Valid choice")

    print(("Request_Type = " + str(request_Type)))


############################################################################################################################
# Defining real_data_tuning_map(), creates real heatmaps using equipment
############################################################################################################################

def real_data_tuning_map(out_file, tester="None", temperature=0):

    # Sets the step size for the current (mA)

    Back_Current_Step = 1
    Front_Current_Step = 1

# I_Drives are called / chosen depending on if GUI == true

    if(GUI == true):  # Not sure how to interface with GUI
        Front_Current_Driver = form.getvalue("front_current_driver")
        Back_Current_Driver = form.getvalue("back_current_driver")
        Channel_1 = form.getvalue("channel_1")
        Channel_2 = form.getvalue("channel_2")

    else:
        Front_Current_Driver = form_getvalue("front_current_driver")
        Back_Current_Driver = form_getvalue("back_current_driver")
        Channel_1 = form_getvalue("channel_1")
        Channel_2 = form_getvalue("channel_2")

    query = c.execute(
        "SELECT set_min_current, set_max_current FROM i_drive WHERE name =" + Front_Current_Driver)
    for col in c:
        Front_Current_Min = col[0]
        Front_Current_Max = col[1]

    query = c.execute(
        "SELECT set_min_current, set_max_current FROM i_drive WHERE name =" + Back_Current_Driver)
    for col in c:
        Back_Current_Min = col[0]
        Back_Current_Max = col[1]

# Initialize the Instruments

    current_source1 = ins.ldc_3916(channel=Channel_1, laser=2)
    current_source2 = ins.ldc_3916(channel=Channel_2, laser=2)
    osa = ins.ms9710c(gpib=8)

# Arrays are formed based on the specified ranges and step sizes. All are empty except the current arrays

    Current_Array_1 = np.arange(
        Front_Current_Min, Front_Current_Max + Front_Current_Step, Front_Current_Step)
    Current_Array_2 = np.arange(
        Back_Current_Min, Back_Current_Max + Back_Current_Step, Back_Current_Step)

    voltage_array1 = np.zeros((len(Current_Array_1), len(Current_Array_2)))
    voltage_array2 = np.zeros((len(Current_Array_1), len(Current_Array_2)))

    peak_power_array = np.zeros(
        (len(Current_Array_1), len(Current_Array_2))) + np.nan
    peak_wavelength_array = np.zeros(
        (len(Current_Array_1), len(Current_Array_2))) + np.nan
    smsr_array = np.zeros(
        (len(Current_Array_1), len(Current_Array_2))) + np.nan

# Set the initial current on the instrument

    current_source1.set_current(1.0)
    current_source1.set_output_on()
    current_source2.set_current(1.0)
    current_source2.set_output_on()
    time.sleep(4)

# Loops across each current2 value for each current1 value, recording necessary values from each iteration

    for i, current1 in enumerate(Current_Array_1):
        current_source1.set_current(current1)

        for o, current2 in enumerate(Current_Array_2):
            current_source2.set_current(current2)
            print((current1, current2, "I1, I2"))

            osa.single_sweep()
            time.sleep(0.025)

            peak_wavelength_array[i, o] = osa.return_peak_wavelength()
            wavelength_writer.writerow(
                [str(current1), str(current2), str(peak_wavelength_array[i, o])])

            peak_power_array[i, o] = osa.return_power()
            power_writer.writerow(
                [str(current1), str(current2), str(peak_power_array[i, o])])

            smsr_array[i, o] = osa.return_smsr()
            smsr_writer.writerow(
                [str(current1), str(current2), str(smsr_array[i, o])])

            v1 = current_source1.return_measured_voltage()
            v2 = current_source2.return_measured_voltage()

            voltage_array1[i, o] = v1
            voltage1_writer.writerow([str(current1), str(current2), str(v1)])

            voltage_array2[i, o] = v2
            voltage2_writer.writerow([str(current1), str(current2), str(v2)])

# Saves in .npz format aswell

        np.savez(out_file, Current_Array_1=Current_Array_1, Current_Array_2=Current_Array_2,
                 voltage_array1=voltage_array1, voltage_array2=voltage_array2,
                 peak_wavelength_array=peak_wavelength_array, peak_power_array=peak_power_array,
                 smsr_array=smsr_array)

    print((json.JSONEncoder().encode(
        {"status": "success", "description": "Successfully Created"})))


############################################################################################################################
# Defining fake_data_tuning_map(), which creates heatmaps filled with arbitrary values
############################################################################################################################

def fake_data_tuning_map(out_file):

    # Sets the step size for the current (mA)

    Back_Current_Step = 1
    Front_Current_Step = 1

# I_Drives are called / chosen depending on if GUI == true

    print("Select two current drivers: \n")

    if(GUI == true):  # Not sure how to interface with GUI
        Front_Current_Driver = form.getvalue("front_current_driver")
        Back_Current_Driver = form.getvalue("back_current_driver")

    else:
        Front_Current_Driver = form_getvalue("front_current_driver")
        Back_Current_Driver = form_getvalue("back_current_driver")

    query = c.execute(
        "SELECT set_min_current, set_current_limit FROM i_drive WHERE name ='" + Front_Current_Driver + "'")
    for col in c:
        Front_Current_Min = col[0]
        Front_Current_Max = col[1]

    query = c.execute(
        "SELECT set_min_current, set_current_limit FROM i_drive WHERE name ='" + Back_Current_Driver + "'")
    for col in c:
        Back_Current_Min = col[0]
        Back_Current_Max = col[1]

# Arrays are formed based on the specified ranges and step sizes. All are empty except the current arrays

    Current_Array_1 = np.arange(
        Front_Current_Min, Front_Current_Max + Front_Current_Step, Front_Current_Step)
    Current_Array_2 = np.arange(
        Back_Current_Min, Back_Current_Max + Back_Current_Step, Back_Current_Step)

    voltage_array1 = np.zeros((len(Current_Array_1), len(Current_Array_2)))
    voltage_array2 = np.zeros((len(Current_Array_1), len(Current_Array_2)))

    peak_power_array = np.zeros(
        (len(Current_Array_1), len(Current_Array_2))) + np.nan
    peak_wavelength_array = np.zeros(
        (len(Current_Array_1), len(Current_Array_2))) + np.nan
    smsr_array = np.zeros(
        (len(Current_Array_1), len(Current_Array_2))) + np.nan

# Randomly generate values for the heatmap

    peak_wavelength = round(random.uniform(1495.0, 1555.0), 2)
    peak_power = round(random.uniform(1, 2), 2)
    smsr = round(random.uniform(10, 50), 2)
    v1 = 1
    v2 = 2

# Loops across each current2 value for each current1 value, recording necessary values from each iteration

    for i, current1 in enumerate(Current_Array_1):

        for o, current2 in enumerate(Current_Array_2):

            print((current1, current2, "I1, I2"))

            peak_wavelength_array[i, o] = peak_wavelength
            wavelength_writer.writerow(
                [str(current1), str(current2), str(peak_wavelength)])
            peak_wavelength = round(random.uniform(1495.0, 1555.0), 2)

            peak_power_array[i, o] = peak_power
            power_writer.writerow(
                [str(current1), str(current2), str(peak_power)])
            peak_power = round(random.uniform(1, 2), 2)

            smsr_array[i, o] = smsr
            smsr_writer.writerow([str(current1), str(current2), str(smsr)])
            smsr = round(random.uniform(10, 50), 2)

            voltage_array1[i, o] = v1
            voltage1_writer.writerow([str(current1), str(current2), str(v1)])

            voltage_array2[i, o] = v2
            voltage2_writer.writerow([str(current1), str(current2), str(v2)])

            v1 += 1
            v2 += 2

# Saves in .npz file aswell

        np.savez(out_file, Current_Array_1=Current_Array_1, Current_Array_2=Current_Array_2,
                 voltage_array1=voltage_array1, voltage_array2=voltage_array2,
                 peak_wavelength_array=peak_wavelength_array, peak_power_array=peak_power_array,
                 smsr_array=smsr_array)

    print((json.JSONEncoder().encode(
        {"status": "success", "description": "Successfully Created"})))


############################################################################################################################
# Defining select_point_heatmap(), allows the user to choose a point on the graph and retrieve corresponding values
############################################################################################################################

def select_point_heatmap():

    # Reads the data sets

    Current_1_List, Current_2_List, Wavelength_List, Power_List, SMSR_List = read_data()

# Either uses values from the GUI or has the user enter values.

    if(GUI == true):
        Current_Point_1 = form.getvalue("current_point_1")
        Current_Point_2 = form.getvalue("current_point_2")
        mapHeader = form.getvalue("graphHeader")

    else:
        Current_Point_1 = form_getvalue("current_point_1")
        Current_Point_2 = form_getvalue("current_point_2")

    Current_Point_1 = float(Current_Point_1)
    Current_Point_2 = float(Current_Point_2)

# Checks if the chosen Current values are in the correct range

    if (Current_Point_1 < min(Current_1_List)) or (Current_Point_1 > max(Current_1_List)):
        print((json.JSONEncoder().encode(
            {"status": "failed", "description": "Current is not within the current range"})))
        sys.exit()

    if (Current_Point_2 < min(Current_2_List)) or (Current_Point_2 > max(Current_2_List)):
        print((json.JSONEncoder().encode(
            {"status": "failed", "description": "Current is not within the current range"})))
        sys.exit()

# Selects the index of the chosen current values

    Current_1_Index = Current_1_List.index(Current_Point_1)

    for i in Current_2_List[(int(max(Current_1_List)) + 1):]:
        if i == Current_Point_2:
            Current_2_Index = Current_2_List.index(i)

# Selects the corresponding values of wavelength, power, and smsr

    Wavelength = Wavelength_List[Current_1_Index + Current_2_Index]
    Power = Power_List[Current_1_Index + Current_2_Index]
    SMSR = SMSR_List[Current_1_Index + Current_2_Index]

# Some values are defined

    Mode_Spacing = 0.08
    linewidth = 0.3
    FSR = float(Mode_Spacing * 125)

#Wavelength (nm), FSR (GHz), optical_power (mW), linewidth (MHz), Power (mW), SMSR (dB)

    # gamma is linewidth/2 and in GHz units
    gamma = float(linewidth) / 2 / 1e3
    # in GHz
    resolution = 0.1
    points = float(FSR) / resolution

    # x-axis for one tone - therefore, tone_span is from -Mode_Spacing/2 to Mode_Spacing/2
    tone_span = np.linspace(-Mode_Spacing / 2, Mode_Spacing / 2, int(points))
    # spectrum of one tone with a Lorentzian profile
    Lorentzian_tone_spectra = Lorentzian_lineshape(tone_span, gamma)

    # demux tone Lorentzian lineshape
    demux_tone_y = Lorentzian_tone_spectra
    # normalize spectrum amplitude
    demux_tone_y = [j * Power / max(demux_tone_y) for j in demux_tone_y]
    demux_tone_y_dB = [10 * math.log10(j) for j in demux_tone_y]
    # demux_x = [j + Wavelength + demux_set_tone*Mode_Spacing - (nb_tones-1)*Mode_Spacing/2 for j in tone_span]          #shifts spectrum to correct wavelength

# Build demux full spectrum

    demux_spectrum = demux_tone_y_dB
    demux_x = tone_span

    # shift whole spectrum to Wavelength
    demux_x = [j + Wavelength for j in demux_x]
    x_values = np.linspace(demux_x[0], demux_x[len(demux_x) - 1], len(demux_x))
    Gaussian = gaussian(x_values, Wavelength, 1)
    # in dB
    Gaussian_dB = [10 * math.log10(j) for j in Gaussian]
    demux_spectrum_shaped = [a + 15 * b for a,
                             b in zip(demux_spectrum, Gaussian_dB)]

# filter values above -50 dB

    ind = [i for i in range(len(demux_spectrum_shaped))
           if demux_spectrum_shaped[i] > -50]
    demux_spectrum_shaped = [demux_spectrum_shaped[i] for i in ind]
    demux_x = [demux_x[i] for i in ind]

# Success Message

    print((json.JSONEncoder().encode(
        {"status": "success", "description": "Successfully Created"})))

# Writes the Data to a .csv file

    x = demux_x
    y = demux_spectrum_shaped

    demux_name = "Single_Mode_Heatmap_"
    demux_full_path = filename + demux_name + ".csv"

    data = [demux_x, demux_spectrum_shaped]
    data = pd.DataFrame(data).T
    data.columns = [mapHeader, " "]
    data.to_csv(demux_full_path, index=False, header=True)

# Prints the Graph

    #print("Wavelenth: " + str(Wavelength))
    #print("Power: " + str(Power))
    #print("SMSR: " + str(SMSR))

    #plt.plot(x, y, ls='--')
    #plt.xlabel("Wavelength (nm)")
    #plt.ylabel("Power (dBm)")
    # plt.show()

    # plt.show()


############################################################################################################################
# Defining select_values(), allows the user to select values for Wavelength, Power, and SMSR
############################################################################################################################

def select_values():

    # Either uses values from the GUI or has the user enter values.

    if(GUI == true):
        Min_Wavelength = form.getvalue("min_wavelength")
        Wavelength = form.getvalue("wavelength")
        Max_Wavelength = form.getvalue("max_wavelength")

        Min_Power = form.getvalue("min_power")
        Power = form.getvalue("power")
        Max_Power = form.getvalue("max_power")

        Min_SMSR = form.getvalue("min_smsr")
        SMSR = form.getvalue("smsr")
        Max_SMSR = form.getvalue("max_smsr")

    else:
        Min_Wavelength = form_getvalue("min_wavelength")
        Max_Wavelength = form_getvalue("max_wavelength")
        Wavelength = form_getvalue("wavelength")

        Min_Power = form_getvalue("min_power")
        Max_Power = form_getvalue("max_power")
        Power = form_getvalue("power")

        Min_SMSR = form_getvalue("min_smsr")
        Max_SMSR = form_getvalue("max_smsr")
        SMSR = form_getvalue("smsr")

# Checks if the values entered are valid

    if (Wavelength > Max_Wavelength) or (Wavelength < Min_Wavelength):
        print((json.JSONEncoder().encode(
            {"status": "failed", "description": "Wavelength was not within the wavelength range"})))
        sys.exit()

    if (Power > Max_Power) or (Wavelength < Min_Power):
        print((json.JSONEncoder().encode(
            {"status": "failed", "description": "Power was not within the powar range"})))
        sys.exit()

    if (SMSR > Max_SMSR) or (SMSR < Min_SMSR):
        print((json.JSONEncoder().encode(
            {"status": "failed", "description": "SMSR was not within the SMSR range"})))
        sys.exit()

# Some values are defined

    Mode_Spacing = 0.08
    linewidth = 0.3
    FSR = float(Mode_Spacing * 125)

#Wavelength (nm), FSR (GHz), optical_power (mW), linewidth (MHz), Power (mW), SMSR (dB)

    # gamma is linewidth/2 and in GHz units
    gamma = float(linewidth) / 2 / 1e3
    # in GHz
    resolution = 0.1
    points = float(FSR) / resolution

    # x-axis for one tone - therefore, tone_span is from -Mode_Spacing/2 to Mode_Spacing/2
    tone_span = np.linspace(-Mode_Spacing / 2, Mode_Spacing / 2, int(points))
    # spectrum of one tone with a Lorentzian profile
    Lorentzian_tone_spectra = Lorentzian_lineshape(tone_span, gamma)

    # demux tone Lorentzian lineshape
    demux_tone_y = Lorentzian_tone_spectra
    # normalize spectrum amplitude
    demux_tone_y = [j * float(Power) / max(demux_tone_y) for j in demux_tone_y]
    demux_tone_y_dB = [10 * math.log10(j) for j in demux_tone_y]
    # demux_x = [j + Wavelength + demux_set_tone*Mode_Spacing - (nb_tones-1)*Mode_Spacing/2 for j in tone_span]          #shifts spectrum to correct wavelength

# Build demux full spectrum

    demux_spectrum = demux_tone_y_dB
    demux_x = tone_span

    # shift whole spectrum to Wavelength
    demux_x = [j + float(Wavelength) for j in demux_x]
    x_values = np.linspace(demux_x[0], demux_x[len(demux_x) - 1], len(demux_x))
    Gaussian = gaussian(x_values, float(Wavelength), 1)
    # in dB
    Gaussian_dB = [10 * math.log10(j) for j in Gaussian]
    demux_spectrum_shaped = [a + 15 * b for a,
                             b in zip(demux_spectrum, Gaussian_dB)]

# filter values above -50 dB

    ind = [i for i in range(len(demux_spectrum_shaped))
           if demux_spectrum_shaped[i] > -50]
    demux_spectrum_shaped = [demux_spectrum_shaped[i] for i in ind]
    demux_x = [demux_x[i] for i in ind]

# Success Message

    print((json.JSONEncoder().encode(
        {"status": "success", "description": "Successfully Created"})))

# Writes the Data to a .csv file

    x = demux_x
    y = demux_spectrum_shaped

    demux_name = "Single_Mode_Values_"
    demux_full_path = filename + demux_name + ".csv"

    data = [demux_x, demux_spectrum_shaped]
    data = pd.DataFrame(data).T
    data.to_csv(demux_full_path, index=False, header=False)

# Prints the Graph

#    print("Wavelenth: " + str(Wavelength))
#    print("Power: " + str(Power))
#    print("SMSR: " + str(SMSR))

#    plt.plot(x, y, ls='--')
#    plt.xlabel("Wavelength (nm)")
#    plt.ylabel("Power (dBm)")
#    plt.show()

    plt.show()


############################################################################################################################
# Defining print_heatmaps(), a function which reads the data and creates heatmaps
############################################################################################################################

def print_heatmaps():

    # Reads the data from the csv files

    Current_1_List, Current_2_List, Wavelength_List, Power_List, SMSR_List = read_data()

# Turns that data into arrays which can be plotted

    Current_1_Array = np.arange(
        min(Current_1_List), max(Current_1_List) + 1, 1)
    Current_2_Array = np.arange(
        min(Current_2_List), max(Current_2_List) + 1, 1)

    Wavelength_Array = np.array(Wavelength_List).reshape(
        Current_1_Array.size, Current_2_Array.size)
    Power_Array = np.array(Power_List).reshape(
        Current_1_Array.size, Current_2_Array.size)
    SMSR_Array = np.array(SMSR_List).reshape(
        Current_1_Array.size, Current_2_Array.size)

# Plots three respective heatmaps; Wavelength, Power, and SMSR

    plt.figure(1)
    plt.clf()
    plt.pcolormesh(Current_1_Array, Current_2_Array,
                   Wavelength_Array.T, cmap="gnuplot")
    plt.colorbar()
    plt.title("Wavelength Heatmap")
    plt.xlabel("current 1")
    plt.ylabel("current 2")

    plt.figure(2)
    plt.clf()
    plt.pcolormesh(Current_1_Array, Current_2_Array,
                   Power_Array.T, cmap="gnuplot")
    plt.colorbar()
    plt.title("Power Heatmap")
    plt.xlabel("current 1")
    plt.ylabel("current 2")

    plt.figure(3)
    plt.clf()
    plt.pcolormesh(Current_1_Array, Current_2_Array,
                   SMSR_Array.T, cmap="gnuplot")
    plt.colorbar()
    plt.title("SMSR Heatmap")
    plt.xlabel("current 1")
    plt.ylabel("current 2")

    plt.show()

    print((json.JSONEncoder().encode(
        {"status": "success", "description": "Successfully Created"})))


############################################################################################################################
# Defining open_files(), a function which globally opens csv files to store data, and writes a header into them
############################################################################################################################

def open_files(filename):

    global peak_wavelength_file, peak_power_file, smsr_file, voltage1_file, voltage2_file, spectra_list_file
    global wavelength_writer, power_writer, smsr_writer, voltage1_writer, voltage2_writer

# Checks if the files already exist, if not they will be created

    if os.path.isfile(filename + "_Peak_Wavelength.csv") == False:
        peak_wavelength_file = open(filename + "_Peak_Wavelength.csv", "w")
        peak_power_file = open(filename + "_Peak_Power.csv", "w")
        smsr_file = open(filename + "_SMSR.csv", "w")
        voltage1_file = open(filename + "_Voltage1.csv", "w")
        voltage2_file = open(filename + "_Voltage2.csv", "w")
        spectra_list_file = open(filename + "_Spectra_List.txt", "w")

# The files are converted into csv.writer objects

        wavelength_writer = csv.writer(peak_wavelength_file)
        power_writer = csv.writer(peak_power_file)
        smsr_writer = csv.writer(smsr_file)
        voltage1_writer = csv.writer(voltage1_file)
        voltage2_writer = csv.writer(voltage2_file)

# The file columns are given headers

        wavelength_writer.writerow(["Current 1", "Current 2", "Wavelength"])
        power_writer.writerow(["Current 1", "Current 2", "Power"])
        smsr_writer.writerow(["Current 1", "Current 2", "SMSR"])
        voltage1_writer.writerow(["Current 1", "Current 2", "Voltage 1"])
        voltage2_writer.writerow(["Current 1", "Current 2", "Voltage 2"])

    else:
        print((json.JSONEncoder().encode(
            {"status": "failed", "description": "These Files already exist"})))
        sys.exit()


############################################################################################################################
# Defining close_files(), a function which closes the files after they have been used
############################################################################################################################

def close_files():

    peak_wavelength_file.close()
    peak_power_file.close()
    smsr_file.close()
    voltage1_file.close()
    voltage2_file.close()
    spectra_list_file.close()


############################################################################################################################
# A function which reads the data in their three column format
############################################################################################################################

def read_data():

    # An input is taken so as to decide which dataset is to be read. The data is then added to the lists globalised above

    peak_wavelength_file = open(filename + "_Peak_Wavelength.csv", "r")
    current_1_list, current_2_list, wavelength_list = data_splitter(
        peak_wavelength_file)
    peak_wavelength_file.close()

    peak_power_file = open(filename + "_Peak_Power.csv", "r")
    current_1_list, current_2_list, power_list = data_splitter(peak_power_file)
    peak_power_file.close()

    smsr_file = open(filename + "_SMSR.csv", "r")
    current_1_list, current_2_list, smsr_list = data_splitter(smsr_file)
    smsr_file.close()

    return current_1_list, current_2_list, wavelength_list, power_list, smsr_list


############################################################################################################################
# A function which splits the columns into their respective arrays
############################################################################################################################

def data_splitter(data_file):

    # Opens csv file in a reader format

    csv_reader = csv.reader(data_file, delimiter=',')

    line_count = 0

# Empty lists are created to be loaded with information

    curr_1_list = []
    curr_2_list = []
    third_col_list = []

    for row in csv_reader:

        # Skips the first line as it contains header information

        if line_count == 0:
            line_count += 1

        else:
            curr_1_list.append(float(row[0]))
            curr_2_list.append(float(row[1]))
            third_col_list.append(float(row[2]))

# Returns the lists

    return curr_1_list, curr_2_list, third_col_list


############################################################################################################################
# Defining form_getvalue(), assigns values to certain variables
############################################################################################################################

def form_getvalue(val):

    # Allows the user to enter a value for different components

    if val == "wavelength":
        channel_wavelength = float(
            eval(input("Enter the wavelength value in nm: ")))
        return channel_wavelength

    if val == "min_wavelength":
        min_wavelength = float(
            eval(input("Enter the minimum wavelength value in nm: ")))
        return min_wavelength

    if val == "max_wavelength":
        max_wavelength = float(
            eval(input("Enter the maximum wavelength value in nm: ")))
        return max_wavelength

    if val == "smsr":
        SMSR = float(eval(input("Enter the SMSR value in dB: ")))
        return SMSR

    if val == "min_smsr":
        min_SMSR = float(eval(input("Enter the minimum SMSR value in dB: ")))
        return min_SMSR

    if val == "max_smsr":
        max_SMSR = float(eval(input("Enter the maximum SMSR value in dB: ")))
        return max_SMSR

    if val == "power":
        power = float(eval(input("Enter the power value in dBm: ")))
        return power

    if val == "min_power":
        min_power = float(
            eval(input("Enter the minimum power value in dBm: ")))
        return min_power

    if val == "max_power":
        max_power = float(
            eval(input("Enter the maximum power value in dBm: ")))
        return max_power

    if val == "channel_1":
        Channel_1 = int(eval(input("Enter the first channel number: ")))
        return Channel_1

    if val == "channel_2":
        Channel_2 = int(eval(input("Enter the second channel number: ")))
        return Channel_2

    if val == "current_point_1":
        Current_Point_1 = int(eval(input("Enter the Current 1 point: ")))
        return Current_Point_1

    if val == "current_point_2":
        Current_Point_2 = int(eval(input("Enter the Current 2 point: ")))
        return Current_Point_2

    if val == "back_current_driver":
        count = 1
        query = c.execute("SELECT name FROM i_drive")
        for col in c:
            print((str(count) + " " + col[0]))
            count += 1

        ID = int(eval(input("Enter the second current driver: ")))
        query = c.execute("SELECT name FROM i_drive WHERE id=" + str(ID))
        Back_Current_Driver = c.fetchone()[0]
        print("\n")
        return Back_Current_Driver

    if val == "front_current_driver":
        count = 1
        query = c.execute("SELECT name FROM i_drive")
        for col in c:
            print((str(count) + " " + col[0]))
            count += 1

        ID = int(eval(input("Enter the first current driver: ")))
        query = c.execute("SELECT name from i_drive WHERE id=" + str(ID))
        Front_Current_Driver = c.fetchone()[0]
        print("\n")
        return Front_Current_Driver


############################################################################################################################
# Defining Lorentzian_lineshape()
############################################################################################################################

def Lorentzian_lineshape(x_range, gamma):

    # Return Lorentzian line shape at x with HWHM gamma

    return gamma / np.pi / (x_range**2 + gamma**2)


############################################################################################################################
# Defining gaussian()
############################################################################################################################

def gaussian(x, mu, sig):

    # Spectrum-shaping

    return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))


############################################################################################################################
# Calling the relevant function
############################################################################################################################

print("Content-type:/text/html\r\n\r\n")

# Functions are called based on the request_Type chosen

if (request_Type == 'create_real_modemap_csv'):
    open_files(filename)
    real_data_tuning_map(filename, tester="Lewis Grant", temperature=20)
    close_files()

elif (request_Type == 'create_fake_modemap_csv'):
    open_files(filename)
    fake_data_tuning_map(filename)
    close_files()

elif(request_Type == 'select_point_on_graph'):
    select_point_heatmap()

elif(request_Type == 'select_values'):
    select_values()

elif(request_Type == 'print_heatmaps'):
    print_heatmaps()
