fix: first stages of report creation are started
This commit is contained in:
parent
58201afda8
commit
7369bc65a4
2
main.py
2
main.py
|
@ -65,4 +65,4 @@ for building in city.buildings:
|
|||
costs.loc['global_capital_costs', f'Scenario {SYSTEM_RETROFIT}'].to_csv(
|
||||
output_path / f'{building.name}_cc.csv')
|
||||
costs.loc['global_maintenance_costs', f'Scenario {SYSTEM_RETROFIT}'].to_csv(
|
||||
output_path / f'{building.name}_m.csv')
|
||||
output_path / f'{building.name}_m.csv')
|
||||
|
|
41
report_test.py
Normal file
41
report_test.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
from pathlib import Path
|
||||
import subprocess
|
||||
from scripts.ep_run_enrich import energy_plus_workflow
|
||||
from hub.imports.geometry_factory import GeometryFactory
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction_factory import ConstructionFactory
|
||||
from hub.imports.usage_factory import UsageFactory
|
||||
from hub.imports.weather_factory import WeatherFactory
|
||||
from hub.imports.results_factory import ResultFactory
|
||||
from scripts.energy_system_retrofit_report import EnergySystemRetrofitReport
|
||||
from scripts.geojson_creator import process_geojson
|
||||
from scripts import random_assignation
|
||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||
from scripts.energy_system_sizing import SystemSizing
|
||||
from scripts.energy_system_retrofit_results import system_results, new_system_results
|
||||
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
|
||||
from scripts.costs.cost import Cost
|
||||
from scripts.costs.constants import SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV
|
||||
import hub.helpers.constants as cte
|
||||
from hub.exports.exports_factory import ExportsFactory
|
||||
|
||||
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
|
||||
file_path = (Path(__file__).parent / 'input_files' / 'output_buildings.geojson')
|
||||
output_path = (Path(__file__).parent / 'out_files').resolve()
|
||||
city = GeometryFactory('geojson',
|
||||
path=file_path,
|
||||
height_field='height',
|
||||
year_of_construction_field='year_of_construction',
|
||||
function_field='function',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
ExportsFactory('sra', city, output_path).export()
|
||||
sra_path = (output_path / f'{city.name}_sra.xml').resolve()
|
||||
subprocess.run(['sra', str(sra_path)])
|
||||
ResultFactory('sra', city, output_path).enrich()
|
||||
energy_plus_workflow(city)
|
||||
|
||||
(EnergySystemRetrofitReport(city, output_path, 'PV Implementation and HVAC Retrofit').
|
||||
create_report(current_system=None, new_system=None))
|
196
scripts/energy_system_retrofit_report.py
Normal file
196
scripts/energy_system_retrofit_report.py
Normal file
|
@ -0,0 +1,196 @@
|
|||
import os
|
||||
import hub.helpers.constants as cte
|
||||
import matplotlib.pyplot as plt
|
||||
import random
|
||||
import matplotlib.colors as mcolors
|
||||
from matplotlib import cm
|
||||
from scripts.report_creation import LatexReport
|
||||
import matplotlib as mpl
|
||||
from matplotlib.ticker import MaxNLocator
|
||||
import numpy as np
|
||||
from pathlib import Path
|
||||
|
||||
class EnergySystemRetrofitReport:
|
||||
def __init__(self, city, output_path, retrofit_scenario):
|
||||
self.city = city
|
||||
self.output_path = output_path
|
||||
self.content = []
|
||||
self.report = LatexReport('energy_system_retrofit_report',
|
||||
'Energy System Retrofit Report', retrofit_scenario, output_path)
|
||||
self.charts_path = Path(output_path) / 'charts'
|
||||
self.charts_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def building_energy_info(self):
|
||||
table_data = [
|
||||
["Building Name", "Year of Construction", "function", "Yearly Heating Demand (MWh)",
|
||||
"Yearly Cooling Demand (MWh)", "Yearly DHW Demand (MWh)", "Yearly Electricity Demand (MWh)"]
|
||||
]
|
||||
intensity_table_data = [["Building Name", "Total Floor Area m2", "Heating Demand Intensity kWh/m2",
|
||||
"Cooling Demand Intensity kWh/m2", "Electricity Intensity kWh/m2"]]
|
||||
|
||||
for building in self.city.buildings:
|
||||
total_floor_area = 0
|
||||
for zone in building.thermal_zones_from_internal_zones:
|
||||
total_floor_area += zone.total_floor_area
|
||||
building_data = [
|
||||
building.name,
|
||||
str(building.year_of_construction),
|
||||
building.function,
|
||||
str(format(building.heating_demand[cte.YEAR][0] / 3.6e9, '.2f')),
|
||||
str(format(building.cooling_demand[cte.YEAR][0] / 3.6e9, '.2f')),
|
||||
str(format(building.domestic_hot_water_heat_demand[cte.YEAR][0] / 3.6e9, '.2f')),
|
||||
str(format(
|
||||
(building.lighting_electrical_demand[cte.YEAR][0] + building.appliances_electrical_demand[cte.YEAR][0])
|
||||
/ 3.6e9, '.2f')),
|
||||
]
|
||||
intensity_data = [
|
||||
building.name,
|
||||
str(format(total_floor_area, '.2f')),
|
||||
str(format(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area), '.2f')),
|
||||
str(format(building.cooling_demand[cte.YEAR][0] / (3.6e6 * total_floor_area), '.2f')),
|
||||
str(format(
|
||||
(building.lighting_electrical_demand[cte.YEAR][0] + building.appliances_electrical_demand[cte.YEAR][0]) /
|
||||
(3.6e6 * total_floor_area), '.2f'))
|
||||
]
|
||||
table_data.append(building_data)
|
||||
intensity_table_data.append(intensity_data)
|
||||
|
||||
self.report.add_table(table_data, caption='Buildings Energy Consumption Data')
|
||||
self.report.add_table(intensity_table_data, caption='Buildings Energy Use Intensity Data')
|
||||
|
||||
def monthly_demands(self):
|
||||
heating = []
|
||||
cooling = []
|
||||
dhw = []
|
||||
lighting_appliance = []
|
||||
for i in range(12):
|
||||
heating_demand = 0
|
||||
cooling_demand = 0
|
||||
dhw_demand = 0
|
||||
lighting_appliance_demand = 0
|
||||
for building in self.city.buildings:
|
||||
heating_demand += building.heating_demand[cte.MONTH][i] / 3.6e6
|
||||
cooling_demand += building.cooling_demand[cte.MONTH][i] / 3.6e6
|
||||
dhw_demand += building.domestic_hot_water_heat_demand[cte.MONTH][i] / 3.6e6
|
||||
lighting_appliance_demand += building.lighting_electrical_demand[cte.MONTH][i] / 3.6e6
|
||||
heating.append(heating_demand)
|
||||
cooling.append(cooling_demand)
|
||||
dhw.append(dhw_demand)
|
||||
lighting_appliance.append(lighting_appliance_demand)
|
||||
|
||||
monthly_demands = {'heating': heating,
|
||||
'cooling': cooling,
|
||||
'dhw': dhw,
|
||||
'lighting_appliance': lighting_appliance}
|
||||
return monthly_demands
|
||||
|
||||
def plot_monthly_energy_demands(self, demands, file_name):
|
||||
# Data preparation
|
||||
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
heating = demands['heating']
|
||||
cooling = demands['cooling']
|
||||
dhw = demands['dhw']
|
||||
electricity = demands['lighting_appliance']
|
||||
|
||||
# Plotting
|
||||
fig, axs = plt.subplots(2, 2, figsize=(15, 10), dpi=96)
|
||||
fig.suptitle('Monthly Energy Demands', fontsize=16, weight='bold', alpha=.8)
|
||||
|
||||
# Heating bar chart
|
||||
axs[0, 0].bar(months, heating, color='#2196f3', width=0.6, zorder=2)
|
||||
axs[0, 0].grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[0, 0].grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[0, 0].set_xlabel('Month', fontsize=12, labelpad=10)
|
||||
axs[0, 0].set_ylabel('Heating Demand (kWh)', fontsize=12, labelpad=10)
|
||||
axs[0, 0].set_title('Monthly Heating Demands', fontsize=14, weight='bold', alpha=.8)
|
||||
axs[0, 0].xaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[0, 0].yaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[0, 0].set_xticks(np.arange(len(months)))
|
||||
axs[0, 0].set_xticklabels(months, rotation=45, ha='right')
|
||||
axs[0, 0].bar_label(axs[0, 0].containers[0], padding=3, color='black', fontsize=8)
|
||||
axs[0, 0].spines[['top', 'left', 'bottom']].set_visible(False)
|
||||
axs[0, 0].spines['right'].set_linewidth(1.1)
|
||||
average_heating = np.mean(heating)
|
||||
axs[0, 0].axhline(y=average_heating, color='grey', linewidth=2, linestyle='--')
|
||||
axs[0, 0].text(len(months)-1, average_heating, f'Average = {average_heating:.1f} kWh', ha='right', va='bottom', color='grey')
|
||||
|
||||
# Cooling bar chart
|
||||
axs[0, 1].bar(months, cooling, color='#ff5a5f', width=0.6, zorder=2)
|
||||
axs[0, 1].grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[0, 1].grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[0, 1].set_xlabel('Month', fontsize=12, labelpad=10)
|
||||
axs[0, 1].set_ylabel('Cooling Demand (kWh)', fontsize=12, labelpad=10)
|
||||
axs[0, 1].set_title('Monthly Cooling Demands', fontsize=14, weight='bold', alpha=.8)
|
||||
axs[0, 1].xaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[0, 1].yaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[0, 1].set_xticks(np.arange(len(months)))
|
||||
axs[0, 1].set_xticklabels(months, rotation=45, ha='right')
|
||||
axs[0, 1].bar_label(axs[0, 1].containers[0], padding=3, color='black', fontsize=8)
|
||||
axs[0, 1].spines[['top', 'left', 'bottom']].set_visible(False)
|
||||
axs[0, 1].spines['right'].set_linewidth(1.1)
|
||||
average_cooling = np.mean(cooling)
|
||||
axs[0, 1].axhline(y=average_cooling, color='grey', linewidth=2, linestyle='--')
|
||||
axs[0, 1].text(len(months)-1, average_cooling, f'Average = {average_cooling:.1f} kWh', ha='right', va='bottom', color='grey')
|
||||
|
||||
# DHW bar chart
|
||||
axs[1, 0].bar(months, dhw, color='#4caf50', width=0.6, zorder=2)
|
||||
axs[1, 0].grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[1, 0].grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[1, 0].set_xlabel('Month', fontsize=12, labelpad=10)
|
||||
axs[1, 0].set_ylabel('DHW Demand (kWh)', fontsize=12, labelpad=10)
|
||||
axs[1, 0].set_title('Monthly DHW Demands', fontsize=14, weight='bold', alpha=.8)
|
||||
axs[1, 0].xaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[1, 0].yaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[1, 0].set_xticks(np.arange(len(months)))
|
||||
axs[1, 0].set_xticklabels(months, rotation=45, ha='right')
|
||||
axs[1, 0].bar_label(axs[1, 0].containers[0], padding=3, color='black', fontsize=8)
|
||||
axs[1, 0].spines[['top', 'left', 'bottom']].set_visible(False)
|
||||
axs[1, 0].spines['right'].set_linewidth(1.1)
|
||||
average_dhw = np.mean(dhw)
|
||||
axs[1, 0].axhline(y=average_dhw, color='grey', linewidth=2, linestyle='--')
|
||||
axs[1, 0].text(len(months)-1, average_dhw, f'Average = {average_dhw:.1f} kWh', ha='right', va='bottom', color='grey')
|
||||
|
||||
# Electricity bar chart
|
||||
axs[1, 1].bar(months, electricity, color='#ffc107', width=0.6, zorder=2)
|
||||
axs[1, 1].grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[1, 1].grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
|
||||
axs[1, 1].set_xlabel('Month', fontsize=12, labelpad=10)
|
||||
axs[1, 1].set_ylabel('Electricity Demand (kWh)', fontsize=12, labelpad=10)
|
||||
axs[1, 1].set_title('Monthly Electricity Demands', fontsize=14, weight='bold', alpha=.8)
|
||||
axs[1, 1].xaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[1, 1].yaxis.set_major_locator(MaxNLocator(integer=True))
|
||||
axs[1, 1].set_xticks(np.arange(len(months)))
|
||||
axs[1, 1].set_xticklabels(months, rotation=45, ha='right')
|
||||
axs[1, 1].bar_label(axs[1, 1].containers[0], padding=3, color='black', fontsize=8)
|
||||
axs[1, 1].spines[['top', 'left', 'bottom']].set_visible(False)
|
||||
axs[1, 1].spines['right'].set_linewidth(1.1)
|
||||
average_electricity = np.mean(electricity)
|
||||
axs[1, 1].axhline(y=average_electricity, color='grey', linewidth=2, linestyle='--')
|
||||
axs[1, 1].text(len(months)-1, average_electricity * 0.95, f'Average = {average_electricity:.1f} kWh', ha='right', va='top', color='grey')
|
||||
|
||||
# Set a white background
|
||||
fig.patch.set_facecolor('white')
|
||||
|
||||
# Adjust the margins around the plot area
|
||||
plt.subplots_adjust(left=0.05, right=0.95, top=0.9, bottom=0.1, wspace=0.3, hspace=0.5)
|
||||
|
||||
|
||||
# Save the plot
|
||||
chart_path = self.charts_path / f'{file_name}.png'
|
||||
plt.savefig(chart_path, bbox_inches='tight')
|
||||
plt.close()
|
||||
|
||||
return chart_path
|
||||
|
||||
def create_report(self, current_system, new_system):
|
||||
os.chdir(self.charts_path)
|
||||
self.report.add_section('Current Status')
|
||||
self.report.add_subsection('City Buildings Characteristics')
|
||||
self.building_energy_info()
|
||||
monthly_demands = self.monthly_demands()
|
||||
monthly_demands_path = str(Path(self.charts_path / 'monthly_demands.png'))
|
||||
self.plot_monthly_energy_demands(demands=monthly_demands,
|
||||
file_name='monthly_demands')
|
||||
self.report.add_image('monthly_demands.png', 'Total Monthly Energy Demands in City' )
|
||||
self.report.save_report()
|
||||
self.report.compile_to_pdf()
|
|
@ -1,38 +1,50 @@
|
|||
import subprocess
|
||||
import datetime
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class LatexReport:
|
||||
def __init__(self, file_name):
|
||||
self.file_name = file_name
|
||||
self.content = []
|
||||
self.content.append(r'\documentclass{article}')
|
||||
self.content.append(r'\usepackage[margin=2.5cm]{geometry}') # Adjust page margins
|
||||
self.content.append(r'\usepackage{graphicx}')
|
||||
self.content.append(r'\usepackage{tabularx}')
|
||||
self.content.append(r'\begin{document}')
|
||||
# Get current date and time
|
||||
current_datetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.content.append(r'\title{Energy System Analysis Report - ' + current_datetime + r'}')
|
||||
self.content.append(r'\author{Next-Generation Cities Institute}')
|
||||
self.content.append(r'\date{}') # Remove the date field, as it's included in the title now
|
||||
self.content.append(r'\maketitle')
|
||||
def __init__(self, file_name, title, subtitle, output_path):
|
||||
self.file_name = file_name
|
||||
self.output_path = Path(output_path) / 'report'
|
||||
self.output_path.mkdir(parents=True, exist_ok=True)
|
||||
self.file_path = self.output_path / f"{file_name}.tex"
|
||||
self.content = []
|
||||
self.content.append(r'\documentclass{article}')
|
||||
self.content.append(r'\usepackage[margin=2.5cm]{geometry}')
|
||||
self.content.append(r'\usepackage{graphicx}')
|
||||
self.content.append(r'\usepackage{tabularx}')
|
||||
self.content.append(r'\begin{document}')
|
||||
|
||||
current_datetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
self.content.append(r'\title{' + title + '}')
|
||||
self.content.append(r'\author{Next-Generation Cities Institute}')
|
||||
self.content.append(r'\date{}')
|
||||
self.content.append(r'\maketitle')
|
||||
|
||||
self.content.append(r'\begin{center}')
|
||||
self.content.append(r'\large ' + subtitle + r'\\')
|
||||
self.content.append(r'\large ' + current_datetime)
|
||||
self.content.append(r'\end{center}')
|
||||
|
||||
def add_section(self, section_title):
|
||||
self.content.append(r'\section{' + section_title + r'}')
|
||||
self.content.append(r'\section{' + section_title + r'}')
|
||||
|
||||
def add_subsection(self, subsection_title):
|
||||
self.content.append(r'\subsection{' + subsection_title + r'}')
|
||||
self.content.append(r'\subsection{' + subsection_title + r'}')
|
||||
|
||||
def add_text(self, text):
|
||||
self.content.append(text)
|
||||
self.content.append(text)
|
||||
|
||||
def add_table(self, table_data, caption=None, first_column_width=None):
|
||||
num_columns = len(table_data[0])
|
||||
total_width = 0.9 # Default total width
|
||||
total_width = 0.9
|
||||
|
||||
if first_column_width is not None:
|
||||
first_column_width_str = str(first_column_width) + 'cm'
|
||||
total_width -= first_column_width / 16.0 # Adjust total width for the first column
|
||||
total_width -= first_column_width / 16.0
|
||||
|
||||
if caption:
|
||||
self.content.append(r'\begin{table}[htbp]')
|
||||
|
@ -55,19 +67,20 @@ class LatexReport:
|
|||
if caption:
|
||||
self.content.append(r'\begin{figure}[htbp]')
|
||||
self.content.append(r'\centering')
|
||||
self.content.append(r'\includegraphics[width=0.8\textwidth]{' + image_path + r'}')
|
||||
self.content.append(r'\includegraphics[width=\textwidth]{' + image_path + r'}')
|
||||
self.content.append(r'\caption{' + caption + r'}')
|
||||
self.content.append(r'\end{figure}')
|
||||
else:
|
||||
self.content.append(r'\begin{figure}[htbp]')
|
||||
self.content.append(r'\centering')
|
||||
self.content.append(r'\includegraphics[width=0.8\textwidth]{' + image_path + r'}')
|
||||
self.content.append(r'\includegraphics[width=\textwidth]{' + image_path + r'}')
|
||||
self.content.append(r'\end{figure}')
|
||||
|
||||
def save_report(self):
|
||||
self.content.append(r'\end{document}') # Add this line to close the document
|
||||
with open(self.file_name, 'w') as f:
|
||||
self.content.append(r'\end{document}')
|
||||
with open(self.file_path, 'w') as f:
|
||||
f.write('\n'.join(self.content))
|
||||
|
||||
def compile_to_pdf(self):
|
||||
subprocess.run(['pdflatex', self.file_name])
|
||||
subprocess.run(['pdflatex', '-output-directory', str(self.output_path), str(self.file_path)])
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user