# Copyright 2022 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Usage:
  models_regression.py [--num_cores=<num>]

  -h, --help             Show help text.
  -v, --version          Show version.
  --num_cores=<num>      Number of cores to be used by simulator
"""

from re import T
from docopt import docopt
import pandas as pd 
import numpy as np
import os 
from jinja2 import Template
import concurrent.futures
import shutil
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

def call_simulator(file_name):
    """Call simulation commands to perform simulation.
    Args:
        file_name (str): Netlist file name.
    """
    os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log")

def ext_measured(device,vds,vgs):
    
    # Get dimensions used for each device 
    dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"])
    loops = dimensions["L (um)"].count()
    
    # Extracting measured values for each W & L 
    for i in range (0,loops*2,2):
        width  = dimensions["W (um)"].iloc[int(i/2)]
        length = dimensions["L (um)"].iloc[int(i/2)]
        
        # Special case for 1st measured values 
        if i == 0 :
            # measured Id
            col_list = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"]
            df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list)
            df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"]
            df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False)
            # measured Rds
            col_list = [f"{vds}",f"vgs ={vgs[0]}.{i+1}",f"vgs ={vgs[1]}.{i+1}",f"vgs ={vgs[2]}.{i+1}",f"vgs ={vgs[3]}.{i+1}",f"vgs ={vgs[4]}.{i+1}",f"vgs ={vgs[5]}.{i+1}"]
            df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list)
            df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"]
            df_measured.to_csv(f"{device}/measured_Rds/{int(i/2)}_measured_W{width}_L{length}.csv", index = False)
        else:
            # measured Id
            col_list = [f"{vds}",f"vgs ={vgs[0]}.{i}",f"vgs ={vgs[1]}.{i}",f"vgs ={vgs[2]}.{i}",f"vgs ={vgs[3]}.{i}",f"vgs ={vgs[4]}.{i}",f"vgs ={vgs[5]}.{i}"]
            df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list)
            df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"]        
            df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False)
            # measured Rds
            col_list = [f"{vds}",f"vgs ={vgs[0]}.{i+1}",f"vgs ={vgs[1]}.{i+1}",f"vgs ={vgs[2]}.{i+1}",f"vgs ={vgs[3]}.{i+1}",f"vgs ={vgs[4]}.{i+1}",f"vgs ={vgs[5]}.{i+1}"]
            df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list)
            df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"]
            df_measured.to_csv(f"{device}/measured_Rds/{int(i/2)}_measured_W{width}_L{length}.csv", index = False)

def ext_simulated(device,vds,vgs,vds_sweep,sim_val):
    
    # Get dimensions used for each device 
    dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"])
    loops = dimensions["L (um)"].count()
    temp_range = int(loops/3) 
    netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice"
    for i in range (0,loops):
        width  = dimensions["W (um)"].iloc[int(i)]
        length = dimensions["L (um)"].iloc[int(i)]
        AD = float(width) * 0.24
        PD = 2 * (float(width) + 0.24)
        AS = AD 
        PS = PD 
        if i in range (0,temp_range): temp = 25 
        elif i in range (temp_range,2*temp_range): temp = -40 
        else:
            temp = 125 
        with open(netlist_tmp) as f:
            tmpl = Template(f.read())
            os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True)
            with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist:
                netlist.write(tmpl.render(width = width,length = length,i = i , temp = temp , AD = AD , PD = PD , AS = AS , PS = PD ))
            netlist_path  = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" 
            # Running ngspice for each netlist 
            with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor:
                executor.submit(call_simulator, netlist_path)
            
            # Writing simulated data 
            df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=None, delimiter=r"\s+")
            df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False)    
            
            # empty array to append in it shaped (vds_sweep, number of trials + 1)
            new_array = np.empty((vds_sweep, 1+int(df_simulated.shape[0]/vds_sweep)))  
            new_array[:, 0] = df_simulated.iloc[:vds_sweep, 0]
            times = int(df_simulated.shape[0]/vds_sweep)

            for j in range(times):
                new_array[:, (j+1)] = df_simulated.iloc[j*vds_sweep:(j+1)*vds_sweep, 1]
                
            # Writing final simulated data                 
            df_simulated = pd.DataFrame(new_array)
            df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False)    
            df_simulated.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"]
            df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False)    

def error_cal(device,vds,vgs,sim_val):
    
    # Get dimensions used for each device 
    dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"])
    loops = dimensions["L (um)"].count()
    temp_range = int(loops/3)     
    df_final = pd.DataFrame()
    for i in range (0,loops):  
        width  = dimensions["W (um)"].iloc[int(i)]
        length = dimensions["L (um)"].iloc[int(i)]
        if i in range (0,temp_range): temp = 25             
        elif i in range (temp_range,2*temp_range): temp = -40             
        else: temp = 125
             
        measured  = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv")
        simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv")

        error_1 = round (100 * abs((abs(measured.iloc[1:, 1]) - abs(simulated.iloc[1:, 1]))/abs(measured.iloc[:, 1])),6)  
        error_2 = round (100 * abs((abs(measured.iloc[1:, 2]) - abs(simulated.iloc[1:, 2]))/abs(measured.iloc[:, 2])),6)
        error_3 = round (100 * abs((abs(measured.iloc[1:, 3]) - abs(simulated.iloc[1:, 3]))/abs(measured.iloc[:, 3])),6) 
        error_4 = round (100 * abs((abs(measured.iloc[1:, 4]) - abs(simulated.iloc[1:, 4]))/abs(measured.iloc[:, 4])),6) 
        error_5 = round (100 * abs((abs(measured.iloc[1:, 5]) - abs(simulated.iloc[1:, 5]))/abs(measured.iloc[:, 5])),6) 
        error_6 = round (100 * abs((abs(measured.iloc[1:, 6]) - abs(simulated.iloc[1:, 6]))/abs(measured.iloc[:, 6])),6) 

        df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5,error_6]).transpose()        
        df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False)
        
        # Mean error 
        mean_error = (df_error[f"vgs ={vgs[0]}"].mean() + df_error[f"vgs ={vgs[1]}"].mean() + df_error[f"vgs ={vgs[2]}"].mean() + 
                      df_error[f"vgs ={vgs[3]}"].mean() + df_error[f"vgs ={vgs[4]}"].mean() + df_error[f"vgs ={vgs[5]}"].mean())/6
        # Max error 
        max_error = df_error[[f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}" ]].max().max()
        # Max error location 
        max_index = max((df_error == max_error).idxmax())
        max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index]
        max_location_vds = df_error[f"{vds}"][max_index]

        df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & Vds (V) = {max_location_vds}'}
        df_final = df_final.append(df_final_, ignore_index = True)
    # Max mean error 
    print (df_final)   
    df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False)
    out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv")
    print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%")    
    print ("=====================================================================================================================================================")

def main():
        
    devices = ["nmos_3p3_iv" , "pmos_3p3_iv" , "nmos_6p0_iv" , "pmos_6p0_iv" , "nmos_6p0_nat_iv", "nmos_3p3_sab_iv", "pmos_3p3_sab_iv" , "nmos_6p0_sab_iv" , "pmos_6p0_sab_iv"] 
    nmos_vds = "vds (V)"
    pmos_vds = "-vds (V)"
    nmos_rds = "Rds"
    Id_sim  = "Id"
    Rds_sim = "Rds"
    mos_3p3_vgs_sweep = 67 
    mos_6p0_vgs_sweep = 133 
    nmos3p3_vgs = [ 0.8 ,  1.3 ,  1.8 ,  2.3 ,  2.8 ,  3.3] 
    pmos3p3_vgs = [-0.8 , -1.3 , -1.8 , -2.3 , -2.8 , -3.3] 
    nmos6p0_vgs = [ 1 ,  2 ,  3 ,  4 ,  5 ,  6] 
    pmos6p0_vgs = [-1 , -2 , -3 , -4 , -5 , -6] 
    nmos6p0_nat_vgs = [ 0.25 ,  1.4 , 2.55 , 3.7 , 4.85 , 6]

    for device in devices: 
        # Folder structure of measured values 
        dirpath = f"{device}"
        if os.path.exists(dirpath) and os.path.isdir(dirpath):
            shutil.rmtree(dirpath)
        os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False)
        os.makedirs(f"{device}/measured_{Rds_sim}",exist_ok=False)

        # From xlsx to csv 
        read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/MOS/{device}.nl_out.xlsx")
        read_file.to_csv (f"{device}/{device}.csv", index = False, header=True)

        # Folder structure of simulated values 
        os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False)
        os.makedirs(f"{device}/simulated_{Rds_sim}",exist_ok=False)
        os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False)
        os.makedirs(f"{device}/error_{Rds_sim}",exist_ok=False)

    # =========== nmos_3p3_iv ==============      
    ext_measured ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs)

    ext_simulated("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim)
    error_cal    ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,Id_sim)

    ext_simulated("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim)
    error_cal    ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,Rds_sim)

    # =========== pmos_3p3_iv ==============      
    ext_measured ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs)

    ext_simulated("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim)
    error_cal    ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,Id_sim)
    
    ext_simulated("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim)    
    error_cal    ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,Rds_sim)

    # =========== nmos_6p0_iv ==============      
    ext_measured ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs)
   
    ext_simulated("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim)
    error_cal    ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,Id_sim)    
    
    ext_simulated("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim)
    error_cal    ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,Rds_sim)    
         
    # =========== pmos_6p0_iv ==============      
    ext_measured ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs)

    ext_simulated("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim)
    error_cal    ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,Id_sim) 
    
    ext_simulated("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim)    
    error_cal    ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,Rds_sim)              

    # ============ nmos_6p0_nat_iv =============              
    ext_measured ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs)

    ext_simulated("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,mos_6p0_vgs_sweep,Id_sim)
    error_cal    ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,Id_sim)     
    
    ext_simulated("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,mos_6p0_vgs_sweep,Rds_sim)    
    error_cal    ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,Rds_sim)    
    
    # ============ nmos_3p3_sab_iv =============                                
    ext_measured ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs)
    
    ext_simulated("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim)
    error_cal    ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,Id_sim)
    
    ext_simulated("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim)
    error_cal    ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,Rds_sim)

    # =========== pmos_3p3_sab_iv ==============      
    ext_measured ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs)

    ext_simulated("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim)
    error_cal    ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,Id_sim)
    
    ext_simulated("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim)    
    error_cal    ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,Rds_sim)

    # =========== nmos_6p0_sab_iv ==============      
    ext_measured ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs)
   
    ext_simulated("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim)
    error_cal    ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,Id_sim)    
    
    ext_simulated("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim)
    error_cal    ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,Rds_sim)    
         
    # =========== pmos_6p0_sab_iv ==============      
    ext_measured ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs)

    ext_simulated("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim)
    error_cal    ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,Id_sim) 
    
    ext_simulated("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim)    
    error_cal    ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,Rds_sim) 
    
# # ================================================================
# -------------------------- MAIN --------------------------------
# ================================================================
        
if __name__ == "__main__":
    
    # Args 
    arguments     = docopt(__doc__, version='comparator: 0.1')
    workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"])
    
    # Calling main function 
    main()
