<commit_before>"""
Evaluation function of an individual

"""
from __future__ import division

import os

import pandas as pd

from cea.optimization import slave_data
from cea.optimization.constants import *
from cea.optimization.constants import DH_CONVERSION_TECHNOLOGIES_SHARE, DC_CONVERSION_TECHNOLOGIES_SHARE
from cea.optimization.master import summarize_network
from cea.resources.geothermal import calc_ground_temperature
from cea.technologies import substation
from cea.utilities import epwreader


def export_data_to_master_to_slave_class(locator,
                                         gen,
                                         ind_num,
                                         individual_with_name_dict,
                                         building_names,
                                         building_names_heating,
                                         building_names_cooling,
                                         building_names_electricity,
                                         DHN_barcode,
                                         DCN_barcode,
                                         district_heating_network,
                                         district_cooling_network,
                                         technologies_heating_allowed,
                                         technologies_cooling_allowed
                                         ):
    # RECALCULATE THE NOMINAL LOADS FOR HEATING AND COOLING, INCL SOME NAMES OF FILES
    Q_cooling_nom_W, \
    Q_heating_nom_W, \
    Q_wasteheat_datacentre_nom_W = extract_loads_individual(locator,
                                                         DCN_barcode,
                                                         DHN_barcode,
                                                         district_heating_network,
                                                         district_cooling_network,
                                                         building_names_heating,
                                                         building_names_cooling)

    # CREATE MASTER TO SLAVE AND FILL-IN
    master_to_slave_vars = calc_master_to_slave_variables(locator, gen,
                                                          ind_num,
                                                          individual_with_name_dict,
                                                          building_names,
                                                          DHN_barcode,
                                                          DCN_barcode,
                                                          Q_heating_nom_W,
                                                          Q_cooling_nom_W,
                                                          Q_wasteheat_datacentre_nom_W,
                                                          district_heating_network,
                                                          district_cooling_network,
                                                          technologies_heating_allowed,
                                                          technologies_cooling_allowed,
                                                          building_names_heating,
                                                          building_names_cooling,
                                                          building_names_electricity,
                                                          )
    return master_to_slave_vars


def extract_loads_individual(locator,
                             DCN_barcode,
                             DHN_barcode,
                             district_heating_network,
                             district_cooling_network,
                             column_names_buildings_heating,
                             column_names_buildings_cooling):
    # local variables
    weather_file = locator.get_weather_file()
    network_depth_m = Z0
    T_ambient = epwreader.epw_reader(weather_file)['drybulb_C']
    ground_temp = calc_ground_temperature(locator, T_ambient, depth_m=network_depth_m)

    # EVALUATE CASES TO CREATE A NETWORK OR NOT
    if district_heating_network:  # network exists
        if not os.path.exists(locator.get_optimization_network_results_summary('DH', DHN_barcode)):
            total_demand = createTotalNtwCsv(DHN_barcode, locator, column_names_buildings_heating)
            num_total_buildings = len(column_names_buildings_heating)
            buildings_in_heating_network = total_demand.Name.values
            # Run the substation and distribution routines
            substation.substation_main_heating(locator,
                                               total_demand,
                                               buildings_in_heating_network,
                                               DHN_barcode=DHN_barcode)
            results = summarize_network.network_main(locator,
                                                     buildings_in_heating_network,
                                                     ground_temp,
                                                     num_total_buildings,
                                                     "DH", DHN_barcode)
        else:
            results = pd.read_csv(locator.get_optimization_network_results_summary('DH', DHN_barcode))

        Q_DHNf_W = results['Q_DHNf_W'].values
        Q_heating_max_W = Q_DHNf_W.max()
        Qcdata_netw_total_kWh = results['Qcdata_netw_total_kWh'].values
        Q_wasteheat_datacentre_max_W = Qcdata_netw_total_kWh.max()
    else:
        Q_heating_max_W = 0.0
        Q_wasteheat_datacentre_max_W = 0.0

    if district_cooling_network:  # network exists
        if not os.path.exists(locator.get_optimization_network_results_summary('DC', DCN_barcode)):
            total_demand = createTotalNtwCsv(DCN_barcode, locator, column_names_buildings_cooling)
            num_total_buildings = len(column_names_buildings_cooling)
            buildings_in_cooling_network = total_demand.Name.values

            # Run the substation and distribution routines
            substation.substation_main_cooling(locator, total_demand, buildings_in_cooling_network,
                                               DCN_barcode=DCN_barcode)
            results = summarize_network.network_main(locator, buildings_in_cooling_network, ground_temp,
                                                     num_total_buildings,
                                                     'DC', DCN_barcode)
        else:
            results = pd.read_csv(locator.get_optimization_network_results_summary('DC', DCN_barcode))

        # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
        Q_DCNf_W = results["Q_DCNf_space_cooling_data_center_and_refrigeration_W"].values
        Q_cooling_max_W = Q_DCNf_W.max()
    else:
        Q_cooling_max_W = 0.0

    Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK)
    Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK)

    return Q_cooling_nom_W, Q_heating_nom_W, Q_wasteheat_datacentre_max_W,


