Source code for pymls.layers.layer

#! /usr/bin/env python
# -*- coding:utf8 -*-
#
# layer.py
#
# This file is part of pymls, a software distributed under the MIT license.
# For any question, please contact one of the authors cited below.
#
# Copyright (c) 2017
# 	Olivier Dazel <olivier.dazel@univ-lemans.fr>
# 	Mathieu Gaborit <gaborit@kth.se>
# 	Peter Göransson <pege@kth.se>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#

import copy


[docs]class Layer(object): def __init__(self, medium, thickness, name="Unnamed Layer"): self.thickness = thickness self.medium = copy.deepcopy(medium) self.name = name self.hooks = { 'pre_update_frequency': [] }
[docs] def update_frequency(self, omega): for f in self.hooks['pre_update_frequency']: f(self) self.medium.update_frequency(omega)
[docs] def register(self, hook_name): if self.hooks.get(hook_name) is None: raise ValueError("Invalid hook name. Use one of : {}".format(','.join(self.hooks.keys()))) def decorator(func): self.hooks[hook_name].append(func) return decorator
def __str__(self): return '{} - {}m of {} ({})'.format( self.name, self.thickness, self.medium.name, self.medium.MEDIUM_TYPE )
[docs]class StochasticLayer(Layer): def __init__(self, medium, thickness, stochastic_param, pdf, name="Unnamed Layer"): """ medium -- medium object thickness -- layer's thickness stochastic_param -- name of the stochastic parameter pdf -- probability density function from which are drawn the random samples name -- optional layer's name Please note that the pdf is a **function handle** that must return a sample per call (and accepts no argument) """ super().__init__(medium, thickness, name) self.stochastic_param = stochastic_param self.pdf = pdf # useful for type lookup and guards self.__medium_params = dict(self.medium.EXPECTED_PARAMS+self.medium.OPT_PARAMS) if self.stochastic_param == 'thickness': setattr(self, 'new_draw', self.__draw_thickness) self.initial_param_value = self.thickness elif self.stochastic_param in self.__medium_params.keys(): self.initial_param_value = getattr(self.medium, self.stochastic_param) setattr(self, 'new_draw', self.__draw_medium_parameter) else: raise ValueError('Unable to draw a parameter undefined in the layer') def __draw_thickness(self): draw = float(self.pdf()) self.thickness = draw return draw def __draw_medium_parameter(self): draw = self.pdf() expected_type = self.__medium_params[self.stochastic_param] if type(draw) == expected_type: setattr(self.medium, self.stochastic_param, draw) self.medium.omega = -1 else: raise TypeError('Draw of type {} but expected type {}'.format( type(draw), expected_type )) return draw
[docs] def reinit(self): if self.stochastic_param == 'thickness': self.thickness = self.initial_param_value else: setattr(self.medium, self.stochastic_param, self.initial_param_value)