fix: first stages of report creation are started

This commit is contained in:
Saeed Ranjbar 2024-06-28 16:40:37 -04:00
parent 58201afda8
commit 7369bc65a4
4 changed files with 275 additions and 25 deletions

View File

@ -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
View 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))

View 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()

View File

@ -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)])