def photovoltaic(args): import cea.inputlocator import cea.utilities.dbfreader as dbfreader from cea.technologies.photovoltaic import calc_PV if not args.latitude: args.latitude = _get_latitude(args.scenario) if not args.longitude: args.longitude = _get_longitude(args.scenario) locator = cea.inputlocator.InputLocator(args.scenario) if not args.weather_path: args.weather_path = locator.get_default_weather() elif args.weather_path in locator.get_weather_names(): args.weather_path = locator.get_weather(args.weather_path) list_buildings_names = dbfreader.dbf_to_dataframe(locator.get_building_occupancy())['Name'] for building in list_buildings_names: radiation_csv = locator.get_radiation_building(building_name=building) radiation_metadata = locator.get_radiation_metadata(building_name=building) calc_PV(locator=locator, radiation_csv=radiation_csv, metadata_csv=radiation_metadata, latitude=args.latitude, longitude=args.longitude, weather_path=args.weather_path, building_name=building, pvonroof=args.pvonroof, pvonwall=args.pvonwall, worst_hour=args.worst_hour, type_PVpanel=args.type_PVpanel, min_radiation=args.min_radiation, date_start=args.date_start)
def calc_spatio_temporal_visuals(locator, period): date = pd.date_range('1/1/2010', periods=8760, freq='H')[period[0]:period[1]] buildings = dbfreader.dbf_to_dataframe( locator.get_building_occupancy())['Name'] location = locator.get_solar_radiation_folder() time = date.strftime("%Y%m%d%H%M%S") for i, building in enumerate(buildings): data = pd.read_csv(os.path.join(location, building + '_geometry.csv')) geometry = data.set_index('SURFACE') solar = pd.read_csv( os.path.join(location, building + '_insolation_Whm2.csv')) surfaces = solar.columns.values for surface in surfaces: Xcoor = geometry.loc[surface, 'Xcoor'] Ycoor = geometry.loc[surface, 'Ycoor'] Zcoor = geometry.loc[surface, 'Zcoor'] result = pd.DataFrame({ 'date': time, 'surface': building + surface, 'I_Wm2': solar[surface].values[period[0]:period[1]], 'Xcoor': Xcoor, 'Ycoor': Ycoor, 'Zcoor': Zcoor }) if i == 0: final = result else: final = final.append(result, ignore_index=True) dbfreader.dataframe_to_dbf( final, locator.get_solar_radiation_folder() + "result_solar_48h.dbf")
def test_photovoltaic(): gv = cea.globalvar.GlobalVariables() scenario_path = gv.scenario_reference locator = cea.inputlocator.InputLocator(scenario_path=scenario_path) weather_path = locator.get_default_weather() list_buildings_names = dbfreader.dbf_to_dataframe( locator.get_building_occupancy())['Name'] min_radiation = 0.75 # points are selected with at least a minimum production of this % from the maximum in the area. type_PVpanel = "PV1" # PV1 monocrystalline, PV2 is poly and PV3 is amorphous. it relates to the database of technologies worst_hour = 8744 # first hour of sun on the solar solstice # TODO: write a function to extract this value automatically pvonroof = True # flag for considering PV on roof pvonwall = True # flag for considering PV on wall longitude = 7.439583333333333 latitude = 46.95240555555556 date_start = gv.date_start for building in list_buildings_names: radiation = locator.get_radiation_building(building_name=building) radiation_metadata = locator.get_radiation_metadata( building_name=building) calc_PV(locator=locator, radiation_csv=radiation, metadata_csv=radiation_metadata, latitude=latitude, longitude=longitude, weather_path=weather_path, building_name=building, pvonroof=pvonroof, pvonwall=pvonwall, worst_hour=worst_hour, type_PVpanel=type_PVpanel, min_radiation=min_radiation, date_start=date_start)
def retrofit_main(locator_baseline, name_new_scenario, keep_partial_matches, age_retrofit=None, age_criteria=None, eui_heating_criteria=None, eui_hotwater_criteria=None, eui_cooling_criteria=None, eui_electricity_criteria=None, heating_costs_criteria=None, hotwater_costs_criteria=None, cooling_costs_criteria=None, electricity_costs_criteria=None, heating_losses_criteria=None, hotwater_losses_criteria=None, cooling_losses_criteria=None, emissions_operation_criteria=None): selection_names = [ ] # list to store names of selected buildings to retrofit #load databases and select only buildings in geometry #geometry geometry_df = gdf.from_file(locator_baseline.get_zone_geometry()) names = geometry_df['Name'].values #age age = dbfreader.dbf_to_dataframe(locator_baseline.get_building_age()) age = age.loc[age['Name'].isin(names)] architecture = dbfreader.dbf_to_dataframe( locator_baseline.get_building_architecture()) architecture = architecture.loc[architecture['Name'].isin(names)] comfort = dbfreader.dbf_to_dataframe( locator_baseline.get_building_comfort()) comfort = comfort.loc[comfort['Name'].isin(names)] internal_loads = dbfreader.dbf_to_dataframe( locator_baseline.get_building_internal()) internal_loads = internal_loads.loc[internal_loads['Name'].isin(names)] hvac = dbfreader.dbf_to_dataframe(locator_baseline.get_building_hvac()) hvac = hvac.loc[hvac['Name'].isin(names)] supply = dbfreader.dbf_to_dataframe(locator_baseline.get_building_supply()) supply = supply.loc[supply['Name'].isin(names)] occupancy = dbfreader.dbf_to_dataframe( locator_baseline.get_building_occupancy()) occupancy = occupancy.loc[occupancy['Name'].isin(names)] # CASE 1 age_crit = [["age", age_criteria]] for criteria_name, criteria_threshold in age_crit: if criteria_threshold is not None: age_difference = age_retrofit - criteria_threshold selection_names.append( ("Crit_" + criteria_name, age_filter_HVAC(age, age_difference))) # CASE 2 eui_crit = [["Qhsf", eui_heating_criteria], ["Qwwf", eui_hotwater_criteria], ["Qcsf", eui_cooling_criteria], ["Ef", eui_electricity_criteria]] for criteria_name, criteria_threshold in eui_crit: if criteria_threshold is not None: demand_totals = pd.read_csv(locator_baseline.get_total_demand()) selection_names.append( ("c_eui_" + criteria_name, eui_filter_HVAC(demand_totals, criteria_name, criteria_threshold))) # CASE 3 op_costs_crit = [["Qhsf", heating_costs_criteria], ["Qwwf", hotwater_costs_criteria], ["Qcsf", cooling_costs_criteria], ["Ef", electricity_costs_criteria]] for criteria_name, criteria_threshold in op_costs_crit: if criteria_threshold is not None: costs_totals = pd.read_csv( locator_baseline.get_costs_operation_file(criteria_name)) selection_names.append( ("c_cost_" + criteria_name, emissions_filter_HVAC(costs_totals, criteria_name + "_cost_m2", criteria_threshold))) # CASE 4 losses_crit = [ ["Qhsf", "Qhsf_MWhyr", "Qhs_MWhyr", heating_losses_criteria], ["Qwwf", "Qwwf_MWhyr", "Qww_MWhyr", hotwater_losses_criteria], ["Qcsf", "Qcsf_MWhyr", "Qcs_MWhyr", cooling_losses_criteria] ] for criteria_name, load_with_losses, load_end_use, criteria_threshold in losses_crit: if criteria_threshold is not None: demand_totals = pd.read_csv(locator_baseline.get_total_demand()) selection_names.append( ("c_loss_" + criteria_name, losses_filter_HVAC(demand_totals, load_with_losses, load_end_use, criteria_threshold))) # CASE 5 LCA_crit = [["ghg", "O_ghg_ton", emissions_operation_criteria]] for criteria_name, lca_name, criteria_threshold in LCA_crit: if criteria_threshold is not None: emissions_totals = pd.read_csv( locator_baseline.get_lca_operation()) selection_names.append( ("c_" + criteria_name, emissions_filter_HVAC(emissions_totals, lca_name, criteria_threshold))) # appending all the results if keep_partial_matches: type_of_join = "outer" else: type_of_join = "inner" counter = 0 for (criteria, list_true_values) in selection_names: if counter == 0: data = pd.DataFrame({"Name": list_true_values}) data[criteria] = "TRUE" else: y = pd.DataFrame({"Name": list_true_values}) y[criteria] = "TRUE" data = data.merge(y, on="Name", how=type_of_join) counter += 1 data.fillna(value="FALSE", inplace=True) if data.empty and (keep_partial_matches == False): raise ValueError( "There is not a single building matching all selected criteria," "try to keep those buildings that partially match the criteria") # Create a retrofit case with the buildings that pass the criteria retrofit_scenario_path = os.path.join(locator_baseline.get_project_path(), name_new_scenario) locator_retrofit = cea.inputlocator.InputLocator( scenario_path=retrofit_scenario_path) retrofit_scenario_creator(locator_baseline, locator_retrofit, geometry_df, age, architecture, internal_loads, comfort, hvac, supply, occupancy, data, type_of_join)
def __init__(self, locator, gv): """ Read building properties from input shape files and construct a new BuildingProperties object. :param locator: an InputLocator for locating the input files :type locator: cea.inputlocator.InputLocator :param gv: contains the context (constants and models) for the calculation :type gv: cea.globalvar.GlobalVariables :returns: object of type BuildingProperties :rtype: BuildingProperties - get_radiation: C:\reference-case\baseline\outputs\data\solar-radiation\radiation.csv - get_surface_properties: C:\reference-case\baseline\outputs\data\solar-radiation\properties_surfaces.csv - get_zone_geometry: C:\reference-case\baseline\inputs\building-geometry\zone.shp - get_building_hvac: C:\reference-case\baseline\inputs\building-properties\technical_systems.shp - get_building_thermal: C:\reference-case\baseline\inputs\building-properties\thermal_properties.shp - get_building_occupancy: C:\reference-case\baseline\inputs\building-properties\occupancy.shp - get_building_architecture: C:\reference-case\baseline\inputs\building-properties\architecture.shp - get_building_age: C:\reference-case\baseline\inputs\building-properties\age.shp - get_building_comfort: C:\reference-case\baseline\inputs\building-properties\indoor_comfort.shp - get_building_internal: C:\reference-case\baseline\inputs\building-properties\internal_loads.shp """ from cea.geometry import geometry_reader self.gv = gv gv.log("read input files") surface_properties = pd.read_csv(locator.get_surface_properties()) prop_geometry = Gdf.from_file(locator.get_zone_geometry()) prop_geometry['footprint'] = prop_geometry.area prop_geometry['perimeter'] = prop_geometry.length prop_geometry['Blength'], prop_geometry['Bwidth'] = self.calc_bounding_box_geom(locator.get_zone_geometry()) prop_geometry = prop_geometry.drop('geometry', axis=1).set_index('Name') prop_hvac = dbf_to_dataframe(locator.get_building_hvac()) prop_occupancy_df = dbf_to_dataframe(locator.get_building_occupancy()).set_index('Name') prop_occupancy_df.fillna(value=0.0, inplace=True) # fix badly formatted occupancy file... prop_occupancy = prop_occupancy_df.loc[:, (prop_occupancy_df != 0).any(axis=0)] prop_architectures = dbf_to_dataframe(locator.get_building_architecture()) prop_age = dbf_to_dataframe(locator.get_building_age()).set_index('Name') prop_comfort = dbf_to_dataframe(locator.get_building_comfort()).set_index('Name') prop_internal_loads = dbf_to_dataframe(locator.get_building_internal()).set_index('Name') # get solar properties solar = get_prop_solar(locator).set_index('Name') # get temperatures of operation prop_HVAC_result = get_properties_technical_systems(locator, prop_hvac).set_index('Name') # get envelope properties prop_envelope = get_envelope_properties(locator, prop_architectures).set_index('Name') # apply overrides if os.path.exists(locator.get_building_overrides()): self._overrides = pd.read_csv(locator.get_building_overrides()).set_index('Name') prop_envelope = self.apply_overrides(prop_envelope) prop_internal_loads = self.apply_overrides(prop_internal_loads) prop_comfort = self.apply_overrides(prop_comfort) # get properties of rc demand model prop_rc_model = self.calc_prop_rc_model(prop_occupancy, prop_envelope, prop_geometry, prop_HVAC_result, surface_properties, gv) # df_windows = geometry_reader.create_windows(surface_properties, prop_envelope) # TODO: to check if the Win_op and height of window is necessary. # TODO: maybe mergin branch i9 with CItyGML could help with this gv.log("done") # save resulting data self._prop_surface = surface_properties self._prop_geometry = prop_geometry self._prop_envelope = prop_envelope self._prop_occupancy = prop_occupancy self._prop_HVAC_result = prop_HVAC_result self._prop_comfort = prop_comfort self._prop_internal_loads = prop_internal_loads self._prop_age = prop_age self._solar = solar self._prop_RC_model = prop_rc_model
def properties(locator, prop_architecture_flag, prop_hvac_flag, prop_comfort_flag, prop_internal_loads_flag): """ algorithm to query building properties from statistical database Archetypes_HVAC_properties.csv. for more info check the integrated demand model of Fonseca et al. 2015. Appl. energy. :param InputLocator locator: an InputLocator instance set to the scenario to work on :param boolean prop_architecture_flag: if True, get properties about the construction and architecture. :param boolean prop_comfort_flag: if True, get properties about thermal comfort. :param boolean prop_hvac_flag: if True, get properties about types of HVAC systems, otherwise False. :param boolean prop_internal_loads_flag: if True, get properties about internal loads, otherwise False. The following files are created by this script, depending on which flags were set: - building_HVAC: .dbf describes the queried properties of HVAC systems. - architecture.dbf describes the queried properties of architectural features - building_thermal: .shp describes the queried thermal properties of buildings - indoor_comfort.shp describes the queried thermal properties of buildings """ # get occupancy and age files building_occupancy_df = dbf_to_dataframe(locator.get_building_occupancy()) list_uses = list(building_occupancy_df.drop(['PFloor', 'Name'], axis=1).columns) # parking excluded in U-Values building_age_df = dbf_to_dataframe(locator.get_building_age()) # get occupant densities from archetypes schedules occupant_densities = {} for use in list_uses: archetypes_schedules = pd.read_excel(locator.get_archetypes_schedules(), use).T area_per_occupant = archetypes_schedules['density'].values[:1][0] if area_per_occupant > 0: occupant_densities[use] = 1 / area_per_occupant else: occupant_densities[use] = 0 # prepare shapefile to store results (a shapefile with only names of buildings names_df = building_age_df[['Name']] # define main use: building_occupancy_df['mainuse'] = calc_mainuse(building_occupancy_df, list_uses) # dataframe with jonned data for categories categories_df = building_occupancy_df.merge(building_age_df, on='Name') # get properties about the construction and architecture if prop_architecture_flag: architecture_DB = get_database(locator.get_archetypes_properties(), 'ARCHITECTURE') architecture_DB['Code'] = architecture_DB.apply(lambda x: calc_code(x['building_use'], x['year_start'], x['year_end'], x['standard']), axis=1) categories_df['cat_built'] = calc_category(architecture_DB, categories_df, 'built', 'C') retrofit_category = ['envelope', 'roof', 'windows'] for category in retrofit_category: categories_df['cat_'+category] = calc_category(architecture_DB, categories_df, category, 'R') prop_architecture_df = get_prop_architecture(categories_df, architecture_DB, list_uses) # write to shapefile prop_architecture_df_merged = names_df.merge(prop_architecture_df, on="Name") fields = ['Name', 'Hs', 'wwr_north', 'wwr_west','wwr_east', 'wwr_south', 'type_cons', 'type_leak', 'type_roof', 'type_wall', 'type_win', 'type_shade'] dataframe_to_dbf(prop_architecture_df_merged[fields], locator.get_building_architecture()) # get properties about types of HVAC systems if prop_hvac_flag: HVAC_DB = get_database(locator.get_archetypes_properties(), 'HVAC') HVAC_DB['Code'] = HVAC_DB.apply(lambda x: calc_code(x['building_use'], x['year_start'], x['year_end'], x['standard']), axis=1) categories_df['cat_HVAC'] = calc_category(HVAC_DB, categories_df, 'HVAC', 'R') # define HVAC systems types prop_HVAC_df = categories_df.merge(HVAC_DB, left_on='cat_HVAC', right_on='Code') # write to shapefile prop_HVAC_df_merged = names_df.merge(prop_HVAC_df, on="Name") fields = ['Name', 'type_cs', 'type_hs', 'type_dhw', 'type_ctrl', 'type_vent'] dataframe_to_dbf(prop_HVAC_df_merged[fields], locator.get_building_hvac()) if prop_comfort_flag: comfort_DB = get_database(locator.get_archetypes_properties(), 'INDOOR_COMFORT') # define comfort prop_comfort_df = categories_df.merge(comfort_DB, left_on='mainuse', right_on='Code') # write to shapefile prop_comfort_df_merged = names_df.merge(prop_comfort_df, on="Name") prop_comfort_df_merged = calculate_average_multiuse(prop_comfort_df_merged, occupant_densities, list_uses, comfort_DB) fields = ['Name', 'Tcs_set_C', 'Ths_set_C', 'Tcs_setb_C', 'Ths_setb_C', 'Ve_lps'] dataframe_to_dbf(prop_comfort_df_merged[fields], locator.get_building_comfort()) if prop_internal_loads_flag: internal_DB = get_database(locator.get_archetypes_properties(), 'INTERNAL_LOADS') # define comfort prop_internal_df = categories_df.merge(internal_DB, left_on='mainuse', right_on='Code') # write to shapefile prop_internal_df_merged = names_df.merge(prop_internal_df, on="Name") prop_internal_df_merged = calculate_average_multiuse(prop_internal_df_merged, occupant_densities, list_uses, internal_DB) fields = ['Name', 'Qs_Wp', 'X_ghp', 'Ea_Wm2', 'El_Wm2', 'Epro_Wm2', 'Ere_Wm2', 'Ed_Wm2', 'Vww_lpd', 'Vw_lpd', 'Qhpro_Wm2'] dataframe_to_dbf(prop_internal_df_merged[fields], locator.get_building_internal())
def lca_embodied(year_to_calculate, locator, gv): """ Algorithm to calculate the embodied emissions and non-renewable primary energy of buildings according to the method of [Fonseca et al., 2015] and [Thoma et al., 2014]. The calculation method assumes a 60 year payoff for the embodied energy and emissions of a building, after which both values become zero. The results are provided in total as well as per square meter: - embodied non-renewable primary energy: E_nre_pen_GJ and E_nre_pen_MJm2 - embodied greenhouse gas emissions: E_ghg_ton and E_ghg_kgm2 As part of the algorithm, the following files are read from InputLocator: - architecture.shp: shapefile with the architecture of each building locator.get_building_architecture() - occupancy.shp: shapefile with the occupancy types of each building locator.get_building_occupancy() - age.shp: shapefile with the age and retrofit date of each building locator.get_building_age() - zone.shp: shapefile with the geometry of each building in the zone of study locator.get_zone_geometry() - Archetypes_properties: csv file with the database of archetypes including embodied energy and emissions locator.get_archetypes_properties() As a result, the following file is created: - Total_LCA_embodied: .csv csv file of yearly primary energy and grey emissions per building stored in locator.get_lca_embodied() :param year_to_calculate: year between 1900 and 2100 indicating when embodied energy is evaluated to account for emissions already offset from building construction and retrofits more than 60 years ago. :type year_to_calculate: int :param locator: an instance of InputLocator set to the scenario :type locator: InputLocator :returns: This function does not return anything :rtype: NoneType .. [Fonseca et al., 2015] Fonseca et al. (2015) "Assessing the environmental impact of future urban developments at neighborhood scale." CISBAT 2015. .. [Thoma et al., 2014] Thoma et al. (2014). "Estimation of base-values for grey energy, primary energy, global warming potential (GWP 100A) and Umweltbelastungspunkte (UBP 2006) for Swiss constructions from before 1920 until today." CUI 2014. Files read / written from InputLocator: get_building_architecture get_building_occupancy get_building_age get_zone_geometry get_archetypes_embodied_energy get_archetypes_embodied_emissions path_LCA_embodied_energy: path to database of archetypes embodied energy file Archetypes_embodied_energy.csv path_LCA_embodied_emissions: path to database of archetypes grey emissions file Archetypes_embodied_emissions.csv path_age_shp: string path to building_age.shp path_occupancy_shp: path to building_occupancyshp path_geometry_shp: path to building_geometrys.hp path_architecture_shp: path to building_architecture.shp path_results : string path to demand results folder emissions """ # local variables architecture_df = dbf_to_dataframe(locator.get_building_architecture()) prop_occupancy_df = dbf_to_dataframe(locator.get_building_occupancy()) occupancy_df = pd.DataFrame(prop_occupancy_df.loc[:, (prop_occupancy_df != 0).any(axis=0)]) age_df = dbf_to_dataframe(locator.get_building_age()) geometry_df = Gdf.from_file(locator.get_zone_geometry()) geometry_df['footprint'] = geometry_df.area geometry_df['perimeter'] = geometry_df.length geometry_df = geometry_df.drop('geometry', axis=1) # get list of uses list_uses = list(occupancy_df.drop({'PFloor', 'Name'}, axis=1).columns) # define main use: occupancy_df['mainuse'] = calc_mainuse(occupancy_df, list_uses) # DataFrame with joined data for all categories cat_df = occupancy_df.merge(age_df, on='Name').merge(geometry_df, on='Name').merge(architecture_df, on='Name') # calculate building geometry ## total window area average_wwr = [np.mean([a,b,c,d]) for a,b,c,d in zip(cat_df['wwr_south'],cat_df['wwr_north'],cat_df['wwr_west'],cat_df['wwr_east'])] cat_df['windows_ag'] = average_wwr * cat_df['perimeter'] * (cat_df['height_ag'] * cat_df['PFloor']) ## wall area above ground cat_df['area_walls_ext_ag'] = cat_df['perimeter'] * (cat_df['height_ag'] * cat_df['PFloor']) - cat_df['windows_ag'] ## wall area below ground cat_df['area_walls_ext_bg'] = cat_df['perimeter'] * cat_df['height_bg'] ## floor area above ground cat_df['floor_area_ag'] = cat_df['footprint'] * cat_df['floors_ag'] ## floor area below ground cat_df['floor_area_bg'] = cat_df['footprint'] * cat_df['floors_bg'] ## total floor area cat_df['total_area'] = cat_df['floor_area_ag'] + cat_df['floor_area_bg'] # get categories for each year of construction/retrofit ## each building component gets categorized according to its occupancy type, construction year and retrofit year ## e.g., for an office building built in 1975, cat_df['cat_built'] = 'OFFICE3' ## e.g., for an office building with windows renovated in 1975, cat_df['cat_windows'] = 'OFFICE9' # calculate contributions to embodied energy and emissions ## calculated by multiplying the area of the given component by the energy and emissions per square meter for the ## given category according to the data in the archetype database result_energy = calculate_contributions('EMBODIED_ENERGY', cat_df, gv, locator, year_to_calculate, total_column='GEN_GJ', specific_column='GEN_MJm2') result_emissions = calculate_contributions('EMBODIED_EMISSIONS', cat_df, gv, locator, year_to_calculate, total_column='CO2_ton', specific_column='CO2_kgm2') # export the results for embodied emissions (E_ghg_) and non-renewable primary energy (E_nre_pen_) for each # building, both total (in t CO2-eq. and GJ) and per square meter (in kg CO2-eq./m2 and MJ/m2) fields_to_plot = ['Name', 'GFA_m2', 'E_nre_pen_GJ', 'E_nre_pen_MJm2', 'E_ghg_ton', 'E_ghg_kgm2'] pd.DataFrame( {'Name': result_energy.Name, 'E_nre_pen_GJ': result_energy.GEN_GJ, 'E_nre_pen_MJm2': result_energy.GEN_MJm2, 'E_ghg_ton': result_emissions.CO2_ton, 'E_ghg_kgm2': result_emissions.CO2_kgm2, 'GFA_m2': result_energy.total_area}).to_csv(locator.get_lca_embodied(), columns=fields_to_plot, index=False, float_format='%.2f') print('done!')