def decentralized_main(locator, building_names, gv):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files.
    There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to
    each technology. it is a classical combinatorial problem.

    :param locator: locator class
    :param building_names: list with names of buildings
    :param gv: global variables class
    :type locator: class
    :type building_names: list
    :type gv: class
    :return: results of operation of buildings located in locator.get_optimization_disconnected_folder
    :rtype: Nonetype

    """
    t0 = time.clock()
    geothermal_potential = pd.read_csv(locator.get_geothermal_potential(), index_col="Name")
    BestData = {}

    def calc_new_load(mdot, TsupDH, Tret, gv):
        """
        This function calculates the load distribution side of the district heating distribution.

        :param mdot: mass flow
        :param TsupDH: supply temeperature
        :param Tret: return temperature
        :param gv: global variables class
        :type mdot: float
        :type TsupDH: float
        :type Tret: float
        :type gv: class
        :return: Qload: load of the distribution
        :rtype: float
        """
        Qload = mdot * gv.cp * (TsupDH - Tret) * (1 + gv.Qloss_Disc)
        if Qload < 0:
            Qload = 0
        if Qload < -1E-5:
            print "Error in discBuildMain, negative heat requirement at hour", hour, building_name
        return Qload

    for building_name in building_names:
        print building_name
        loads = pd.read_csv(locator.get_optimization_substations_results_file(building_name),
                            usecols=["T_supply_DH_result", "T_return_DH_result", "mdot_DH_result"])
        Qload = np.vectorize(calc_new_load)(loads["mdot_DH_result"], loads["T_supply_DH_result"],
                                            loads["T_return_DH_result"], gv)
        Qannual = Qload.sum()
        Qnom = Qload.max()* (1+gv.Qmargin_Disc) # 1% reliability margin on installed capacity

        # Create empty matrices
        result = np.zeros((13,7))
        result[0][0] = 1
        result[1][1] = 1
        result[2][2] = 1
        InvCosts = np.zeros((13,1))
        resourcesRes = np.zeros((13,4))
        QannualB_GHP = np.zeros((10,1)) # For the investment costs of the boiler used with GHP
        Wel_GHP = np.zeros((10,1)) # For the investment costs of the GHP
        
        # Supply with the Boiler / FC / GHP
        Tret = loads["T_return_DH_result"].values
        TsupDH = loads["T_supply_DH_result"].values
        mdot = loads["mdot_DH_result"].values
        for hour in range(8760):

            if Tret[hour] == 0:
                Tret[hour] = TsupDH[hour]
                
            # Boiler NG
            BoilerEff = Boiler.calc_Cop_boiler(Qload[hour], Qnom, Tret[hour])
            
            Qgas = Qload[hour] / BoilerEff
            
            result[0][4] += gv.NG_PRICE * Qgas # CHF
            result[0][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2
            result[0][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq
            resourcesRes[0][0] += Qload[hour]
            
            if gv.DiscBioGasFlag == 1:
                result[0][4] += gv.BG_PRICE * Qgas # CHF
                result[0][5] += gv.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2
                result[0][6] += gv.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq
                
            # Boiler BG
            result[1][4] += gv.BG_PRICE * Qgas # CHF
            result[1][5] += gv.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2
            result[1][6] += gv.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq
            resourcesRes[1][1] += Qload[hour]
                
            # FC
            (FC_Effel, FC_Effth) = FC.calc_eta_FC(Qload[hour], Qnom, 1, "B")
            Qgas = Qload[hour] / (FC_Effth+FC_Effel)
            Qelec = Qgas * FC_Effel            
            
            result[2][4] += gv.NG_PRICE * Qgas - gv.ELEC_PRICE * Qelec # CHF, extra electricity sold to grid
            result[2][5] += 0.0874 * Qgas * 3600E-6 + 773 * 0.45 * Qelec * 1E-6 - gv.EL_TO_CO2 * Qelec * 3600E-6 # kgCO2
            # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
            # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
            result[2][6] += 1.51 * Qgas * 3600E-6 - gv.EL_TO_OIL_EQ * Qelec * 3600E-6 # MJ-oil-eq
            
            resourcesRes[2][0] += Qload[hour]
            resourcesRes[2][2] += Qelec
            
            # GHP
            for i in range(10):
                
                QnomBoiler = i/10 * Qnom
                QnomGHP = Qnom - QnomBoiler
                
                if Qload[hour] <= QnomGHP:
                
                    (wdot_el, qcolddot, qhotdot_missing, tsup2) = HP.calc_Cop_GHP(mdot[hour], TsupDH[hour], Tret[hour],
                                                                                  gv.TGround, gv)
                    
                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el
                    
                    result[3+i][4] += gv.ELEC_PRICE * wdot_el   # CHF
                    result[3+i][5] += gv.SMALL_GHP_TO_CO2_STD  * wdot_el   * 3600E-6 # kgCO2
                    result[3+i][6] += gv.SMALL_GHP_TO_OIL_STD  * wdot_el   * 3600E-6 # MJ-oil-eq
                    
                    resourcesRes[3+i][2] -= wdot_el
                    resourcesRes[3+i][3] += Qload[hour] - qhotdot_missing
                    
                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff
                        
                        result[3+i][4] += gv.NG_PRICE * Qgas   # CHF
                        result[3+i][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas   * 3600E-6 # kgCO2
                        result[3+i][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas   * 3600E-6 # MJ-oil-eq
                        
                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3+i][0] += qhotdot_missing
    
                else:
                    #print "Boiler activated to compensate GHP", i
                    #if gv.DiscGHPFlag == 0:
                    #    print QnomGHP
                    #   QnomGHP = 0 
                    #   print "GHP not allowed 2, set QnomGHP to zero"
                        
                    TexitGHP = QnomGHP / (mdot[hour] * gv.cp) + Tret[hour]
                    (wdot_el, qcolddot, qhotdot_missing, tsup2) = HP.calc_Cop_GHP(mdot[hour], TexitGHP, Tret[hour], gv.TGround, gv)
                    
                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el
                        
                    result[3+i][4] += gv.ELEC_PRICE * wdot_el   # CHF
                    result[3+i][5] += gv.SMALL_GHP_TO_CO2_STD  * wdot_el   * 3600E-6 # kgCO2
                    result[3+i][6] += gv.SMALL_GHP_TO_OIL_STD  * wdot_el   * 3600E-6 # MJ-oil-eq
                    
                    resourcesRes[3+i][2] -= wdot_el
                    resourcesRes[3+i][3] += QnomGHP - qhotdot_missing
                    
                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff
                        
                        result[3+i][4] += gv.NG_PRICE * Qgas   # CHF
                        result[3+i][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas   * 3600E-6 # kgCO2
                        result[3+i][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas   * 3600E-6 # MJ-oil-eq
                        
                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3+i][0] += qhotdot_missing
                        
                    QtoBoiler = Qload[hour] - QnomGHP
                    QannualB_GHP[i][0] += QtoBoiler
                    
                    BoilerEff = Boiler.calc_Cop_boiler(QtoBoiler, QnomBoiler, TexitGHP)
                    Qgas = QtoBoiler / BoilerEff
                    
                    result[3+i][4] += gv.NG_PRICE * Qgas   # CHF
                    result[3+i][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas   * 3600E-6 # kgCO2
                    result[3+i][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas   * 3600E-6 # MJ-oil-eq
                    resourcesRes[3+i][0] += QtoBoiler

        # Investment Costs / CO2 / Prim
        InvCaBoiler = Boiler.calc_Cinv_boiler(Qnom, Qannual, gv)
        InvCosts[0][0] = InvCaBoiler
        InvCosts[1][0] = InvCaBoiler
        
        InvCosts[2][0] = FC.calc_Cinv_FC(Qnom, gv)
        
        for i in range(10):
            result[3+i][0] = i/10
            result[3+i][3] = 1-i/10

            QnomBoiler = i/10 * Qnom
            
            InvCaBoiler = Boiler.calc_Cinv_boiler(QnomBoiler, QannualB_GHP[i][0], gv)
            InvCosts[3+i][0] = InvCaBoiler
            
            InvCaGHP = HP.GHP_InvCost( Wel_GHP[i][0] , gv)
            InvCosts[3+i][0] += InvCaGHP * gv.EURO_TO_CHF
        

        # Best configuration
        Best = np.zeros((13,1))
        indexBest = 0

        TotalCosts = np.zeros((13,2))
        TotalCO2 = np.zeros((13,2))
        TotalPrim = np.zeros((13,2))
        
        for i in range(13):
            TotalCosts[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i

            TotalCosts[i][1] = InvCosts[i][0] + result[i][4]
            TotalCO2[i][1] = result[i][5]
            TotalPrim[i][1] = result[i][6]
        
        CostsS = TotalCosts[np.argsort(TotalCosts[:,1])]
        CO2S = TotalCO2[np.argsort(TotalCO2[:,1])]
        PrimS = TotalPrim[np.argsort(TotalPrim[:,1])]
        
        el = len(CostsS)
        rank = 0
        Bestfound = False
        
        optsearch = np.empty(el)
        optsearch.fill(3)
        indexBest = 0
        
        # Check the GHP area constraint
        for i in range(10):
            QGHP = (1-i/10) * Qnom
            areaAvail = geothermal_potential.ix[building_name,"Area_geo"]
            Qallowed = np.ceil(areaAvail/gv.GHP_A) * gv.GHP_HmaxSize #[W_th]
            
            if Qallowed < QGHP:
                optsearch[i+3] += 1
                Best[i+3][0] = - 1
        
        while not Bestfound and rank<el:
            
            optsearch[CostsS[rank][0]] -= 1
            optsearch[CO2S[rank][0]] -= 1
            optsearch[PrimS[rank][0]] -= 1
            
            if np.count_nonzero(optsearch) != el:
                Bestfound = True
                indexBest = np.where(optsearch == 0)[0][0]
                
            rank += 1

        # get the best option according to the ranking.
        Best[indexBest][0] = 1
        Qnom_array = np.ones(len(Best[:,0])) * Qnom

        # Save results in csv file
        dico = {}
        dico[ "BoilerNG Share" ] = result[:,0]
        dico[ "BoilerBG Share" ] = result[:,1]
        dico[ "FC Share" ] = result[:,2]
        dico[ "GHP Share" ] = result[:,3]
        dico[ "Operation Costs [CHF]" ] = result[:,4]
        dico[ "CO2 Emissions [kgCO2-eq]" ] = result[:,5]
        dico[ "Primary Energy Needs [MJoil-eq]" ] = result[:,6]
        dico[ "Annualized Investment Costs [CHF]" ] = InvCosts[:,0]
        dico[ "Total Costs [CHF]" ] = TotalCosts[:,1]
        dico[ "Best configuration" ] = Best[:,0]
        dico[ "Nominal Power" ] = Qnom_array
        dico[ "QfromNG" ] = resourcesRes[:,0]
        dico[ "QfromBG" ] = resourcesRes[:,1]
        dico[ "EforGHP" ] = resourcesRes[:,2]
        dico[ "QfromGHP" ] = resourcesRes[:,3]


        results_to_csv = pd.DataFrame(dico)
        fName_result = locator.get_optimization_disconnected_folder_building_result(building_name)
        results_to_csv.to_csv(fName_result, sep= ',')
        
    
        BestComb = {}
        BestComb[ "BoilerNG Share" ] = result[indexBest,0]
        BestComb[ "BoilerBG Share" ] = result[indexBest,1]
        BestComb[ "FC Share" ] = result[indexBest,2]
        BestComb[ "GHP Share" ] = result[indexBest,3]
        BestComb[ "Operation Costs [CHF]" ] = result[indexBest,4]
        BestComb[ "CO2 Emissions [kgCO2-eq]" ] = result[indexBest,5]
        BestComb[ "Primary Energy Needs [MJoil-eq]" ] = result[indexBest,6]
        BestComb[ "Annualized Investment Costs [CHF]" ] = InvCosts[indexBest,0]
        BestComb[ "Total Costs [CHF]" ] = TotalCosts[indexBest,1]
        BestComb[ "Best configuration" ] = Best[indexBest,0]
        BestComb[ "Nominal Power" ] = Qnom
        
        BestData[building_name] = BestComb

    if 0:
        fName = locator.get_optimization_disconnected_folder_disc_op_summary()
        results_to_csv = pd.DataFrame(BestData)
        results_to_csv.to_csv(fName, sep= ',')

    print time.clock() - t0, "seconds process time for the Disconnected Building Routine \n"
def disconnected_buildings_heating_main(locator, building_names, config,
                                        prices, lca):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files.
    There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to
    each technology. it is a classical combinatorial problem.
    :param locator: locator class
    :param building_names: list with names of buildings
    :type locator: class
    :type building_names: list
    :return: results of operation of buildings located in locator.get_optimization_disconnected_folder
    :rtype: Nonetype
    """
    t0 = time.clock()
    prop_geometry = Gdf.from_file(locator.get_zone_geometry())
    restrictions = Gdf.from_file(locator.get_building_restrictions())

    geometry = pd.DataFrame({
        'Name': prop_geometry.Name,
        'Area': prop_geometry.area
    })
    geothermal_potential_data = dbf.dbf_to_dataframe(
        locator.get_building_supply())
    geothermal_potential_data = pd.merge(geothermal_potential_data,
                                         geometry,
                                         on='Name').merge(restrictions,
                                                          on='Name')
    geothermal_potential_data['Area_geo'] = (
        1 - geothermal_potential_data['GEOTHERMAL']
    ) * geothermal_potential_data['Area']
    weather_data = epwreader.epw_reader(config.weather)[[
        'year', 'drybulb_C', 'wetbulb_C', 'relhum_percent', 'windspd_ms',
        'skytemp_C'
    ]]
    ground_temp = calc_ground_temperature(locator,
                                          weather_data['drybulb_C'],
                                          depth_m=10)

    BestData = {}
    total_demand = pd.read_csv(locator.get_total_demand())

    def calc_new_load(mdot, TsupDH, Tret):
        """
        This function calculates the load distribution side of the district heating distribution.
        :param mdot: mass flow
        :param TsupDH: supply temeperature
        :param Tret: return temperature
        :param gv: global variables class
        :type mdot: float
        :type TsupDH: float
        :type Tret: float
        :type gv: class
        :return: Qload: load of the distribution
        :rtype: float
        """
        Qload = mdot * HEAT_CAPACITY_OF_WATER_JPERKGK * (TsupDH - Tret) * (
            1 + Q_LOSS_DISCONNECTED)
        if Qload < 0:
            Qload = 0

        return Qload

    for building_name in building_names:
        print building_name
        substation.substation_main(locator,
                                   total_demand,
                                   building_names=[building_name],
                                   heating_configuration=7,
                                   cooling_configuration=7,
                                   Flag=False)
        loads = pd.read_csv(
            locator.get_optimization_substations_results_file(building_name),
            usecols=[
                "T_supply_DH_result_K", "T_return_DH_result_K",
                "mdot_DH_result_kgpers"
            ])
        Qload = np.vectorize(calc_new_load)(loads["mdot_DH_result_kgpers"],
                                            loads["T_supply_DH_result_K"],
                                            loads["T_return_DH_result_K"])
        Qannual = Qload.sum()
        Qnom = Qload.max() * (1 + SIZING_MARGIN
                              )  # 1% reliability margin on installed capacity

        # Create empty matrices
        result = np.zeros((13, 7))
        result[0][0] = 1
        result[1][1] = 1
        result[2][2] = 1
        InvCosts = np.zeros((13, 1))
        resourcesRes = np.zeros((13, 4))
        QannualB_GHP = np.zeros(
            (10, 1))  # For the investment costs of the boiler used with GHP
        Wel_GHP = np.zeros((10, 1))  # For the investment costs of the GHP

        # Supply with the Boiler / FC / GHP
        Tret = loads["T_return_DH_result_K"].values
        TsupDH = loads["T_supply_DH_result_K"].values
        mdot = loads["mdot_DH_result_kgpers"].values

        for hour in range(8760):

            if Tret[hour] == 0:
                Tret[hour] = TsupDH[hour]

            # Boiler NG
            BoilerEff = Boiler.calc_Cop_boiler(Qload[hour], Qnom, Tret[hour])

            Qgas = Qload[hour] / BoilerEff

            result[0][4] += prices.NG_PRICE * Qgas  # CHF
            result[0][
                5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
            result[0][
                6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq
            resourcesRes[0][0] += Qload[hour]

            if DISC_BIOGAS_FLAG == 1:
                result[0][4] += prices.BG_PRICE * Qgas  # CHF
                result[0][
                    5] += lca.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                result[0][
                    6] += lca.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq

            # Boiler BG
            result[1][4] += prices.BG_PRICE * Qgas  # CHF
            result[1][
                5] += lca.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
            result[1][
                6] += lca.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq
            resourcesRes[1][1] += Qload[hour]

            # FC
            (FC_Effel, FC_Effth) = FC.calc_eta_FC(Qload[hour], Qnom, 1, "B")
            Qgas = Qload[hour] / (FC_Effth + FC_Effel)
            Qelec = Qgas * FC_Effel

            result[2][
                4] += prices.NG_PRICE * Qgas - lca.ELEC_PRICE * Qelec  # CHF, extra electricity sold to grid
            result[2][
                5] += 0.0874 * Qgas * 3600E-6 + 773 * 0.45 * Qelec * 1E-6 - lca.EL_TO_CO2 * Qelec * 3600E-6  # kgCO2
            # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
            # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
            result[2][
                6] += 1.51 * Qgas * 3600E-6 - lca.EL_TO_OIL_EQ * Qelec * 3600E-6  # MJ-oil-eq

            resourcesRes[2][0] += Qload[hour]
            resourcesRes[2][2] += Qelec

            # GHP
            for i in range(10):

                QnomBoiler = i / 10 * Qnom
                QnomGHP = Qnom - QnomBoiler

                if Qload[hour] <= QnomGHP:
                    (wdot_el, qcolddot, qhotdot_missing,
                     tsup2) = HP.calc_Cop_GHP(ground_temp[hour], mdot[hour],
                                              TsupDH[hour], Tret[hour])

                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el

                    result[3 + i][4] += lca.ELEC_PRICE * wdot_el  # CHF
                    result[3 + i][
                        5] += lca.SMALL_GHP_TO_CO2_STD * wdot_el * 3600E-6  # kgCO2
                    result[3 + i][
                        6] += lca.SMALL_GHP_TO_OIL_STD * wdot_el * 3600E-6  # MJ-oil-eq

                    resourcesRes[3 + i][2] -= wdot_el
                    resourcesRes[3 + i][3] += Qload[hour] - qhotdot_missing

                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(
                            qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff

                        result[3 + i][4] += prices.NG_PRICE * Qgas  # CHF
                        result[3 + i][
                            5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                        result[3 + i][
                            6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq

                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3 + i][0] += qhotdot_missing

                else:
                    # print "Boiler activated to compensate GHP", i
                    # if gv.DiscGHPFlag == 0:
                    #    print QnomGHP
                    #   QnomGHP = 0
                    #   print "GHP not allowed 2, set QnomGHP to zero"

                    TexitGHP = QnomGHP / (
                        mdot[hour] *
                        HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret[hour]
                    (wdot_el, qcolddot, qhotdot_missing,
                     tsup2) = HP.calc_Cop_GHP(ground_temp[hour], mdot[hour],
                                              TexitGHP, Tret[hour])

                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el

                    result[3 + i][4] += lca.ELEC_PRICE * wdot_el  # CHF
                    result[3 + i][
                        5] += lca.SMALL_GHP_TO_CO2_STD * wdot_el * 3600E-6  # kgCO2
                    result[3 + i][
                        6] += lca.SMALL_GHP_TO_OIL_STD * wdot_el * 3600E-6  # MJ-oil-eq

                    resourcesRes[3 + i][2] -= wdot_el
                    resourcesRes[3 + i][3] += QnomGHP - qhotdot_missing

                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(
                            qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff

                        result[3 + i][4] += prices.NG_PRICE * Qgas  # CHF
                        result[3 + i][
                            5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                        result[3 + i][
                            6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq

                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3 + i][0] += qhotdot_missing

                    QtoBoiler = Qload[hour] - QnomGHP
                    QannualB_GHP[i][0] += QtoBoiler

                    BoilerEff = Boiler.calc_Cop_boiler(QtoBoiler, QnomBoiler,
                                                       TexitGHP)
                    Qgas = QtoBoiler / BoilerEff

                    result[3 + i][4] += prices.NG_PRICE * Qgas  # CHF
                    result[3 + i][
                        5] += lca.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6  # kgCO2
                    result[3 + i][
                        6] += lca.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6  # MJ-oil-eq
                    resourcesRes[3 + i][0] += QtoBoiler

        # Investment Costs / CO2 / Prim
        Capex_a_Boiler, Opex_Boiler = Boiler.calc_Cinv_boiler(
            Qnom, locator, config, 'BO1')
        InvCosts[0][0] = Capex_a_Boiler + Opex_Boiler
        InvCosts[1][0] = Capex_a_Boiler + Opex_Boiler

        Capex_a_FC, Opex_FC = FC.calc_Cinv_FC(Qnom, locator, config)
        InvCosts[2][0] = Capex_a_FC + Opex_FC

        for i in range(10):
            result[3 + i][0] = i / 10
            result[3 + i][3] = 1 - i / 10

            QnomBoiler = i / 10 * Qnom

            Capex_a_Boiler, Opex_Boiler = Boiler.calc_Cinv_boiler(
                QnomBoiler, locator, config, 'BO1')

            InvCosts[3 + i][0] = Capex_a_Boiler + Opex_Boiler

            Capex_a_GHP, Opex_GHP = HP.calc_Cinv_GHP(Wel_GHP[i][0], locator,
                                                     config)
            InvCaGHP = Capex_a_GHP + Opex_GHP
            InvCosts[3 + i][0] += InvCaGHP * prices.EURO_TO_CHF

        # Best configuration
        Best = np.zeros((13, 1))
        indexBest = 0

        TotalCosts = np.zeros((13, 2))
        TotalCO2 = np.zeros((13, 2))
        TotalPrim = np.zeros((13, 2))

        for i in range(13):
            TotalCosts[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i

            TotalCosts[i][1] = InvCosts[i][0] + result[i][4]
            TotalCO2[i][1] = result[i][5]
            TotalPrim[i][1] = result[i][6]

        CostsS = TotalCosts[np.argsort(TotalCosts[:, 1])]
        CO2S = TotalCO2[np.argsort(TotalCO2[:, 1])]
        PrimS = TotalPrim[np.argsort(TotalPrim[:, 1])]

        el = len(CostsS)
        rank = 0
        Bestfound = False

        optsearch = np.empty(el)
        optsearch.fill(3)
        indexBest = 0
        geothermal_potential = geothermal_potential_data.set_index('Name')

        # Check the GHP area constraint
        for i in range(10):
            QGHP = (1 - i / 10) * Qnom
            areaAvail = geothermal_potential.ix[building_name, 'Area_geo']
            Qallowed = np.ceil(areaAvail / GHP_A) * GHP_HMAX_SIZE  # [W_th]
            if Qallowed < QGHP:
                optsearch[i + 3] += 1
                Best[i + 3][0] = -1

        while not Bestfound and rank < el:

            optsearch[int(CostsS[rank][0])] -= 1
            optsearch[int(CO2S[rank][0])] -= 1
            optsearch[int(PrimS[rank][0])] -= 1

            if np.count_nonzero(optsearch) != el:
                Bestfound = True
                indexBest = np.where(optsearch == 0)[0][0]

            rank += 1

        # get the best option according to the ranking.
        Best[indexBest][0] = 1
        Qnom_array = np.ones(len(Best[:, 0])) * Qnom

        # Save results in csv file
        dico = {}
        dico["BoilerNG Share"] = result[:, 0]
        dico["BoilerBG Share"] = result[:, 1]
        dico["FC Share"] = result[:, 2]
        dico["GHP Share"] = result[:, 3]
        dico["Operation Costs [CHF]"] = result[:, 4]
        dico["CO2 Emissions [kgCO2-eq]"] = result[:, 5]
        dico["Primary Energy Needs [MJoil-eq]"] = result[:, 6]
        dico["Annualized Investment Costs [CHF]"] = InvCosts[:, 0]
        dico["Total Costs [CHF]"] = TotalCosts[:, 1]
        dico["Best configuration"] = Best[:, 0]
        dico["Nominal Power"] = Qnom_array
        dico["QfromNG"] = resourcesRes[:, 0]
        dico["QfromBG"] = resourcesRes[:, 1]
        dico["EforGHP"] = resourcesRes[:, 2]
        dico["QfromGHP"] = resourcesRes[:, 3]

        results_to_csv = pd.DataFrame(dico)

        fName_result = locator.get_optimization_disconnected_folder_building_result_heating(
            building_name)
        results_to_csv.to_csv(fName_result, sep=',')

        BestComb = {}
        BestComb["BoilerNG Share"] = result[indexBest, 0]
        BestComb["BoilerBG Share"] = result[indexBest, 1]
        BestComb["FC Share"] = result[indexBest, 2]
        BestComb["GHP Share"] = result[indexBest, 3]
        BestComb["Operation Costs [CHF]"] = result[indexBest, 4]
        BestComb["CO2 Emissions [kgCO2-eq]"] = result[indexBest, 5]
        BestComb["Primary Energy Needs [MJoil-eq]"] = result[indexBest, 6]
        BestComb["Annualized Investment Costs [CHF]"] = InvCosts[indexBest, 0]
        BestComb["Total Costs [CHF]"] = TotalCosts[indexBest, 1]
        BestComb["Best configuration"] = Best[indexBest, 0]
        BestComb["Nominal Power"] = Qnom

        BestData[building_name] = BestComb

    if 0:
        fName = locator.get_optimization_disconnected_folder_disc_op_summary_heating(
        )
        results_to_csv = pd.DataFrame(BestData)
        results_to_csv.to_csv(fName, sep=',')

    print time.clock(
    ) - t0, "seconds process time for the Disconnected Building Routine \n"
def disconnected_buildings_heating_main(locator, total_demand, building_names, config, prices, lca):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files.
    There is no optimization at this point. The different technologies are calculated and compared 1 to 1 to
    each technology. it is a classical combinatorial problem.
    :param locator: locator class
    :param building_names: list with names of buildings
    :type locator: class
    :type building_names: list
    :return: results of operation of buildings located in locator.get_optimization_decentralized_folder
    :rtype: Nonetype
    """
    t0 = time.clock()
    prop_geometry = Gdf.from_file(locator.get_zone_geometry())
    geometry = pd.DataFrame({'Name': prop_geometry.Name, 'Area': prop_geometry.area})
    geothermal_potential_data = dbf.dbf_to_dataframe(locator.get_building_supply())
    geothermal_potential_data = pd.merge(geothermal_potential_data, geometry, on='Name')
    geothermal_potential_data['Area_geo'] = geothermal_potential_data['Area']
    weather_path = locator.get_weather_file()
    weather_data = epwreader.epw_reader(weather_path)[['year', 'drybulb_C', 'wetbulb_C',
                                                         'relhum_percent', 'windspd_ms', 'skytemp_C']]

    T_ground_K = calc_ground_temperature(locator, weather_data['drybulb_C'], depth_m=10)


    # This will calculate the substation state if all buildings where connected(this is how we study this)
    substation.substation_main_heating(locator, total_demand, building_names)

    for building_name in building_names:
        print('running for building %s') %(building_name)
        # run substation model to derive temperatures of the building
        substation_results = pd.read_csv(locator.get_optimization_substations_results_file(building_name, "DH", ""))
        q_load_Wh = np.vectorize(calc_new_load)(substation_results["mdot_DH_result_kgpers"],
                                                substation_results["T_supply_DH_result_K"],
                                                substation_results["T_return_DH_result_K"])
        Qnom_W = q_load_Wh.max()

        # Create empty matrices
        Opex_a_var_USD = np.zeros((13, 7))
        Capex_total_USD = np.zeros((13, 7))
        Capex_a_USD = np.zeros((13, 7))
        Opex_a_fixed_USD = np.zeros((13, 7))
        Capex_opex_a_fixed_only_USD = np.zeros((13, 7))
        Opex_a_USD = np.zeros((13, 7))
        GHG_tonCO2 = np.zeros((13, 7))
        PEN_MJoil = np.zeros((13, 7))
        # indicate supply technologies for each configuration
        Opex_a_var_USD[0][0] = 1  # Boiler NG
        Opex_a_var_USD[1][1] = 1  # Boiler BG
        Opex_a_var_USD[2][2] = 1  # Fuel Cell

        resourcesRes = np.zeros((13, 4))
        Q_Boiler_for_GHP_W = np.zeros((10, 1))  # Save peak capacity of GHP Backup Boilers
        GHP_el_size_W = np.zeros((10, 1))  # Save peak capacity of GHP

        # save supply system activation of all supply configurations
        heating_dispatch = {}

        # Supply with the Boiler / FC / GHP
        Tret_K = substation_results["T_return_DH_result_K"].values
        Tsup_K = substation_results["T_supply_DH_result_K"].values
        mdot_kgpers = substation_results["mdot_DH_result_kgpers"].values

        ## Start Hourly calculation
        print building_name, ' decentralized heating supply systems simulations...'
        Tret_K = np.where(Tret_K > 0.0, Tret_K, Tsup_K)

        ## 0: Boiler NG
        BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_Wh, Qnom_W, Tret_K)
        Qgas_to_Boiler_Wh = np.divide(q_load_Wh, BoilerEff, out=np.zeros_like(q_load_Wh), where=BoilerEff != 0.0)
        Boiler_Status = np.where(Qgas_to_Boiler_Wh > 0.0, 1, 0)
        # add costs
        Opex_a_var_USD[0][4] += sum(prices.NG_PRICE * Qgas_to_Boiler_Wh)  # CHF
        GHG_tonCO2[0][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_CO2_EQ)  # ton CO2
        PEN_MJoil[0][6] += calc_pen_Whyr_to_MJoilyr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_OIL_EQ)  # MJ-oil-eq
        # add activation
        resourcesRes[0][0] += sum(q_load_Wh)  # q from NG
        heating_dispatch[0] = {'Q_Boiler_gen_directload_W': q_load_Wh,
                                         'Boiler_Status': Boiler_Status,
                                         'NG_Boiler_req_W': Qgas_to_Boiler_Wh,
                                         'E_hs_ww_req_W': np.zeros(8760)}
        ## 1: Boiler BG
        # add costs
        Opex_a_var_USD[1][4] += sum(prices.BG_PRICE * Qgas_to_Boiler_Wh)  # CHF
        GHG_tonCO2[1][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_CO2_EQ)  # ton CO2
        PEN_MJoil[1][6] += calc_pen_Whyr_to_MJoilyr(sum(Qgas_to_Boiler_Wh), lca.NG_TO_OIL_EQ)  # MJ-oil-eq
        # add activation
        resourcesRes[1][1] += sum(q_load_Wh)  # q from BG
        heating_dispatch[1] = {'Q_Boiler_gen_directload_W': q_load_Wh,
                               'Boiler_Status': Boiler_Status,
                               'BG_Boiler_req_W': Qgas_to_Boiler_Wh,
                               'E_hs_ww_req_W': np.zeros(8760)}

        ## 2: Fuel Cell
        (FC_Effel, FC_Effth) = np.vectorize(FC.calc_eta_FC)(q_load_Wh, Qnom_W, 1, "B")
        Qgas_to_FC_Wh = q_load_Wh / (FC_Effth + FC_Effel)  # FIXME: should be q_load_Wh/FC_Effth?
        el_from_FC_Wh = Qgas_to_FC_Wh * FC_Effel
        FC_Status = np.where(Qgas_to_FC_Wh > 0.0, 1, 0)
        # add variable costs, emissions and primary energy
        Opex_a_var_USD[2][4] += sum(prices.NG_PRICE * Qgas_to_FC_Wh - prices.ELEC_PRICE_EXPORT * el_from_FC_Wh)  # CHF, extra electricity sold to grid
        GHG_tonCO2_from_FC = (0.0874 * Qgas_to_FC_Wh * 3600E-6 + 773 * 0.45 * el_from_FC_Wh * 1E-6 -
                              lca.EL_TO_CO2_EQ * el_from_FC_Wh * 3600E-6) / 1E3
        GHG_tonCO2[2][5] += sum(GHG_tonCO2_from_FC)  # tonCO2
        # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
        # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
        PEN_MJoil_from_FC = 1.51 * Qgas_to_FC_Wh * 3600E-6 - lca.EL_TO_OIL_EQ * el_from_FC_Wh * 3600E-6
        PEN_MJoil[2][6] += sum(PEN_MJoil_from_FC)  # MJ-oil-eq
        # add activation
        resourcesRes[2][0] = sum(q_load_Wh)  # q from NG
        resourcesRes[2][2] = sum(el_from_FC_Wh)  # el for GHP # FIXME: el from FC
        heating_dispatch[2] = {'Q_Fuelcell_gen_directload_W': q_load_Wh,
                               'Fuelcell_Status': FC_Status,
                               'NG_FuelCell_req_W': Qgas_to_FC_Wh,
                               'E_Fuelcell_gen_export_W': el_from_FC_Wh,
                               'E_hs_ww_req_W': np.zeros(8760)}

        # 3-13: Boiler NG + GHP
        for i in range(10):
            # set nominal size for Boiler and GHP
            QnomBoiler_W = i / 10.0 * Qnom_W
            mdot_kgpers_Boiler = i / 10.0 * mdot_kgpers
            QnomGHP_W = Qnom_W - QnomBoiler_W

            # GHP operation
            Texit_GHP_nom_K = QnomGHP_W / (mdot_kgpers * HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret_K
            el_GHP_Wh, q_load_NG_Boiler_Wh, \
            qhot_missing_Wh, \
            Texit_GHP_K, q_from_GHP_Wh = np.vectorize(calc_GHP_operation)(QnomGHP_W, T_ground_K, Texit_GHP_nom_K,
                                                                      Tret_K, Tsup_K, mdot_kgpers, q_load_Wh)
            GHP_el_size_W[i][0] = max(el_GHP_Wh)
            GHP_Status = np.where(q_from_GHP_Wh > 0.0, 1, 0)

            # GHP Backup Boiler operation
            if max(qhot_missing_Wh) > 0.0:
                print "GHP unable to cover the whole demand, boiler activated!"
                Qnom_GHP_Backup_Boiler_W = max(qhot_missing_Wh)
                BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(qhot_missing_Wh, Qnom_GHP_Backup_Boiler_W, Texit_GHP_K)
                Qgas_to_GHPBoiler_Wh = np.divide(qhot_missing_Wh, BoilerEff,
                                                 out=np.zeros_like(qhot_missing_Wh), where=BoilerEff != 0.0)
            else:
                Qgas_to_GHPBoiler_Wh = np.zeros(q_load_Wh.shape[0])
                Qnom_GHP_Backup_Boiler_W = 0.0
            Q_Boiler_for_GHP_W[i][0] = Qnom_GHP_Backup_Boiler_W
            GHPbackupBoiler_Status = np.where(qhot_missing_Wh > 0.0, 1, 0)

            # NG Boiler operation
            BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_NG_Boiler_Wh, QnomBoiler_W, Texit_GHP_K)
            Qgas_to_Boiler_Wh = np.divide(q_load_NG_Boiler_Wh, BoilerEff,
                                          out=np.zeros_like(q_load_NG_Boiler_Wh), where=BoilerEff != 0.0)
            Boiler_Status = np.where(q_load_NG_Boiler_Wh > 0.0, 1, 0)

            # add costs
            # electricity
            el_total_Wh = el_GHP_Wh
            Opex_a_var_USD[3 + i][4] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
            GHG_tonCO2[3 + i][5] += calc_emissions_Whyr_to_tonCO2yr(sum(el_total_Wh), lca.EL_TO_CO2_EQ)  # ton CO2
            PEN_MJoil[3 + i][6] += calc_pen_Whyr_to_MJoilyr(sum(el_total_Wh), lca.EL_TO_OIL_EQ)  # MJ-oil-eq
            # gas
            Q_gas_total_Wh = Qgas_to_GHPBoiler_Wh + Qgas_to_Boiler_Wh
            Opex_a_var_USD[3 + i][4] += sum(prices.NG_PRICE * Q_gas_total_Wh)  # CHF
            GHG_tonCO2[3 + i][5] += calc_emissions_Whyr_to_tonCO2yr(sum(Q_gas_total_Wh), lca.NG_TO_CO2_EQ)  # ton CO2
            PEN_MJoil[3 + i][6] += calc_pen_Whyr_to_MJoilyr(sum(Q_gas_total_Wh), lca.NG_TO_OIL_EQ)  # MJ-oil-eq
            # add activation
            resourcesRes[3 + i][0] = sum(qhot_missing_Wh + q_load_NG_Boiler_Wh)
            resourcesRes[3 + i][2] = sum(el_GHP_Wh)
            resourcesRes[3 + i][3] = sum(q_from_GHP_Wh)

            heating_dispatch[3 + i] = {'Q_GHP_gen_directload_W': q_from_GHP_Wh,
                                       'Q_BackupBoiler_gen_directload_W': qhot_missing_Wh,
                                       'Q_Boiler_gen_directload_W': q_load_NG_Boiler_Wh,
                                       'GHP_Status': GHP_Status,
                                       'BackupBoiler_Status': GHPbackupBoiler_Status,
                                       'Boiler_Status': Boiler_Status,
                                       'NG_BackupBoiler_req_Wh': Qgas_to_GHPBoiler_Wh,
                                       'NG_Boiler_req_Wh': Qgas_to_Boiler_Wh,
                                       'E_hs_ww_req_W': el_GHP_Wh}

        # Add all costs
        # 0: Boiler NG
        Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(Qnom_W, locator, config,
                                                                                                'BO1')
        Capex_total_USD[0][0] = Capex_Boiler_USD
        Capex_a_USD[0][0] = Capex_a_Boiler_USD
        Opex_a_fixed_USD[0][0] = Opex_a_fixed_Boiler_USD
        Capex_opex_a_fixed_only_USD[0][0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

        # 1: Boiler BG
        Capex_total_USD[1][0] = Capex_Boiler_USD
        Capex_a_USD[1][0] = Capex_a_Boiler_USD
        Opex_a_fixed_USD[1][0] = Opex_a_fixed_Boiler_USD
        Capex_opex_a_fixed_only_USD[1][0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

        # 2: Fuel Cell
        Capex_a_FC_USD, Opex_fixed_FC_USD, Capex_FC_USD = FC.calc_Cinv_FC(Qnom_W, locator, config)
        Capex_total_USD[2][0] = Capex_FC_USD
        Capex_a_USD[2][0] = Capex_a_FC_USD
        Opex_a_fixed_USD[2][0] = Opex_fixed_FC_USD
        Capex_opex_a_fixed_only_USD[2][0] = Capex_a_FC_USD + Opex_fixed_FC_USD  # TODO:variable price?

        # 3-13: BOILER + GHP
        for i in range(10):
            Opex_a_var_USD[3 + i][0] = i / 10.0  # Boiler share
            Opex_a_var_USD[3 + i][3] = 1 - i / 10.0  # GHP share

            # Get boiler costs
            QnomBoiler_W = i / 10.0 * Qnom_W
            Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(QnomBoiler_W,
                                                                                                    locator,
                                                                                                    config, 'BO1')

            Capex_total_USD[3 + i][0] += Capex_Boiler_USD
            Capex_a_USD[3 + i][0] += Capex_a_Boiler_USD
            Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_Boiler_USD
            Capex_opex_a_fixed_only_USD[3 + i][
                0] += Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

            # Get back up boiler costs
            Qnom_Backup_Boiler_W = Q_Boiler_for_GHP_W[i][0]
            Capex_a_GHPBoiler_USD, Opex_a_fixed_GHPBoiler_USD, Capex_GHPBoiler_USD = Boiler.calc_Cinv_boiler(
                Qnom_Backup_Boiler_W, locator,
                config, 'BO1')

            Capex_total_USD[3 + i][0] += Capex_GHPBoiler_USD
            Capex_a_USD[3 + i][0] += Capex_a_GHPBoiler_USD
            Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHPBoiler_USD
            Capex_opex_a_fixed_only_USD[3 + i][
                0] += Capex_a_GHPBoiler_USD + Opex_a_fixed_GHPBoiler_USD  # TODO:variable price?

            # Get ground source heat pump costs
            Capex_a_GHP_USD, Opex_a_fixed_GHP_USD, Capex_GHP_USD = HP.calc_Cinv_GHP(GHP_el_size_W[i][0], locator,
                                                                                    config)
            Capex_total_USD[3 + i][0] += Capex_GHP_USD
            Capex_a_USD[3 + i][0] += Capex_a_GHP_USD
            Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHP_USD
            Capex_opex_a_fixed_only_USD[3 + i][0] += Capex_a_GHP_USD + Opex_a_fixed_GHP_USD  # TODO:variable price?

        # Best configuration
        Best = np.zeros((13, 1))
        indexBest = 0
        TAC_USD = np.zeros((13, 2))
        TotalCO2 = np.zeros((13, 2))
        TotalPrim = np.zeros((13, 2))
        for i in range(13):
            TAC_USD[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i
            Opex_a_USD[i][1] = Opex_a_fixed_USD[i][0] + + Opex_a_var_USD[i][4]
            TAC_USD[i][1] = Capex_opex_a_fixed_only_USD[i][0] + Opex_a_var_USD[i][4]
            TotalCO2[i][1] = GHG_tonCO2[i][5]
            TotalPrim[i][1] = PEN_MJoil[i][6]

        CostsS = TAC_USD[np.argsort(TAC_USD[:, 1])]
        CO2S = TotalCO2[np.argsort(TotalCO2[:, 1])]
        PrimS = TotalPrim[np.argsort(TotalPrim[:, 1])]

        el = len(CostsS)
        rank = 0
        Bestfound = False

        optsearch = np.empty(el)
        optsearch.fill(3)
        indexBest = 0
        geothermal_potential = geothermal_potential_data.set_index('Name')

        # Check the GHP area constraint
        for i in range(10):
            QGHP = (1 - i / 10.0) * Qnom_W
            areaAvail = geothermal_potential.ix[building_name, 'Area_geo']
            Qallowed = np.ceil(areaAvail / GHP_A) * GHP_HMAX_SIZE  # [W_th]
            if Qallowed < QGHP:
                optsearch[i + 3] += 1
                Best[i + 3][0] = - 1

        while not Bestfound and rank < el:

            optsearch[int(CostsS[rank][0])] -= 1
            optsearch[int(CO2S[rank][0])] -= 1
            optsearch[int(PrimS[rank][0])] -= 1

            if np.count_nonzero(optsearch) != el:
                Bestfound = True
                indexBest = np.where(optsearch == 0)[0][0]

            rank += 1

        # get the best option according to the ranking.
        Best[indexBest][0] = 1

        # Save results in csv file
        performance_results = {
            "Nominal heating load": Qnom_W,
            "Capacity_BaseBoiler_NG_W": Qnom_W * Opex_a_var_USD[:, 0],
            "Capacity_FC_NG_W": Qnom_W * Opex_a_var_USD[:, 2],
            "Capacity_GS_HP_W": Qnom_W * Opex_a_var_USD[:, 3],
            "TAC_USD": TAC_USD[:, 1],
            "Capex_a_USD": Capex_a_USD[:, 0],
            "Capex_total_USD": Capex_total_USD[:, 0],
            "Opex_fixed_USD": Opex_a_fixed_USD[:, 0],
            "Opex_var_USD": Opex_a_var_USD[:, 4],
            "GHG_tonCO2": GHG_tonCO2[:, 5],
            "PEN_MJoil": PEN_MJoil[:, 6],
            "Best configuration": Best[:, 0]}

        results_to_csv = pd.DataFrame(performance_results)

        fName_result = locator.get_optimization_decentralized_folder_building_result_heating(building_name)
        results_to_csv.to_csv(fName_result, sep=',')

        # save activation for the best supply system configuration
        best_activation_df = pd.DataFrame.from_dict(heating_dispatch[indexBest])  #
        best_activation_df.to_csv(
            locator.get_optimization_decentralized_folder_building_result_heating_activation(building_name))

    print time.clock() - t0, "seconds process time for the Disconnected Building Routine \n"
def disconnected_heating_for_building(building_name, supply_systems,
                                      T_ground_K, geothermal_potential_data,
                                      lca, locator, prices):
    print('{building_name} disconnected heating supply system simulations...'.
          format(building_name=building_name))
    GHP_cost_data = supply_systems.HP
    BH_cost_data = supply_systems.BH
    boiler_cost_data = supply_systems.Boiler

    # run substation model to derive temperatures of the building
    substation_results = pd.read_csv(
        locator.get_optimization_substations_results_file(
            building_name, "DH", ""))
    q_load_Wh = np.vectorize(calc_new_load)(
        substation_results["mdot_DH_result_kgpers"],
        substation_results["T_supply_DH_result_K"],
        substation_results["T_return_DH_result_K"])
    Qnom_W = q_load_Wh.max()
    # Create empty matrices
    Opex_a_var_USD = np.zeros((13, 7))
    Capex_total_USD = np.zeros((13, 7))
    Capex_a_USD = np.zeros((13, 7))
    Opex_a_fixed_USD = np.zeros((13, 7))
    Capex_opex_a_fixed_only_USD = np.zeros((13, 7))
    Opex_a_USD = np.zeros((13, 7))
    GHG_tonCO2 = np.zeros((13, 7))
    # indicate supply technologies for each configuration
    Opex_a_var_USD[0][0] = 1  # Boiler NG
    Opex_a_var_USD[1][1] = 1  # Boiler BG
    Opex_a_var_USD[2][2] = 1  # Fuel Cell
    resourcesRes = np.zeros((13, 4))
    Q_Boiler_for_GHP_W = np.zeros(
        (10, 1))  # Save peak capacity of GHP Backup Boilers
    GHP_el_size_W = np.zeros((10, 1))  # Save peak capacity of GHP
    # save supply system activation of all supply configurations
    heating_dispatch = {}
    # Supply with the Boiler / FC / GHP
    Tret_K = substation_results["T_return_DH_result_K"].values
    Tsup_K = substation_results["T_supply_DH_result_K"].values
    mdot_kgpers = substation_results["mdot_DH_result_kgpers"].values
    ## Start Hourly calculation
    print(building_name,
          ' decentralized heating supply systems simulations...')
    Tret_K = np.where(Tret_K > 0.0, Tret_K, Tsup_K)
    ## 0: Boiler NG
    BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_Wh, Qnom_W, Tret_K)
    Qgas_to_Boiler_Wh = np.divide(q_load_Wh,
                                  BoilerEff,
                                  out=np.zeros_like(q_load_Wh),
                                  where=BoilerEff != 0.0)
    Boiler_Status = np.where(Qgas_to_Boiler_Wh > 0.0, 1, 0)
    # add costs
    Opex_a_var_USD[0][4] += sum(prices.NG_PRICE * Qgas_to_Boiler_Wh)  # CHF
    GHG_tonCO2[0][5] += sum(
        calc_emissions_Whyr_to_tonCO2yr(Qgas_to_Boiler_Wh,
                                        lca.NG_TO_CO2_EQ))  # ton CO2
    # add activation
    resourcesRes[0][0] += sum(q_load_Wh)  # q from NG
    heating_dispatch[0] = {
        'Q_Boiler_gen_directload_W': q_load_Wh,
        'Boiler_Status': Boiler_Status,
        'NG_Boiler_req_W': Qgas_to_Boiler_Wh,
        'E_hs_ww_req_W': np.zeros(8760)
    }
    ## 1: Boiler BG
    # add costs
    Opex_a_var_USD[1][4] += sum(prices.BG_PRICE * Qgas_to_Boiler_Wh)  # CHF
    GHG_tonCO2[1][5] += sum(
        calc_emissions_Whyr_to_tonCO2yr(Qgas_to_Boiler_Wh,
                                        lca.NG_TO_CO2_EQ))  # ton CO2
    # add activation
    resourcesRes[1][1] += sum(q_load_Wh)  # q from BG
    heating_dispatch[1] = {
        'Q_Boiler_gen_directload_W': q_load_Wh,
        'Boiler_Status': Boiler_Status,
        'BG_Boiler_req_W': Qgas_to_Boiler_Wh,
        'E_hs_ww_req_W': np.zeros(8760)
    }
    ## 2: Fuel Cell
    (FC_Effel, FC_Effth) = np.vectorize(FC.calc_eta_FC)(q_load_Wh, Qnom_W, 1,
                                                        "B")
    Qgas_to_FC_Wh = q_load_Wh / (FC_Effth + FC_Effel
                                 )  # FIXME: should be q_load_Wh/FC_Effth?
    el_from_FC_Wh = Qgas_to_FC_Wh * FC_Effel
    FC_Status = np.where(Qgas_to_FC_Wh > 0.0, 1, 0)
    # add variable costs, emissions and primary energy
    Opex_a_var_USD[2][4] += sum(
        prices.NG_PRICE * Qgas_to_FC_Wh - prices.ELEC_PRICE_EXPORT *
        el_from_FC_Wh)  # CHF, extra electricity sold to grid
    GHG_tonCO2_from_FC = (0.0874 * Qgas_to_FC_Wh * 3600E-6 +
                          773 * 0.45 * el_from_FC_Wh * 1E-6 -
                          lca.EL_TO_CO2_EQ * el_from_FC_Wh * 3600E-6) / 1E3
    GHG_tonCO2[2][5] += sum(GHG_tonCO2_from_FC)  # tonCO2
    # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
    # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
    # add activation
    resourcesRes[2][0] = sum(q_load_Wh)  # q from NG
    resourcesRes[2][2] = sum(el_from_FC_Wh)  # el for GHP # FIXME: el from FC
    heating_dispatch[2] = {
        'Q_Fuelcell_gen_directload_W': q_load_Wh,
        'Fuelcell_Status': FC_Status,
        'NG_FuelCell_req_W': Qgas_to_FC_Wh,
        'E_Fuelcell_gen_export_W': el_from_FC_Wh,
        'E_hs_ww_req_W': np.zeros(8760)
    }
    # 3-13: Boiler NG + GHP
    for i in range(10):
        # set nominal size for Boiler and GHP
        QnomBoiler_W = i / 10.0 * Qnom_W
        QnomGHP_W = Qnom_W - QnomBoiler_W

        # GHP operation
        Texit_GHP_nom_K = QnomGHP_W / (mdot_kgpers *
                                       HEAT_CAPACITY_OF_WATER_JPERKGK) + Tret_K
        el_GHP_Wh, q_load_NG_Boiler_Wh, \
        qhot_missing_Wh, \
        Texit_GHP_K, q_from_GHP_Wh = np.vectorize(calc_GHP_operation)(QnomGHP_W, T_ground_K, Texit_GHP_nom_K,
                                                                      Tret_K, Tsup_K, mdot_kgpers, q_load_Wh)
        GHP_el_size_W[i][0] = max(el_GHP_Wh)
        GHP_Status = np.where(q_from_GHP_Wh > 0.0, 1, 0)

        # GHP Backup Boiler operation
        if max(qhot_missing_Wh) > 0.0:
            print("GHP unable to cover the whole demand, boiler activated!")
            Qnom_GHP_Backup_Boiler_W = max(qhot_missing_Wh)
            BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(
                qhot_missing_Wh, Qnom_GHP_Backup_Boiler_W, Texit_GHP_K)
            Qgas_to_GHPBoiler_Wh = np.divide(
                qhot_missing_Wh,
                BoilerEff,
                out=np.zeros_like(qhot_missing_Wh),
                where=BoilerEff != 0.0)
        else:
            Qgas_to_GHPBoiler_Wh = np.zeros(q_load_Wh.shape[0])
            Qnom_GHP_Backup_Boiler_W = 0.0
        Q_Boiler_for_GHP_W[i][0] = Qnom_GHP_Backup_Boiler_W
        GHPbackupBoiler_Status = np.where(qhot_missing_Wh > 0.0, 1, 0)

        # NG Boiler operation
        BoilerEff = np.vectorize(Boiler.calc_Cop_boiler)(q_load_NG_Boiler_Wh,
                                                         QnomBoiler_W,
                                                         Texit_GHP_K)
        Qgas_to_Boiler_Wh = np.divide(q_load_NG_Boiler_Wh,
                                      BoilerEff,
                                      out=np.zeros_like(q_load_NG_Boiler_Wh),
                                      where=BoilerEff != 0.0)
        Boiler_Status = np.where(q_load_NG_Boiler_Wh > 0.0, 1, 0)

        # add costs
        # electricity
        el_total_Wh = el_GHP_Wh
        Opex_a_var_USD[3 + i][4] += sum(prices.ELEC_PRICE * el_total_Wh)  # CHF
        GHG_tonCO2[3 + i][5] += sum(
            calc_emissions_Whyr_to_tonCO2yr(el_total_Wh,
                                            lca.EL_TO_CO2_EQ))  # ton CO2
        # gas
        Q_gas_total_Wh = Qgas_to_GHPBoiler_Wh + Qgas_to_Boiler_Wh
        Opex_a_var_USD[3 + i][4] += sum(prices.NG_PRICE *
                                        Q_gas_total_Wh)  # CHF
        GHG_tonCO2[3 + i][5] += sum(
            calc_emissions_Whyr_to_tonCO2yr(Q_gas_total_Wh,
                                            lca.NG_TO_CO2_EQ))  # ton CO2
        # add activation
        resourcesRes[3 + i][0] = sum(qhot_missing_Wh + q_load_NG_Boiler_Wh)
        resourcesRes[3 + i][2] = sum(el_GHP_Wh)
        resourcesRes[3 + i][3] = sum(q_from_GHP_Wh)

        heating_dispatch[3 + i] = {
            'Q_GHP_gen_directload_W': q_from_GHP_Wh,
            'Q_BackupBoiler_gen_directload_W': qhot_missing_Wh,
            'Q_Boiler_gen_directload_W': q_load_NG_Boiler_Wh,
            'GHP_Status': GHP_Status,
            'BackupBoiler_Status': GHPbackupBoiler_Status,
            'Boiler_Status': Boiler_Status,
            'NG_BackupBoiler_req_Wh': Qgas_to_GHPBoiler_Wh,
            'NG_Boiler_req_Wh': Qgas_to_Boiler_Wh,
            'E_hs_ww_req_W': el_GHP_Wh
        }
    # Add all costs
    # 0: Boiler NG
    Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(
        Qnom_W, 'BO1', boiler_cost_data)
    Capex_total_USD[0][0] = Capex_Boiler_USD
    Capex_a_USD[0][0] = Capex_a_Boiler_USD
    Opex_a_fixed_USD[0][0] = Opex_a_fixed_Boiler_USD
    Capex_opex_a_fixed_only_USD[0][
        0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?
    # 1: Boiler BG
    Capex_total_USD[1][0] = Capex_Boiler_USD
    Capex_a_USD[1][0] = Capex_a_Boiler_USD
    Opex_a_fixed_USD[1][0] = Opex_a_fixed_Boiler_USD
    Capex_opex_a_fixed_only_USD[1][
        0] = Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?
    # 2: Fuel Cell
    Capex_a_FC_USD, Opex_fixed_FC_USD, Capex_FC_USD = FC.calc_Cinv_FC(
        Qnom_W, supply_systems.FC)
    Capex_total_USD[2][0] = Capex_FC_USD
    Capex_a_USD[2][0] = Capex_a_FC_USD
    Opex_a_fixed_USD[2][0] = Opex_fixed_FC_USD
    Capex_opex_a_fixed_only_USD[2][
        0] = Capex_a_FC_USD + Opex_fixed_FC_USD  # TODO:variable price?
    # 3-13: BOILER + GHP
    for i in range(10):
        Opex_a_var_USD[3 + i][0] = i / 10.0  # Boiler share
        Opex_a_var_USD[3 + i][3] = 1 - i / 10.0  # GHP share

        # Get boiler costs
        QnomBoiler_W = i / 10.0 * Qnom_W
        Capex_a_Boiler_USD, Opex_a_fixed_Boiler_USD, Capex_Boiler_USD = Boiler.calc_Cinv_boiler(
            QnomBoiler_W, 'BO1', boiler_cost_data)

        Capex_total_USD[3 + i][0] += Capex_Boiler_USD
        Capex_a_USD[3 + i][0] += Capex_a_Boiler_USD
        Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_Boiler_USD
        Capex_opex_a_fixed_only_USD[3 + i][
            0] += Capex_a_Boiler_USD + Opex_a_fixed_Boiler_USD  # TODO:variable price?

        # Get back up boiler costs
        Qnom_Backup_Boiler_W = Q_Boiler_for_GHP_W[i][0]
        Capex_a_GHPBoiler_USD, Opex_a_fixed_GHPBoiler_USD, Capex_GHPBoiler_USD = Boiler.calc_Cinv_boiler(
            Qnom_Backup_Boiler_W, 'BO1', boiler_cost_data)

        Capex_total_USD[3 + i][0] += Capex_GHPBoiler_USD
        Capex_a_USD[3 + i][0] += Capex_a_GHPBoiler_USD
        Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHPBoiler_USD
        Capex_opex_a_fixed_only_USD[3 + i][
            0] += Capex_a_GHPBoiler_USD + Opex_a_fixed_GHPBoiler_USD  # TODO:variable price?

        # Get ground source heat pump costs
        Capex_a_GHP_USD, Opex_a_fixed_GHP_USD, Capex_GHP_USD = HP.calc_Cinv_GHP(
            GHP_el_size_W[i][0], GHP_cost_data, BH_cost_data)
        Capex_total_USD[3 + i][0] += Capex_GHP_USD
        Capex_a_USD[3 + i][0] += Capex_a_GHP_USD
        Opex_a_fixed_USD[3 + i][0] += Opex_a_fixed_GHP_USD
        Capex_opex_a_fixed_only_USD[3 + i][
            0] += Capex_a_GHP_USD + Opex_a_fixed_GHP_USD  # TODO:variable price?
    # Best configuration
    Best = np.zeros((13, 1))
    indexBest = 0
    TAC_USD = np.zeros((13, 2))
    TotalCO2 = np.zeros((13, 2))
    for i in range(13):
        TAC_USD[i][0] = TotalCO2[i][0] = i
        Opex_a_USD[i][1] = Opex_a_fixed_USD[i][0] + +Opex_a_var_USD[i][4]
        TAC_USD[i][
            1] = Capex_opex_a_fixed_only_USD[i][0] + Opex_a_var_USD[i][4]
        TotalCO2[i][1] = GHG_tonCO2[i][5]
    CostsS = TAC_USD[np.argsort(TAC_USD[:, 1])]
    CO2S = TotalCO2[np.argsort(TotalCO2[:, 1])]
    el = len(CostsS)
    rank = 0
    Bestfound = False
    optsearch = np.empty(el)
    optsearch.fill(3)
    indexBest = 0
    geothermal_potential = geothermal_potential_data.set_index('Name')
    # Check the GHP area constraint
    for i in range(10):
        QGHP = (1 - i / 10.0) * Qnom_W
        areaAvail = geothermal_potential.loc[building_name, 'Area_geo']
        Qallowed = np.ceil(areaAvail / GHP_A) * GHP_HMAX_SIZE  # [W_th]
        if Qallowed < QGHP:
            optsearch[i + 3] += 1
            Best[i + 3][0] = -1
    while not Bestfound and rank < el:

        optsearch[int(CostsS[rank][0])] -= 1
        optsearch[int(CO2S[rank][0])] -= 1

        if np.count_nonzero(optsearch) != el:
            Bestfound = True
            indexBest = np.where(optsearch == 0)[0][0]

        rank += 1
    # get the best option according to the ranking.
    Best[indexBest][0] = 1
    # Save results in csv file
    performance_results = {
        "Nominal heating load": Qnom_W,
        "Capacity_BaseBoiler_NG_W": Qnom_W * Opex_a_var_USD[:, 0],
        "Capacity_FC_NG_W": Qnom_W * Opex_a_var_USD[:, 2],
        "Capacity_GS_HP_W": Qnom_W * Opex_a_var_USD[:, 3],
        "TAC_USD": TAC_USD[:, 1],
        "Capex_a_USD": Capex_a_USD[:, 0],
        "Capex_total_USD": Capex_total_USD[:, 0],
        "Opex_fixed_USD": Opex_a_fixed_USD[:, 0],
        "Opex_var_USD": Opex_a_var_USD[:, 4],
        "GHG_tonCO2": GHG_tonCO2[:, 5],
        "Best configuration": Best[:, 0]
    }
    results_to_csv = pd.DataFrame(performance_results)
    fName_result = locator.get_optimization_decentralized_folder_building_result_heating(
        building_name)
    results_to_csv.to_csv(fName_result, sep=',', index=False)
    # save activation for the best supply system configuration
    best_activation_df = pd.DataFrame.from_dict(heating_dispatch[indexBest])  #
    best_activation_df.to_csv(
        locator.
        get_optimization_decentralized_folder_building_result_heating_activation(
            building_name),
        index=False)
def discBuildOp(locator, building_names, gv):
    """
    Computes the parameters for the operation of disconnected buildings
    output results in csv files
    
    Parameters
    ----------
    locator : string
        path to folders    
    
    """
    print "Start Disconnected Building Routine \n"
    t0 = time.clock()
    geothermal_potential = pd.read_csv(locator.get_geothermal_potential, index_col="Name")
    BestData = {}

    def calc_new_load(mdot, TsupDH, Tret, gv):
        Qload = mdot * gv.cp * (TsupDH - Tret) * (1 + gv.Qloss_Disc)
        if Qload < 0:
            Qload = 0
        if Qload < -1E-5:
            print "Error in discBuildMain, negative heat requirement at hour", hour, buildName
        return Qload

    for buildName in building_names:
        fName = locator.pathSubsRes + "/" + buildName + "_result.csv"

        loads = pd.read_csv(fName, usecols=["T_supply_DH_result", "T_return_DH_result", "mdot_DH_result"])
        Qload = np.vectorize(calc_new_load)(loads["mdot_DH_result"], loads["T_supply_DH_result"], loads["T_return_DH_result"], gv)
        Qannual = Qload.sum()
        Qnom = Qload.max()* (1+gv.Qmargin_Disc) # 1% reliability margin on installed capacity

        # Create empty matrices
        result = np.zeros((13,7))
        result[0][0] = 1
        result[1][1] = 1
        result[2][2] = 1
        InvCosts = np.zeros((13,1))
        resourcesRes = np.zeros((13,4))
        QannualB_GHP = np.zeros((10,1)) # For the investment costs of the boiler used with GHP
        Wel_GHP = np.zeros((10,1)) # For the investment costs of the GHP
        
        # Supply with the Boiler / FC / GHP
        print "Operation with the Boiler / FC / GHP"

        Tret = loads["T_return_DH_result"].values
        TsupDH = loads["T_supply_DH_result"].values
        mdot = loads["mdot_DH_result"].values
        for hour in range(8760):

            if Tret[hour] == 0:
                Tret[hour] = TsupDH[hour]
                
            # Boiler NG
            BoilerEff = Boiler.calc_Cop_boiler(Qload[hour], Qnom, Tret[hour])
            
            Qgas = Qload[hour] / BoilerEff
            
            result[0][4] += gv.NG_PRICE * Qgas # CHF
            result[0][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2
            result[0][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq
            resourcesRes[0][0] += Qload[hour]
            
            if gv.DiscBioGasFlag == 1:
                result[0][4] += gv.BG_PRICE * Qgas # CHF
                result[0][5] += gv.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2
                result[0][6] += gv.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq
                
            # Boiler BG
            result[1][4] += gv.BG_PRICE * Qgas # CHF
            result[1][5] += gv.BG_BACKUPBOILER_TO_CO2_STD * Qgas * 3600E-6 # kgCO2
            result[1][6] += gv.BG_BACKUPBOILER_TO_OIL_STD * Qgas * 3600E-6 # MJ-oil-eq
            resourcesRes[1][1] += Qload[hour]
                
            # FC
            (FC_Effel, FC_Effth) = FC.calc_eta_FC(Qload[hour], Qnom, 1, "B")
            Qgas = Qload[hour] / (FC_Effth+FC_Effel)
            Qelec = Qgas * FC_Effel            
            
            result[2][4] += gv.NG_PRICE * Qgas - gv.ELEC_PRICE * Qelec # CHF, extra electricity sold to grid
            result[2][5] += 0.0874 * Qgas * 3600E-6 + 773 * 0.45 * Qelec * 1E-6 - gv.EL_TO_CO2 * Qelec * 3600E-6 # kgCO2
            # Bloom box emissions within the FC: 773 lbs / MWh_el (and 1 lbs = 0.45 kg)
            # http://www.carbonlighthouse.com/2011/09/16/bloom-box/
            result[2][6] += 1.51 * Qgas * 3600E-6 - gv.EL_TO_OIL_EQ * Qelec * 3600E-6 # MJ-oil-eq
            
            resourcesRes[2][0] += Qload[hour]
            resourcesRes[2][2] += Qelec
            
            # GHP
            for i in range(10):
                
                QnomBoiler = i/10 * Qnom
                QnomGHP = Qnom - QnomBoiler
                
                if Qload[hour] <= QnomGHP:
                
                    (wdot_el, qcolddot, qhotdot_missing, tsup2) = HP.calc_Cop_GHP(mdot[hour], TsupDH[hour], Tret[hour], gv.TGround, gv)
                    
                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el
                    
                    result[3+i][4] += gv.ELEC_PRICE * wdot_el   # CHF
                    result[3+i][5] += gv.SMALL_GHP_TO_CO2_STD  * wdot_el   * 3600E-6 # kgCO2
                    result[3+i][6] += gv.SMALL_GHP_TO_OIL_STD  * wdot_el   * 3600E-6 # MJ-oil-eq
                    
                    resourcesRes[3+i][2] -= wdot_el
                    resourcesRes[3+i][3] += Qload[hour] - qhotdot_missing
                    
                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff
                        
                        result[3+i][4] += gv.NG_PRICE * Qgas   # CHF
                        result[3+i][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas   * 3600E-6 # kgCO2
                        result[3+i][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas   * 3600E-6 # MJ-oil-eq
                        
                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3+i][0] += qhotdot_missing
    
                else:
                    #print "Boiler activated to compensate GHP", i
                    #if gv.DiscGHPFlag == 0:
                    #    print QnomGHP
                    #   QnomGHP = 0 
                    #   print "GHP not allowed 2, set QnomGHP to zero"
                        
                    TexitGHP = QnomGHP / (mdot[hour] * gv.cp) + Tret[hour]
                    (wdot_el, qcolddot, qhotdot_missing, tsup2) = HP.calc_Cop_GHP(mdot[hour], TexitGHP, Tret[hour], gv.TGround, gv)
                    
                    if Wel_GHP[i][0] < wdot_el:
                        Wel_GHP[i][0] = wdot_el
                        
                    result[3+i][4] += gv.ELEC_PRICE * wdot_el   # CHF
                    result[3+i][5] += gv.SMALL_GHP_TO_CO2_STD  * wdot_el   * 3600E-6 # kgCO2
                    result[3+i][6] += gv.SMALL_GHP_TO_OIL_STD  * wdot_el   * 3600E-6 # MJ-oil-eq
                    
                    resourcesRes[3+i][2] -= wdot_el
                    resourcesRes[3+i][3] += QnomGHP - qhotdot_missing
                    
                    if qhotdot_missing > 0:
                        print "GHP unable to cover the whole demand, boiler activated!"
                        BoilerEff = Boiler.calc_Cop_boiler(qhotdot_missing, QnomBoiler, tsup2)
                        Qgas = qhotdot_missing / BoilerEff
                        
                        result[3+i][4] += gv.NG_PRICE * Qgas   # CHF
                        result[3+i][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas   * 3600E-6 # kgCO2
                        result[3+i][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas   * 3600E-6 # MJ-oil-eq
                        
                        QannualB_GHP[i][0] += qhotdot_missing
                        resourcesRes[3+i][0] += qhotdot_missing
                        
                    QtoBoiler = Qload[hour] - QnomGHP
                    QannualB_GHP[i][0] += QtoBoiler
                    
                    BoilerEff = Boiler.calc_Cop_boiler(QtoBoiler, QnomBoiler, TexitGHP)
                    Qgas = QtoBoiler / BoilerEff
                    
                    result[3+i][4] += gv.NG_PRICE * Qgas   # CHF
                    result[3+i][5] += gv.NG_BACKUPBOILER_TO_CO2_STD * Qgas   * 3600E-6 # kgCO2
                    result[3+i][6] += gv.NG_BACKUPBOILER_TO_OIL_STD * Qgas   * 3600E-6 # MJ-oil-eq
                    resourcesRes[3+i][0] += QtoBoiler

        print time.clock() - t0, "seconds process time for the operation \n"
        
        # Investment Costs / CO2 / Prim
        InvCaBoiler = Boiler.calc_Cinv_boiler(Qnom, Qannual, gv)
        InvCosts[0][0] = InvCaBoiler
        InvCosts[1][0] = InvCaBoiler
        
        InvCosts[2][0] = FC.calc_Cinv_FC(Qnom, gv)
        
        for i in range(10):
            result[3+i][0] = i/10
            result[3+i][3] = 1-i/10

            QnomBoiler = i/10 * Qnom
            
            InvCaBoiler = Boiler.calc_Cinv_boiler(QnomBoiler, QannualB_GHP[i][0], gv)
            InvCosts[3+i][0] = InvCaBoiler
            
            InvCaGHP = HP.GHP_InvCost( Wel_GHP[i][0] , gv)
            InvCosts[3+i][0] += InvCaGHP * gv.EURO_TO_CHF
        

        # Best configuration
        print "Find the best configuration"
        
        Best = np.zeros((13,1))
        indexBest = 0

        TotalCosts = np.zeros((13,2))
        TotalCO2 = np.zeros((13,2))
        TotalPrim = np.zeros((13,2))
        
        for i in range(13):
            TotalCosts[i][0] = TotalCO2[i][0] = TotalPrim[i][0] = i

            TotalCosts[i][1] = InvCosts[i][0] + result[i][4]
            TotalCO2[i][1] = result[i][5]
            TotalPrim[i][1] = result[i][6]
        
        CostsS = TotalCosts[np.argsort(TotalCosts[:,1])]
        CO2S = TotalCO2[np.argsort(TotalCO2[:,1])]
        PrimS = TotalPrim[np.argsort(TotalPrim[:,1])]
        
        el = len(CostsS)
        rank = 0
        Bestfound = False
        
        optsearch = np.empty(el)
        optsearch.fill(3)
        indexBest = 0
        
        # Check the GHP area constraint
        for i in range(10):
            QGHP = (1-i/10) * Qnom
            areaAvail = geothermal_potential.ix[buildName,"Area_geo"]
            Qallowed = np.ceil(areaAvail/gv.GHP_A) * gv.GHP_HmaxSize #[W_th]
            
            if Qallowed < QGHP:
                optsearch[i+3] += 1
                Best[i+3][0] = -1
        
        while not Bestfound and rank<el:
            
            optsearch[CostsS[rank][0]] -= 1
            optsearch[CO2S[rank][0]] -= 1
            optsearch[PrimS[rank][0]] -= 1
            
            if np.count_nonzero(optsearch) != el:
                Bestfound = True
                indexBest = np.where(optsearch == 0)[0][0]
                
            rank += 1

        Best[indexBest][0] = 1
        print indexBest, "Best"
        Qnom_array = np.ones(len(Best[:,0])) * Qnom

        # Save results in csv file
        print "Save the results for", buildName, "\n"
        
        dico = {}
        dico[ "BoilerNG Share" ] = result[:,0]
        dico[ "BoilerBG Share" ] = result[:,1]
        dico[ "FC Share" ] = result[:,2]
        dico[ "GHP Share" ] = result[:,3]
        dico[ "Operation Costs [CHF]" ] = result[:,4]
        dico[ "CO2 Emissions [kgCO2-eq]" ] = result[:,5]
        dico[ "Primary Energy Needs [MJoil-eq]" ] = result[:,6]
        dico[ "Annualized Investment Costs [CHF]" ] = InvCosts[:,0]
        dico[ "Total Costs [CHF]" ] = TotalCosts[:,1]
        dico[ "Best configuration" ] = Best[:,0]
        dico[ "Nominal Power" ] = Qnom_array
        dico[ "QfromNG" ] = resourcesRes[:,0]
        dico[ "QfromBG" ] = resourcesRes[:,1]
        dico[ "EforGHP" ] = resourcesRes[:,2]
        dico[ "QfromGHP" ] = resourcesRes[:,3]

        os.chdir(locator.pathDiscRes)
        fName = buildName + "_result.csv"
        results_to_csv = pd.DataFrame(dico)
        fName_result = "DiscOp_" + fName[0:(len(fName)-4)] + ".csv"
        results_to_csv.to_csv(fName_result, sep= ',')
        
    
        BestComb = {}
        BestComb[ "BoilerNG Share" ] = result[indexBest,0]
        BestComb[ "BoilerBG Share" ] = result[indexBest,1]
        BestComb[ "FC Share" ] = result[indexBest,2]
        BestComb[ "GHP Share" ] = result[indexBest,3]
        BestComb[ "Operation Costs [CHF]" ] = result[indexBest,4]
        BestComb[ "CO2 Emissions [kgCO2-eq]" ] = result[indexBest,5]
        BestComb[ "Primary Energy Needs [MJoil-eq]" ] = result[indexBest,6]
        BestComb[ "Annualized Investment Costs [CHF]" ] = InvCosts[indexBest,0]
        BestComb[ "Total Costs [CHF]" ] = TotalCosts[indexBest,1]
        BestComb[ "Best configuration" ] = Best[indexBest,0]
        BestComb[ "Nominal Power" ] = Qnom
        
        BestData[buildName] = BestComb

    if 0:
        os.chdir(locator.pathDiscRes)
        fName = "DiscOpSummary.csv"
        results_to_csv = pd.DataFrame(BestData)
        results_to_csv.to_csv(fName, sep= ',')
        
        
    print "Disconnected Building Routine Completed"
    print time.clock() - t0, "seconds process time for the Disconnected Building Routine \n"