Source code for raytraverse.sampler.samplerpt

# -*- coding: utf-8 -*-
# Copyright (c) 2020 Stephen Wasilewski, HSLU and EPFL
# =======================================================================
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# =======================================================================
import numpy as np

from raytools import translate, io
from raytraverse.sampler.basesampler import BaseSampler
from raytraverse.lightpoint import LightPointKD
from raytraverse.mapper import ViewMapper


[docs] class SamplerPt(BaseSampler): """wavelet based sampling class for direction rays from a point Parameters ---------- scene: raytraverse.scene.Scene scene class containing geometry and formatter compatible with engine engine: raytraverse.renderer.Renderer should inherit from raytraverse.renderer.Renderer idres: int, optional initial direction resolution (as sqrt of samples per hemisphere) nlev: int, optional number of levels to sample (eeach lvl doubles idres) accuracy: float, optional parameter to set threshold at sampling level relative to final level threshold (smaller number will increase sampling, default is 1.0) srcn: int, optional number of sources return per vector by run stype: str, optional sampler type (prefixes output files) srcdef: str, optional path or string with source definition to add to scene plotp: bool, optional show probability distribution plots at each level (first point only) features: int, optional number of values evaluated for detail engine_args: str, optional command line arguments used to initialize engine nproc: int, optional number of processors to give to the engine, if None, uses os.cpu_count() """ _includeorigin = True def __init__(self, scene, engine, idres=32, nlev=5, accuracy=1.0, srcn=1, stype='generic', features=1, samplerlevel=0, **kwargs): #: int: number of sources return per vector by run self.srcn = srcn #: int: initial direction resolution (as sqrt of samples per hemisphere #: (or view angle) self.idres = idres self.nlev = nlev super().__init__(scene, engine, accuracy=accuracy, stype=stype, samplerlevel=samplerlevel, features=features, **kwargs)
[docs] def sampling_scheme(self, a): """calculate sampling scheme""" return np.array([(self.idres*2**i*a, self.idres*2**i) for i in range(self.nlev)])
[docs] def run(self, point, posidx, mapper=None, lpargs=None, **kwargs): """sample a single point, position index handles file naming Parameters ---------- point: np.array point to sample posidx: int position index mapper: raytraverse.mapper.ViewMapper view direction to sample lpargs: dict, optional keyword arguments forwarded to LightPointKD construction kwargs: passed to BaseSampler.run() Returns ------- LightPointKD """ if lpargs is None: lpargs = {} if mapper is None: mapper = ViewMapper() point = np.asarray(point).flatten()[0:3] mapper.origin = point name = f"{mapper.name}_{posidx:06d}" levels = self.sampling_scheme(mapper.aspect) super().run(mapper, name, levels, **kwargs) return self._run_callback(point, posidx, mapper, **lpargs)
[docs] def repeat(self, guide, stype): ostype = self.stype self.stype = stype mapper = guide.vm mapper.origin = guide.pt self.vecs = None self.lum = [] gvecs = guide.vec vecs = np.hstack((np.broadcast_to(mapper.origin, gvecs.shape), gvecs)) self.sample(vecs) lp = self._run_callback(guide.pt, guide.posidx, mapper, parent=guide.parent) self.stype = ostype return lp
def _run_callback(self, point, posidx, vm, write=True, **kwargs): """handle class specific lightpointKD construction""" lightpoint = LightPointKD(self.scene, self.vecs, self.lum, src=self.stype, pt=point, write=write, srcn=self.srcn, posidx=posidx, vm=vm, features=self.engine.features, **kwargs) return lightpoint @staticmethod def _plot_dist(ps, vm, outf, fisheye=True): outshape = (512*vm.aspect, 512) res = outshape[-1] if fisheye: pixelxyz = vm.pixelrays(res) uv = vm.xyz2uv(pixelxyz.reshape(-1, 3)) pdirs = np.concatenate((pixelxyz[0:res], -pixelxyz[res:]), 0) mask = vm.in_view(pdirs, indices=False).reshape(outshape) ij = translate.uv2ij(uv, ps.shape[-1], aspect=vm.aspect) img = ps[ij[:, 0], ij[:, 1]].reshape(outshape) io.array2hdr(np.where(mask, img, 0), outf) else: detail = translate.resample(ps, outshape, radius=0, gauss=False) io.array2hdr(detail, outf) def _plot_p(self, p, level, vm, name, suffix=".hdr", fisheye=True): ps = p.reshape(self.weights.shape[-2:]) outp = (f"{self.scene.outdir}_{name}_{self.stype}_detail_" f"{level:02d}{suffix}") self._plot_dist(ps, vm, outp, fisheye) def _plot_weights(self, level, vm, name, suffix=".hdr", fisheye=True): outw = (f"{self.scene.outdir}_{name}_{self.stype}_weights_" f"{level:02d}{suffix}") if self.features > 1: w = np.average(self.weights, 0) else: w = self.weights self._plot_dist(w, vm, outw, fisheye) def _plot_vecs(self, vecs, level, vm, name, suffix=".hdr", fisheye=True): outshape = (512*vm.aspect, 512) outf = (f"{self.scene.outdir}_{name}_{self.stype}_samples_" f"{level:02d}{suffix}") img = np.zeros(outshape) img = vm.add_vecs_to_img(img, vecs[:, 3:], channels=level+1, grow=1, fisheye=fisheye) io.array2hdr(img, outf)