# +++++++++++++++++++++++++++++++++++
# Boundary conditions
# +++++++++++++++++++++++++++++
def calc_master_to_slave_variables(locator, gen,
                                   ind_num,
                                   individual_with_names_dict,
                                   building_names,
                                   DHN_barcode,
                                   DCN_barcode,
                                   Q_heating_nom_W,
                                   Q_cooling_nom_W,
                                   Q_wasteheat_datacentre_nom_W,
                                   district_heating_network,
                                   district_cooling_network,
                                   technologies_heating_allowed,
                                   technologies_cooling_allowed,
                                   building_names_heating,
                                   building_names_cooling,
                                   building_names_electricity,
                                   ):


    """
    This function reads the list encoding a configuration and implements the corresponding
    for the slave routine's to use
    :param individual_with_names_dict: list with inidividual
    :param Q_heating_max_W:  peak heating demand
    :param locator: locator class
    :type individual_with_names_dict: list
    :type Q_heating_max_W: float
    :type locator: string
    :return: master_to_slave_vars : class MasterSlaveVariables
    :rtype: class
    """

    # calculate local variables
    num_total_buildings = len(building_names)

    # initialise class storing dynamic variables transfered from master to slave optimization
    master_to_slave_vars = slave_data.SlaveData()

    # Store information aobut individual regarding the configuration of the network and curstomers connected
    if district_heating_network and DHN_barcode.count("1") > 0:
        master_to_slave_vars.DHN_exists = True
    if district_cooling_network and DCN_barcode.count("1") > 0:
        master_to_slave_vars.DCN_exists = True

    # store how many buildings are connected to district heating or cooling
    master_to_slave_vars.number_of_buildings_connected_heating = DHN_barcode.count("1")
    master_to_slave_vars.number_of_buildings_connected_cooling = DCN_barcode.count("1")

    # store the names of the buildings connected to district heating or district cooling
    master_to_slave_vars.buildings_connected_to_district_heating = calc_connected_names(building_names_heating,
                                                                                        DHN_barcode)
    master_to_slave_vars.buildings_connected_to_district_cooling = calc_connected_names(building_names_cooling,
                                                                                        DCN_barcode)

    # store the name of the file where the network configuration is stored
    master_to_slave_vars.technologies_heating_allowed = technologies_heating_allowed
    master_to_slave_vars.technologies_cooling_allowed = technologies_cooling_allowed

    # store the barcode which identifies which buildings are connected and disconencted
    master_to_slave_vars.DHN_barcode = DHN_barcode
    master_to_slave_vars.DCN_barcode = DCN_barcode

    # store the total number of buildings in the district (independent of district cooling or heating)
    master_to_slave_vars.num_total_buildings = num_total_buildings

    # store the name of all buildings in the district (independent of district cooling or heating)
    master_to_slave_vars.building_names_all = building_names

    # store the name used to didentified the individual (this helps to know where is inside)
    master_to_slave_vars.building_names_heating = building_names_heating
    master_to_slave_vars.building_names_cooling = building_names_cooling
    master_to_slave_vars.building_names_electricity = building_names_electricity
    master_to_slave_vars.individual_with_names_dict = individual_with_names_dict

    # Store the number of the individual and the generation to which it belongs
    master_to_slave_vars.individual_number = ind_num
    master_to_slave_vars.generation_number = gen

    # Store useful variables to know where to save the results of the individual
    master_to_slave_vars.date = pd.read_csv(locator.get_demand_results_file(building_names[0])).DATE.values

    # Store inforamtion about which units are activated
    master_to_slave_vars = master_to_slave_electrical_technologies(individual_with_names_dict, locator,
                                                                   master_to_slave_vars,
                                                                   district_heating_network,
                                                                   district_cooling_network,
                                                                   )

    if master_to_slave_vars.DHN_exists:
        master_to_slave_vars.Q_heating_nom_W = Q_heating_nom_W
        master_to_slave_vars = master_to_slave_district_heating_technologies(Q_heating_nom_W,
                                                                             Q_wasteheat_datacentre_nom_W,
                                                                             individual_with_names_dict, locator,
                                                                             master_to_slave_vars)

    if master_to_slave_vars.DCN_exists:
        master_to_slave_vars.Q_cooling_nom_W = Q_cooling_nom_W
        master_to_slave_vars = master_to_slave_district_cooling_technologies(Q_cooling_nom_W,
                                                                             individual_with_names_dict,
                                                                             master_to_slave_vars)

    return master_to_slave_vars


