# coding=utf-8
"""Methods for resolving MRT from Radiance and EnergyPlus output files."""
from __future__ import division
from ladybug.sql import SQLiteResult
[docs]def irradiance_contrib_map(
sql, direct_specular, indirect_specular, ref_specular, indirect_diffuse, ref_diffuse,
sun_up_hours, aperture_id=None
):
"""Get matrices of irradiance contribution for a given dynamic aperture.
Args:
result_sql: Path to an SQLite file that was generated by EnergyPlus.
This file must contain results for window transmittance.
direct_specular: Path to an .ill file output by Radiance containing direct
irradiance for the specular version of the aperture group.
indirect_specular: Path to an .ill file output by Radiance containing
the indirect irradiance for the specular version of the aperture group.
ref_specular: Path to an .ill file output by Radiance containing ground-reflected
irradiance for the specular version of the aperture group.
indirect_diffuse: Path to an .ill file output by Radiance containing
the indirect irradiance for the diffuse version of the aperture group.
ref_diffuse: Path to an .ill file output by Radiance containing ground-reflected
irradiance for the diffuse version of the aperture group.
sun_up_hours: Path to a sun-up-hours.txt file output by an annual
irradiance simulation.
aperture_id: Text string for the identifier of the aperture associated with
the irradiance. If unspecified, it will the first aperture found in the
result-sql, essentially assuming there is only one dynamic group in the file.
Returns:
A tuple fo three values.
* direct_mtx -- A matrix with the direct irradiance contribution.
* indirect_mtx -- A matrix with the indirect irradiance contribution.
* ref_mtx - A matrix with the ground-reflected irradiance contribution.
"""
# load the relevant transmittance data from the SQLite
sql_obj = SQLiteResult(sql)
incident_out = 'Surface Outside Face Incident Solar Radiation Rate per Area'
beam_to_beam_out = 'Surface Window Transmitted Beam To Beam Solar Radiation Rate'
beam_to_diff_out = 'Surface Window Transmitted Beam To Diffuse Solar Radiation Rate'
diff_to_diff_out = 'Surface Window Transmitted Diffuse Solar Radiation Rate'
incident_dat = sql_obj.data_collections_by_output_name(incident_out)
beam_to_beam_dat = sql_obj.data_collections_by_output_name(beam_to_beam_out)
beam_to_diff_dat = sql_obj.data_collections_by_output_name(beam_to_diff_out)
diff_to_diff_dat = sql_obj.data_collections_by_output_name(diff_to_diff_out)
# compute beam and diff transmittance for the relevant aperture
incident_per_area = _data_for_surface(incident_dat, aperture_id)
beam_to_beam = _data_for_surface(beam_to_beam_dat, aperture_id)
beam_to_diff = _data_for_surface(beam_to_diff_dat, aperture_id)
diff_to_diff = _data_for_surface(diff_to_diff_dat, aperture_id)
ap_dict = sql_obj.tabular_data_by_name('Exterior Fenestration')
ap_area = ap_dict[aperture_id.upper()][2] if aperture_id is not None \
else ap_dict.values()[0][2]
incident = incident_per_area * ap_area
dts = incident_per_area.datetimes
beam_trans_all, diff_trans_all = {}, {}
all_data = zip(beam_to_beam, beam_to_diff, diff_to_diff, incident, dts)
for bb, bd, dd, inc, dt in all_data:
if inc != 0:
try:
beam_trans_all[dt.int_hoy].append(bb / inc)
diff_trans_all[dt.int_hoy].append((bd + dd) / inc)
except KeyError:
beam_trans_all[dt.int_hoy] = [bb / inc]
diff_trans_all[dt.int_hoy] = [(bd + dd) / inc]
# open the sun-up-hours file and get transmittance for just those hours
with open(sun_up_hours) as soh_f:
sun_indices = [int(float(h)) for h in soh_f]
beam_trans, diff_trans = [], []
for s_ind in sun_indices:
try:
b_trans = sum(beam_trans_all[s_ind]) / len(beam_trans_all[s_ind])
d_trans = sum(diff_trans_all[s_ind]) / len(diff_trans_all[s_ind])
except KeyError: # no incident solar on window for that hour
b_trans = d_trans = 0
beam_trans.append(b_trans)
diff_trans.append(d_trans)
# compute the direct irradiance contribution
direct_mtx = []
for pt_irr in _ill_vals(direct_specular):
direct_mtx.append([irr * bt for irr, bt in zip(pt_irr, beam_trans)])
# compute the indirect irradiance contribution
indirect_mtx = []
for s_irr, d_irr in zip(_ill_vals(indirect_specular), _ill_vals(indirect_diffuse)):
sen_mtx = []
for si, di, bt, dt in zip(s_irr, d_irr, beam_trans, diff_trans):
sen_mtx.append((si * bt) + (di * dt))
indirect_mtx.append(sen_mtx)
# compute the ground-reflected irradiance contribution
ref_mtx = []
for s_irr, d_irr in zip(_ill_vals(ref_specular), _ill_vals(ref_diffuse)):
sen_mtx = []
for si, di, bt, dt in zip(s_irr, d_irr, beam_trans, diff_trans):
sen_mtx.append((si * bt) + (di * dt))
ref_mtx.append(sen_mtx)
return direct_mtx, indirect_mtx, ref_mtx
def _data_for_surface(data_colls, aperture_id):
"""Get a data collection for a specific aperture.
Args:
data_colls: A list of data collections from an SQLite file.
aperture_id: The identifier if an aperture to be selected from the list of
data collections.
Return:
A data collection for the specified aperture_id.
"""
if aperture_id is None:
return data_colls[0]
ap_id = aperture_id.upper()
for dat_c in data_colls:
if dat_c.header.metadata['Surface'] == ap_id:
return dat_c
return data_colls[0]
def _ill_vals(ill_file):
"""Parse an .ill file into a iterator of values.
Args:
ill_file: Path to an .ill file.
Return:
A list of list where each sub-list contains irradiance data.
"""
with open(ill_file) as results:
return [[float(v) for v in pt_res.split()] for pt_res in results]