def get_wea(config, window_normals=None): """Obtain and prepare weather file data.""" if config.wea_path != '': logger.info('Using user specified .wea file.') wea_path = os.path.join(config.rsodir, config.wea_path) with open(wea_path) as rdr: raw = rdr.read() sec = raw.split('\n\n') lines = [line.split() for line in sec[1].splitlines()] datetime_stamps = [ "%02d%02d_%02d%02d" % (int(line[0]), int( line[1]), int(float(line[2])), 60 * float(line[2]) % 1) for line in lines ] else: if config.zipcode != '': logger.info('Downloading EPW file using zipcode.') epw = makesky.getEPW.from_zip(config.zipcode) elif '' not in (config.latitude, config.longitude): logger.info('Downloading EPW file using lat&lon.') epw = makesky.getEPW(config.latitude, config.longitude) else: raise NameError("Not site info defined") logger.info("Downloaded: %s", epw.fname) epw_path = os.path.join(config.rsodir, epw.fname) try: os.rename(epw.fname, epw_path) except FileExistsError as fee: logger.info(fee) logger.info('Converting EPW to a .wea file') if window_normals is None: remove_zero = False wea_name = util.basename(epw.fname) + '.wea' else: remove_zero = True wea_name = util.basename(epw.fname) + '_d6.wea' shour = None if config.start_hour == '' else float(config.start_hour) ehour = None if config.end_hour == '' else float(config.end_hour) wea_metadata, wea_data = makesky.epw2wea( epw_path, dhour=config.daylight_hours_only, shour=shour, ehour=ehour, remove_zero=remove_zero, window_normal=window_normals) wea_path = os.path.join(config.rsodir, wea_name) with open(wea_path, 'w') as wtr: wtr.write(wea_metadata.wea_header()) wtr.write('\n'.join(map(str, wea_data))) datetime_stamps = [row.dt_string() for row in wea_data] return wea_path, datetime_stamps
def pcomb(inputs): """Image operations with pcomb. Parameter: inputs, e.g: ['img1.hdr', '+', img2.hdr', '-', 'img3.hdr', 'output.hdr'] """ input_list = inputs[:-1] out_dir = inputs[-1] component_idx = range(0, len(input_list), 2) components = [input_list[i] for i in component_idx] color_op_list = [] for c in 'rgb': color_op = input_list[:] for i in component_idx: color_op[i] = '%si(%d)' % (c, i / 2 + 1) cstr = '%so=%s' % (c, ''.join(color_op)) color_op_list.append(cstr) rgb_str = ';'.join(color_op_list) cmd = ['pcomb', '-e', '%s' % rgb_str] img_name = util.basename(input_list[0], keep_ext=True) for c in components: cmd.append('-o') cmd.append(c) res = util.spcheckout(cmd) with open(os.path.join(out_dir, img_name), 'wb') as wtr: wtr.write(res)
def run(args: argparse.Namespace) -> None: """Call mtxmethod to carry out the actual simulation.""" cfg = ConfigParser(allow_no_value=True, inline_comment_prefixes='#') with open(args.cfg) as rdr: cfg.read_string(rdr.read()) config = convert_config(cfg) config.name = util.basename(args.cfg) mkdirs(config) model = mtxmethod.assemble_model(config) if config.method != '': _method = getattr(mtxmethod, config.method) _method(model, config, direct=config.separate_direct) else: if '' in (config.window_xml, config.windows): logger.info("Using two-phase method") mtxmethod.two_phase(model, config) else: if config.ncp_shade != '' and len(config.ncp_shade.split()) > 1: if config.separate_direct: logger.info('Using six-phase simulation') mtxmethod.four_phase(model, config, direct=True) else: logger.info('Using four-phase simulation') mtxmethod.four_phase(model, config) else: if config.separate_direct: logger.info('Using five-phase simulation') mtxmethod.three_phase(model, config, direct=True) else: logger.info('Using three-phase simulation') mtxmethod.three_phase(model, config)
def epw2sunmtx(epw_path: str) -> str: """Generate reinhart 6 sun matrix file from a epw file.""" smx_path = util.basename(epw_path) + ".smx" with tf.NamedTemporaryFile() as wea: cmd = f"epw2wea {epw_path} {wea.name}" sp.call(cmd, shell=True) # large file cmd = f"gendaymtx -od -u -m 6 -d -5 .533 {wea.name} > {smx_path}" sp.call(cmd, shell=True) return smx_path
def dctimestep(input_list): """Image operations in forms of Vs, VDs, VTDs, VDFs, VTDFs.""" inputs = input_list[:-1] out_dir = input_list[-1] inp_dir_count = len(inputs) sky = input_list[-2] img_name = util.basename(sky) out_path = os.path.join(out_dir, img_name) if inputs[1].endswith('.xml') is False\ and inp_dir_count > 2 and os.path.isdir(inputs[0]): combined = "'!rmtxop %s" % (' '.join(inputs[1:-1])) img = [i for i in os.listdir(inputs[0]) if i.endswith('.hdr')][0] str_count = len(img.split('.hdr')[0]) # figure out unix %0d string appendi = r"%0" + "%sd.hdr" % (str_count) new_inp_dir = [os.path.join(inputs[0], appendi), combined] cmd = "dctimestep -oc %s %s' > %s.hdr" \ % (' '.join(new_inp_dir), sky, out_path) else: if not os.path.isdir(inputs[0]) and not inputs[1].endswith('.xml'): combined = os.path.join(os.path.dirname(inputs[0]), "tmp.vfdmtx") stderr = combine_mtx(inputs[:-1], combined) if stderr != "": print(stderr) return inputs_ = [combined] elif inp_dir_count == 5: combined = os.path.join(os.path.dirname(inputs[2]), "tmp.fdmtx") stderr = combine_mtx(inputs[2:4], combined) if stderr != "": print(stderr) return inputs_ = [inputs[0], inputs[1], combined] else: inputs_ = inputs[:-1] if os.path.isdir(inputs[0]): img = [i for i in os.listdir(inputs[0]) if i.endswith('.hdr')][0] str_count = len(img.split('.hdr')[0]) appendi = r"%0" + "%sd.hdr" % (str_count) inputs_[0] = os.path.join(inputs[0], appendi) out_ext = ".hdr" else: out_ext = ".dat" input_string = ' '.join(inputs_) out_path = out_path + out_ext cmd = "dctimestep %s %s > %s" % (input_string, sky, out_path) sp.call(cmd, shell=True)
def assemble_model(config: util.MradConfig) -> Model: """Assemble all the pieces together.""" material_primitives: List[radutil.Primitive] material_primitives = sum( [radutil.unpack_primitives(path) for path in config.material_paths], []) window_groups, _window_normals = get_window_group(config) window_normals = [ item for idx, item in enumerate(_window_normals) if item not in _window_normals[:idx] ] sender_grid = get_sender_grid(config) sender_view, view_dicts = get_sender_view(config) rcvr_sky = radmtx.Receiver.as_sky(basis=config.smx_basis) # Sun CFS _cfs_path = [] for wname, path in config.sun_cfs.items(): ident = util.basename(path) if path.endswith('.xml'): window_primitives = window_groups[wname] upvec = radgeom.Vector(0, 0, 1) bsdf_prim = radutil.bsdf_prim('void', ident, path, upvec, pe=True) if bsdf_prim not in material_primitives: material_primitives.append(bsdf_prim) _tmp_cfs_path = f'tmpcfs{wname}.rad' with open(_tmp_cfs_path, 'w') as wtr: for primitive in window_primitives: new_primitive = radutil.Primitive(ident, primitive.ptype, primitive.identifier, primitive.str_arg, primitive.real_arg) wtr.write(str(new_primitive) + '\n') _cfs_path.append(_tmp_cfs_path) elif path.endswith('.rad'): _cfs_path.append(path) black_mat = radutil.Primitive('void', 'plastic', 'black', '0', '5 0 0 0 0 0') glow_mat = radutil.Primitive('void', 'glow', 'glowing', '0', '4 1 1 1 0') if black_mat not in material_primitives: material_primitives.append(black_mat) if glow_mat not in material_primitives: material_primitives.append(glow_mat) material_path = os.path.join(config.objdir, "all_material.mat") with open(material_path, 'w') as wtr: [wtr.write(str(primitive) + '\n') for primitive in material_primitives] _blackenvpath = os.path.join(config.objdir, 'blackened.rad') with open(_blackenvpath, 'w') as wtr: for path in config.scene_paths: wtr.write(f'\n!xform -m black {path}') return Model(material_path, window_groups, window_normals, sender_grid, sender_view, view_dicts, rcvr_sky, _cfs_path, _blackenvpath)
def facade_matrix(model, config, direct=False): """Generate facade matrices. Args: model (namedtuple): model assembly config (namedtuple): model configuration Returns: facade matrices file path """ logger.info("Computing facade matrix...") fmxs = {} _opt = config.dmx_opt _env = [model.material_path] + config.scene_paths if direct: _opt += ' -ab 0' _env = [model.material_path, model.blackenvpath] ncp_prims = {} for ncppath in config.ncppath: name = util.basename(ncppath) ncp_prims[name] = radutil.unpack_primitives(ncppath) all_ncp_prims = [prim for key, prim in ncp_prims.items()] all_window_prims = [prim for key, prim in model.window_groups.items()] port_prims = mfacade.genport(wpolys=all_window_prims, npolys=all_ncp_prims, depth=None, scale=None) port_rcvr = radmtx.Receiver.as_surface(prim_list=port_prims, basis=config.fmx_basis, out=None) for wname in model.window_groups: _name = wname + '_d' if direct else wname fmxs[wname] = os.path.join(config.mtxdir, f'fmx_{_name}.mtx') window_prim = model.window_groups[wname] sndr_window = radmtx.Sender.as_surface(prim_list=window_prim, basis=config.fmx_basis) if not os.path.isfile(fmxs[wname]) or config.overwrite: logger.info("Generating facade matrix for %s", _name) fmx_res = radmtx.rfluxmtx(sender=sndr_window, receiver=port_rcvr, env=_env, out=None, opt=_opt) with open(fmxs[wname], 'wb') as wtr: wtr.write(fmx_res) return fmxs
def gen_smx(wea_path, mfactor, outdir, onesun=False, direct=False): """Generate sky/sun matrix.""" sun_only = ' -d' if direct else '' _five = ' -5 .533' if onesun else '' oname = util.basename(wea_path) cmd = f"gendaymtx -of -m {mfactor[-1]}{sun_only}{_five}".split() cmd.append(wea_path) logger.info('Generating sku/sun matrix using command') logger.info(' '.join(cmd)) res = util.spcheckout(cmd) if direct: if onesun: smxpath = os.path.join(outdir, oname + '_d6.smx') else: smxpath = os.path.join(outdir, oname + '_d.smx') else: smxpath = os.path.join(outdir, oname + '.smx') with open(smxpath, 'wb') as wtr: wtr.write(res) return smxpath
def main(): parser = ArgumentParser() genfmtx_parser = genfmtx_args(parser) genfmtx_parser.add_argument('-v', '--verbose', action='count', default=0, help='verbose mode') args = genfmtx_parser.parse_args() logger = logging.getLogger('frads') formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler = logging.StreamHandler() _level = args.verbose * 10 logger.setLevel(_level) console_handler.setLevel(_level) console_handler.setFormatter(formatter) logger.addHandler(console_handler) raw_wndw_prims = radutil.unpack_primitives(args.window) ncp_prims = radutil.unpack_primitives(args.ncp) wndw_prims = [p for p in raw_wndw_prims if p.ptype == 'polygon'] port_prims = fcd.genport(wpolys=wndw_prims, npolys=ncp_prims, depth=None, scale=None) wndw_polygon = [ radutil.parse_polygon(p.real_arg) for p in wndw_prims if p.ptype == 'polygon' ] args.env.append(args.ncp) all_prims = [] for env in args.env: all_prims.extend(radutil.unpack_primitives(env)) ncp_mod = [prim.modifier for prim in ncp_prims if prim.ptype == 'polygon'][0] ncp_mat: radutil.Primitive ncp_type: str = '' for prim in all_prims: if prim.identifier == ncp_mod: ncp_mat = prim ncp_type = prim.ptype break if ncp_type == '': raise ValueError("Unknown NCP material") wrap2xml = args.wrap dirname = os.path.dirname(args.o) dirname = '.' if dirname == '' else dirname if args.solar and ncp_type == 'BSDF': logger.info('Computing for solar and visible spectrum...') wrap2xml = False xmlpath = ncp_mat.str_arg.split()[2] td = tf.mkdtemp() with open(xmlpath) as rdr: raw = rdr.read() raw = raw.replace('<Wavelength unit="Integral">Visible</Wavelength>', '<Wavelength unit="Integral">Visible2</Wavelength>') raw = raw.replace('<Wavelength unit="Integral">Solar</Wavelength>', '<Wavelength unit="Integral">Visible</Wavelength>') raw = raw.replace('<Wavelength unit="Integral">Visible2</Wavelength>', '<Wavelength unit="Integral">Solar</Wavelength>') solar_xml_path = os.path.join(td, 'solar.xml') with open(solar_xml_path, 'w') as wtr: wtr.write(raw) _strarg = ncp_mat.str_arg.split() _strarg[2] = solar_xml_path solar_ncp_mat = radutil.Primitive(ncp_mat.modifier, ncp_mat.ptype, ncp_mat.identifier + ".solar", ' '.join(_strarg), '0') _env_path = os.path.join(td, 'env_solar.rad') with open(_env_path, 'w') as wtr: for prim in all_prims: wtr.write(str(prim)) outsolar = os.path.join(dirname, '_solar_' + util.basename(args.o)) process_thread = Thread(target=fcd.Genfmtx, kwargs={ 'win_polygons': wndw_polygon, 'port_prim': port_prims, 'out': outsolar, 'env': [_env_path], 'sbasis': args.ss, 'rbasis': args.rs, 'opt': args.opt, 'refl': args.refl, 'forw': args.forw, 'wrap': wrap2xml }) process_thread.start() #fcd.Genfmtx(win_polygons=wndw_polygon, port_prim=port_prims, out=outsolar, # env=[_env_path], sbasis=args['ss'], rbasis=args['rs'], # opt=args['opt'], refl=args['refl'], forw=args['forw'], wrap=wrap2xml) fcd.Genfmtx(win_polygons=wndw_polygon, port_prim=port_prims, out=args.o, env=args.env, sbasis=args.ss, rbasis=args.rs, opt=args.opt, refl=args.refl, forw=args.forw, wrap=wrap2xml) if args.solar and ncp_type == 'BSDF': process_thread.join() vis_dict = {} sol_dict = {} oname = util.basename(args['o']) mtxs = [ os.path.join(dirname, mtx) for mtx in os.listdir(dirname) if mtx.endswith('.mtx') ] for mtx in mtxs: _direc = util.basename(mtx).split('_')[-1][:2] mtxname = util.basename(mtx) if mtxname.startswith(oname): #vis_dict[_direc] = os.path.join(dirname, f"_vis_{_direc}") vis_dict[_direc] = os.path.join(td, f"vis_{_direc}") out2 = os.path.join(dirname, f"vis_{_direc}") klems_wrap(vis_dict[_direc], out2, mtx, args.ss) if mtxname.startswith('_solar_'): sol_dict[_direc] = os.path.join(td, f"sol_{_direc}") out2 = os.path.join(dirname, f"sol_{_direc}") klems_wrap(sol_dict[_direc], out2, mtx, args.ss) cmd = f"wrapBSDF -a {args.ss} -c -s Visible " cmd += ' '.join([f"-{key} {vis_dict[key]}" for key in vis_dict]) cmd += ' -s Solar ' cmd += ' '.join([f"-{key} {sol_dict[key]}" for key in sol_dict]) cmd += f" > {os.path.join(dirname, oname)}.xml" os.system(cmd) shutil.rmtree(td) [os.remove(mtx) for mtx in mtxs]
def __init__(self, *, win_polygons, port_prim, out, env, sbasis, rbasis, opt, refl, forw, wrap): """Generate the appropriate aperture for F matrix generation. Parameters: win_prim: window geometry primitive; ncs_prim: shading geometry primitive; out_path: output file path depth: distance between the window and the farther point of the shade geometry; scale: scale factor to window geometry so that it encapsulate the projected shadeing geometry onto the window surface; FN: Bool, whether to generate four aperture separately rs: receiver sampling basis; ss: sender sampling basis; refl: Do reflection?; forw: Do forward tracing calculation?; wrap: wrap to .XML file?; **kwargs: other arguments that will be passed to Genmtx; """ self.win_polygon = win_polygons self.port_prim = port_prim self.out = out self.outdir: str = os.path.dirname(out) self.out_name = util.basename(out) self.env = env self.rbasis = rbasis self.sbasis = sbasis self.opt = opt self.refl = refl if wrap == True and rbasis.startswith('sc') and sbasis.startswith('sc'): sc = int(rbasis[2:]) ttlog2 = math.log(sc, 2) assert ttlog2 % int(ttlog2) == 0 self.ttrank = 4 # only anisotropic self.pctcull = 90 self.ttlog2 = int(ttlog2) self.opt += ' -hd -ff' self.td = tf.mkdtemp() src_dict = {} fwrap_dict = {} for idx in range(len(self.win_polygon)): _tf = f'tf{idx}' _rf = f'rf{idx}' _tb = f'tb{idx}' _rb = f'rb{idx}' src_dict[_tb] = os.path.join(self.td, f'{_tb}.dat') fwrap_dict[_tb] = os.path.join(self.td, f'{_tb}p.dat') if forw: src_dict[_tf] = os.path.join(self.td, f'{_tf}.dat') fwrap_dict[_tf] = os.path.join(self.td, f'{_tf}p.dat') if refl: src_dict[_rb] = os.path.join(self.td, f'{_rb}.dat') fwrap_dict[_rb] = os.path.join(self.td, f'{_rb}p.dat') if forw: src_dict[_rf] = os.path.join(self.td, f'{_rf}.dat') fwrap_dict[_rf] = os.path.join(self.td, f'{_rf}p.dat') self.compute_back(src_dict) if forw: self.compute_front(src_dict) self.src_dict = src_dict self.fwrap_dict = fwrap_dict if wrap: self.wrap() else: for key in src_dict: out_name = f"{self.out_name}_{key}.mtx" shutil.move(src_dict[key], os.path.join(self.outdir, out_name)) shutil.rmtree(self.td, ignore_errors=True)