{ "cells": [ { "cell_type": "markdown", "id": "f0e04a9a-582f-4756-87cc-816eeb5e3f70", "metadata": {}, "source": [ "# Accessing Data from a Physics 180E HDF5 File" ] }, { "cell_type": "code", "execution_count": null, "id": "39d13605-ff86-4702-8198-2b6c85719a37", "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": null, "id": "8651f5a4-9cec-401c-a00e-1124bbdd4c96", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "from pathlib import Path\n", "\n", "from bapsflib import phys180E" ] }, { "cell_type": "code", "execution_count": null, "id": "5957d9b0-f932-43b4-903a-3fefcd35b9c1", "metadata": {}, "outputs": [], "source": [ "plt.rcParams.update(\n", " {\"figure.figsize\": [10, 0.6 * 10], \"font.size\": 16}\n", ")" ] }, { "cell_type": "markdown", "id": "9bf40a64-f563-4f7e-be3d-2290db22f535", "metadata": {}, "source": [ "Let's define the file name and path to the HDF5 file." ] }, { "cell_type": "code", "execution_count": null, "id": "6d6aefea-d02f-44a1-9e92-7f68088dbe6c", "metadata": {}, "outputs": [], "source": [ "# _HERE is the location of this jupyter notebook\n", "_HERE = Path.cwd()\n", "_FILENAME = \"sample_phys180e_axial_bdot.hdf5\"\n", "_FILE = (_HERE / _FILENAME).resolve()\n", "\n", "print(\n", " f\"File name & path: {_FILE}\\n\"\n", " f\"File exists: {_FILE.exists()}\"\n", ")" ] }, { "cell_type": "markdown", "id": "dfa6294b-e72d-45d1-8f75-b1a8bf2eeff4", "metadata": {}, "source": [ "The HDF5 file can now be opened using the `File` class on `phys180e`." ] }, { "cell_type": "code", "execution_count": null, "id": "5dd29a4a-b5d3-4305-8c25-7d2a3989cef7", "metadata": {}, "outputs": [], "source": [ "f = phys180E.File(_FILE)" ] }, { "cell_type": "markdown", "id": "5e21df78-b496-4534-87fb-2b0914407fc4", "metadata": {}, "source": [ "`f` is now an object instance of the `phys180e.File` class. All the functionality provided by the `File` class is accessible via dot access.\n", "\n", "For example, a summary of the digitizer can shown by..." ] }, { "cell_type": "code", "execution_count": null, "id": "c95c34c0-cd1a-4b7c-8078-e32212471fac", "metadata": {}, "outputs": [], "source": [ "f.digitizers" ] }, { "cell_type": "markdown", "id": "2e3a33cf-aa70-4b63-a13b-c14516290a47", "metadata": {}, "source": [ "Here, the digitizer used to recorded data was the `'LeCroy_scope'` and all 4 channels recorded data with a record length of `2500`.\n", "\n", "And a more details digitizer report can be accessed on the `overview` attribute." ] }, { "cell_type": "code", "execution_count": null, "id": "22d66ec5-f345-4ee9-b21c-2392810eac2f", "metadata": {}, "outputs": [], "source": [ "f.overview.report_digitizers()" ] }, { "cell_type": "markdown", "id": "d1ab3014-2722-4dd3-84a4-a91dda8f2767", "metadata": {}, "source": [ "## Reading Digitizer Data\n", "\n", "Digitizer data can be retrieved by using the `read_data()` method.\n", "\n", "For example, lets retrieve all the recorded data for channel 2 of the digitizer." ] }, { "cell_type": "code", "execution_count": null, "id": "4c2e97c6-fbc8-4fac-9e4e-ae8e8b9e56a1", "metadata": {}, "outputs": [], "source": [ "data = f.read_data(board=0, channel=2, silent=True)\n", "data.dtype" ] }, { "cell_type": "markdown", "id": "aab3d8ec-59aa-4256-add1-ef7a86354240", "metadata": {}, "source": [ "The retrieved data has three fields:\n", "\n", "- `\"shotnum\"`: This is the shot number array.\n", "- `\"signal\"`: This is the recorded signal data.\n", "- `\"xyz\"`: This field contains probe positions. However, we have not read out any position data, so this will be covered later in the notebook.\n", "\n", "The total number of shots for this HDF5 file is..." ] }, { "cell_type": "code", "execution_count": null, "id": "ebe86418-1e96-4af6-aaa2-4fd4cd911416", "metadata": {}, "outputs": [], "source": [ "data[\"shotnum\"].size" ] }, { "cell_type": "markdown", "id": "29db7896-b18c-409b-b05e-24e2400edbdf", "metadata": {}, "source": [ "Let's say we wanted to plot the signal for shot number 49. We could do something like..." ] }, { "cell_type": "code", "execution_count": null, "id": "e13d9fae-2acc-4d83-8d6a-88ee9062f7a2", "metadata": {}, "outputs": [], "source": [ "mask = data[\"shotnum\"] == 49\n", "data49 = data[\"signal\"][mask, ...]" ] }, { "cell_type": "markdown", "id": "3491e5c6-5991-4e39-b2a4-11aad7346fef", "metadata": {}, "source": [ "The ellipses `...` is requires since `data[\"shotnum\"]` (and thus `mask`) have a shape of `(50,)`, where as `data[\"signal\"]` has a shape of `(50, 2500)`." ] }, { "cell_type": "code", "execution_count": null, "id": "34f65a94-1ccd-4a1f-bc88-b9f1268f377e", "metadata": {}, "outputs": [], "source": [ "plt.plot(data49.squeeze());" ] }, { "cell_type": "markdown", "id": "8865ac59-aed0-4a60-8071-d13a4edb8fb8", "metadata": {}, "source": [ "A single record can also be read directly by `read_data()`." ] }, { "cell_type": "code", "execution_count": null, "id": "ddf71da7-d906-4ba9-a8d6-378beba2906c", "metadata": {}, "outputs": [], "source": [ "data35 = f.read_data(0, 2, shotnum=35, silent=True)\n", "\n", "plt.plot(data35[\"signal\"].squeeze());" ] }, { "cell_type": "markdown", "id": "373ea280-4855-41e5-8410-6a903079932e", "metadata": {}, "source": [ "## Reading the Time Series\n", "\n", "The `File` object also provides a convienece method, `get_time_array()`, to retrieve the time array associated with the digitized data. This method takes just one argument, the data array." ] }, { "cell_type": "code", "execution_count": null, "id": "466f88b9-31f4-4a14-a595-8bd318251a22", "metadata": {}, "outputs": [], "source": [ "# let's just work with data35 from now on\n", "data = data35\n", "\n", "# get the time array\n", "time = f.get_time_array(data)\n", "\n", "plt.plot(time, data[\"signal\"].squeeze())\n", "ax = plt.gca()\n", "ax.set_xlabel(\"Time (ns)\")\n", "ax.set_ylabel(\"Voltge (V)\");" ] }, { "cell_type": "markdown", "id": "cd3597a7-5ebc-446a-8287-e053d3cb48be", "metadata": {}, "source": [ "The time array can also be retrieved before any data is extracted." ] }, { "cell_type": "code", "execution_count": null, "id": "b1af5c65-5612-4714-97f2-aa02dfcdd057", "metadata": {}, "outputs": [], "source": [ "digitized_info = f.get_digitizer_specs(0, 2, silent=True)\n", "time_from_digi_info = f.get_time_array(digitized_info)\n", "\n", "# see... both arrays are equal\n", "np.allclose(time, time_from_digi_info)" ] }, { "cell_type": "markdown", "id": "41dd6e4c-d49f-485a-90ac-a0a3e9bd09c0", "metadata": {}, "source": [ "## Reading Position Information\n", "\n", "The digitized data is often associated with a probe that is connected to an automated probe drive (or a control device). This probe drive also records this position data in the HDF5 file. Similarly to `f.digitizers`, `f.controls` will yield a brief summary of the mapped control devices..." ] }, { "cell_type": "code", "execution_count": null, "id": "49e118ce-5071-4382-9b02-07ebd4625e96", "metadata": {}, "outputs": [], "source": [ "f.controls" ] }, { "cell_type": "markdown", "id": "942ef3bc-86ea-4b48-8d2a-04f33e5035f0", "metadata": {}, "source": [ "Here the control device is call `\"180E_positions\"` and will map to the `\"xyz\"` field briefly mentioned when discussing the extracted digitizer data.\n", "\n", "A more detailed report can also be displayed using the `overview` attribute." ] }, { "cell_type": "code", "execution_count": null, "id": "1a2bbc59-462c-4005-9f0c-7d91ecf81463", "metadata": {}, "outputs": [], "source": [ "f.overview.report_controls()" ] }, { "cell_type": "markdown", "id": "32edd728-83a9-49e6-9921-5f593d0d890d", "metadata": {}, "source": [ "Retrieving the control data can be done using the `read_control()` method." ] }, { "cell_type": "code", "execution_count": null, "id": "06ad7973-e84d-4d37-9961-4b90f8889bd5", "metadata": {}, "outputs": [], "source": [ "cdata = f.read_controls([\"180E_positions\"], silent=True)\n", "cdata.dtype" ] }, { "cell_type": "markdown", "id": "e5d8750a-6ae1-4f92-9d31-0b664cb864d0", "metadata": {}, "source": [ "The retrieved control data has two fields:\n", "\n", "- `\"shotnum\"`: This is the shot number array.\n", "- `\"xyz\"`: This field contains probe positions.\n", "\n", "So, the position for shot number 35 is..." ] }, { "cell_type": "code", "execution_count": null, "id": "8bd91905-6f1c-4090-a4f5-39e7036f72e2", "metadata": {}, "outputs": [], "source": [ "print(\n", " f\"Shot number: {cdata['shotnum'][34]}\\n\"\n", " f\"Position [x, y, z]: {cdata['xyz'][34]}\"\n", ")" ] }, { "cell_type": "markdown", "id": "29d44d31-744b-4640-be32-0bd761cf9b04", "metadata": {}, "source": [ "Now, this is not so convenient since the position data is not paired with the signal data. So, `read_data` provides a mechanism for mating the digitizer and position data at the same time." ] }, { "cell_type": "code", "execution_count": null, "id": "eebfef6e-c97d-4a26-b4db-221c616e63f0", "metadata": {}, "outputs": [], "source": [ "all_data = f.read_data(0, 2, add_controls=[\"180E_positions\"], shotnum=35, silent=True)" ] }, { "cell_type": "markdown", "id": "4d03af24-626c-4005-82c3-025a70476862", "metadata": {}, "source": [ "All the extracted data in `all_data` is the same as what we have extracted before." ] }, { "cell_type": "code", "execution_count": null, "id": "0cbe0c59-a900-42cb-8fe4-0f2995adcbdb", "metadata": {}, "outputs": [], "source": [ "print(\n", " f\"Shot number is the same: {np.allclose(data['shotnum'], all_data['shotnum'])}\\n\"\n", " f\"Signal data is the same: {np.allclose(data['signal'], all_data['signal'])}\\n\"\n", " f\"Position data is the same: {np.allclose(cdata['xyz'][34], all_data['xyz'])}\\n\"\n", ")" ] }, { "cell_type": "markdown", "id": "043b66b2-0772-4cc7-baf9-2ef7661a13c0", "metadata": {}, "source": [ "## Close the `File` instance\n", "\n", "The `File` instance will automatically close itself when Python garbage collects at the close of this notebook. However, it is good practice to explicitly close the file." ] }, { "cell_type": "code", "execution_count": null, "id": "e7fd5236-48df-480e-9849-a3934d9031e1", "metadata": {}, "outputs": [], "source": [ "f.close()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.14.2" } }, "nbformat": 4, "nbformat_minor": 5 }