.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gallery/extras/experiment_photodiode_angular_weights.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_gallery_extras_experiment_photodiode_angular_weights.py: Experiment Photodiode Angular Weights ===================================== This example demonstrates how to model a large lens with ``NA=1.2`` oriented at ``phi=45 degree`` and split by a mirror plane. Only one side of the lens is kept by building explicit ``angular_weights`` arrays for a sequential ``PhotodiodeSet`` experiment. At the moment, experiment-side angular weights are supported only through ``PhotodiodeSet.build_sequential(...)``. .. GENERATED FROM PYTHON SOURCE LINES 13-172 .. image-sg:: /gallery/extras/images/sphx_glr_experiment_photodiode_angular_weights_001.png :alt: NA=1.2 lens at phi=45 degree split by a mirror, Full NA=1.2 lens, Mirror keeps one side, Coupling after mirror split :srcset: /gallery/extras/images/sphx_glr_experiment_photodiode_angular_weights_001.png :class: sphx-glr-single-img .. code-block:: Python import numpy as np import matplotlib.pyplot as plt from PyMieSim.units import ureg from PyMieSim.polarization import PolarizationState from PyMieSim.single.source import Gaussian as SingleGaussian from PyMieSim.single.scatterer import Sphere as SingleSphere from PyMieSim.single.detector import Photodiode as SinglePhotodiode from PyMieSim.experiment import Setup from PyMieSim.experiment.detector_set import PhotodiodeSet from PyMieSim.experiment.scatterer_set import SphereSet from PyMieSim.experiment.source_set import GaussianSet from PyMieSim.experiment.polarization_set import PolarizationSet sampling = 1400 detector_numerical_aperture = 1.2 detector_phi_offset = 45 * ureg.degree detector_gamma_offset = 0 * ureg.degree detector_medium = 1.5 def normalize(vector: np.ndarray) -> np.ndarray: return vector / np.linalg.norm(vector) # Build one reference single detector so the mesh ordering can be used to create # explicit experiment-side angular weight vectors. single_source = SingleGaussian( wavelength=1000 * ureg.nanometer, polarization=PolarizationState(angle=0 * ureg.degree), optical_power=1 * ureg.watt, numerical_aperture=0.2, ) single_scatterer = SingleSphere( diameter=1000 * ureg.nanometer, material=1.5 + 0.5j, medium=1.0, ) reference_detector = SinglePhotodiode( numerical_aperture=detector_numerical_aperture, phi_offset=detector_phi_offset, gamma_offset=detector_gamma_offset, sampling=sampling, medium=detector_medium, ) single_scatterer.init(single_source) reference_detector.initialize_mesh(single_scatterer) x_coordinates = np.asarray(reference_detector.mesh.cartesian.x.magnitude) y_coordinates = np.asarray(reference_detector.mesh.cartesian.y.magnitude) z_coordinates = np.asarray(reference_detector.mesh.cartesian.z.magnitude) mesh_coordinates = np.column_stack([x_coordinates, y_coordinates, z_coordinates]) # Build a detector-local basis. The mirror plane contains the collection axis # and the local horizontal direction, so the sign of the local vertical # projection selects which side of the split lens is kept. collection_axis = normalize(mesh_coordinates.mean(axis=0)) reference_up = np.array([0.0, 0.0, 1.0]) if np.abs(np.dot(collection_axis, reference_up)) > 0.95: reference_up = np.array([0.0, 1.0, 0.0]) local_horizontal = normalize(np.cross(reference_up, collection_axis)) local_vertical = normalize(np.cross(collection_axis, local_horizontal)) local_vertical_coordinates = mesh_coordinates @ local_vertical full_weights = np.ones(sampling, dtype=np.complex128) mirror_kept_side = np.zeros(sampling, dtype=np.complex128) mirror_kept_side[local_vertical_coordinates >= 0.0] = 1.0 blocked_weights = np.zeros(sampling, dtype=np.complex128) source_set = GaussianSet.build_sequential( target_size=3, wavelength=[1000, 1000, 1000] * ureg.nanometer, polarization=PolarizationSet(angles=[0, 0, 0] * ureg.degree), optical_power=[1, 1, 1] * ureg.watt, numerical_aperture=[0.2, 0.2, 0.2], ) scatterer_set = SphereSet.build_sequential( target_size=3, diameter=[1000, 1000, 1000] * ureg.nanometer, material=[1.5 + 0.5j, 1.5 + 0.5j, 1.5 + 0.5j], medium=[1.0, 1.0, 1.0], ) detector_set = PhotodiodeSet.build_sequential( target_size=3, numerical_aperture=[detector_numerical_aperture] * 3, phi_offset=[45, 45, 45] * ureg.degree, gamma_offset=[0, 0, 0] * ureg.degree, sampling=[sampling, sampling, sampling], polarization_filter=[0, 0, 0] * ureg.degree, medium=[detector_medium, detector_medium, detector_medium], angular_weights=[ full_weights, mirror_kept_side, blocked_weights, ], ) experiment = Setup( scatterer_set=scatterer_set, source_set=source_set, detector_set=detector_set, ) coupling = experiment.get_sequential("coupling") figure = plt.figure(figsize=(14, 4.5)) axis_full = figure.add_subplot(1, 3, 1, projection="3d") axis_full.scatter(x_coordinates, y_coordinates, z_coordinates, s=10, c="#4c72b0") axis_full.set(title="Full NA=1.2 lens", xlabel="x", ylabel="y", zlabel="z") axis_half = figure.add_subplot(1, 3, 2, projection="3d") active_half = np.abs(mirror_kept_side) > 0.0 axis_half.scatter( x_coordinates[active_half], y_coordinates[active_half], z_coordinates[active_half], s=10, c="#4c72b0", ) axis_half.scatter( x_coordinates[~active_half], y_coordinates[~active_half], z_coordinates[~active_half], s=10, c="#d9d9d9", ) axis_half.set(title="Mirror keeps one side", xlabel="x", ylabel="y", zlabel="z") for axis in (axis_full, axis_half): axis.set_xlim(-1.0, 1.0) axis.set_ylim(-1.0, 1.0) axis.set_zlim(-1.0, 1.0) axis.view_init(elev=22, azim=38) axis_bar = figure.add_subplot(1, 3, 3) axis_bar.bar( ["full", "kept side", "blocked"], coupling * 1e6, color=["#4c72b0", "#dd8452", "#9a9a9a"], ) axis_bar.set( title="Coupling after mirror split", ylabel="Coupling [$\\mu$W]", ) figure.suptitle("NA=1.2 lens at phi=45 degree split by a mirror") figure.tight_layout() if plt.get_backend().lower() != "agg": plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.442 seconds) .. _sphx_glr_download_gallery_extras_experiment_photodiode_angular_weights.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: experiment_photodiode_angular_weights.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: experiment_photodiode_angular_weights.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: experiment_photodiode_angular_weights.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_