{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the BRDF module\n",
"===================="
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this notebook, we demonstrate how to use the pySCATMECH BRDF module. This module defines the class `BRDF_Model`, which provides an interface to SCATMECH's `BRDF_Model`, which in turn, is a base class for representing all models that predict the bidirectional reflectance distribution function (BRDF). \n",
"\n",
"First, we import the necessary libraries. We will be using `matplotlib.pyplot` for graphing."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from pySCATMECH.brdf import *\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's create a `Correlated_Roughness_Stack_BRDF_Model` and print its default parameters."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{None : 'Correlated_Roughness_Stack_BRDF_Model',\n",
"'lambda' : '0.532',\n",
"'substrate' : '(4.05,0.05)',\n",
"'type' : '0',\n",
"'psd' : {None : 'ABC_PSD_Function',\n",
" 'A' : '0.01',\n",
" 'B' : '362',\n",
" 'C' : '2.5'},\n",
"'stack' : 'No_StackModel'}\n"
]
}
],
"source": [
"model = BRDF_Model('Correlated_Roughness_Stack_BRDF_Model')\n",
"print(model)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can create the model with parameters. Notice in the following how we can set parameters that are themselves models."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{None : 'Correlated_Roughness_Stack_BRDF_Model',\n",
"'lambda' : '0.532',\n",
"'substrate' : '(4.05,0.05)',\n",
"'type' : '0',\n",
"'psd' : {None : 'ABC_PSD_Function',\n",
" 'A' : '0.01',\n",
" 'B' : '360',\n",
" 'C' : '2.4'},\n",
"'stack' : {None : 'SingleFilm_StackModel',\n",
" 'material' : '(1.59,0)',\n",
" 'thickness' : '0.05'}}\n"
]
}
],
"source": [
"psd = {None : \"ABC_PSD_Function\",\n",
" \"A\" : 0.01,\n",
" \"B\" : 360,\n",
" \"C\" : 2.4}\n",
"\n",
"stack = {None : 'SingleFilm_StackModel',\n",
" 'material' : 1.59,\n",
" 'thickness': 0.05\n",
" }\n",
"\n",
"parameters = {'lambda' : 0.532,\n",
" 'substrate' : 4.05+0.05j,\n",
" 'type' : 0,\n",
" 'stack' : stack,\n",
" 'psd' : psd}\n",
"\n",
"model = BRDF_Model('Correlated_Roughness_Stack_BRDF_Model',parameters)\n",
"print(model)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can set parameters later using the `setParameters` function."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{None : 'Correlated_Roughness_Stack_BRDF_Model',\n",
"'lambda' : '0.6',\n",
"'substrate' : '(4.05,0.05)',\n",
"'type' : '0',\n",
"'psd' : {None : 'ABC_PSD_Function',\n",
" 'A' : '0.01',\n",
" 'B' : '360',\n",
" 'C' : '2.3'},\n",
"'stack' : {None : 'SingleFilm_StackModel',\n",
" 'material' : '(1.59,0)',\n",
" 'thickness' : '0.1'}}\n"
]
}
],
"source": [
"parameters['lambda'] = 0.600\n",
"psd['C'] = 2.3\n",
"stack['thickness'] = 0.1\n",
"model.setParameters(parameters)\n",
"print(model)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One can use keyword arguments to set parameters, and if the parameters are models, one can set them to models. Note that because `lambda` is a Python keyword, we use `wavelength` in place of the parameter `lambda`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{None : 'Correlated_Roughness_Stack_BRDF_Model',\n",
"'lambda' : '0.6',\n",
"'substrate' : 'silicon',\n",
"'type' : '0',\n",
"'psd' : {None : 'ABC_PSD_Function',\n",
" 'A' : '0.01',\n",
" 'B' : '360',\n",
" 'C' : '2.4'},\n",
"'stack' : {None : 'Stack_StackModel',\n",
" 'stack' : 'zm95qrx7RMFx.tmp 0.05'}}\n"
]
}
],
"source": [
"# Needed to use OpticalFunction, Film, and FilmStack...\n",
"from pySCATMECH.fresnel import *\n",
"\n",
"# Define two materials...\n",
"SiO2 = OpticalFunction(lambda L: 1.4580 + 0.00354/L**2,np.arange(0.2,1.5,0.1))\n",
"Si = OpticalFunction('silicon')\n",
"\n",
"# Define the power spectral density function...\n",
"psd = Model(\"ABC_PSD_Function\", A=0.01, B=360, C=2.4)\n",
"\n",
"# Define the stack...\n",
"stack = FilmStack([Film(SiO2,thickness =0.05)])\n",
"\n",
"model.setParameters(wavelength = 0.600, substrate=Si, stack = stack, psd = psd)\n",
"print(model)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{None: 'Correlated_Roughness_Stack_BRDF_Model',\n",
" 'lambda': '0.6',\n",
" 'substrate': 'silicon',\n",
" 'type': '0',\n",
" 'psd': 'ABC_PSD_Function',\n",
" 'psd.A': '0.01',\n",
" 'psd.B': '360',\n",
" 'psd.C': '2.4',\n",
" 'stack': 'Stack_StackModel',\n",
" 'stack.stack': 'zm95qrx7RMFx.tmp 0.05'}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.getParameters()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's evaluate the BRDF! The BRDF, in general, is a Mueller matrix. (Note here that `deg` is defined in pySCATMECH to be $\\pi/180$.) Let's evaluate it for incident and scattering angles, $\\theta_i=60^\\circ$ and $\\theta_s=30^\\circ$, respectively: "
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 4.21363211e-06 6.14518402e-07 0.00000000e+00 0.00000000e+00]\n",
" [ 6.14518402e-07 4.21363211e-06 -0.00000000e+00 0.00000000e+00]\n",
" [ 0.00000000e+00 -0.00000000e+00 -3.83310078e-06 1.63841420e-06]\n",
" [ 0.00000000e+00 0.00000000e+00 -1.63841420e-06 -3.83310078e-06]]\n"
]
}
],
"source": [
"print(model.MuellerBRDF(60*deg, 30*deg))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can determine it for an input Stokes vector of p-polarization and with polarization insensitivity:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3.599113704481351e-06"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mBRDF = model.MuellerBRDF(60*deg, 30*deg)\n",
"inc = Polarization('p')\n",
"sens = Sensitivity('u')\n",
"sens @ mBRDF @ inc"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another way of doing this is:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3.599113704481351e-06"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.BRDF(60*deg, 30*deg, inc=Polarization('p'), sens=Sensitivity('u'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The unpolarized BRDF is:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4.2136321066656146e-06"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.BRDF(60*deg, 30*deg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's plot the BRDF:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\r\n",
"\r\n",
"\r\n",
"\r\n"
],
"text/plain": [
"