{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Specific arguments for particular field geometry\n", "\n", "The openPMD format supports 3 types of geometries:\n", "\n", "- Cartesian 2D\n", "- Cartesian 3D\n", "- Cylindrical with azimuthal decomposition (thetaMode)\n", "\n", "This notebook shows how to use the arguments of `get_field` which are specific to a given geometry. You can run this notebook locally by downloading it from [this link](https://github.com/openPMD/openPMD-viewer/blob/dev/docs/source/tutorials/2_Specific-field-geometries.ipynb).\n", "\n", "## (optional) Preparing this notebook to run it locally\n", "\n", "If you choose to run this notebook on your local machine, you will need to download the openPMD data files which will then be visualized. To do so, execute the following cell. (Downloading the data may take a few seconds.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os, sys\n", "\n", "def download_if_absent( dataset_name ):\n", " \"Function that downloads and decompress a chosen dataset\"\n", " if os.path.exists( dataset_name ) is False:\n", " import wget, tarfile\n", " tar_name = \"%s.tar.gz\" %dataset_name\n", " url = \"https://github.com/openPMD/openPMD-example-datasets/raw/draft/%s\" %tar_name\n", " wget.download(url, tar_name)\n", " with tarfile.open( tar_name ) as tar_file:\n", " tar_file.extractall()\n", " os.remove( tar_name )\n", "\n", "download_if_absent( 'example-3d' )\n", "download_if_absent( 'example-thetaMode' )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "In addition, we choose here to incorporate the plots inside the notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Preparing the API\n", "\n", "Again, we need to import the `OpenPMDTimeSeries` object:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from openpmd_viewer import OpenPMDTimeSeries" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "and to create objects that point to the 3D data and the cylindrical data. \n", "\n", "(NB: The argument `check_all_files` below is optional. By default, `check_all_files` is `True`, and in this case the code checks that all files in the timeseries are consistent\n", "i.e. that they all contain the same fields and particle quantities, with the same metadata. When `check_all_files` is `False`, these verifications are skipped, and this allows to create the `OpenPMDTimeSeries` object faster.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ts_3d = OpenPMDTimeSeries('./example-3d/hdf5/', check_all_files=False )\n", "ts_circ = OpenPMDTimeSeries('./example-thetaMode/hdf5/', check_all_files=False )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## 3D Cartesian geometry\n", "\n", "For 3D Cartesian geometry, the `get_field` method has additional arguments, in order to select a 2D slice into the 3D volume:\n", "- `slice_across` allows to choose the axis across which the slice is taken. See the examples below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Slice across y (i.e. in a plane parallel to x-z)\n", "Ez1, info_Ez1 = ts_3d.get_field( field='E', coord='z', iteration=500, \n", " slice_across='y', plot=True )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Slice across z (i.e. in a plane parallel to x-y)\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500,\n", " slice_across='z', plot=True )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Slice across x and y (i.e. along a line parallel to the z axis)\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500,\n", " slice_across=['x','y'], plot=True )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- For one given slicing direction, `slice_relative_position` allows to select which slice to take: `slice_relative_position` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_{min}$ if `slice_across` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_{max}$ if `slice_across` is `z`). For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Slice across z, very close to zmin.\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500, \n", " slice_across='z', slice_relative_position=-0.9, plot=True )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "When passing `slice_across=None`, `get_field` returns a full 3D Cartesian array. This can be useful for further analysis by hand, with `numpy` (e.g. calculating the total energy in the field)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Get the full 3D Cartesian array\n", "Ez_3d, info_Ez_3d = ts_3d.get_field( field='E', coord='z', iteration=500, slice_across=None )\n", "print( Ez_3d.ndim )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Cylindrical geometry (with azimuthal decomposition)\n", "\n", "In for data in the `thetaMode` geometry, the fields are decomposed into azimuthal modes. Thus, the `get_field` method has an argument `m`, which allows to select the mode:\n", "\n", "- Choosing an integer value for selects a particular mode (for instance, here one can see a laser-wakefield, which is entirely contained in the mode 0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Ey, info_Ey = ts_circ.get_field( field='E', coord='y', iteration=500, m=0, \n", " plot=True, theta=0.5)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- Choosing `m='all'` sums all the modes (for instance, here the laser field, which is in the mode 1, dominates the fields)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Ey, info_Ey = ts_circ.get_field( field='E', coord='y', iteration=500, m='all', \n", " plot=True, theta=0.5)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "The argument `theta` (in radians) selects the plane of observation: this plane contains the $z$ axis and has an angle `theta` with respect to the $x$ axis.\n", "\n", "When passing `theta=None`, `get_field` returns a full 3D Cartesian array. This can be useful for further analysis by hand, with `numpy` (e.g. calculating the total energy in the field), or for comparison with Cartesian simulations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Get the full 3D Cartesian array\n", "Ey_3d, info_Ey3d = ts_circ.get_field( field='E', coord='y', iteration=500, theta=None )\n", "print( Ey_3d.ndim )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- In cylindrical geometry, the users can also choose the coordinates `r` and `t` for the radial and azimuthal components of the fields. For instance:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Er, info_Er = ts_circ.get_field( field='E', coord='r', iteration=500, m=0, \n", " plot=True, theta=0.5)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- Finally, in cylindrical geometry, fields can also be sliced, by using the `r` and `z` direction. (Keep in mind that `slice_across` is the direction **orthogonal** to the slice.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slice_across='r' )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slice_across='z' )" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }