import numpy as np
import pandas as pd
import sys

sys.path.insert(0, dirName) # dirName = location where the files listed here are located
from heatTransClass import HeatTrans
from heatTransLiqUncClass import HeatTransLiqUnc
from miscUncClass import MiscUnc

def wsCalcs(df1,mData):
    '''Calculations for the water side of the IBAL.'''
    ht = HeatTrans() # create an instance of the heat transfer class
    
    # Heat transfer calculations for the evaporator and condenser in each chiller
    df1['q_ch1_c'],df1['rho_ch1_c'],df1['cp_ch1_c'],df1['mDotCH1c'] = \
    ht.heatTransLiq(df1.pump4_out_rtd,df1.ch1_c_out_rtd,df1.ch1_f_c,'IP','water',0.3)   
    df1['q_ch1_e'],df1['rho_ch1_e'],df1['cp_ch1_e'],df1['mDotCH1e'] = \
    ht.heatTransLiq(df1.ch1_e_out_rtd,df1.ch1_e_in_rtd,df1.ch1_f_e,'IP','pg',0.3)   
    df1['q_ch2_c'],df1['rho_ch2_c'],df1['cp_ch2_c'],df1['mDotCH2c'] = \
    ht.heatTransLiq(df1.pump4_out_rtd,df1.ch2_c_out_rtd,df1.ch2_f_c,'IP','water',0.3)   
    df1['q_ch2_e'],df1['rho_ch2_e'],df1['cp_ch2_e'],df1['mDotCH2e'] = \
    ht.heatTransLiq(df1.ch2_e_out_rtd,df1.ch1_e_in_rtd,df1.ch2_f_e,'IP','pg',0.3)
    # Heat transfer calculations on the propylene glycol and hot water sides of HX1
    df1['q_hx1_hw'],df1['rho_hx1_hw'],df1['cp_hx1_hw'],df1['mDotHX1hw'] = \
    ht.heatTransLiq(df1.hx1_hw_rtd,df1.hw_rtd,df1.hx1_f_hw,'IP','water',0.3)   
    df1['q_hx1_pg'],df1['rho_hx1_pg'],df1['cp_hx1_pg'],df1['mDotHX1pg'] = \
    ht.heatTransLiq(df1.hx1_pg_rtd,df1.pump3_out_rtd,df1.hx1_f_pg,'IP','pg',0.3)  
    # Heat transfer calculations across the primary loop and secondary loop
    df1['q_pl'],df1['rho_pl'],df1['cp_pl'],df1['mDotPL'] = ht.heatTransLiq(df1.pl_out_rtd,df1.ch1_e_in_rtd,df1.pl_f,'IP','water',0.3)  
    df1['q_sl'],df1['rho_sl'],df1['cp_sl'],df1['mDotSL'] = ht.heatTransLiq(df1.pump3_out_rtd,df1.sl_out_rtd,df1.sl_f,'IP','water',0.3)  
    # Alternative calculations for the heat transfer in the secondary loop:
    # _suma uses the sum of the flow rates through HX1, and AHU1 and AHU2 cooling coils
    # _sum sums the individual heat transfer calculations on the propylene glycol sides of HX1 and AHU1 and AHU2 cooling coils
    # _sum_max sums the max of the heat transfer calculation on the hot water and propylene glycol sides of HX1 and AHU1 and AHU2 cooling coils
    df1['q_sl_suma'],df1['rho_sl_sum'],df1['cp_sl_sum'],df1['mDotSLsum'] = \
    ht.heatTransLiq(df1.pump3_out_rtd,df1.sl_out_rtd,df1.hx1_f_pg+df1.ahu1_f_cc+df1.ahu2_f_cc,'IP','water',0.3)  
    df1['q_sl_sum'] = df1.q_hx1_pg + df1.q_ahu1_cc_pg + df1.q_ahu2_cc_pg
    df1['q_sl_sum_max'] = [max(a,b) for a,b in zip(df1.q_hx1_pg,df1.q_hx1_hw)] + df1.q_ahu1_cc_pg + df1.q_ahu2_cc_pg
    # Heat transfer calculation across the thermal storage
    df1['q_ts'],df1['rho_ts_pg'],df1['cp_ts_pg'],df1['mDotTS'] = \
    ht.heatTransLiq(df1.ts_in_rtd,df1.ts_out_rtd,df1.ts_f,'IP','pg',0.3)  
    # The building load calculated as the max of the secondary loop heat transfers, the sum of the heat transfers in AHU1 and AHU2, and the 
    # setpoints in AHU1 and AHU2
    df1['q_building_load'] = [max(a,b,c,d) for a,b,c,d in \
                              zip(df1.q_sl,df1.q_sl_sum_max,df1.q_ahu1_cc+df1.q_ahu2_cc,\
                                  df1.q_ahu1_cc_sp+df1.q_ahu2_cc_sp)]
    
    uQ = HeatTransLiqUnc() # Create an instance of the class for the uncertainty of heat transfer in liquid systems
    # Calculate heat transfer uncertainty for the various prior values 
    df1 = uQ.uTot(df1,mData,'ch1_c_out_rtd','pump4_out_rtd','ch1_f_c','q_ch1_c',fluid = 'water',conc = 0,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'ch1_e_in_rtd','ch1_e_out_rtd','ch1_f_e','q_ch1_e',fluid = 'PG',conc = 0.3,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'ch2_c_out_rtd','pump4_out_rtd','ch2_f_c','q_ch2_c',fluid = 'water',conc = 0,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'ch1_e_in_rtd','ch2_e_out_rtd','ch2_f_e','q_ch2_e',fluid = 'PG',conc = 0.3,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'hw_rtd','hx1_hw_rtd','hx1_f_hw','q_hx1_hw',fluid = 'water',conc = 0,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'hx1_pg_rtd','pump3_out_rtd','hx1_f_pg','q_hx1_pg',fluid = 'PG',conc = 0.3,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'ch1_e_in_rtd','pl_out_rtd','pl_f','q_pl',fluid = 'PG',conc = 0.3,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'sl_out_rtd','pump3_out_rtd','sl_f','q_sl',fluid = 'PG',conc = 0.3,unitsIn = 'IP',unitsOut = 'SI')
    df1 = uQ.uTot(df1,mData,'ts_in_rtd','ts_out_rtd','ts_f','q_ts',fluid = 'PG',conc = 0.3,unitsIn = 'IP',unitsOut = 'SI')
        
    uM = MiscUnc() # Create an instance of the MiscUnc class for calculating uncertainty of power measurements 
    powerMeas = ['ch1_power','ch2_power','pump1_power','pump2_power','pump3_power','pump4_power','pump5_power']
    for pn in powerMeas:
        df1 = uM.uPower(df1,mData,pn)
    
    return df1