def master_to_slave_district_cooling_technologies(Q_cooling_nom_W,
                                                  individual_with_names_dict,
                                                  master_to_slave_vars):
    # COOLING SYSTEMS<commit_msg>Update master_to_slave.py<commit_after>"""
Evaluation function of an individual

"""
from __future__ import division

import os

import pandas as pd

from cea.optimization import slave_data
from cea.optimization.constants import *
from cea.optimization.constants import DH_CONVERSION_TECHNOLOGIES_SHARE, DC_CONVERSION_TECHNOLOGIES_SHARE
from cea.optimization.master import summarize_network
from cea.technologies import substation


def export_data_to_master_to_slave_class(locator,
                                         gen,
                                         ind_num,
                                         individual_with_name_dict,
                                         building_names,
                                         building_names_heating,
                                         building_names_cooling,
                                         building_names_electricity,
                                         DHN_barcode,
                                         DCN_barcode,
                                         district_heating_network,
                                         district_cooling_network,
                                         technologies_heating_allowed,
                                         technologies_cooling_allowed,
                                         weather_features
                                         ):
    # get thermal network for this individual

    # RECALCULATE THE NOMINAL LOADS FOR HEATING AND COOLING, INCL SOME NAMES OF FILES
    DH_network_summary_individual, \
    DC_network_summary_individual = thermal_networks_in_individual(locator,
                                                                   weather_features,
                                                                   DCN_barcode,
                                                                   DHN_barcode,
                                                                   district_heating_network,
                                                                   district_cooling_network,
                                                                   building_names_heating,
                                                                   building_names_cooling)

    # CALCULATE PEAK LOADS
    Q_cooling_nom_W, \
    Q_heating_nom_W, \
    Q_wasteheat_datacentre_nom_W = extract_peak_loads(district_heating_network,
                                                      district_cooling_network,
                                                      DH_network_summary_individual,
                                                      DC_network_summary_individual,
                                                      )

    # CREATE MASTER TO SLAVE AND FILL-IN
    master_to_slave_vars = calc_master_to_slave_variables(locator, gen,
                                                          ind_num,
                                                          individual_with_name_dict,
                                                          building_names,
                                                          DHN_barcode,
                                                          DCN_barcode,
                                                          Q_heating_nom_W,
                                                          Q_cooling_nom_W,
                                                          Q_wasteheat_datacentre_nom_W,
                                                          district_heating_network,
                                                          district_cooling_network,
                                                          technologies_heating_allowed,
                                                          technologies_cooling_allowed,
                                                          building_names_heating,
                                                          building_names_cooling,
                                                          building_names_electricity,
                                                          DH_network_summary_individual,
                                                          DC_network_summary_individual
                                                          )
    return master_to_slave_vars


def extract_peak_loads(district_heating_network,
                       district_cooling_network,
                       DH_network_summary_individual,
                       DC_network_summary_individual,
                       ):
    if district_heating_network:
        Q_DHNf_W = DH_network_summary_individual['Q_DHNf_W'].values
        Q_heating_max_W = Q_DHNf_W.max()
        Qcdata_netw_total_kWh = DH_network_summary_individual['Qcdata_netw_total_kWh'].values
        Q_wasteheat_datacentre_max_W = Qcdata_netw_total_kWh.max()

    else:
        Q_heating_max_W = 0.0
        Q_wasteheat_datacentre_max_W = 0.0

    if district_cooling_network:
        # if heat recovery is ON, then only need to satisfy cooling load of space cooling and refrigeration
        Q_DCNf_W = DC_network_summary_individual["Q_DCNf_space_cooling_data_center_and_refrigeration_W"].values
        Q_cooling_max_W = Q_DCNf_W.max()
    else:
        Q_cooling_max_W = 0.0

    Q_heating_nom_W = Q_heating_max_W * (1 + Q_MARGIN_FOR_NETWORK)
    Q_cooling_nom_W = Q_cooling_max_W * (1 + Q_MARGIN_FOR_NETWORK)

    return Q_cooling_nom_W, Q_heating_nom_W, Q_wasteheat_datacentre_max_W


def thermal_networks_in_individual(locator,
                                   weather_features,
                                   DCN_barcode,
                                   DHN_barcode,
                                   district_heating_network,
                                   district_cooling_network,
                                   column_names_buildings_heating,
                                   column_names_buildings_cooling
                                   ):
    # local variables
    ground_temp = weather_features.ground_temp

    # EVALUATE CASES TO CREATE A NETWORK OR NOT
    if district_heating_network:  # network exists
        if not os.path.exists(locator.get_optimization_network_results_summary('DH', DHN_barcode)):
            total_demand = createTotalNtwCsv(DHN_barcode, locator, column_names_buildings_heating)
            num_total_buildings = len(column_names_buildings_heating)
            buildings_in_heating_network = total_demand.Name.values
            # Run the substation and distribution routines
            substation.substation_main_heating(locator,
                                               total_demand,
                                               buildings_in_heating_network,
                                               DHN_barcode=DHN_barcode)
            DH_network_summary_individual = summarize_network.network_main(locator,
                                                                           buildings_in_heating_network,
                                                                           ground_temp,
                                                                           num_total_buildings,
                                                                           "DH", DHN_barcode)
        else:
            DH_network_summary_individual = pd.read_csv(
                locator.get_optimization_network_results_summary('DH', DHN_barcode))

    if district_cooling_network:  # network exists
        if not os.path.exists(locator.get_optimization_network_results_summary('DC', DCN_barcode)):
            total_demand = createTotalNtwCsv(DCN_barcode, locator, column_names_buildings_cooling)
            num_total_buildings = len(column_names_buildings_cooling)
            buildings_in_cooling_network = total_demand.Name.values

            # Run the substation and distribution routines
            substation.substation_main_cooling(locator, total_demand, buildings_in_cooling_network,
                                               DCN_barcode=DCN_barcode)
            DC_network_summary_individual = summarize_network.network_main(locator, buildings_in_cooling_network,
                                                                           ground_temp,
                                                                           num_total_buildings,
                                                                           'DC', DCN_barcode)
        else:
            DC_network_summary_individual = pd.read_csv(
                locator.get_optimization_network_results_summary('DC', DCN_barcode))

    return DH_network_summary_individual, DC_network_summary_individual


# +++++++++++++++++++++++++++++++++++
# Boundary conditions
# +++++++++++++++++++++++++++++
def calc_master_to_slave_variables(locator, gen,
                                   ind_num,
                                   individual_with_names_dict,
                                   building_names,
                                   DHN_barcode,
                                   DCN_barcode,
                                   Q_heating_nom_W,
                                   Q_cooling_nom_W,
                                   Q_wasteheat_datacentre_nom_W,
                                   district_heating_network,
                                   district_cooling_network,
                                   technologies_heating_allowed,
                                   technologies_cooling_allowed,
                                   building_names_heating,
                                   building_names_cooling,
                                   building_names_electricity,
                                   DH_network_summary_individual,
                                   DC_network_summary_individual
                                   ):
    """
    This function reads the list encoding a configuration and implements the corresponding
    for the slave routine's to use
    :param individual_with_names_dict: list with inidividual
    :param Q_heating_max_W:  peak heating demand
    :param locator: locator class
    :type individual_with_names_dict: list
    :type Q_heating_max_W: float
    :type locator: string
    :return: master_to_slave_vars : class MasterSlaveVariables
    :rtype: class
    """

    # calculate local variables
    num_total_buildings = len(building_names)

    # initialise class storing dynamic variables transfered from master to slave optimization
    master_to_slave_vars = slave_data.SlaveData()

    # Store information aobut individual regarding the configuration of the network and curstomers connected
    if district_heating_network and DHN_barcode.count("1") > 0:
        master_to_slave_vars.DHN_exists = True
    if district_cooling_network and DCN_barcode.count("1") > 0:
        master_to_slave_vars.DCN_exists = True

    # store how many buildings are connected to district heating or cooling
    master_to_slave_vars.number_of_buildings_connected_heating = DHN_barcode.count("1")
    master_to_slave_vars.number_of_buildings_connected_cooling = DCN_barcode.count("1")

    # store the names of the buildings connected to district heating or district cooling
    master_to_slave_vars.buildings_connected_to_district_heating = calc_connected_names(building_names_heating,
                                                                                        DHN_barcode)
    master_to_slave_vars.buildings_connected_to_district_cooling = calc_connected_names(building_names_cooling,
                                                                                        DCN_barcode)

    #these are dataframes describing the opeartion of the thermal networks in the individual
    master_to_slave_vars.DH_network_summary_individual = DH_network_summary_individual
    master_to_slave_vars.DC_network_summary_individual = DC_network_summary_individual

    # store the name of the file where the network configuration is stored
    master_to_slave_vars.technologies_heating_allowed = technologies_heating_allowed
    master_to_slave_vars.technologies_cooling_allowed = technologies_cooling_allowed

    # store the barcode which identifies which buildings are connected and disconencted
    master_to_slave_vars.DHN_barcode = DHN_barcode
    master_to_slave_vars.DCN_barcode = DCN_barcode

    # store the total number of buildings in the district (independent of district cooling or heating)
    master_to_slave_vars.num_total_buildings = num_total_buildings

    # store the name of all buildings in the district (independent of district cooling or heating)
    master_to_slave_vars.building_names_all = building_names

    # store the name used to didentified the individual (this helps to know where is inside)
    master_to_slave_vars.building_names_heating = building_names_heating
    master_to_slave_vars.building_names_cooling = building_names_cooling
    master_to_slave_vars.building_names_electricity = building_names_electricity
    master_to_slave_vars.individual_with_names_dict = individual_with_names_dict

    # Store the number of the individual and the generation to which it belongs
    master_to_slave_vars.individual_number = ind_num
    master_to_slave_vars.generation_number = gen

    # Store inforamtion about which units are activated
    master_to_slave_vars = master_to_slave_electrical_technologies(individual_with_names_dict, locator,
                                                                   master_to_slave_vars,
                                                                   district_heating_network,
                                                                   district_cooling_network,
                                                                   )

    if master_to_slave_vars.DHN_exists:
        master_to_slave_vars.Q_heating_nom_W = Q_heating_nom_W
        master_to_slave_vars = master_to_slave_district_heating_technologies(Q_heating_nom_W,
                                                                             Q_wasteheat_datacentre_nom_W,
                                                                             individual_with_names_dict, locator,
                                                                             master_to_slave_vars)

    if master_to_slave_vars.DCN_exists:
        master_to_slave_vars.Q_cooling_nom_W = Q_cooling_nom_W
        master_to_slave_vars = master_to_slave_district_cooling_technologies(Q_cooling_nom_W,
                                                                             individual_with_names_dict,
                                                                             master_to_slave_vars)

    return master_to_slave_vars


def master_to_slave_district_cooling_technologies(Q_cooling_nom_W,
                                                  individual_with_names_dict,
                                                  master_to_slave_vars):
    # COOLING SYSTEMS
{'fraction_non_alphanumeric': 0.03656151082974713, 'fraction_numerical': 0.0010669701604011808, 'mean_word_length': 1.371426161760985, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 319, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4321025', 'n_tokens_mistral': 6689, 'n_tokens_neox': 6146, 'n_words': 1150}