diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..606a646 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,126 @@ +name: Build and upload to PyPI + +on: + pull_request: + branches: + - "package-*" + push: + branches: + - "package-*" + tags: + - "package-*" + release: + types: + - published + +concurrency: + group: "${{ github.ref }}-${{ github.head_ref }}-${{ github.workflow }}" + cancel-in-progress: true + + +defaults: + run: + shell: bash -l {0} + + +jobs: + build_wheels: + if: github.repository == 'Becksteinlab/zarrtraj' + name: Build wheels + runs-on: ${{ matrix.buildplat[0] }} + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + buildplat: + - [ubuntu-22.04, manylinux_x86_64, x86_64] + - [macos-11, macosx_*, x86_64] + - [windows-2019, win_amd64, AMD64] + - [macos-14, macosx_*, arm64] + python: ["cp310", "cp311", "cp312"] + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel==2.19.2 + + - name: Build wheels + run: python -m cibuildwheel --output-dir wheelhouse + env: + CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }} + CIBW_ARCHS: ${{ matrix.buildplat[2] }} + CIBW_BUILD_VERBOSITY: 1 + + - name: upload artifacts + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/package')) || + (github.event_name == 'release' && github.event.action == 'published') + uses: actions/upload-artifact@v4 + with: + path: ./wheelhouse/*.whl + + build_sdist: + if: github.repository == 'Becksteinlab/zarrtraj' + name: build package source distribution + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: pipx run build --sdist + + - name: upload artifacts + if: | + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/package')) || + (github.event_name == 'release' && github.event.action == 'published') + uses: actions/upload-artifact@v4 + with: + path: ./dist/*.tar.gz + retention-days: 7 + + upload_testpypi_zarrtraj: + if: github.repository == 'Becksteinlab/zarrtraj' && + (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/package')) + name: testpypi_upload_zarrtraj + environment: + name: publisher + url: https://test.pypi.org/p/zarrtraj + permissions: + id-token: write + runs-on: ubuntu-latest + needs: [build_wheels, build_sdist] + steps: + - uses: actions/download-artifact@v4 + with: + name: artifact + path: dist + + - name: upload_source_and_wheels + uses: pypa/gh-action-pypi-publish@v1.9.0 + with: + skip-existing: true + repository-url: https://test.pypi.org/legacy/ + + upload_pypi_zarrtraj: + if: | + github.repository == 'Becksteinlab/zarrtraj' && + (github.event_name == 'release' && github.event.action == 'published') + name: pypi_upload_zarrtraj + environment: + name: publisher + url: https://pypi.org/p/zarrtraj + permissions: + id-token: write + runs-on: ubuntu-latest + needs: [build_wheels, build_sdist] + steps: + - uses: actions/download-artifact@v4 + with: + name: artifact + path: dist + + - name: upload_source_and_wheels + uses: pypa/gh-action-pypi-publish@v1.9.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index e7ce56a..0a8a31b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,23 @@ The rules for this file: * YYYY-MM-DD date format (following ISO 8601) * accompany each entry with github issue/PR number (Issue #xyz) --> +## [0.2.0] + + +### Authors +- ljwoods2 + +### Added +- Rewrite of repository, zarrtraj supports reading H5MD-formatted files + +### Fixed + + +### Changed + + +### Deprecated +- Proprietary zarrtraj format no longer supported ## [0.1.0] diff --git a/README.md b/README.md index 50d0529..d20abdd 100755 --- a/README.md +++ b/README.md @@ -21,70 +21,14 @@ zarrtraj [url_license]: https://www.gnu.org/licenses/gpl-2.0 [url_mda]: https://www.mdanalysis.org -This is a kit that provides the ability to read and write trajectory data in the Zarr file format. For more information on the format and usage, -see the [zarrtraj documentation](https://zarrtraj.readthedocs.io/en/latest/index.html) +This is an MDAKit that provides the ability to read and write H5MD-formatted trajectory data into MDAnalysis using Zarr. +Zarrtraj can read local H5MD files, H5MD files in S3 buckets, and files served via http or https. +It can read both [H5MD-formatted files stored in hdf5](https://www.nongnu.org/h5md/h5md.html) and [H5MD-formatted files stored +in Zarr](https://zarrtraj.readthedocs.io/en/latest/zarrmd-file-spec/v0.1.0.html) (.zarrmd files). -zarrtraj is bound by a [Code of Conduct](https://github.com/Becksteinlab/zarrtraj/blob/main/CODE_OF_CONDUCT.md). - -### Installation - -To build zarrtraj from source, -we highly recommend using virtual environments. -If possible, we strongly recommend that you use -[Anaconda](https://docs.conda.io/en/latest/) as your package manager. -Below we provide instructions both for `conda` and -for `pip`. - -#### With conda - -Ensure that you have [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html) installed. - -Create a virtual environment and activate it: - -``` -conda create --name zarrtraj -conda activate zarrtraj -``` - -Install the development and documentation dependencies: - -``` -conda env update --name zarrtraj --file devtools/conda-envs/test_env.yaml -conda env update --name zarrtraj --file docs/requirements.yaml -``` - -Build this package from source: +For more information on installation and usage, see the [zarrtraj documentation](https://zarrtraj.readthedocs.io/en/latest/index.html) -``` -pip install -e . -``` - -If you want to update your dependencies (which can be risky!), run: - -``` -conda update --all -``` - -And when you are finished, you can exit the virtual environment with: - -``` -conda deactivate -``` - -#### With pip - -To build the package from source, run: - -``` -pip install . -``` - -If you want to create a development environment, install -the dependencies required for tests and docs with: - -``` -pip install ".[test,doc]" -``` +zarrtraj is bound by a [Code of Conduct](https://github.com/Becksteinlab/zarrtraj/blob/main/CODE_OF_CONDUCT.md). ### Copyright diff --git a/benchmarks/reader_bms.py b/benchmarks/reader_bms.py index e818694..d2c25ef 100644 --- a/benchmarks/reader_bms.py +++ b/benchmarks/reader_bms.py @@ -22,11 +22,11 @@ Development: - asv run -q -v -e > bm.log & + asv run -q -v -e ^! > bm.log & Full run: - asv run -v -e > bm.log & + asv run -v -e ^! > bm.log & 4. To publish, use diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 74dabf1..4b4dbbc 100755 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -12,16 +12,15 @@ dependencies: - zarr>=2.11.0 - kerchunk>=0.2.6 - h5py>=3.11.0 - - dask ### AWS dependencies ### # AWS reading/writing - - s3fs=2024.3.0 + - s3fs>=2024.3.0 - aiobotocore=2.12.1 - botocore>=1.34.41,<1.34.52 - boto3>=1.9.201 # AWS testing - - moto=5.0.3 + - moto>=5.0.3 ### General testing ### - MDAnalysisTests>=2.7.0 @@ -30,9 +29,6 @@ dependencies: - pytest-cov>=4.1.0 - codecov - ### Notebooks ### - - jupyter - # Pip-only installs # - pip: diff --git a/docs/source/benchmarks.rst b/docs/source/benchmarks.rst index 16ff581..d3a4116 100644 --- a/docs/source/benchmarks.rst +++ b/docs/source/benchmarks.rst @@ -1,219 +1,13 @@ Benchmarks ========== -Nightly benchmarks -################## - Speed benchmarks are available via AirSpeedVelocity `here `_ -Inital benchmarking -################### - -The following benchmarks were performed in the `Beckstein Lab `_ -on an Ubuntu 22.04 machine with dual Intel Xeon E5-2665 2.40GHz 8-core processors, 32GB of RAM, and an -NVIDIA GeForce 780 graphics card. Disk tests were performed on an NFS drive backed by SSD storage - -File Writing Speed Test -^^^^^^^^^^^^^^^^^^^^^^^ -Test code:: - - import zarrtraj - import MDAnalysis as mda - import MDAnalysisData - import zarr - import os - import s3fs - import time - import json - - # Setup benchmarking - write_speeds = dict() - - # 1. Download the 90ns YiiP trajectory to the local filesystem - yiip = MDAnalysisData.yiip_equilibrium.fetch_yiip_equilibrium_long(data_home='notebook_data_tmp') - u = mda.Universe(yiip.topology, yiip.trajectory) - - # 2. Write it into the xtc format on disk (for benchmarking comparative speed) - start = time.time() - with mda.Writer("notebook_data_tmp/yiip.xtc", u.atoms.n_atoms) as W: - for ts in u.trajectory: - W.write(u.atoms) - stop = time.time() - write_speeds["XTC"] = stop - start - - # 3. Write it into the zarrtraj format on disk - zHDD = zarr.open_group("notebook_data_tmp/yiip.zarrtraj", mode = 'w') - - start = time.time() - with mda.Writer(zHDD, u.atoms.n_atoms, - format='ZARRTRAJ') as W: - for ts in u.trajectory: - W.write(u.atoms) - stop = time.time() - write_speeds["Zarrtraj_Disk"] = stop - start - - # 4. Write it into the zarrtraj format on an accessible AWS S3 bucket - # Use your own bucket here - - s3_fs = s3fs.S3FileSystem( - # anon must be false to allow authentication - anon=False, - profile='sample_profile', - client_kwargs=dict( - region_name='us-east-1', - ) - ) - - cloud_store = s3fs.S3Map( - root=f'zarrtraj-test-data/yiip.zarrtraj', - s3=s3_fs, - check=False - ) - - zS3 = zarr.open_group(store=cloud_store, mode='w') - - start = time.time() - with mda.Writer(zS3, u.atoms.n_atoms, - n_frames=u.trajectory.n_frames, - format='ZARRTRAJ') as W: - for ts in u.trajectory: - W.write(u.atoms) - stop = time.time() - write_speeds["Zarrtraj_S3"] = stop - start - - with open('notebook_data_tmp/write_speeds.json', 'w') as j: - json.dump(write_speeds, j) - -.. image:: _static/benchmark_figures/write_speeds.svg - -Principal Component Analysis Speed Test -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Test code:: - - import zarrtraj - import MDAnalysis as mda - import zarr - from zarr.storage import LRUStoreCache - import s3fs - import os - import MDAnalysis.analysis.pca as pca - import time - import json - - # 1 Open a zzarr group from the aligned trajectory stored on disk - yiipHDD = zarr.open_group("notebook_data_tmp/yiip.zarrtraj", mode='r') - - # 2 Open a group from the trajectory uploaded to an AWS S3 bucket - s3_fs = s3fs.S3FileSystem( - # anon must be false to allow authentication - anon=False, - # use profiles defined in a .aws/credentials file to store secret keys - # docs: - profile='sample_profile', - client_kwargs=dict( - region_name='us-west-1', - ) - ) - store = s3fs.S3Map(root=f'zarrtraj-test-data/yiip.zarrtraj', - s3=s3_fs, - check=False) - cache = LRUStoreCache(store, max_size=10485760) - yiipS3 = zarr.open_group(store=cache, mode='r') - - # 3 Create an universe for both zarr groups and one for the original .xtc trajectory - uHDD = mda.Universe("notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb", yiipHDD) - uS3 = mda.Universe("notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb", yiipS3) - uXTC = mda.Universe("notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb", "notebook_data_tmp/yiip.xtc") - import MDAnalysis as mda - - #4 Perform the PCA analysis for each universe, time, and record results - universes = dict() - universes["uHDD"] = dict() - universes["uHDD"]["ref"] = uHDD - universes["uS3"] = dict() - universes["uS3"]["ref"] = uS3 - universes["uXTC"] = dict() - universes["uXTC"]["ref"] = uXTC - - for name in ("uHDD", "uS3", "uXTC"): - start = time.time() - PSF_pca = pca.PCA(universes[name]["ref"], select='backbone') - PSF_pca.run() - stop = time.time() - universes[name]["PCA"] = stop - start - - pca_speeds = dict() - pca_speeds["uXTC"] = universes["uXTC"]["PCA"] - pca_speeds["uS3"] = universes["uS3"]["PCA"] - pca_speeds["uHDD"] = universes["uHDD"]["PCA"] - with open('notebook_data_tmp/pca_speeds.json', 'w') as j: - json.dump(pca_speeds, j) - -.. image:: _static/benchmark_figures/pca_speeds.svg - -RMSF Speed Test -^^^^^^^^^^^^^^^ -Test code:: - - import zarrtraj - import MDAnalysis as mda - import zarr - from zarr.storage import LRUStoreCache - import s3fs - import os - import time - from MDAnalysis.analysis import rms - import json - - # 1 Open a zarr group from the aligned trajectory stored on disk - yiipHDD = zarr.open_group("notebook_data_tmp/yiip_aligned.zarrtraj", mode='r') - - # 2 Open a group from the trajectory uploaded to an AWS S3 bucket - - s3_fs = s3fs.S3FileSystem( - anon=False, - profile='sample_profile', - client_kwargs=dict( - region_name='us-west-1', - ) - ) - store = s3fs.S3Map(root=f'zarrtraj-test-data/yiip_aligned.zarrtraj', - s3=s3_fs, - check=False) - cache = LRUStoreCache(store, max_size=10485760) - yiipS3 = zarr.open_group(store=cache, mode='r') - - # 3 Create an universe for both zarr groups and one for the original .xtc trajectory - uHDD = mda.Universe("notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb", yiipHDD) - uS3 = mda.Universe("notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb", yiipS3) - uXTC = mda.Universe("notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb", "notebook_data_tmp/yiip_aligned.xtc") - - - #4 Perform the RMSF analysis for each universe, time, and record results - universes = dict() - universes["uHDD"] = dict() - universes["uHDD"]["ref"] = uHDD - universes["uS3"] = dict() - universes["uS3"]["ref"] = uS3 - universes["uXTC"] = dict() - universes["uXTC"]["ref"] = uXTC - - for name in ("uHDD", "uS3", "uXTC"): - c_alphas = universes[name]["ref"].select_atoms("protein and name CA") - - start = time.time() - R = rms.RMSF(c_alphas).run() - stop = time.time() - - universes[name]["RMSF_time"] = stop - start - - rmsf_speeds = dict() - rmsf_speeds["uXTC"] = universes["uXTC"]["RMSF_time"] - rmsf_speeds["uS3"] = universes["uS3"]["RMSF_time"] - rmsf_speeds["uHDD"] = universes["uHDD"]["RMSF_time"] - with open('notebook_data_tmp/RMSF_speeds.json', 'w') as j: - json.dump(rmsf_speeds, j) +Initial benchmarks were performed in the `Beckstein Lab ` +on Spudda, which has: +- 2 Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz +- 12 total cores +- 32GB RAM -.. image:: _static/benchmark_figures/RMSF_speeds.svg \ No newline at end of file +Additionally, local file speed tests were performed in the 1.31 TB SSD scratch space using RAID 0. \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index ab75f13..e707f2d 100755 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,7 +10,8 @@ Welcome to zarrtraj's documentation! :maxdepth: 2 :caption: Contents: - getting_started + installation + walkthrough api zarrmd-file-spec/v0.1.0 benchmarks diff --git a/docs/source/getting_started.rst b/docs/source/installation.rst similarity index 90% rename from docs/source/getting_started.rst rename to docs/source/installation.rst index 6ff95bd..06b1217 100755 --- a/docs/source/getting_started.rst +++ b/docs/source/installation.rst @@ -14,6 +14,10 @@ With conda Ensure that you have `conda `_ installed. +Clone the repository:: + + git clone https://github.com/Becksteinlab/zarrtraj.git . + Create a virtual environment and activate it:: conda create --name zarrtraj @@ -23,8 +27,8 @@ Build this package from source:: pip install -e -Development environment installation ------------------------------------- +Development installation +------------------------ After creating and activating a conda environment as described, install the package with documentation and testing dependencies:: diff --git a/docs/source/walkthrough.rst b/docs/source/walkthrough.rst new file mode 100644 index 0000000..f6ac97a --- /dev/null +++ b/docs/source/walkthrough.rst @@ -0,0 +1,109 @@ +Full walkthrough +================ + +Reading H5MD trajectories from cloud storage +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Uploading your H5MD file +######################## + +First, upload your H5MD trajectories to an AWS S3 bucket. This requires that an S3 Bucket is setup and configured for +write access using the credentials stored in "sample_profile" If you've never configured an S3 Bucket before, see +`this guide `_. You can setup a profile to easily manage AWS +credentials using `this VSCode extension `_. +Here is a sample profile (stored in ~/.aws/credentials) where +`the key is an access key associated with a user that has read and write permissions for the bucket +`_:: + + [sample_profile] + aws_access_key_id = + +MDAnalysis can write a trajectory from +`any of its supported formats into H5MD `_. We +recommend using the `chunks` kwarg with the MDAnalysis H5MDWriter with a value that yields ~8-16MB chunks of data for best S3 performance. +Once written locally, you can upload the trajectory to S3 programatically:: + + import os + from botocore.exceptions import ClientError + import boto3 + import logging + + os.environ["AWS_PROFILE"] = "sample_profile" + # This is the AWS region the bucket is stored in + os.environ["AWS_REGION"] = "us-west-1" + + def upload_h5md_file(bucket_name, file_name): + s3_client = boto3.client("s3") + obj_name = os.path.basename(file_name) + try: + response = s3_client.upload_file( + file_name, bucket_name, obj_name + ) + except ClientError as e: + logging.error(e) + return False + return True + + if __name__ == "__main__": + # Using test H5MD file from the zarrtraj repo + upload_h5md_file("sample-bucket-name", "zarrtraj/data/COORDINATES_SYNTHETIC_H5MD.h5md") + +You can also upload the H5MD file directly using the AWS web interface by navigating to S3, the bucket name, and pressing +"upload". + +Reading your H5MD file +###################### + +After the file is uploaded, you can use the same credentials to stream the file into MDAnalysis:: + + import zarrtraj + import MDAnalysis as mda + # This sample topology requires installing MDAnalysisTests + from MDAnalysisTests.datafiles import COORDINATES_TOPOLOGY + import os + + os.environ["AWS_PROFILE"] = "sample_profile" + os.environ["AWS_REGION"] = "us-west-1" + + u = mda.Universe(COORDINATES_TOPOLOGY, "s3://sample-bucket-name/COORDINATES_SYNTHETIC_H5MD.h5md") + for ts in u.trajectory: + pass + +You can follow this same process for reading `.zarrmd` files with the added advantage +that Zarrtarj can write `.zarrmd` files directly into an S3 bucket. + +Writing trajectories from MDAnalysis into a zarrmd file in an S3 Bucket +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Using the same credentials with read/write access, you can write a trajectory +into your bucket. + +You can change the stored precision of floating point values in the file with the optional +`precision` kwarg and pass in any `numcodecs.Codec` compressor with the optional +`compressor` kwarg. See [numcodecs](https://numcodecs.readthedocs.io/en/stable/) +for more on the available compressors. + +Chunking is automatically determined for all datasets to be optimized for +cloud storage and is not configurable by the user. +Initial benchmarks show this chunking strategy is effective for disk storage as well.:: + + import zarrtraj + import MDAnalysis as mda + from MDAnalysisTests.datafiles import PSF, DCD + import numcodecs + import os + + os.environ["AWS_PROFILE"] = "sample_profile" + os.environ["AWS_REGION"] = "us-west-1" + + u = mda.Universe(PSF, DCD) + with mda.Writer("s3://sample-bucket-name/test.zarrmd", + n_atoms=u.trajectory.n_atoms, + precision=3, + compressor=numcodecs.Blosc(cname="zstd", clevel=9)) as W: + for ts in u.trajectory: + W.write(u.atoms) + +If you have additional questions, please don't hesitate to open a discussion on the `zarrtarj github `_. +The `MDAnalysis discord `_ is also a +great resource for asking questions and getting involved in MDAnalysis. \ No newline at end of file diff --git a/notebooks/cloud_disk_others.ipynb b/notebooks/cloud_disk_others.ipynb deleted file mode 100644 index dee7d5a..0000000 --- a/notebooks/cloud_disk_others.ipynb +++ /dev/null @@ -1,111 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, we will compare the zarrtraj 0.0.0 reader and writer disk and cloud capabilities with other file format capabilities" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from zarrtraj import *\n", - "import MDAnalysis as mda\n", - "import MDAnalysisData\n", - "import zarr\n", - "import h5py\n", - "import numcodecs\n", - "import os\n", - "import subprocess\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import time\n", - "\n", - "os.chdir('notebook_data_tmp')" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - } - ], - "source": [ - "# Using yiip for benchmarking\n", - "yiip = MDAnalysisData.yiip_equilibrium.fetch_yiip_equilibrium_short()\n", - "u = mda.Universe(yiip.topology, yiip.trajectory)\n", - "positions = mda.Universe(yiip.topology, yiip.trajectory, in_memory=True).trajectory.get_array()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u = mda.Universe(yiip.topology, positions)\n", - "\n", - "with mda.Writer(f\"yiip_xtc.xtc\", n_atoms) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u)\n", - "\n", - "with mda.Writer(f\"yiip_trr.trr\", n_atoms) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u) \n", - "\n", - "with mda.Writer(f\"yiip_h5md_c.h5md\", n_atoms, convert_units=False) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u) \n", - "\n", - "with mda.Writer(f\"yiip_h5md_un.h5md\", n_atoms, convert_units=False) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/format.ipynb b/notebooks/format.ipynb deleted file mode 100644 index 06cbb8a..0000000 --- a/notebooks/format.ipynb +++ /dev/null @@ -1,275 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[5805. 601. 4015.]\n", - "[11610. 1202. 8030.]\n", - "[23220. 2404. 16060.]\n", - "[46440. 4808. 32120.]\n", - "[92880. 9616. 64240.]\n", - "[185760. 19232. 128480.]\n", - "[371520. 38464. 256960.]\n", - "[743040. 76928. 513920.]\n", - "[1486080. 153856. 1027840.]\n", - "[2972160. 307712. 2055680.]\n", - "[5944320. 615424. 4111360.]\n", - "[11888640. 1230848. 8222720.]\n", - "[23777280. 2461696. 16445440.]\n", - "[47554560. 4923392. 32890880.]\n", - "[95109120. 9846784. 65781760.]\n", - "[1.9021824e+08 1.9693568e+07 1.3156352e+08]\n", - "[3.8043648e+08 3.9387136e+07 2.6312704e+08]\n", - "[7.6087296e+08 7.8774272e+07 5.2625408e+08]\n", - "[1.52174592e+09 1.57548544e+08 1.05250816e+09]\n", - "[3.0434918e+09 3.1509709e+08 2.1050163e+09]\n", - "[6.0869837e+09 6.3019418e+08 4.2100326e+09]\n", - "[1.2173967e+10 1.2603884e+09 8.4200653e+09]\n", - "[2.4347935e+10 2.5207767e+09 1.6840131e+10]\n", - "[4.8695869e+10 5.0415534e+09 3.3680261e+10]\n", - "[9.7391739e+10 1.0083107e+10 6.7360522e+10]\n", - "[1.94783478e+11 2.01662136e+10 1.34721044e+11]\n", - "[3.8956696e+11 4.0332427e+10 2.6944209e+11]\n", - "[7.7913391e+11 8.0664855e+10 5.3888418e+11]\n", - "[1.55826782e+12 1.61329709e+11 1.07776836e+12]\n", - "[3.1165356e+12 3.2265942e+11 2.1555367e+12]\n", - "[6.2330713e+12 6.4531884e+11 4.3110734e+12]\n", - "[1.2466143e+13 1.2906377e+12 8.6221468e+12]\n", - "[2.4932285e+13 2.5812753e+12 1.7244294e+13]\n", - "[4.9864570e+13 5.1625507e+12 3.4488587e+13]\n", - "[9.9729141e+13 1.0325101e+13 6.8977175e+13]\n", - "[1.9945828e+14 2.0650203e+13 1.3795435e+14]\n", - "[3.9891656e+14 4.1300406e+13 2.7590870e+14]\n", - "[7.978331e+14 8.260081e+13 5.518174e+14]\n", - "[1.5956662e+15 1.6520162e+14 1.1036348e+15]\n", - "[3.1913325e+15 3.3040324e+14 2.2072696e+15]\n", - "[6.3826650e+15 6.6080649e+14 4.4145392e+15]\n", - "[1.2765330e+16 1.3216130e+15 8.8290784e+15]\n", - "[2.5530660e+16 2.6432260e+15 1.7658157e+16]\n", - "[5.1061320e+16 5.2864519e+15 3.5316313e+16]\n", - "[1.0212264e+17 1.0572904e+16 7.0632627e+16]\n", - "[2.0424528e+17 2.1145808e+16 1.4126525e+17]\n", - "[4.0849056e+17 4.2291615e+16 2.8253051e+17]\n", - "[8.169811e+17 8.458323e+16 5.650610e+17]\n", - "[1.6339622e+18 1.6916646e+17 1.1301220e+18]\n", - "[3.2679245e+18 3.3833292e+17 2.2602441e+18]\n", - "[6.5358490e+18 6.7666584e+17 4.5204881e+18]\n", - "[-5.3750462e+18 1.3533317e+18 9.0409763e+18]\n", - "[ 7.6966518e+18 2.7066634e+18 -3.6479157e+17]\n", - "[-3.0534405e+18 5.4133268e+18 -7.2958314e+17]\n", - "[-6.1068811e+18 -7.6200906e+18 -1.4591663e+18]\n", - "[ 6.2329819e+18 3.2065629e+18 -2.9183326e+18]\n", - "[-5.9807803e+18 6.4131259e+18 -5.8366651e+18]\n", - "[ 6.4851835e+18 -5.6204923e+18 6.7734138e+18]\n", - "[-5.4763771e+18 7.2057594e+18 -4.8999164e+18]\n", - "[ 7.4939898e+18 -4.0352253e+18 8.6469113e+18]\n", - "[-3.4587645e+18 -8.0704505e+18 -1.1529215e+18]\n", - "[-6.917529e+18 2.305843e+18 -2.305843e+18]\n", - "[ 4.611686e+18 4.611686e+18 -4.611686e+18]\n", - "[5.3541675e+22 5.5432466e+21 3.7031839e+22]\n", - "[1.0708335e+23 1.1086493e+22 7.4063677e+22]\n", - "[2.14166699e+23 2.21729864e+22 1.48127355e+23]\n", - "[4.2833340e+23 4.4345973e+22 2.9625471e+23]\n", - "[8.5666679e+23 8.8691946e+22 5.9250942e+23]\n", - "[1.71333359e+24 1.77383891e+23 1.18501884e+24]\n", - "[3.4266672e+24 3.5476778e+23 2.3700377e+24]\n", - "[6.8533344e+24 7.0953556e+23 4.7400754e+24]\n", - "[1.3706669e+25 1.4190711e+24 9.4801507e+24]\n", - "[2.7413337e+25 2.8381423e+24 1.8960301e+25]\n", - "[5.4826675e+25 5.6762845e+24 3.7920603e+25]\n", - "[1.0965335e+26 1.1352569e+25 7.5841206e+25]\n", - "[2.1930670e+26 2.2705138e+25 1.5168241e+26]\n", - "[4.3861340e+26 4.5410276e+25 3.0336482e+26]\n", - "[8.7722680e+26 9.0820552e+25 6.0672965e+26]\n", - "[1.7544536e+27 1.8164110e+26 1.2134593e+27]\n", - "[3.5089072e+27 3.6328221e+26 2.4269186e+27]\n", - "[7.0178144e+27 7.2656442e+26 4.8538372e+27]\n", - "[1.4035629e+28 1.4531288e+27 9.7076743e+27]\n", - "[2.8071258e+28 2.9062577e+27 1.9415349e+28]\n", - "[5.6142515e+28 5.8125153e+27 3.8830697e+28]\n", - "[1.1228503e+29 1.1625031e+28 7.7661395e+28]\n", - "[2.2457006e+29 2.3250061e+28 1.5532279e+29]\n", - "[4.4914012e+29 4.6500123e+28 3.1064558e+29]\n", - "[8.9828024e+29 9.3000245e+28 6.2129116e+29]\n", - "[1.7965605e+30 1.8600049e+29 1.2425823e+30]\n", - "[3.5931210e+30 3.7200098e+29 2.4851646e+30]\n", - "[7.1862419e+30 7.4400196e+29 4.9703293e+30]\n", - "[1.4372484e+31 1.4880039e+30 9.9406585e+30]\n", - "[2.8744968e+31 2.9760079e+30 1.9881317e+31]\n", - "[5.7489935e+31 5.9520157e+30 3.9762634e+31]\n", - "[1.1497987e+32 1.1904031e+31 7.9525268e+31]\n", - "[2.2995974e+32 2.3808063e+31 1.5905054e+32]\n", - "[4.5991948e+32 4.7616126e+31 3.1810107e+32]\n", - "[9.1983897e+32 9.5232251e+31 6.3620214e+32]\n", - "[1.8396779e+33 1.9046450e+32 1.2724043e+33]\n", - "[3.6793559e+33 3.8092901e+32 2.5448086e+33]\n" - ] - } - ], - "source": [ - "import zarrtraj\n", - "import MDAnalysis as mda\n", - "from MDAnalysisTests.datafiles import PSF\n", - "import zarr\n", - "import numpy as np\n", - "import os\n", - "import h5py\n", - "\n", - "\n", - "u = mda.Universe(PSF, 'zarr_3341_100.zarrtraj')\n", - "\n", - "for ts in u.trajectory:\n", - " print(ts[0])\n" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "Unable to read particles with .", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[31], line 15\u001b[0m\n\u001b[1;32m 12\u001b[0m root \u001b[38;5;241m=\u001b[39m zarr\u001b[38;5;241m.\u001b[39mopen_group(store\u001b[38;5;241m=\u001b[39mstore, mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28misinstance\u001b[39m(root, zarr\u001b[38;5;241m.\u001b[39mGroup)\n\u001b[0;32m---> 15\u001b[0m u \u001b[38;5;241m=\u001b[39m \u001b[43mmda\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mUniverse\u001b[49m\u001b[43m(\u001b[49m\u001b[43mPSF\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mZARRTRAJ\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 17\u001b[0m \u001b[38;5;66;03m#for ts in u.trajectory:\u001b[39;00m\n\u001b[1;32m 18\u001b[0m \u001b[38;5;66;03m# print(ts[0])\u001b[39;00m\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/core/universe.py:375\u001b[0m, in \u001b[0;36mUniverse.__init__\u001b[0;34m(self, topology, all_coordinates, format, topology_format, transformations, guess_bonds, vdwradii, fudge_factor, lower_bound, in_memory, in_memory_step, *coordinates, **kwargs)\u001b[0m\n\u001b[1;32m 370\u001b[0m coordinates \u001b[38;5;241m=\u001b[39m _resolve_coordinates(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfilename, \u001b[38;5;241m*\u001b[39mcoordinates,\n\u001b[1;32m 371\u001b[0m \u001b[38;5;28mformat\u001b[39m\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mformat\u001b[39m,\n\u001b[1;32m 372\u001b[0m all_coordinates\u001b[38;5;241m=\u001b[39mall_coordinates)\n\u001b[1;32m 374\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m coordinates:\n\u001b[0;32m--> 375\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload_new\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcoordinates\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43min_memory\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43min_memory\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 376\u001b[0m \u001b[43m \u001b[49m\u001b[43min_memory_step\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43min_memory_step\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 378\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m transformations:\n\u001b[1;32m 379\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mcallable\u001b[39m(transformations):\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/core/universe.py:580\u001b[0m, in \u001b[0;36mUniverse.load_new\u001b[0;34m(self, filename, format, in_memory, in_memory_step, **kwargs)\u001b[0m\n\u001b[1;32m 577\u001b[0m \u001b[38;5;66;03m# supply number of atoms for readers that cannot do it for themselves\u001b[39;00m\n\u001b[1;32m 578\u001b[0m kwargs[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mn_atoms\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39matoms\u001b[38;5;241m.\u001b[39mn_atoms\n\u001b[0;32m--> 580\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtrajectory \u001b[38;5;241m=\u001b[39m \u001b[43mreader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mformat\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 581\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtrajectory\u001b[38;5;241m.\u001b[39mn_atoms \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39matoms):\n\u001b[1;32m 582\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe topology and \u001b[39m\u001b[38;5;132;01m{form}\u001b[39;00m\u001b[38;5;124m trajectory files don\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mt\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 583\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m have the same number of atoms!\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 584\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTopology number of atoms \u001b[39m\u001b[38;5;132;01m{top_n_atoms}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 588\u001b[0m fname\u001b[38;5;241m=\u001b[39mfilename,\n\u001b[1;32m 589\u001b[0m trj_n_atoms\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtrajectory\u001b[38;5;241m.\u001b[39mn_atoms))\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/lib/util.py:2553\u001b[0m, in \u001b[0;36mstore_init_arguments..wrapper\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 2551\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2552\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_kwargs[key] \u001b[38;5;241m=\u001b[39m arg\n\u001b[0;32m-> 2553\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/coordinates/chain.py:270\u001b[0m, in \u001b[0;36mChainReader.__init__\u001b[0;34m(self, filenames, skip, dt, continuous, convert_units, **kwargs)\u001b[0m\n\u001b[1;32m 268\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dt \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 269\u001b[0m kwargs[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdt\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m dt\n\u001b[0;32m--> 270\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreaders \u001b[38;5;241m=\u001b[39m [core\u001b[38;5;241m.\u001b[39mreader(filename, convert_units\u001b[38;5;241m=\u001b[39mconvert_units, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 271\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m filename \u001b[38;5;129;01min\u001b[39;00m filenames]\n\u001b[1;32m 272\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfilenames \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([fn[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(fn, \u001b[38;5;28mtuple\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m fn\n\u001b[1;32m 273\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m fn \u001b[38;5;129;01min\u001b[39;00m filenames])\n\u001b[1;32m 274\u001b[0m \u001b[38;5;66;03m# pointer to \"active\" trajectory index into self.readers\u001b[39;00m\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/coordinates/chain.py:270\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 268\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dt \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 269\u001b[0m kwargs[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdt\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m dt\n\u001b[0;32m--> 270\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreaders \u001b[38;5;241m=\u001b[39m [\u001b[43mcore\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreader\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconvert_units\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconvert_units\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 271\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m filename \u001b[38;5;129;01min\u001b[39;00m filenames]\n\u001b[1;32m 272\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfilenames \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([fn[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(fn, \u001b[38;5;28mtuple\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m fn\n\u001b[1;32m 273\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m fn \u001b[38;5;129;01min\u001b[39;00m filenames])\n\u001b[1;32m 274\u001b[0m \u001b[38;5;66;03m# pointer to \"active\" trajectory index into self.readers\u001b[39;00m\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/coordinates/core.py:85\u001b[0m, in \u001b[0;36mreader\u001b[0;34m(filename, format, **kwargs)\u001b[0m\n\u001b[1;32m 83\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[1;32m 84\u001b[0m errmsg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mUnable to read \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfilename\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m with \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mReader\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[0;32m---> 85\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(errmsg) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", - "\u001b[0;31mTypeError\u001b[0m: Unable to read particles with ." - ] - } - ], - "source": [ - "import fsspec\n", - "import s3fs\n", - "import zarr\n", - "\n", - "\n", - "s3 = s3fs.S3FileSystem(key='AKIAUODTGZQXMD5QNMP5', \n", - " secret='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',\n", - ")\n", - "\n", - "\n", - "store = s3fs.S3Map(root='s3://test-zarrtraj-bucket/zarr_3341_100.zarrtraj', s3=s3, check=False)\n", - "root = zarr.open_group(, mode='r')\n", - "\n", - "isinstance(root, zarr.Group)\n", - "u = mda.Universe(PSF, root, format=\"ZARRTRAJ\")\n", - "\n", - "#for ts in u.trajectory:\n", - "# print(ts[0])\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "u = mda.Universe(PSF, 's3://test-zarrtraj-bucket/zarr_3341_100.zarrtraj', storage_options={'key':'AKIAUODTGZQXMD5QNMP5', 'secret':'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'})" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "eecd529570564c04b9fd3da4824a569f", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Tree(nodes=(Node(disabled=True, name='/', nodes=(Node(disabled=True, name='particles', nodes=(Node(disabled=Tr…" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "\n", - "root = zarr.open_group('s3://test-zarrtraj-bucket/zarr_3341_100.zarrtraj', mode='r',storage_options={'key':'AKIAUODTGZQXMD5QNMP5', 'secret':'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'})\n", - "root.tree()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'mda' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[36], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m u \u001b[38;5;241m=\u001b[39m \u001b[43mmda\u001b[49m\u001b[38;5;241m.\u001b[39mUniverse(PSF, root)\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ts \u001b[38;5;129;01min\u001b[39;00m u\u001b[38;5;241m.\u001b[39mtrajectory:\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(ts)\n", - "\u001b[0;31mNameError\u001b[0m: name 'mda' is not defined" - ] - } - ], - "source": [ - "u = mda.Universe(PSF, root)\n", - "\n", - "for ts in u.trajectory:\n", - " print(ts)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/format_comparison_benchmark.ipynb b/notebooks/format_comparison_benchmark.ipynb deleted file mode 100644 index 095af9d..0000000 --- a/notebooks/format_comparison_benchmark.ipynb +++ /dev/null @@ -1,483 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "importing zarrtraj...\n" - ] - }, - { - "ename": "FileNotFoundError", - "evalue": "[Errno 2] No such file or directory: 'benchmark_files'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[9], line 14\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpd\u001b[39;00m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mtime\u001b[39;00m\n\u001b[0;32m---> 14\u001b[0m \u001b[43mos\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mchdir\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mbenchmark_files\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'benchmark_files'" - ] - } - ], - "source": [ - "# Import parking garage\n", - "from zarrtraj import *\n", - "import MDAnalysis as mda\n", - "import MDAnalysisData\n", - "import zarr\n", - "import h5py\n", - "import numcodecs\n", - "import os\n", - "import subprocess\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import time\n", - "os.chdir('benchmark_files')\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "YiiP_system.pdb: 0.00B [00:00, ?B/s]" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "YiiP_system.pdb: 8.84MB [00:03, 2.88MB/s] \n", - "YiiP_system_9ns_center.xtc: 373MB [00:22, 16.2MB/s] \n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "135.99\n" - ] - } - ], - "source": [ - "# Setup yiip data\n", - "yiip = MDAnalysisData.yiip_equilibrium.fetch_yiip_equilibrium_short()\n", - "u = mda.Universe(yiip.topology, yiip.trajectory)\n", - "positions = mda.Universe(yiip.topology, yiip.trajectory, in_memory=True).trajectory.get_array()\n", - "\n", - "print(np.max(positions))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# Convenience methods\n", - "\n", - "def generate_traj(n_atoms):\n", - " frames = 100\n", - " # Generate positions array using min and max position value from yiip_equilibrium\n", - " pos = (135.99 + 35.31) * np.random.random_sample((frames, n_atoms, 3)) - 35.31\n", - " pos = pos.astype('float32')\n", - " return pos\n", - "\n", - "def filesize(filename):\n", - " return int(subprocess.check_output(['du','-s', filename]).split()[0].decode('utf-8'))\n", - "\n", - "def exponential_range(start, stop, step):\n", - " return [pow(10, i) for i in range(start, stop, step)]\n", - "\n", - "\n", - " \n" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/zarr/creation.py:295: UserWarning: ignoring keyword argument 'maxshape'\n", - " warn(\"ignoring keyword argument %r\" % k)\n" - ] - }, - { - "data": { - "text/plain": [ - "'\\n with mda.Writer(f\"10e{i}_trr.trr\", n_atoms) as w:\\n for ts in u.trajectory:\\n w.write(u.atoms) \\n \\n with mda.Writer(f\"10e{i}_h5md_c.h5md\", n_atoms, compression=\\'gzip\\', compression_opts=9, convert_units=False) as w:\\n for ts in u.trajectory:\\n w.write(u.atoms) \\n\\n with mda.Writer(f\"10e{i}_h5md_un.h5md\", n_atoms, convert_units=False) as w:\\n for ts in u.trajectory:\\n w.write(u.atoms) \\n\\n'" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "filters = [numcodecs.Quantize(digits=6, dtype='f4')]\n", - "compressor = numcodecs.Blosc(cname='zstd', clevel=9)\n", - "compressor2 = numcodecs.Blosc(cname='zstd', clevel=0)\n", - "\n", - "for i in range(3, 8):\n", - " n_atoms = pow(10, i)\n", - " traj = generate_traj(n_atoms)\n", - " u = mda.Universe(traj)\n", - "\n", - " z1 = zarr.open_group(f\"10e{i}_zarr_c_f.zarr\", mode='w')\n", - " z2 = zarr.open_group(f\"10e{i}_zarr_un_f.zarr\", mode='w')\n", - " z3 = zarr.open_group(f\"10e{i}_zarr_c.zarr\", mode='w')\n", - " z4 = zarr.open_group(f\"10e{i}_zarr_un.zarr\", mode= 'w')\n", - "\n", - " with mda.Writer(z1, n_atoms, format='ZARRTRAJ', mode='w', compressor=compressor, filters=filters) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms)\n", - "\n", - " with mda.Writer(z2, n_atoms, format='ZARRTRAJ', mode='w', compressor=compressor2, filters=filters) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms)\n", - "\n", - " with mda.Writer(z3, n_atoms, format='ZARRTRAJ', mode='w', compressor=compressor) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms)\n", - "\n", - " with mda.Writer(z4, n_atoms, format='ZARRTRAJ', mode='w', compressor=compressor2) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms)\n", - "\n", - " with mda.Writer(f\"10e{i}_xtc.xtc\", n_atoms) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms)\n", - "\"\"\"\n", - " with mda.Writer(f\"10e{i}_trr.trr\", n_atoms) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms) \n", - " \n", - " with mda.Writer(f\"10e{i}_h5md_c.h5md\", n_atoms, compression='gzip', compression_opts=9, convert_units=False) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms) \n", - "\n", - " with mda.Writer(f\"10e{i}_h5md_un.h5md\", n_atoms, convert_units=False) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u.atoms) \n", - "\n", - "\"\"\"\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "n = np.logspace(3, 7, 5)\n", - "\n", - "x_filesize = []\n", - "t_filesize = []\n", - "z_filesize = []\n", - "z_c_filesize = []\n", - "h_filesize =[]\n", - "h_c_filesize =[]\n", - "\n", - "for i in range(3, 8, 1):\n", - " x_filesize.append(filesize(f'10e{i}_xtc.xtc'))\n", - " t_filesize.append(filesize(f'10e{i}_trr.trr'))\n", - " z_filesize.append(filesize(f'10e{i}_zarr_un.zarr'))\n", - " z_c_filesize.append(filesize(f'10e{i}_zarr_c.zarr'))\n", - " h_filesize.append(filesize(f'10e{i}_h5md_un.h5md'))\n", - " h_c_filesize.append(filesize(f'10e{i}_h5md_c.h5md'))\n", - "\n", - "\n", - "# Graph zarrtraj size vs h5 size\n", - "plt.title('Number of atoms vs trajectory filesize for different formats')\n", - "plt.xlabel('Number of atoms')\n", - "plt.ylabel('Trajectory filesize (kilobytes)')\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", - "\n", - "plt.scatter(n, z_filesize, c='blue', s=50, label=\"Zarr Uncompressed\", marker='x')\n", - "plt.scatter(n, z_c_filesize, c='magenta', s=50, label=\"Zarr Compressed\", marker='x')\n", - "plt.scatter(n, h_filesize, c='cyan', s=50, label=\"H5MD Uncompressed\", marker='+')\n", - "plt.scatter(n, h_c_filesize, c='green', s=50, label=\"H5MD Compressed\", marker='x')\n", - "plt.scatter(n, x_filesize, c='red', s=50, label=\"XTC\", marker='1')\n", - "plt.scatter(n, t_filesize, c='black', s=50, label=\"TRR\", marker='2')\n", - "\n", - "plt.legend()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = n.astype('int')\n", - "n_atoms = np.tile(n, 6)\n", - "formats = ['Zarr compressed' for _ in range(5)] + ['Zarr uncompressed' for _ in range(5)] + ['H5MD compressed' for _ in range(5)] + ['H5MD uncompressed' for _ in range(5)] + ['XTC' for _ in range(5)] + ['TRR' for _ in range(5)]\n", - "fsizes = z_c_filesize + z_filesize + h_c_filesize + h_filesize + x_filesize + t_filesize\n", - "\n", - "data = {'Format' : formats, 'Number of atoms' : n_atoms, 'Filesize (kilobyte)' : fsizes} \n", - "df = pd.DataFrame(data)\n", - "\n", - "# Displaying the table\n", - "print(df)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Testing quantize filter\n", - "\n", - "n = np.logspace(3, 7, 5)\n", - "\n", - "x_filesize = []\n", - "z_f_filesize = []\n", - "z_c_f_filesize = []\n", - "z_filesize = []\n", - "z_c_filesize = []\n", - "\n", - "\n", - "for i in range(3, 8, 1):\n", - " x_filesize.append(filesize(f'10e{i}_xtc.xtc'))\n", - " z_filesize.append(filesize(f'10e{i}_zarr_un.zarr'))\n", - " z_c_filesize.append(filesize(f'10e{i}_zarr_c.zarr'))\n", - " z_f_filesize.append(filesize(f'10e{i}_zarr_un_f.zarr'))\n", - " z_c_f_filesize.append(filesize(f'10e{i}_zarr_c_f.zarr'))\n", - "\n", - "# Graph zarrtraj size vs h5 size\n", - "plt.title('Number of atoms vs trajectory filesize for Zarr and XTC on SSD')\n", - "plt.xlabel('Number of atoms')\n", - "plt.ylabel('Trajectory filesize (kilobytes)')\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", - "\n", - "plt.scatter(n, z_filesize, c='blue', s=75, label=\"Zarr Uncompressed\", marker='o')\n", - "plt.scatter(n, z_c_filesize, c='cyan', s=100, label=\"Zarr Compressed\", marker='x')\n", - "plt.scatter(n, z_f_filesize, c='red', s=50, label=\"Zarr Uncompressed, Quantized\", marker='x')\n", - "plt.scatter(n, z_c_f_filesize, c='orange', s=50, label=\"Zarr Compressed, Quantized\", marker='x')\n", - "plt.scatter(n, x_filesize, c='black', s=50, label=\"XTC\", marker='1')\n", - "\n", - "\n", - "plt.legend()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - }, - { - "ename": "TypeError", - "evalue": "only length-1 arrays can be converted to Python scalars", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[27], line 13\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m mda\u001b[38;5;241m.\u001b[39mWriter(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124myiip_trr.trr\u001b[39m\u001b[38;5;124m\"\u001b[39m, n_atoms) \u001b[38;5;28;01mas\u001b[39;00m w:\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ts \u001b[38;5;129;01min\u001b[39;00m u\u001b[38;5;241m.\u001b[39mtrajectory:\n\u001b[0;32m---> 13\u001b[0m \u001b[43mw\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mu\u001b[49m\u001b[43m)\u001b[49m \n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m mda\u001b[38;5;241m.\u001b[39mWriter(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124myiip_h5md_c.h5md\u001b[39m\u001b[38;5;124m\"\u001b[39m, n_atoms, compression\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mgzip\u001b[39m\u001b[38;5;124m'\u001b[39m, compression_opts\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m9\u001b[39m, convert_units\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m w:\n\u001b[1;32m 16\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ts \u001b[38;5;129;01min\u001b[39;00m u\u001b[38;5;241m.\u001b[39mtrajectory:\n", - "File \u001b[0;32m~/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/coordinates/base.py:1609\u001b[0m, in \u001b[0;36mWriterBase.write\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 1591\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrite\u001b[39m(\u001b[38;5;28mself\u001b[39m, obj):\n\u001b[1;32m 1592\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Write current timestep, using the supplied `obj`.\u001b[39;00m\n\u001b[1;32m 1593\u001b[0m \n\u001b[1;32m 1594\u001b[0m \u001b[38;5;124;03m Parameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1607\u001b[0m \u001b[38;5;124;03m removed. Use AtomGroup or Universe as an input instead.\u001b[39;00m\n\u001b[1;32m 1608\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 1609\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_write_next_frame\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/coordinates/TRR.py:128\u001b[0m, in \u001b[0;36mTRRWriter._write_next_frame\u001b[0;34m(self, ag)\u001b[0m\n\u001b[1;32m 125\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlambda\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m ts\u001b[38;5;241m.\u001b[39mdata:\n\u001b[1;32m 126\u001b[0m lmbda \u001b[38;5;241m=\u001b[39m ts\u001b[38;5;241m.\u001b[39mdata[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlambda\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m--> 128\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_xdr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mxyz\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvelo\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mforces\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbox\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtime\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlmbda\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 129\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mn_atoms\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/lib/formats/libmdaxdr.pyx:597\u001b[0m, in \u001b[0;36mMDAnalysis.lib.formats.libmdaxdr.TRRFile.write\u001b[0;34m()\u001b[0m\n", - "\u001b[0;31mTypeError\u001b[0m: only length-1 arrays can be converted to Python scalars" - ] - } - ], - "source": [ - "# YIIP size and iteration time tests\n", - "compressor = numcodecs.Blosc(cname='zstd', clevel=9)\n", - "compressor2 = numcodecs.Blosc(cname='zstd', clevel=0)\n", - "\n", - "u = mda.Universe(yiip.topology, yiip.trajectory)\n", - "\n", - "with mda.Writer(f\"yiip_xtc.xtc\", n_atoms) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u)\n", - "\n", - "with mda.Writer(f\"yiip_trr.trr\", n_atoms) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u) \n", - "\n", - "with mda.Writer(f\"yiip_h5md_c.h5md\", n_atoms, compression='gzip', compression_opts=9, convert_units=False) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u) \n", - "\n", - "with mda.Writer(f\"yiip_h5md_un.h5md\", n_atoms, convert_units=False) as w:\n", - " for ts in u.trajectory:\n", - " w.write(u) \n", - "\n", - "root = zarr.open(f\"yiip_zarr_c.zarr\", mode='w')\n", - "root.create_dataset('positions', data=positions, \n", - " chunks = (1, n_atoms, 3), \n", - " compressor=compressor)\n", - "\n", - "root2 = zarr.open(f\"yiip_zarr_un.zarr\", mode='w')\n", - "root2.create_dataset('positions', data=positions, \n", - " chunks = (1, n_atoms, 3), \n", - " compressor=compressor2)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/scratch/ljwoods2/workspace/zarrtraj/notebooks/benchmark_files\n" - ] - } - ], - "source": [ - "filters = [numcodecs.Quantize(digits=3, dtype='f4')]\n", - "compressor = numcodecs.Blosc(cname='zstd', clevel=9)\n", - "\n", - "z = zarr.open_group('test.zarr', 'w')\n", - "z.require_dataset('test', 10000000, filters=filters, compressor=compressor)\n", - "z['test'] = np.random.random_sample(size=10000000)\n", - "\n", - "z2 = zarr.open_group('test2.zarr', 'w')\n", - "z2.require_dataset('test', 10000000)\n", - "z2['test'] = np.random.random_sample(size=10000000)\n", - "\n", - "print(os.getcwd())" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[ 32.45393 52.221672 121.138695]\n", - "[ 32453 52221 121138]\n", - "[ 29.723679 134.0101 63.78008 ]\n", - "[ 29723 134010 63780]\n", - "[133.78802 64.78357 110.687935]\n", - "[133788 64783 110687]\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[18], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m3\u001b[39m, \u001b[38;5;241m8\u001b[39m):\n\u001b[1;32m 2\u001b[0m n_atoms \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mpow\u001b[39m(\u001b[38;5;241m10\u001b[39m, i)\n\u001b[0;32m----> 3\u001b[0m traj \u001b[38;5;241m=\u001b[39m \u001b[43mgenerate_traj\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn_atoms\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(traj[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m])\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(traj\u001b[38;5;241m.\u001b[39mshape[\u001b[38;5;241m2\u001b[39m]):\n", - "Cell \u001b[0;32mIn[4], line 7\u001b[0m, in \u001b[0;36mgenerate_traj\u001b[0;34m(n_atoms)\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;66;03m# Generate positions array using min and max position value from yiip_equilibrium\u001b[39;00m\n\u001b[1;32m 6\u001b[0m pos \u001b[38;5;241m=\u001b[39m (\u001b[38;5;241m135.99\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m35.31\u001b[39m) \u001b[38;5;241m*\u001b[39m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mrandom_sample((frames, n_atoms, \u001b[38;5;241m3\u001b[39m)) \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m35.31\u001b[39m\n\u001b[0;32m----> 7\u001b[0m pos \u001b[38;5;241m=\u001b[39m pos\u001b[38;5;241m.\u001b[39mastype(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfloat32\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m pos\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [] - } - ], - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/initial_benchmark.ipynb b/notebooks/initial_benchmark.ipynb deleted file mode 100644 index b40e8a8..0000000 --- a/notebooks/initial_benchmark.ipynb +++ /dev/null @@ -1,487 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "# Method to create trajectory data\n", - "# based on MDAnalaysisTests/data/coordinates/create_data.py\n", - "\n", - "# This method will create a psuedo-random array using np.arange and np.random.shuffle\n", - "# it will return a list of the randomly generated data\n", - "import numpy as np\n", - "\n", - "def generate_traj(n_atoms, frames):\n", - " pos = np.arange(3 * n_atoms)\n", - " np.random.shuffle(pos)\n", - " pos = pos.reshape(n_atoms, 3)\n", - " orig_box = np.array([81.1, 82.2, 83.3], dtype=np.float32)\n", - "\n", - " positions = np.empty((frames, n_atoms, 3), dtype=np.float32)\n", - " velocities = np.empty((frames, n_atoms, 3), dtype=np.float32)\n", - " forces = np.empty((frames, n_atoms, 3), dtype=np.float32)\n", - " time = np.empty((frames), dtype=np.float32)\n", - " frame = np.empty((frames), dtype=np.int32)\n", - "\n", - " dimensions = np.empty((frames, 3))\n", - "\n", - " for i in range(frames):\n", - " positions[i] = 2** i * pos\n", - " velocities[i] = positions[i] / 10\n", - " forces[i] = positions[i] / 100\n", - " time[i] = i\n", - " frame[i] = i\n", - "\n", - " dimensions[i][:3] = orig_box[:3] + i\n", - " dimensions[i][3:] = orig_box[3:] + i * 0.1\n", - "\n", - " return [frame, dimensions, positions, velocities, forces, time]\n" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "# Method to load trajectory data into a zarr trajectory \n", - "# Also includes a method to load data into an hdf5 traj using the same \n", - "# test format to make a fair comparison\n", - "\n", - "import zarr\n", - "import h5py\n", - "\n", - "def create_zarr_traj(n_atoms, frames, compressor):\n", - " # create zarr group layout\n", - " root = zarr.open(f'zarrfiles/zarr_{n_atoms}_{frames}.zarrtraj', mode='a')\n", - " particles = root.create_group('particles')\n", - " group1 = particles.create_group('group1')\n", - " box = group1.create_group('box')\n", - " edges = box.create_group('edges')\n", - " position = group1.create_group('position')\n", - " velocity = group1.create_group('velocity')\n", - " force = group1.create_group('force')\n", - "\n", - " traj = generate_traj(n_atoms, frames)\n", - "\n", - " edges.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " edges.create_dataset('value', data=traj[1], dtype=np.float32)\n", - " position.create_dataset('value', data=traj[2], compressor=compressor, \n", - " chunks=(1, n_atoms, 3), dtype=np.float32)\n", - " position.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " position.create_dataset('time', data=traj[-1], dtype=np.float32)\n", - " velocity.create_dataset('value', data=traj[3], compressor=compressor, \n", - " chunks=(1, n_atoms, 3), dtype=np.float32)\n", - " velocity.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " velocity.create_dataset('time', data=traj[-1], dtype=np.float32)\n", - " force.create_dataset('value', data=traj[4], compressor=compressor, \n", - " chunks=(1, n_atoms, 3), dtype=np.float32)\n", - " force.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " force.create_dataset('time', data=traj[-1], dtype=np.float32)\n", - "\n", - " # Return filename to make it easy to open file\n", - " return f'zarrfiles/zarr_{n_atoms}_{frames}.zarrtraj'\n", - "\n", - "\n", - "def create_hdf5_traj(n_atoms, frames, compression, compression_opts):\n", - " with h5py.File(f'h5files/h5_{n_atoms}_{frames}.h5', 'w') as root:\n", - " particles = root.create_group('particles')\n", - " group1 = particles.create_group('group1')\n", - " box = group1.create_group('box')\n", - " edges = box.create_group('edges')\n", - " position = group1.create_group('position')\n", - " velocity = group1.create_group('velocity')\n", - " force = group1.create_group('force')\n", - "\n", - " traj = generate_traj(n_atoms, frames)\n", - "\n", - " edges.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " edges.create_dataset('value', data=traj[1], dtype=np.float32)\n", - " position.create_dataset('value', data=traj[2], compression=compression, \n", - " compression_opts=compression_opts, chunks=(1, n_atoms, 3),\n", - " dtype=np.float32)\n", - " position.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " position.create_dataset('time', data=traj[-1], dtype=np.float32)\n", - " velocity.create_dataset('value', data=traj[3], compression=compression, \n", - " compression_opts=compression_opts, chunks=(1, n_atoms, 3),\n", - " dtype=np.float32)\n", - " velocity.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " velocity.create_dataset('time', data=traj[-1], dtype=np.float32)\n", - " force.create_dataset('value', data=traj[4], compression=compression, \n", - " compression_opts=compression_opts, chunks=(1, n_atoms, 3),\n", - " dtype=np.float32)\n", - " force.create_dataset('step', data=traj[0], dtype=np.int32)\n", - " force.create_dataset('time', data=traj[-1], dtype=np.float32)\n", - "\n", - " # Return filename to make it easy to open file\n", - " return f'h5files/h5_{n_atoms}_{frames}.h5'\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "import subprocess\n", - "\n", - "\n", - "def zarr_filesize(filename):\n", - " return int(subprocess.check_output(['du','-s', filename]).split()[0].decode('utf-8'))\n", - "def h5_filesize(filename):\n", - " return int(subprocess.check_output(['du','-s', filename]).split()[0].decode('utf-8'))\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "import zarr\n", - "import h5py\n", - "import time\n", - "\n", - "# Each method opens, iterates through each frame, and closes the file\n", - "\n", - "def zarr_iterate_frames(filename):\n", - " start_time = time.time()\n", - " root = zarr.open(filename, mode='a')\n", - " pos_vals = root['particles/group1/position/value']\n", - " num = 0\n", - " for i in range(len(pos_vals)):\n", - " # arbitrary task that requires accessing third dimension\n", - " num += pos_vals[i][0][0]\n", - " end_time = time.time()\n", - " return end_time - start_time\n", - "\n", - "def h5_iterate_frames(filename):\n", - " start_time = time.time()\n", - " with h5py.File(filename, 'r') as root:\n", - " pos_vals = root['particles/group1/position/value']\n", - " num = 0\n", - " for i in range(len(pos_vals)):\n", - " # arbitrary task that requires accessing third dimension\n", - " num += pos_vals[i][0][0]\n", - " end_time = time.time()\n", - " return end_time - start_time\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "import zarr\n", - "\n", - "# Create files of different sizes\n", - "\n", - "n = []\n", - "z_filesize = []\n", - "h_filesize =[]\n", - "\n", - "def exponential_range(start, stop, step):\n", - " return [pow(10, i) for i in range(start, stop, step)]\n", - "\n", - "for i in exponential_range(3, 8, 1):\n", - " compressor = zarr.Blosc(cname='zstd', clevel=9, shuffle=zarr.Blosc.SHUFFLE)\n", - " zarr_fname = create_zarr_traj(i, 5, compressor)\n", - " h5_fname = create_hdf5_traj(i, 5, compression='gzip', compression_opts=9)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1.e+03 1.e+04 1.e+05 1.e+06 1.e+07]\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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bkkAAAAkuUHQ+f7779W8eXMlJSVJkgIb+gJ9AADQaDl96GrdunUaOnSowsLCZDAYtHz58hr7zJs3z3xlTlxcnNavX2/etm/fPvn5+enWW29Vz549NWvWrAasHgAANGZODzplZWWKjY3Vq6++Wuv2xYsXa+LEiZo6dap27NihpKQkDRo0yHxPprNnz2r9+vXKysrSV199pdWrV2v16tUXfb8zZ86otLTU4gEAANyT04POoEGD9NRTT130Ttgvvviixo0bp3vuuUddunTRnDlzFB4ervnz50uS2rVrp4SEBIWHh8vb21uDBw9WTk7ORd8vMzNTAQEB5kd4eLgjfiwAANAIOD3oXEplZaW2b9+ulJQUi/aUlBRt2rRJkpSQkKCjR4/qxIkTqq6u1rp169SlS5eLHnPKlCkqKSkxP/Lz8x36MwAAAOdp1EHn+PHjqqqqUkhIiEV7SEiI+f5NzZo106xZs9S3b19169ZNHTt21JAhQy56TG9vb/n7+1s83M3YsWOVmppao33NmjUyGAw6efKk+XuDwSAPDw8FBASoR48eevTRR1VQUGDxuunTp5v3vfDx73//W5K0cOHCWrdXVFQ0xI8LAMBFucRVVwaDweK50Wi0aBs0aJAGDRrU0GW5hb1798rf31+lpaX65ptv9Oyzz+qvf/2r1qxZo5iYGPN+Xbt2NQeb8y68ws3f31979+612M5tHQAAztaog05wcLA8PT1r3H27sLCwRi+PrbKyspSVlaWqqqp6HeeyKitNN/u48OaaBQWmNbG9vBz73lZo27atWrdurSuvvFKdOnXSsGHD1KNHD91///3asGGDeb9mzZrpyiuvvOhxDAbDJbcDAOAMjXroysvLS3FxcTWuolq9erV69+5dr2Onp6dr165d2rp1a72Oc0mVldKIEVKfPqbbt0qmr336mNorKx333nXk6+ur8ePHa+PGjSosLLT6dadPn1b79u3Vrl07DRkyRDt27HBglQAAWMfpPTqnT5/W/v37zc9zc3OVk5OjwMBARUREKCMjQ6NHj1Z8fLx69eqlBQsWKC8vT+PHj3di1VYqKpK++046eFBKTpYWLZLS0kzPz2+/sKfHjj755BP5+flZtFnbe3XttddKkg4dOqS2bdtKknbu3GlxvKioKG3ZssW8/8KFCxUTE6PS0lLNnTtXiYmJ+s9//qOOHTva48cB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x65DV64WXgAAACQrg863336r6OhoeXh46Ntvv73kvt26dbNLYQAAAPVlVdDp3r27jhw5orZt26p79+4yGAy13rXcleboAAAA92dV0MnNzVWbNm3M3wMAALgCq4JO+/btzd8HBASodevWte63f/9+uxQFAABgDzavjDx48OBab9y5d+9e9e/f3x41AQAA2IXNQeeKK65Qamqqzp07Z27bvXu3+vfvr9tvv92uxTlSVlaWoqKilJCQ4OxSAACAg9h8C4iKigrdfPPNCg0N1eLFi/X9999rwIABuvPOO/Xiiy86qk6HYR0dAABcj7Wf3zb36Pj4+OiTTz7Rvn37NGLECA0YMEBpaWkuGXIAAIB7q9O9rgwGgxYvXqybbrpJt99+ux5//HHzPvSKAACAxsKqoSsPD49a73V1/qXn19VxxXV0GLoCAMD12PUWENnZ2XYrDAAAoKFwrysAAOC2rJqMnJeXZ9NBf/rppzoVAwAAYE9WBZ2EhATde++92rJly0X3KSkp0RtvvKHo6Gh9+OGHdisQAACgrqwautq9e7dmzZqlW265Rc2bN1d8fLzCwsLk4+OjEydOaNeuXfr+++8VHx+v5557ToMGDXJ03QAAAJdl04KBFRUVWrlypdavX69Dhw7pl19+UXBwsHr06KGBAwcqOjrakbXaVVZWlrKyslRVVaUffviBq64AAHAh1l51ZfPKyO6Gy8sBAHA9DlsZGQAAwFUQdAAAgNsi6AAAALdF0AEAAG6LoAMAANxWnYLOO++8o8TERIWFhenw4cOSpDlz5mjFihV2LQ4AAKA+bA468+fPV0ZGhgYPHqyTJ0+a71beunVrzZkzx971AQAA1JnNQeeVV17RG2+8oalTp8rT09PcHh8fr507d9q1OAAAgPqwOejk5uaqR48eNdq9vb1VVlZml6IAAADsweagExkZqZycnBrtn376qaKiouxREwAAgF1YdVPPCz3yyCNKT09XRUWFjEajtmzZovfff1+ZmZl68803HVEjAABAndgcdO666y6dO3dOjz76qMrLy/WHP/xBV111lebOnavf//73jqgRAACgTup1U8/jx4+rurpabdu2tWdNDYqbegIA4HocdlPPmTNn6ssvv5QkBQcHm0NOWVmZZs6cWcdyG15WVpaioqKUkJDg7FIAAICD2Nyj4+HhoebNmyszM1MZGRnm9qNH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kdFoVFRUlO688075+vo6okaHYo4OAACux9rPb5t7dNatW6fevXvr3nvvtWg/d+6c1q1bp759+9peLQAAgAPYPEcnOTlZxcXFNdpLSkqUnJxsl6IaQlZWlqKiopSQkODsUgAAgIPYHHSMRqMMBkON9qKioho3+GzM0tPTtWvXLm3dutXZpQAAAAexeuhq+PDhkiSDwaCxY8fK29vbvK2qqkrffvutevfubf8KAQAA6sjqoBMQECDJ1KPTqlUri4nHXl5euuGGG2rM2wEAAHAmq4PO+buWX3311XrkkUfUokULhxUFAABgDzbP0UlLS9NPP/1Uo33fvn06dOiQPWoCAACwC5uDztixY7Vp06Ya7Zs3b9bYsWPtURMAAIBd2Bx0duzYocTExBrtN9xwg3JycuxREwAAgF3YHHQMBoNOnTpVo72kpERVVVV2KQoAAMAebA46SUlJyszMtAg1VVVVyszMVJ8+fexaHAAAQH3YfAuIZ599Vn379lXnzp2VlJQkSVq/fr1KS0v15Zdf2r1AAACAurK5RycqKkrffvutRo4cqcLCQp06dUppaWnas2ePoqOjHVEjAABAndTp7uXuhLuXAwDgeqz9/La5R0cyDVX98Y9/VO/evc1r6rzzzjvasGFD3aoFAABwAJuDzj//+U8NHDhQvr6++uabb3TmzBlJ0qlTpzRr1iy7FwgAAFBXNgedp556Sq+99preeOMNNW/e3Nzeu3dvffPNN3YtzpGysrIUFRWlhIQEZ5cCAAAcxOags3fvXvXt27dGu7+/v06ePGmPmhpEenq6du3apa1btzq7FAAA4CA2B53Q0FDt37+/RvuGDRvUoUMHuxQFAABgDzYHnT/96U966KGHtHnzZhkMBv3888/6+9//rsmTJ+uBBx5wRI0AAAB1YvOCgY8++qhKSkqUnJysiooK9e3bV97e3po8ebImTJjgiBoBAADqpM7r6JSXl2vXrl2qrq5WVFSU/Pz87F1bg2AdHQAAXI+1n9829+ic16JFC8XHx9f15QAAAA5nVdAZPny4Fi5cKH9/fw0fPvyS+/r5+alr164aP368AgIC7FIkAABAXVgVdAICAmQwGMzfX8qZM2f02muvaePGjfroo4/qXyEAAEAdOeReV7t27VJCQoLKysrsfWi7Y44OAACux6H3urqczp07a9OmTY44NAAAgNXqNBl5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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "# Graph filesize vs num atoms for hdf5 and zarr\n", - "\n", - "n = np.logspace(3, 7, 5)\n", - "print(n)\n", - "z_filesize = []\n", - "h_filesize =[]\n", - "\n", - "for i in exponential_range(3, 8, 1):\n", - " z_filesize.append(zarr_filesize(f'zarrfiles/zarr_{i}_5.zarr'))\n", - " h_filesize.append(h5_filesize(f'h5files/h5_{i}_5.h5'))\n", - "\n", - "# Graph zarrtraj size vs h5 size\n", - "plt.xlabel('Number of atoms')\n", - "plt.ylabel('Trajectory filesize (kilobytes)')\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", - "\n", - "plt.scatter(n, z_filesize, c='blue', s=20, label=\"Zarr\", alpha=0.5)\n", - "plt.scatter(n, h_filesize, c='red', s=20, label=\"HDF5\", marker='x')\n", - "\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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8MTv4K5du7Rhwwa99tpruvfee1VSUuKr8KHqP8MzZ84oOztbVqtVa9as0dKlS7V06VJffoSg5onfQcn+H5JVq1Z5t3XdhFdJMj/44AOnsmuvvdYcPXq0U9lVV11lPvbYY5VeY/To0ebChQu9FSIuoirP77HHHjNjY2PN+Ph4s3nz5mZYWJg5ZcoUX4WM83jid/CWW24x161b560QcQlVeYarV682+/Xr5zg3Y8YMc8aMGV6PFRVV53dw/vz55j333OPV+GgR8rHTp09rw4YNSktLcypPS0vT6tWrJUm//PKL43+fJSUlWrlypdq3b+/zWFGRK89v2rRpys/P165duzRz5kzdf//9evLJJ/0RLirhyjM8dOiQTp06JUnas2ePtmzZotatW/s8VlTOlWeYnJysX375RYcOHVJZWZlWrlypDh06+CNcnMeV51fO291iksTIMR87cOCAbDaboqKinMqjoqK0b98+SfZ/eEeNGiXTNGWaph566CFdc801/ggX53Hl+aFmc+UZbt26VX/4wx9Up04dGYahWbNmKSIiwh/hohKuPMO6devqueee0w033CDTNJWWlqbbbrvNH+HiPK7+O3rkyBF98803+sc//uHVeEiE/MQwDKdj0zQdZUlJScrJyfFDVHDVxZ7fuYYPH+6jiOCuiz3Dnj176rvvvvNHWHDDpX4P+/fvr/79+/s6LLjoUs+vadOmPhkfS9eYj0VGRspisVRoPSgqKqqQHaPm4fkFPp5h4OMZBraa9vxIhHysfv36SkpKqjB7YenSperZs6efooKreH6Bj2cY+HiGga2mPT+6xrzg2LFj+umnnxzHubm5ysnJUUREhK644gplZGRo6NCh6t69u3r06KE33nhDeXl5Gj16tB+jRjmeX+DjGQY+nmFgC6jn59U5aUHqq6++MiVVeA0bNsxRx2q1mvHx8Wb9+vXNbt26mStWrPBfwHDC8wt8PMPAxzMMbIH0/NhrDAAABC3GCAEAgKBFIgQAAIIWiRAAAAhaJEIAACBokQgBAICgRSIEAACCFokQAAAIWiRCAAAgaJEIAahRdu3aJcMwlJOT4+9QHLZt26brrrtOoaGh6tKli7/DAeBBJEIAnAwfPlyGYWj69OlO5YsXL5ZhGH6Kyr+eeuopNWrUSNu3b9eyZcuqdI2amOABIBECUInQ0FA9//zzOnTokL9D8ZjTp09X+b07d+7U9ddfr/j4eDVv3tyDUQHwNxIhABXcfPPNuvzyyzVt2rQL1nn66acrdBNlZmaqVatWjuPhw4dr0KBBeu655xQVFaXw8HBNmTJFZ8+e1cSJExUREaHY2Fj99a9/rXD9bdu2qWfPngoNDdXVV1+t5cuXO53fsmWLbr31VjVu3FhRUVEaOnSoDhw44Djfp08fPfTQQ8rIyFBkZKT69u1b6ecoKyvT1KlTFRsbq5CQEHXp0kWfffaZ47xhGNqwYYOmTp0qwzD09NNPV3qdzz77TNdff73Cw8PVvHlz3Xbbbdq5c6fjfEJCgiSpa9euMgxDffr0cen+5S1JCxcuVEpKiho0aKDk5GT9+OOPWrdunbp3767GjRvrlltu0f79+x3vW758ua699lo1atRI4eHh6tWrl3bv3l1p7EAwIxECUIHFYtFzzz2nV155RXv27KnWtb788kvt3btXK1eu1Isvvqinn35at912m5o1a6a1a9dq9OjRGj16tPLz853eN3HiRE2YMEGbNm1Sz549dfvtt6u4uFiSVFhYqN69e6tLly5av369PvvsM/3yyy+68847na7xzjvvqG7dulq1apVef/31SuObNWuWXnjhBc2cOVPffvut+vXrp9tvv107duxw3Ovqq6/WhAkTVFhYqEceeaTS6xw/flwZGRlat26dli1bpjp16uiOO+5QWVmZJOmbb76RJH3xxRcqLCxUVlaWS/cv99RTT+l//ud/tHHjRtWtW1d33XWXHn30Uc2aNUvZ2dnauXOnnnzySUnS2bNnNWjQIPXu3Vvffvut1qxZowceeCBouzaBi/LLnvcAaqxhw4aZAwcONE3TNK+77jpz5MiRpmma5gcffGCe+0/GU089ZXbu3NnpvS+99JIZHx/vdK34+HjTZrM5ytq3b2+mpKQ4js+ePWs2atTIfO+990zTNM3c3FxTkjl9+nRHnTNnzpixsbHm888/b5qmaT7xxBNmWlqa073z8/NNSeb27dtN0zTN3r17m126dLnk542JiTGfffZZp7Lk5GTzwQcfdBx37tzZfOqppy55rXMVFRWZkszvvvvO6XNt2rTJrfuXv+/NN990nH/vvfdMSeayZcscZdOmTTPbt29vmqZpFhcXm5LM5cuXuxUzEIxoEQJwQc8//7zeeecdbdmypcrXuPrqq1Wnzn//qYmKilKnTp0cxxaLRc2bN1dRUZHT+3r06OH4uW7duurevbu2bt0qSdqwYYO++uorNW7c2PG66qqrJMmpO6p79+4Xja2kpER79+5Vr169nMp79erluJerdu7cqbvvvlutW7dWWFiYoyssLy/PI/e/5pprHD9HRUVJktPfY1RUlOPvMCIiQsOHD1e/fv00YMAAzZo1S4WFhW59HiBYkAgBuKAbbrhB/fr10+OPP17hXJ06dWSaplPZmTNnKtSrV6+e07FhGJWWlXchXUx5105ZWZkGDBignJwcp9eOHTt0ww03OOo3atToktc897rlTNN0uxtpwIABKi4u1ty5c7V27VqtXbtWkmuDtF25/7l/Z+Xnzi879+/w7bff1po1a9SzZ08tWLBA7dq107///W+3PhMQDEiEAFzU9OnT9c9//lOrV692Kr/sssu0b98+p2TIk1PDz/3SPnv2rDZs2OBo9enWrZt++OEHtWrVSm3btnV6uZr8SFJYWJhiYmL09ddfO5WvXr1aHTp0cPk6xcXF2rp1q/7nf/5HN910kzp06FBhxl39+vUlSTabzeP3v5CuXbtq0qRJWr16tTp27Kh333232tcEahsSIQAX1alTJ91zzz165ZVXnMr79Omj/fv3a8aMGdq5c6esVqs+/fRTj93XarXqgw8+0LZt2zRmzBgdOnRII0eOlCSNGTNGBw8e1F133aVvvvlGP//8sz7//HONHDnSKdFwxcSJE/X8889rwYIF2r59ux577DHl5ORo7NixLl+jWbNmat68ud544w399NNP+vLLL5WRkeFUp0WLFmrQoIFjYPeRI0c8dv/z5ebmatKkSVqzZo12796tzz//XD/++KNHkiugtiERAnBJzzzzTIVusA4dOmjOnDmyWq3q3LmzvvnmmwvOqKqK6dOn6/nnn1fnzp2VnZ2tDz/8UJGRkZKkmJgYrVq1SjabTf369VPHjh01duxYNW3a1Gk8kisefvhhTZgwQRMmTFCnTp302Wef6aOPPtKVV17p8jXq1Kmj999/Xxs2bFDHjh01fvx4/eUvf3GqU7duXb388st6/fXXFRMTo4EDB3rs/udr2LChtm3bpt/85jdq166dHnjgAT300EP6wx/+UOVrArWVYZ7/rxsAAECQoEUIAAAELRIhAAAQtEiEAABA0CIRAgAAQYtECAAABC0SIQAAELRIhAAAQNAiEQIAAEGLRAgAAAQtEiEAABC0SIQAAEDQIhECAABB6/8D0MI5sQxDly4AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "# Graph iteration time vs number atoms for hdf5 and zarr\n", - "\n", - "n = np.logspace(3, 7, 5)\n", - "print(len(n))\n", - "\n", - "z_iteration_time = []\n", - "h_iteration_time = []\n", - "\n", - "for i in exponential_range(3, 8, 1):\n", - " z_iteration_time.append(zarr_iterate_frames(f'zarrfiles/zarr_{i}_5.zarr'))\n", - " h_iteration_time.append(h5_iterate_frames(f'h5files/h5_{i}_5.h5'))\n", - "\n", - "\n", - "\n", - "\n", - "# Graph zarrtraj time vs h5 size\n", - "plt.xlabel('Number of atoms')\n", - "plt.ylabel('Open file + iteration + close time (s)')\n", - "plt.xscale('log')\n", - "plt.yscale('log')\n", - "plt.scatter(n, z_iteration_time, c='blue', label=\"Zarr\")\n", - "plt.scatter(n, h_iteration_time, c='red', label=\"HDF5\")\n", - "\n", - "plt.legend()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[[165 150 0]\n", - " [118 151 117]\n", - " [114 296 35]\n", - " [267 225 94]\n", - " [176 149 257]\n", - " [228 32 244]\n", - " [243 183 236]\n", - " [100 274 194]\n", - " [ 18 237 59]\n", - " [127 57 24]\n", - " [ 43 206 138]\n", - " [ 80 258 21]\n", - " [ 82 247 124]\n", - " [107 173 213]\n", - " [271 134 104]\n", - " [238 115 3]\n", - " [ 92 251 205]\n", - " [147 88 273]\n", - " [ 89 290 179]\n", - " [ 67 113 36]\n", - " [269 246 221]\n", - " [130 45 72]\n", - " [250 19 155]\n", - " [ 11 203 28]\n", - " [252 286 270]\n", - " [215 29 144]\n", - " [122 27 199]\n", - " [ 23 266 76]\n", - " [ 73 4 140]\n", - " [192 152 116]\n", - " [162 15 276]\n", - " [ 81 259 226]\n", - " [ 91 230 212]\n", - " [255 7 61]\n", - " [ 86 167 49]\n", - " [137 223 278]\n", - " [ 63 154 51]\n", - " [ 56 295 172]\n", - " [287 13 170]\n", - " [ 5 10 200]\n", - " [239 42 110]\n", - " [ 30 241 291]\n", - " [ 64 74 216]\n", - " [254 128 207]\n", - " [210 222 189]\n", - " [132 293 87]\n", - " [159 26 55]\n", - " [211 204 284]\n", - " [214 245 123]\n", - " [121 197 233]\n", - " [ 34 220 22]\n", - " [ 54 120 164]\n", - " [261 169 6]\n", - " [209 20 77]\n", - " [ 78 260 33]\n", - " [240 95 139]\n", - " [112 282 198]\n", - " [145 90 25]\n", - " [ 1 106 157]\n", - " [135 217 277]\n", - " [178 125 46]\n", - " [142 119 2]\n", - " [161 297 285]\n", - " [158 279 131]\n", - " [248 268 133]\n", - " [148 38 60]\n", - " [ 65 208 93]\n", - " [ 17 294 103]\n", - " [143 193 201]\n", - " [292 129 70]\n", - " [ 53 156 234]\n", - " [283 102 182]\n", - " [263 14 196]\n", - " [126 166 68]\n", - " [190 101 262]\n", - " [191 69 171]\n", - " [256 174 9]\n", - " [281 39 242]\n", - " [185 187 202]\n", - " [ 48 275 177]\n", - " [160 153 16]\n", - " [195 188 231]\n", - " [146 175 232]\n", - " [ 37 83 105]\n", - " [ 31 235 280]\n", - " [180 41 168]\n", - " [184 50 98]\n", - " [ 52 99 97]\n", - " [111 265 8]\n", - " [181 289 264]\n", - " [109 136 84]\n", - " [ 58 12 224]\n", - " [ 44 40 229]\n", - " [141 253 96]\n", - " [299 219 298]\n", - " [108 79 163]\n", - " [ 47 218 272]\n", - " [288 62 66]\n", - " [ 71 227 186]\n", - " [ 75 249 85]]\n" - ] - } - ], - "source": [ - "import numpy as np\n", - "\n", - "# pos = np.arange(3 * n_atoms).reshape(n_atoms, 3)\n", - "\n", - "pos = np.arange(3 * 100)\n", - "np.random.shuffle(pos)\n", - "pos = pos.reshape(100, 3)\n", - "\n", - "\n", - "print(pos)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zarrfiles/zarr_3341_100.zarrtraj'" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "import numcodecs\n", - "create_zarr_traj(3341, 100, compressor=numcodecs.Blosc(cname='zstd', clevel=9))" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/raw_zarr_benchmarks/filesize_compressed_filtered.ipynb b/notebooks/raw_zarr_benchmarks/filesize_compressed_filtered.ipynb deleted file mode 100644 index 5da830e..0000000 --- a/notebooks/raw_zarr_benchmarks/filesize_compressed_filtered.ipynb +++ /dev/null @@ -1,158 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "XTC and aggressively quantised compressed Zarr (3 digits precision, GROMACS default) in terms of file size\n", - "\n", - "Also @Lawson could I have a < 50 Mb aggressively quantised zarrtraj file? Or even better an S3 link to one?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Compare yiip filesize between xtc and zarrtraj with max compression and 3 digits of precision" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - } - ], - "source": [ - "from zarrtraj import *\n", - "import MDAnalysis as mda\n", - "import MDAnalysisData\n", - "import zarr\n", - "import h5py\n", - "import numcodecs\n", - "import os\n", - "import subprocess\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import time\n", - "\n", - "u_yiip = mda.Universe(\"../notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", \"../notebook_data_tmp/yiip_equilibrium/YiiP_system_90ns_center.xtc\")\n", - "\n", - "# Write to zarrtraj with (1, n_atoms, 3) chunks\n", - "filters = [numcodecs.Quantize(digits=3, dtype='f4')]\n", - "compressor = numcodecs.Blosc(cname='zstd', clevel=9)\n", - "with mda.Writer(\"../notebook_data_tmp/filesize_benchmarks/yiip_1_frame.zarrtraj\", u_yiip.trajectory.n_atoms,\n", - " n_frames=u_yiip.trajectory.n_frames, chunks=(1, u_yiip.trajectory.n_atoms, 3),\n", - " compressor=compressor, filters=filters) as w:\n", - " for ts in u_yiip.trajectory:\n", - " w.write(u_yiip)\n", - "\n", - "# Write to zarrtraj with (10, n_atoms, 3) chunks\n", - "with mda.Writer(\"../notebook_data_tmp/filesize_benchmarks/yiip_10_frame.zarrtraj\", u_yiip.trajectory.n_atoms, \n", - " n_frames=u_yiip.trajectory.n_frames, chunks=(10, u_yiip.trajectory.n_atoms, 3),\n", - " compressor=compressor, filters=filters) as w:\n", - " for ts in u_yiip.trajectory:\n", - " w.write(u_yiip)\n", - "\n", - "# Write to zarrtraj with (100, n_atoms, 3) chunks\n", - "with mda.Writer(\"../notebook_data_tmp/filesize_benchmarks/yiip_100_frame.zarrtraj\", u_yiip.trajectory.n_atoms,\n", - " n_frames=u_yiip.trajectory.n_frames, chunks=(100, u_yiip.trajectory.n_atoms, 3),\n", - " compressor=compressor, filters=filters) as w:\n", - " for ts in u_yiip.trajectory:\n", - " w.write(u_yiip)\n", - "\n", - "# # Write to xtc\n", - "# with mda.Writer(\"../notebook_data_tmp/filesize_benchmarks/yiip.xtc\", u_yiip.trajectory.n_atoms) as w:\n", - "# for ts in u_yiip.trajectory:\n", - "# w.write(u_yiip)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "def filesize(filename):\n", - " return int(subprocess.check_output(['du','-s', filename]).split()[0].decode('utf-8'))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABHUAAAIwCAYAAAAI11fIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAACGOUlEQVR4nOzdd3gUVfv/8c+SXkggIYTQQpEqIE0QkCZCDEV51EdE6aAiYgGxIEpXFHuhiFLEBxGVIkhHAUFQqRZAkSJFQJokgJSQ3L8/+O7+sskGEggkG96v68oFOzkzc8+cs2dm7pyZcZiZCQAAAAAAAF4lX04HAAAAAAAAgKwjqQMAAAAAAOCFSOoAAAAAAAB4IZI6AAAAAAAAXoikDgAAAAAAgBciqQMAAAAAAOCFSOoAAAAAAAB4IZI6AAAAAAAAXoikDgAAAAAAgBe6pKTOzz//rK5du6p06dIKDAxUaGioatasqZEjR+ro0aPZHWOu06VLF5UqVSqnw7hsGzZsUOPGjRUeHi6Hw6G33norp0NCBgYPHiyHw5Hp8s2aNVPPnj2zPY5PPvkkS+3kzz//lMPh0KRJky5YbtmyZXI4HFq2bNllxZcdMhuzJO3fv19dunRR4cKFFRgYqGrVqmn8+PHpyr3wwguqWbOmUlJSrkDEly4r2/r111+rdu3aCgkJkcPh0KxZszRp0iQ5HA79+eefrnKe+seXXnpJs2bNytbYs4unbfBkyZIlat68uYoWLaqAgAAVLlxYt9xyi+bNm3dZ62/SpImaNGni+pyVOvGkVKlS6tKli+vzvn37NHjwYG3cuPGy4sxJafdRZlyNPiUpKUlly5b1qmPnvHnzNHjw4Cu2/Eupq6zI6jHoajp69KjuvfdeFS5cWA6HQ23btpUkORwOt31+pdtmVs8XclLa9vLvv/9q8ODBHveNc7sOHz58RWPIqA+eNm2arr/+egUFBcnhcLj61HfffVfXXXed/P395XA4dOzYsWyNL7tciWOBsy1/8cUX2bbMrGjSpImqVKlyxZaf9nh6rcns+VFmXan++/nnn1fJkiXl6+urAgUKSPJ8LErbF2en3HAd45vVGT744AP16tVLFSpU0FNPPaXKlSsrKSlJa9eu1dixY7V69WrNnDnzSsSaa7zwwgt6/PHHczqMy9atWzedPHlSn376qQoWLJgnElWQvvzyS3333XeaPHlyti/7k08+0a+//qonnngi25ftbRISEnTzzTfr7NmzGjlypGJiYjR16lT16NFDCQkJ6tu3r6tsv3799N577+mjjz5S165dczDqS2Nmuueee1S+fHnNnj1bISEhqlChgs6dO6fVq1crJibmgvO/9NJLuvvuu10XOd7oyJEjuv7669WjRw8VKVJER48e1dixY9WqVSt9/PHH6tChQ7asJyYmRqtXr1bZsmUvaf6ZM2cqLCzM9Xnfvn0aMmSISpUqperVq2dLjFfb6NGjszxPzZo1tXr1alWuXPkKRHSen5+fBg4cqD59+qhjx46KjIy8YuvKLvPmzdOoUaOu2IntpdRVVuTmY9CwYcM0c+ZMTZgwQWXLllVERIQkafXq1SpevPhVi6NHjx667bbbrtr6Lkfa9vLvv/9qyJAhknRFk4MX4qkPPnTokDp27KjbbrtNo0ePVkBAgMqXL6+NGzfqscceU48ePdS5c2f5+voqf/78ORL3xeSFY8HVlvZ4istzJfrvL7/8Ui+++KIGDBig+Ph4BQQESLryx6K0rsY5x8VkKamzevVqPfzww2revLlmzZrl2nGS1Lx5cz355JNasGBBtgeZW/z7778KDg6+5JPt3ObXX3/VAw88oPj4+JwO5aoxM50+fVpBQUE5HcoV89JLL+k///mPihUrltOh5GljxozRjh07tHbtWtWqVUuSFBcXp/3792vgwIHq1q2b6y8G4eHh6tChg15++WV16dLFa/6K6rRv3z4dPXpU//nPf9SsWTO330VFReVITMnJyTp37pzbcehKateundq1a+c2rXXr1ipdurTGjRuXbUmdgIAA3XTTTZc8f40aNbIljkvlPE5mp0s5SQoLC7us/ZhZ7du3V9++ffX+++/rueeeu+Lrczp16pQCAwM99iXZVQeXcrzMyRPaS5Vd5wW//vqrypYtq/vvv99t+tVoh6kVL178qiaRLkdubC+e+uCtW7cqKSlJHTp0UOPGjV3TN23aJEl64IEHVKdOnWxZ/5XoQ3Fpcvp4iov79ddfJUmPPfaYChcu7Jp+tfuWq3XOcSFZuv3qpZdeksPh0Lhx4zyeSPv7++v22293fU5JSdHIkSNVsWJF13D1Tp06ae/evW7zOYfPrV69WvXr11dQUJBKlSqliRMnSpLmzp2rmjVrKjg4WFWrVk2XOHIOydywYYPuvPNOhYWFuS6iDh065FZ22rRpatGihWJiYhQUFKRKlSrp2Wef1cmTJ93KdenSRaGhofrll1/UokUL5c+f33Ux4+n2gs8//1x169ZVeHi4goODVaZMGXXr1s2tzO7du9WhQwcVLlxYAQEBqlSpkl5//XW3WzKcwz5fe+01vfHGGypdurRCQ0NVr149ff/99xeqHpdff/1Vd9xxhwoWLKjAwEBVr15dH330kev3zuF0586d05gxY+RwOC56kXnmzBkNHTpUlSpVUmBgoCIjI9W0aVOtWrXKVeb06dPq37+/SpcuLX9/fxUrVkyPPPJIuqGopUqVUuvWrfXVV1+pRo0arnr46quvXPFVqlRJISEhqlOnjtauXes2v7NuNm3apGbNmikkJERRUVHq3bu3/v33X7eyDodDvXv31tixY1WpUiUFBAS49sUff/yh++67z60+Ro0a5TZ/SkqKhg8frgoVKigoKEgFChRQtWrV9Pbbb7vKHDp0SA8++KBKlCihgIAARUVFqUGDBlqyZInbspYsWaJmzZopLCxMwcHBatCggb7++ut0+3ru3LmqXr26AgICVLp0ab322msXrJvUNmzYoB9//FEdO3ZMt8+d9Zz2xzlU8GLb0aRJE82dO1e7du1ym99p3759uueee5Q/f36Fh4erXbt2OnDgQKZj92Tt2rW6/fbbFRERocDAQNWoUUOfffaZ6/c//fSTHA6Hx1ue5s+fL4fDodmzZ7umZabOM+u7775TdHS0K6Hj1Lp1a508eTJdP9WxY0dt3bpVS5cuveiys9pPbdu2TS1btlRoaKhKlCihJ598UmfOnHEre6n1M3jwYNcFwjPPPCOHw+Hq/zIzNNfhcOjkyZP66KOPXG0m9V9gDxw4oIceekjFixeXv7+/SpcurSFDhujcuXOuMs5+ceTIkRo+fLhKly6tgIAA1768WDtx+v7779WgQQMFBgaqaNGi6t+/v5KSki66DzLi5+enAgUKyNf34n8fMTONHDlSsbGxCgwMVM2aNTV//vx05TIa+v/ll1+qWrVqCggIUJkyZfT22297vM0i9XDxZcuW6cYbb5Qkde3a1bX/LzRKw1mnixcvVteuXRUREaGQkBC1adNGO3bscCvrPHZ/++23ql+/voKDg13HvcTERPXr18/tePDEE0+ka8MpKSl69913Vb16dVcfe9NNN7l9bz0Nox4zZoxuuOEGhYaGKn/+/KpYsaJbUiWjodCzZ89WvXr1FBwcrPz586t58+ZavXq1Wxnnft20aZPat2+v8PBwRUdHq1u3bkpISHAr6+/vr3bt2mncuHEyM9f0jPrb1N+XtWvX6t5771WpUqVc5z3t27fXrl27PNbJokWL1K1bN0VFRSk4OFhnzpy5YB2k1aVLF1d/5ymeCx0vhwwZorp16yoiIkJhYWGqWbOmxo8f77bNGdXV2bNnNXz4cNe5YFRUlLp27Zru/Ew6/5fcevXqKTQ0VKGhoapevbqrf7/YMejo0aPq1auXihUrJn9/f5UpU0YDBgxI1xd62s5JkyapXLlyiouLSxfTiRMnFB4erkceecTjfnV+Z5csWaItW7akO7Zmdsh/Zvqxf//91/W9CgwMVEREhGrXrq2pU6e6yqTtF5ztx9NP6royM40ePdr1XSxYsKDuvvvudN/7tDZt2iSHw6HPP//cNW3dunVyOBy6/vrr3crefvvtbsfM1O3lzz//dP2RYMiQIa4Y097+8vfff1/0e+nJpfbBXbp00c033yzpfHLfud+aNGniSubXrVs3XayZOedz1tX69et19913q2DBgq4/HGe2Ppx9wJo1a9SwYUPXNcjLL7/sur64lGOBJP3111+u80J/f38VLVpUd999t/7++2+3cklJSRowYICKFi2qsLAw3Xrrrfr999/dymR0K1PaPsPZd0+dOvWiy/Rk5syZCg4OVo8ePdzOI9LasGGDWrdu7TofLFq0qFq1auV2jZo25iZNmmT4XUp9zM7MeY108eNYRjLbHzuvtxYsWKCaNWsqKChIFStW1IQJE9It81LPjw4fPqwSJUqofv36buU3b96skJAQ1/XIxfrvzFxnplWqVCk9//zzkqTo6Gi3Nu3pWORJdtVV2nMOZz+S0U9qmb0+vCjLpHPnzllwcLDVrVs3s7PYgw8+aJKsd+/etmDBAhs7dqxFRUVZiRIl7NChQ65yjRs3tsjISKtQoYKNHz/eFi5caK1btzZJNmTIEKtatapNnTrV5s2bZzfddJMFBATYX3/95Zp/0KBBJsliY2PtqaeesoULF9obb7xhISEhVqNGDTt79qyr7LBhw+zNN9+0uXPn2rJly2zs2LFWunRpa9q0qVvsnTt3Nj8/PytVqpSNGDHCvv76a1u4cKHrd7Gxsa6yq1atMofDYffee6/NmzfPvvnmG5s4caJ17NjRVebgwYNWrFgxi4qKsrFjx9qCBQusd+/eJskefvhhV7mdO3eaJCtVqpTddtttNmvWLJs1a5ZVrVrVChYsaMeOHbvgPv/tt98sf/78VrZsWZs8ebLNnTvX2rdvb5LslVdeccWyevVqk2R33323rV692lavXp3hMpOSkqxp06bm6+tr/fr1s3nz5tns2bPtueees6lTp5qZWUpKisXFxZmvr6+98MILtmjRInvttddcdXD69GnX8mJjY6148eJWpUoVV73WrVvX/Pz8bODAgdagQQObMWOGzZw508qXL2/R0dH277//utWNv7+/lSxZ0l588UVbtGiRDR482Hx9fa1169ZusUuyYsWKWbVq1eyTTz6xb775xn799VfbtGmThYeHW9WqVW3y5Mm2aNEie/LJJy1fvnw2ePBg1/wjRowwHx8fGzRokH399de2YMECe+utt9zKxMXFWVRUlI0bN86WLVtms2bNsoEDB9qnn37qKvPxxx+bw+Gwtm3b2owZM2zOnDnWunVr8/HxsSVLlrjKLVmyxHx8fOzmm2+2GTNm2Oeff2433nijlSxZ0jLzdR06dKj5+PjY8ePH3aavX7/eVc+rV6+27777zqpWrWohISG2ffv2TG3Hpk2brEGDBlakSBG3ZZmZ/fvvv1apUiULDw+3d9991xYuXGiPPfaYK+6JEydeMO6lS5eaJFu6dKlr2jfffGP+/v7WsGFDmzZtmi1YsMC6dOmSbnk1atSwBg0apFvmPffcY4ULF7akpCRX/Jmpc+d38GIxt2jRwkqWLJlu+vvvv2+SrH///m7Tz507Z6Ghoda3b98LLtcsa/2Uv7+/VapUyV577TVbsmSJDRw40BwOhw0ZMsRV7nLqZ8+ePTZjxgyTZI8++qitXr3a1q9fb2ZmEydONEm2c+dOt5hS94+rV6+2oKAga9mypavNbNq0yczM9u/fbyVKlLDY2Fh7//33bcmSJTZs2DALCAiwLl26uJbhrJNixYpZ06ZN7YsvvrBFixbZzp07M91ONm3aZMHBwVa5cmWbOnWqffnllxYXF+faB6m34UKSk5MtKSnJ/vrrLxs4cKD5+fnZV199ddH5nMep7t272/z5823cuHFWrFgxK1KkiDVu3DjdtqaOff78+ZYvXz5r0qSJzZw50z7//HOrW7eulSpVKl2/EBsba507dzYzs4SEBFcdPf/88679v2fPngzjdJYvUaKEdevWzRVr4cKFrUSJEvbPP/+4yjZu3NgiIiKsRIkS9u6779rSpUtt+fLldvLkSatevboVKlTI3njjDVuyZIm9/fbbFh4ebrfccoulpKS4ltGxY0dzOBzWo0cP+/LLL23+/Pn24osv2ttvv+22ntT7aOrUqa72uGjRIluyZImNHTvWHnvsMVcZT33KlClTTJK1aNHCZs2aZdOmTbNatWqZv7+/rVixIl1dVahQwQYOHGiLFy+2N954wwICAqxr167p9tm0adNMkv3888+uaan7yNWrV9s333zjqu+EhAQzM/v8889t4MCBNnPmTFu+fLl9+umn1rhxY4uKinI7R3LWSbFixezBBx+0+fPn2xdffGHnzp3LsA482bZtm919990myS025/E5o+OlmVmXLl1s/PjxtnjxYlu8eLENGzbMgoKC3PoZT3WVnJxst912m4WEhNiQIUNs8eLF9uGHH1qxYsWscuXKbsf2F154wSTZnXfeaZ9//rktWrTI3njjDXvhhRfM7MLHoFOnTlm1atUsJCTEXnvtNVu0aJG98MIL5uvray1btnSLMaPtfPvtt83hcNjWrVvdyo8aNcokufqttE6fPm2rV6+2GjVqWJkyZVxxOetZkg0aNMhV/nKOdw899JAFBwfbG2+8YUuXLrWvvvrKXn75ZXv33XddZZzt18l5zpf654033jBJ1qtXL1e5Bx54wPz8/OzJJ5+0BQsW2CeffGIVK1a06OhoO3DggMdtd4qJibEHH3zQ9fnll1+2oKAgk+Q6X09KSrKwsDB7+umnXeVSt5fTp0/bggULXP2kM9Zt27a5bVdmv5dpXWofvG3bNlcbeOmll1zHsE2bNtnzzz/vKps61sye86W+fnnmmWds8eLFNmvWrCzVh/Maqly5cjZ27FhbvHix9erVyyTZRx99ZGaXdizYu3evxcTEuPXj06ZNs27dutmWLVvM7P+35VKlStn9999vc+fOtalTp1rJkiWtXLlydu7cOdfyUh+bUkvbZ2RlmY0bN7brr7/e9fmNN94wHx8fGzZsWIbbZWZ24sQJi4yMtNq1a9tnn31my5cvt2nTplnPnj1t8+bNGca8adOmdN+lW2+91Xx8fGzVqlVmlvnzmswcxzKS2f7Yeb1VuXJlmzx5si1cuND++9//miS348Tlnh+tXLnSfH19rU+fPmZmdvLkSatcubJVrFjRTpw44VpHRv13Zq4zPVm/fr11797dJNmCBQvc2nTadmWWvi/OzrpK2687jwupf2bPnm1hYWFWqVIl13yZ7SsyI9NJnQMHDpgku/feezNVfsuWLekOGGZmP/zwg0my5557zjWtcePGJsnWrl3rmnbkyBHz8fGxoKAgtwTOxo0bTZK98847rmnOTtHZmJycJ3D/+9//PMaYkpJiSUlJtnz5cpNkP/30k+t3nTt3Nkk2YcKEdPOlvWh57bXXTNIFEy7PPvusSbIffvjBbfrDDz9sDofDfv/9dzP7/weTqlWrunVcP/74o0m6YOM2M7v33nstICDAdu/e7TY9Pj7egoOD3WKUZI888sgFl2dmNnnyZJNkH3zwQYZlnAfikSNHuk13nuyOGzfONS02NtaCgoJs7969rmnOeo2JibGTJ0+6ps+aNcsk2ezZs13TnHWT+qTfzOzFF180SbZy5Uq3bQwPD7ejR4+6lY2Li7PixYu7TrqcevfubYGBga7yrVu3turVq2e43WZmoaGh9sQTT2T4+5MnT1pERIS1adPGbXpycrLdcMMNVqdOHde0unXrWtGiRe3UqVOuaYmJiRYREZGppE58fLxVrFjxouV69+5tvr6+Nm/evExvh5lZq1at3Nq+05gxY0ySffnll27TH3jggUtO6lSsWNFq1KjhSso4tW7d2mJiYiw5OdnMzN555x2T5PoOmZkdPXrUAgIC7Mknn3RNy2ydZzap88QTT1i+fPls165dbtM7duxoktxOcJ0aNGiQpcS4Web6qc8++8xtnpYtW1qFChVcny+3fpz75NVXX3WbnpmkjplZSEiIx5O5hx56yEJDQ9PtQ2ef6ryIcq6/bNmybkl6s8y3k3bt2llQUJDbyfC5c+esYsWKWUrqxMXFmSSTZGFhYTZjxoyLzvPPP/9YYGCg/ec//3Gb/t1335mkiyZ1brzxRitRooSdOXPGNe348eMWGRl5waSOmdmaNWsyVcdOzjrNKNbhw4e7pjmP3V9//bVb2REjRli+fPlszZo1btO/+OILk+Tqd7799luTZAMGDLhgTGlPznr37m0FChS44Dxp+5Tk5GQrWrSoVa1a1dUmzM7vx8KFC1v9+vVd05znFGmPZ7169bLAwEC3pJSZ2R9//GGSbMyYMR5jOXfunN1xxx0WGhpq69atyzDmc+fO2YkTJywkJMTt+Oask06dOqWbJ6M6yMgjjzyS4bEko+NlWs7E5tChQy0yMtJtf2SUgJs+fbrbMpztcvTo0WZmtmPHDvPx8bH777//guvO6Bg0duxYj33hK6+8YpJs0aJFF93OxMREy58/vz3++ONu0ytXrpwuoe5J2gvM1Ou7WFIns/1YlSpVrG3btheMI21SJ63ffvvNIiMjrWnTpq4+xfmHvtdff92t7J49eywoKMgtEeNJhw4drEyZMq7Pt956qz3wwANWsGBBV2LB2Yekrou07eXQoUPp9lfa7crs9zK1y+2DnXX2+eefu83v/G6m7uuycs7n3KaBAwe6lc1KfTj7gLTXF5UrV7a4uDjX56weC7p162Z+fn5uSY60nPslbeL0s88+cyWPnbKa1MnMMp3fueTkZOvdu7f5+/tneM2X2tq1a02SK4GWkYxidnr11VfTXeNk9rwmM8exzLhQfxwbG2uBgYFusZw6dcoiIiLsoYceck3LjvMjZ187c+ZM69y5swUFBbn9ocMs4/47M9eZGXF+h1L/IcQsc0md7KwrT/16aidPnrQ6depYTEyM/fnnn65pme0rMuOKvdLcOSw+7VC7OnXqqFKlSumGFcXExLgNyYyIiFDhwoVVvXp1FS1a1DW9UqVKkpRueLKkdPcx33PPPfL19XW73WHHjh267777VKRIEfn4+MjPz891f+yWLVvSLfOuu+666LY6hzTec889+uyzz/TXX3+lK/PNN9+ocuXK6e657dKli8xM33zzjdv0Vq1aycfHx/W5WrVqkjxvd9r1NGvWTCVKlEi3nn///TfdMPPMmD9/vgIDAzMc0u1cr3M9qf33v/9VSEhIuvquXr262zNfnPXapEkTt3uJs1Lf9913nySlu73llltuUcGCBV2fT58+ra+//lr/+c9/FBwcrHPnzrl+WrZsqdOnT7tudatTp45++ukn9erVSwsXLlRiYmK6OOrUqaNJkyZp+PDh+v7779MNV1y1apWOHj2qzp07u60rJSVFt912m9asWaOTJ0/q5MmTWrNmje68804FBga65s+fP7/atGmTbr2e7Nu3z+2eUk9efvllvffeexo7dqzb85Quth0XsnTpUuXPn9/t9kvp/9dJVm3btk2//fabq47T1tH+/ftdw3Dvv/9+1/B5p6lTp+rMmTOuhxJnpc4z68EHH5Sfn5/uv/9+bdq0SUeOHNGoUaM0bdo0SVK+fOm718KFC3vsH9LKSj/lcDjStY9q1aq5fWeyu36yy1dffaWmTZuqaNGibnXibJfLly93K3/77bfLz8/P9Tkr7WTp0qVq1qyZoqOjXfP7+Pike07Oxbz77rv68ccf9eWXXyouLk7t2rVzu/XBk9WrV+v06dPp+qz69esrNjb2gvOePHlSa9euVdu2beXv7++aHhoamul+4VJkFGva/rVgwYK65ZZb3KZ99dVXqlKliqpXr+5WJ3FxcW7Dk523PmR0W0tG6tSpo2PHjql9+/b68ssvM/U2nN9//1379u1Tx44d3b6boaGhuuuuu/T999+nu3037felWrVqOn36tA4ePOg23dnnZvTd7t27t+bOnavPP/9cNWvWdE0/ceKEnnnmGV133XXy9fWVr6+vQkNDdfLkySydj3iqg0uV9njp9M033+jWW29VeHi4q08aOHCgjhw5km5/pPbVV1+pQIECatOmjVtbqF69uooUKeJqC4sXL1ZycnKW20Lq+EJCQnT33Xe7TXeek6Q9B/G0nfnz51fXrl01adIk122C33zzjTZv3qzevXtfUlyZkZV+rE6dOpo/f76effZZLVu2TKdOncrSug4cOKDbbrtNMTExmjlzpqtP+eqrr+RwONShQwe39RcpUkQ33HDDRd/o0qxZM+3YsUM7d+7U6dOntXLlSt12221q2rSpFi9eLOn8LQYBAQGuW5kuVWa/l6ldTh+cVZk950st7Xc7q/VRpEiRdNcXac8Dsmr+/Plq2rSp6zz8QjzViXTxa5bsWObp06fVtm1bTZkyRYsWLUpXx55cd911KliwoJ555hmNHTtWmzdvznJ8U6dO1dNPP63nn39eDzzwgGt6Zs9rLuU45pSV/rh69eoqWbKk63NgYKDKly+f7hzxcs+PnnrqKbVq1Urt27fXRx99pHfffVdVq1bN1LyZuc68Eq5GXUnnnwHZrl07bdmyRfPmzXP1OZfSV1xIppM6hQoVUnBwsHbu3Jmp8keOHJEkj29FKVq0qOv3Ts63BKTm7++fbrrzAHT69Ol05YsUKeL22dfXV5GRka51nThxQg0bNtQPP/yg4cOHa9myZVqzZo1mzJghSekOjsHBwZl66nmjRo00a9YsnTt3Tp06dVLx4sVVpUoVtxP9I0eOZLgvnL9PLe1bNJzPMLrYATyr68mMQ4cOqWjRoh4vUlOv19fXN91DUx0Oh4oUKXLR+nbWa2br21m3qTnrP+260u6PI0eO6Ny5c3r33Xfl5+fn9tOyZUtJcn1h+/fvr9dee03ff/+94uPjFRkZqWbNmrk952fatGnq3LmzPvzwQ9WrV08RERHq1KmT63klznuP77777nTre+WVV2RmOnr0qP755x+lpKSka8ept+1inA/PzMj//vc/Pffccxo4cKC6d+/u9ruLbceFHDlyxO1gkNW403Lus379+qXbZ7169ZL0/+soIiJCt99+uyZPnqzk5GRJ558hUKdOHdf9/Fmp88yqVKmSZs6cqV27dqlKlSoqVKiQXnnlFb3++uuS5PFB1YGBgRf9Dl9KP5W2zgMCAty+M9ldP9nl77//1pw5c9LVibPe0tZJ2u9yVtrJkSNHLuu75VSuXDndeOONuv322/XZZ5+pWbNmeuSRRy74unpnn3Qp6//nn39kZh7rz9O07JJRrBfrX6Xz9fLzzz+nq5P8+fPLzFx1cujQIfn4+GS5Djp27KgJEyZo165duuuuu1S4cGHVrVvXdfHoycXOSVJSUvTPP/+4Tc/scdj5/fP03R4+fLjGjh2r999/P90bie677z6999576tGjhxYuXKgff/xRa9asUVRUlMdlZfSWuYu9fS4rPC3rxx9/VIsWLSSdfwPqd999pzVr1mjAgAGSLnxe8vfff+vYsWPy9/dP1x4OHDjg1hYkXfIDfp3f77TPKihcuLB8fX0z1W4l6dFHH9Xx48c1ZcoUSdJ7772n4sWL64477rikuDIjK/3YO++8o2eeeUazZs1S06ZNFRERobZt2+qPP/646HqOHz+uli1bKikpSfPnz1d4eLhbDM5+Jm0M33///UWPj7feequk84mblStXKikpSbfccotuvfVWV0JtyZIlatCgwWU/kPpSzo8vpw/Oqsye86Xm6diWlfrw9Oa9gICALCf9Ujt06FCmv4+Xes2SHcs8ePCgFi5cqHr16ql+/fqZWnZ4eLiWL1+u6tWr67nnntP111+vokWLatCgQZn6g+bSpUvVpUsXderUScOGDXP7XWbPay7lOCZlvT/OTNvIjvMj5zOlTp8+rSJFiqR7tueFZOY680q40nXl1LNnTy1YsEBffPGF25vnLqWv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LiQ76iOtrO7b+Ph4LV26NFNvnMqMUqVK6eeff3abtnXr1mxZfosWLbRw4UJ9++23rjeQZpbD4dANN9ygN998UwUKFEh3nZba7t27FR8frzJlymj69Olut4M7Xcp5TWaPY854L7U/zsjlnh8lJyerffv2cjgcmj9/vkaMGKF3333XNcLcKaP+OzPXmVfCla6r8ePHa8iQIRo6dKjHN79lR1+RWqZH6khSvXr1NGbMGPXq1Uu1atXSww8/rOuvv15JSUnasGGDxo0bpypVqqhNmzaqUKGCHnzwQb377rvKly+f4uPj9eeff+qFF15QiRIl1KdPn6ysOlNmzJghX19fNW/eXJs2bdILL7ygG264Qffcc4+k8/fOFixYUD179tSgQYPk5+enKVOm6Keffrqs9Q4cOFB79+5Vs2bNVLx4cR07dkxvv/2223Mw+vTpo8mTJ6tVq1YaOnSoYmNjNXfuXI0ePVoPP/ywypcvf9nbL0mDBg1y3SM4cOBARUREaMqUKZo7d65GjhzpNtw2s9q3b6+JEyeqZ8+e+v3339W0aVOlpKTohx9+UKVKlXTvvfeqefPmiouL0zPPPKPExEQ1aNBAP//8swYNGqQaNWpkaRheZvj7++v111/XiRMndOONN2rVqlUaPny44uPjM3W/9ttvv62bb75ZDRs21MMPP6xSpUrp+PHj2rZtm+bMmeN6RlCbNm1UpUoV1a5dW1FRUdq1a5feeustxcbGqly5ckpISFDTpk113333qWLFisqfP7/WrFmjBQsWuP7iFhoaqnfffVedO3fW0aNHdffdd6tw4cI6dOiQfvrpJx06dMh1Ijts2DDddtttat68uZ588kklJyfrlVdeUUhISKaG4DVp0kQTJkzQ1q1bXW0qMTFRLVu2VFBQkPr165fuFfGVK1eWmV10O6Tzf9mYMWOGxowZo1q1ailfvnyqXbu2OnXqpDfffFOdOnXSiy++qHLlymnevHlauHBh5irUg/fff1/x8fGKi4tTly5dVKxYMR09elRbtmzR+vXr3V6f6uPjo06dOumNN95QWFiY7rzzznRtPbN1nhWPPvqomjRposjISO3YsUPvvPOO9u7dm+5ZMNL54a1//PGHHn300Qsu80r0U1eifrKiatWqWrZsmebMmaOYmBjlz59fFSpU0NChQ7V48WLVr19fjz32mCpUqKDTp0/rzz//1Lx58zR27NiLjgrNbDt5/vnnNXv2bN1yyy0aOHCggoODNWrUqEyf/N1xxx264YYbVL16dUVGRmrfvn2aNGmSli9frlGjRl3wteYFCxZUv379NHz4cPXo0UP//e9/tWfPHg0ePDhTw5uHDh2qVq1aKS4uTo8//riSk5P16quvKjQ09KL9QtmyZRUUFKQpU6aoUqVKCg0NVdGiRS+aMFu7dq1brAMGDFCxYsVct4NcyBNPPKHp06erUaNG6tOnj6pVq6aUlBTt3r1bixYt0pNPPqm6deuqYcOG6tixo4YPH66///5brVu3VkBAgDZs2KDg4OAMvysPPPCAgoKC1KBBA8XExOjAgQMaMWKEwsPDMxwVmi9fPo0cOVL333+/WrdurYceekhnzpzRq6++qmPHjunll1++6HZl5Pvvv5ePj48rkbtz507997//VZkyZdS1a9d0z+uqUaOGwsLC1KhRI7366qsqVKiQSpUqpeXLl2v8+PEqUKDAJcdyMc6LwVdeeUXx8fHy8fFRtWrVLnji2KpVK73xxhu677779OCDD+rIkSN67bXXMjVa4N5779WUKVPUsmVLPf7446pTp478/Py0d+9eLV26VHfccYf+85//qFSpUnruuec0bNgwnTp1yvXK6s2bN+vw4cOuER4XOgaNGjVKnTt31p9//qmqVatq5cqVeumll9SyZcuLJhNSa968uSpXrqylS5eqQ4cOF31OXXbIbD9Wt25dtW7dWtWqVVPBggW1ZcsWffzxxxdMSr766qv6+OOP9eijjyokJMStPYaFhaly5cpq0KCBHnzwQXXt2lVr165Vo0aNFBISov3792vlypWqWrWqHn744QtuQ7NmzTR69GgdPnxYb731ltv0iRMnqmDBgm7PzvQkf/78io2N1ZdffqlmzZopIiLC9f24HJfbB2dFVs75MpId9ZFWVo8FQ4cO1fz589WoUSM999xzqlq1qo4dO6YFCxaob9++qlixYpbW37FjR3Xo0EG9evXSXXfdpV27dmnkyJHpHttwqW6++WZ9/fXXuu2229SiRQvNmzcvw2uer776SqNHj1bbtm1VpkwZmZlmzJihY8eOuRKSnsTHx+vYsWN677330l3Mly1bVlFRUZk+r7mU45h0ef1xRi73/GjQoEFasWKFFi1apCJFiujJJ5/U8uXL1b17d9WoUcM1Ej6j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F2elSpWyfPnyWYECBVxtOjY21l588UW77rrrzMfHx8LDwy08PNytTQ8dOtRCQkJMksXGxtKmM6gvM7PRo0dbeHi4nT592jVtxIgRVrRoUUtJSclwWZ5i9NTPmJl9/PHHVqtWLQsNDbXo6Ghr3769/f33367lLV261CTZggULrHr16hYYGGhNmza1v//+2+bNm2cVK1a0/Pnz27333msnT550zZeSkmKvvPKKlS5d2gIDA61atWr2+eefX3A/nD592p566ikrXry4+fv723XXXWcffvihWxxLliyxWrVqWVBQkNWrV89+++031/zObUzt8ccft8aNG7s+165d2/z9/e2mm26yggULWnR0tL3wwgtu/bQk69atm2ueIUOGWGBgoDVp0sReeukl8/HxsYIFC7ratCQrX7685cuXz/z8/Dy26S+//NJ8fX3N19fXoqOjLSgoyCTZP//8Q5tO06affvppq1ixott8Dz30kN10000Zrq9z585u2+Bs340bN7ZHHnnE+vTpY5GRkdaoUSMzM3v99detSpUqFhwcbMWLF7eHH37Yjh8/7lqec/vnzJlj5cuXt6CgILvrrrvsxIkTNmnSJIuNjbUCBQpY79697dy5c675zpw5Y0899ZQVLVrUgoODrU6dOrZ06dIL7qt//vnHHnjgAStcuLAFBATY9ddfb3PmzHGL40L1kLo+ne644w7r3Lmz67Ozb+7atauFhoZaiRIl7P3333f93tmWN2zYYGbnj0E9evSwcuXK2Z9//mlmZpJs5syZbuUvdBwyMxs3bpwVL17cgoKCrG3btvb6669fsC3nVW+//bYVLFjQ/vrrL5s1a5b5+fm59rVT2jpwio+Pt2LFitmJEyfSLfeff/65ckEDuOaR1ME1559//rHy5ctbmzZt3C62zp49awMHDrQff/zRduzYYf/73/8sODjYpk2b5irTuXNnCw0NtY4dO9qvv/5qv/zyi+vgXqpUKZs+fbrt2LHDdu3aZW+99ZaFhYXZ/v37bf/+/a6T0NjYWAsLC7NXX33V/vjjD/vjjz/MzGzYsGH23Xff2c6dO2327NkWHR1tr7zyimvdF7tYeOedd6xKlSquz9WrV7dChQq5khKrVq0yX19fVxypTy6PHDlixYsXt6FDh7rida7Tz8/Pbr31VluzZo2tW7fOKlWqZPfdd1+m9nVmkzr//vuvLVmyxCTZjz/+aPv377dz587ZoEGDXCfG69evt59++slSUlLsiy++sOnTp9vWrVttw4YN1qZNG6tataolJyeb2f8/4apYsaItWLDANm/ebDfddJPVrFnTmjRpYitXrrT169fbddddZz179nTFMW7cOIuJiXHV4/Tp0y0iIsImTZqUYexPP/20FSxY0CZNmmTbtm2zFStW2AcffJAujq+++sp+//13u/vuuy02NtaSkpIy3EeekjphYWHWs2dP27Jli82ZM8eCg4Nt3LhxZna+Tfv6+tr1119vKSkp9uqrr1pERIStWLHC1abr1KljcXFxrjYdGxtrERERVrduXQsJCbEaNWqYw+GwL7/80hV3vnz5rFGjRrZw4UKbNGmSRUVFmSRbvHgxbTqNjh072u233+42bf369SbJduzY4XFZx48fdyU0U8foqZ8xMxs/frzNmzfPtm/fbqtXr7abbrrJ4uPjXctzJlNuuukmtzbeuHFja9Giha1fv96+/fZbi4yMtJdfftk133PPPef6rmzfvt0mTpxoAQEBtmzZsgz3wz333GMlSpSwGTNm2Pbt223JkiX26aefusVRt25dW7ZsmW3atMkaNmxo9evXd81/saTOP//8Y0FBQebr62uDBg2yrVu32kcffWSSrEOHDq5+WpIFBATYp59+ao899piVLFnS/vOf/7j2X0xMjD399NNuSZ3IyEh76623bPny5daoUSOTZJs3b7b9+/fbr7/+an5+fhYWFmahoaF2//33W3R0tCupQ5t2b9MNGza0xx57zK3MjBkzzNfX1y3ZldqxY8ds6NChVrx4cdu/f78rsd64cWMLDQ21p556yn777TfbsmWLmZ3vD7/55hvbsWOHff3111ahQgV7+OGHXctzbn/z5s1t/fr1tnz5couMjLQWLVrYPffcY5s2bbI5c+aYv7+/q42amd13331Wv359+/bbb23btm326quvWkBAgG3dutVj3MnJyXbTTTfZ9ddfb4sWLbLt27fbnDlzbN68eW5xXKgeMpvUiYiIsFGjRtkff/xhI0aMsHz58rn2R+qEwpkzZ+yuu+6y6tWruyV4PSV1LnQcWrlypeXLl89effVV+/33323UqFEWERFxTSZ1UlJSrEmTJtasWTMrXLiwDRs2LF0ZT0mdI0eOmMPhsJdeeukqRgsA55HUwTUlOTnZ4uPjrVKl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RIRWrlyp7t27u/WTnrb/Yu3ex8dH69atS9e/p04EpZaZdn+xeric/j513yxJLVu21P/+9z99//33uuWWW7IUW9rvY+p273S57cdbrV69Wm+++abmz5+vkSNHqnv37lqyZMlFkzXlypWTw+HQli1b1LZt26sTLAD8H5I6uCZs3LhR3bp108svv6y4uDiPZVasWKH69eu7vWUlo7/YZYa/v7+Sk5MzVfa7775TbGysBgwY4Jq2a9euLK+zSZMmGjdunPz9/TV06FA5HA41bNhQr732mk6dOqUGDRpkS7yX67rrrrvkeY8cOaItW7bo/fffV8OGDSVJK1euvOyYoqOjVaxYMe3YscN1YXgx5cqVU1BQkL7++mv16NHjktYbFRWlAwcOuJ1Up74IysihQ4f0+++/65VXXnG16Tp16ujRRx9VXFycfHx8tHv3bleb/uyzz1SgQAH9+uuvmY7tjz/+0JkzZ1wX95n9i6V07bXpevXq6bnnnnN7Y8+iRYtUtGhRlSpVSg6H47La/W+//abDhw/r5ZdfVokSJSRJa9euvey4K1eurICAAO3evTvTI0SqVq2qlJQULV++XLfeeuslrTcqKipdW/zuu+/c2vSIESPSzXfkyBFFRUW59dOBgYGKjY1Vjx49MkzAZiTtaJ6KFStq3rx5btOc+/mHH36gTadq084yc+bMcZtv0aJFql27tvz8/OTn53dZ7X7t2rU6d+6cXn/9deXLd35w+WeffXbJy3OqUaOGkpOTdfDgQddx5GKqVaumvXv3auvWrRccrXMhUVFRbm95S05O1q+//qqmTZtmeVkPP/ywqlSpottvv11z5869pBFeThUrVtSPP/7oNi07+hdvc+rUKXXu3FkPPfSQbr31VpUvX15VqlTR+++/f9FRxREREYqLi9OoUaP02GOPpUtQHjt2TAUKFLiC0QO4lnH7FfK8w4cPq23btmrSpIk6dOigAwcOuP0cOnRI0vlEw9q1a7Vw4UJt3bpVL7zwgtasWXPJ6y1VqpROnDihr7/+WocPH9a///6bYdnrrrtOu3fv1qeffqrt27frnXfe0cyZM7O8ziZNmmjTpk365ZdfXCeqTZo00ZQpU1SzZs0LjoopVaqUvv32W/311186fPhwlted2rZt27Rx40YdOHBAp06d0saNG7Vx48YMXy2cFQULFlRkZKTGjRunbdu26ZtvvlHfvn0ve7mSNHjwYI0YMUJvv/22tm7dql9++UUTJ07UG2+84bF8YGCgnnnmGT399NOu21W+//57jR8/PtPrbNKkiQ4dOqSRI0dq+/btGjVqlObPn3/BeQ4fPqw5c+aoQIECrjadnJysxMRElS5dWp988omGDh2qvXv3utr0v//+q9WrV2epTaekpOjBBx/Uli1btHDhQi1cuFCS9OOPP9Km07Tp++67TwEBAerSpYt+/fVXzZw5Uy+99JL69u2bLcPxS5YsKX9/f7377rvasWOHZs+erWHDhl32cvPnz69+/fqpT58++uijj7R9+3Zt2LBBo0aN0kcffeRxnlKlSqlz587q1q2bZs2apZ07d2rZsmVZuti+5ZZbtHbtWk2ePFl//PGHnnrqKf38889ubfrs2bM6efKkWz8dEhKiI0eOuPpp6XzdhIeH6+OPP1bXrl31559/ZjoOZ3Ji8+bNOnz4sDp16qTffvtN//zzjw4ePKjPPvtMkyZNknT+9kPatHub7tmzp3bt2qW+fftqy5YtmjBhgsaPH69+/fpdVmxOZcuW1blz51zt/uOPP9bYsWMve7nly5fX/fffr06dOmnGjBnauXOn1qxZo1deeSVdUs+pcePGatSoke666y4tXrxYO3fu1Pz587VgwYJMr/eWW27R3LlzNXfuXP3222/q1auXjh07dsnb8eijj2r48OFq3br1Zf1x49FHH9W8efP0xhtv6I8//tD777+v+fPnX3O3Ej377LNKSUnRK6+8Iul8v/v666/rqaeeylS/Mnr0aCUnJ6tOnTqaPn26/vjjD23ZssU1shAArhSSOsjz5s6dq127dmnevHmKiYlJ9+N8fkLPnj115513ql27dqpbt66OHDni9tfgrKpfv7569uypdu3aKSoqSiNHjsyw7B133KE+ffqod+/eql69ulatWqUXXnghy+usUqWKChUqpBtuuMF1YdC4cWMlJydf9K94Q4cO1Z9//qmyZcume4ZNVvXo0UM1atTQ+++/r61bt6pGjRqqUaOG9u3bd1nLlc4PX//000+1bt06ValSRX369NGrr7562cuVzsf94YcfatKkSapataoaN26sSZMmuZ7Z48kLL7ygJ598UgMHDlSlSpXUrl27LD1DoVKlSho9erRGjRqlG264QT/++ONFL4jmzp2r48eP6+jRo652vHfv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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# File vs filesize \n", - "import matplotlib.pyplot as plt\n", - "\n", - "filesizes= [filesize(\"../notebook_data_tmp/filesize_benchmarks/yiip_1_frame.zarrtraj\"),\n", - " filesize(\"../notebook_data_tmp/filesize_benchmarks/yiip_10_frame.zarrtraj\"),\n", - " filesize(\"../notebook_data_tmp/filesize_benchmarks/yiip_100_frame.zarrtraj\"),\n", - " filesize(\"../notebook_data_tmp/filesize_benchmarks/yiip.xtc\")]\n", - "\n", - "filenames = [\"Zarrtraj with 1-frame chunking\", \"Zarrtraj with 10-frame chunking\", \"Zarrtraj with 100-frame chunking\", \"XTC\"]\n", - "\n", - "\n", - "plt.figure(figsize=(10, 6))\n", - "plt.bar(filenames, filesizes, color='blue')\n", - "\n", - "plt.title('Comparison of compressed (zstd level 9) and filtered 3 digit precision)' +\n", - " 'zarr trajectory filesize with different chunk sizes and xtc filesize')\n", - "plt.xlabel('Filename')\n", - "plt.ylabel('Size (bytes)')\n", - "\n", - "# Show the graph\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/yiip_benchmark.ipynb b/notebooks/yiip_benchmark.ipynb deleted file mode 100644 index e78cf5e..0000000 --- a/notebooks/yiip_benchmark.ipynb +++ /dev/null @@ -1,417 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/law/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysisData/base.py:34: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html\n", - " from pkg_resources import resource_string\n", - "/home/law/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/home/law/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/home/law/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/home/law/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - } - ], - "source": [ - "import MDAnalysis as mda\n", - "import MDAnalysisData\n", - "\n", - "yiip = MDAnalysisData.yiip_equilibrium.fetch_yiip_equilibrium_short()\n", - "# NOTE: change this to five before doing true benchmark test\n", - "u = mda.Universe(yiip.topology, 1 * [yiip.trajectory], in_memory=True)\n", - "positions = u.trajectory.get_array()" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import zarr\n", - "import h5py\n", - "import numcodecs\n", - "\n", - "zarr_compressors = ['zstd', 'blosclz', 'lz4', 'lz4hc', 'zlib']\n", - "hdf5_compressors = ['gzip']\n", - "\n", - "# Load yiip data into minimal zarr file and hdf5 files of different compressors\n", - "# and compressor levels\n", - "def create_zarr_traj(compression, compression_opts):\n", - " root = zarr.open(f'zarrfiles/yiip_{compression}_{compression_opts}_zarr.zarr', mode='w')\n", - " compressor = numcodecs.Blosc(cname=compression, clevel=compression_opts)\n", - " root.create_dataset('positions', data=positions, \n", - " chunks = (1, np.shape(positions)[1], 3), \n", - " compressor=compressor)\n", - "\n", - "\n", - "def create_hdf5_traj(compression, compression_opts):\n", - " with h5py.File(f'h5files/yiip_{compression}_{compression_opts}_hdf5.h5', 'w') as root:\n", - " root.create_dataset('positions', data=positions, \n", - " chunks = (1, np.shape(positions)[1], 3), \n", - " compression=compression, compression_opts=compression_opts)\n", - "\n", - "\n", - "for c in zarr_compressors:\n", - " for i in range(10):\n", - " create_zarr_traj(c, i)\n", - "\n", - "\n", - "\n", - "for c in hdf5_compressors:\n", - " for i in range(10):\n", - " create_hdf5_traj(c, i)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [], - "source": [ - "import subprocess\n", - "import time\n", - "\n", - "def filesize(filename):\n", - " return int(subprocess.check_output(['du','-s', filename]).split()[0].decode('utf-8'))\n", - "\n", - "def zarr_iteration_time(filename):\n", - " start_time = time.time()\n", - " root = zarr.open(filename, mode='a')\n", - " pos_vals = root['positions']\n", - " num = 0\n", - " for i in range(len(pos_vals)):\n", - " # arbitrary task that requires accessing third dimension\n", - " num += pos_vals[i][0][0]\n", - " end_time = time.time()\n", - " return end_time - start_time\n", - "\n", - "def h5_iteration_time(filename):\n", - " start_time = time.time()\n", - " with h5py.File(filename, 'r') as root:\n", - " pos_vals = root['positions']\n", - " num = 0\n", - " for i in range(len(pos_vals)):\n", - " # arbitrary task that requires accessing third dimension\n", - " num += pos_vals[i][0][0]\n", - " end_time = time.time()\n", - " return end_time - start_time" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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77//vtm8ebOZP3++mTFjhnXM1q1bjaenp2nWrJlJSUkxb7zxhunSpYuxWCzm1VdftTu30NBQc//995tNmzaZ//znPyYvL8907drVVK5c2SxevNhs3brVvPHGG2batGk2+19N/ucm36effmokmSVLltiM++KLL4wk89JLL1nb8t/z+vXrm+TkZPPmm2+abt26GUnmtddes47LysoyYWFhpkaNGubll1827733nnn88ceNt7e3GTJkiHVccnKykWQefPBB8+6775r33nvPLFq0yIwdO/aq5zFkyBCzbNkys2XLFrNlyxbz+OOPG19fXzNz5kybcTVq1DDVqlUz9evXN6tWrTLvvPOOueuuu4wkk5qaanO+fn5+1nP773//a7p27WqqV69uJJn09PRC87naz7AxxnzwwQfGy8vLtG3b1qSkpJjNmzebIUOGGEkmKSnJOq5p06amTZs2dvvHxcWZoKAgc/HiRWvO/v7+plGjRmbVqlXm3XffNQ8//LBxc3Oz+ezl/zv5x2MU57N0+PBh89JLLxlJ5qmnnjI7d+40X3zxhTHGmDVr1hhJpkuXLuaNN94wKSkpplmzZsbLy8ts377d7n2qUaOGeeSRR8yWLVvMG2+84fB4x44dM+vXr7d+Rnbu3Gk++eQTY8z//Zz88fty5f9rjDEmPj7eeHp6mocffths3rzZvPLKK6Zu3bqmSpUq5vjx48YYY3799VdTqVIlEx0dbdauXWtSU1NNSkqKGTlypDl48KA1Vo0aNczgwYOt21988YX1/wf5r06dOhl3d3fz8ccfG2Oc/1kAgNJA0Y0b3vHjx40k069fP6fGf/nll9ZC7Y/+97//GUnm0Ucftba1a9fOrgg5deqUcXd3N76+vjYF9v79+40k889//tPalv9LT0JCgs2x8n9pWr16tcMcL1++bC5evGhSU1ONJPPpp59a+wYPHmwkOSzmrvxF6LnnnjOSCi2IJ0+ebCSZ//3vfzbto0aNMhaLxXz99dfGmP/7ZbJRo0Y2xebu3buNJJOcnFzgMYwxpl+/fsbb29scPXrUpr179+7Gz8/PJkdJ5oEHHig03h/HXu1VlKI7NzfXSDLdu3e3tuW/51e+rvxlfcCAAWbNmjVm27Zt5j//+Y/p3r27kWSmTJly1fPw8fExLVu2dOqcs7Ozja+vr+nRo4dN+9GjR423t7cZMGCA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f3+lpqYqMjJSjz76qBo0aKCqVatq+vTpTv0x4sMPP9SQIUM0aNAgPf7443Y5OPOzAACl4W+9enn37t0LXR35woULmjJlitasWaOff/5ZDRs21Jw5c6yLmXz55ZdauHChDhw44NQv33ANd3d3dezYUZs2bdL3339vXQymIPm/FGZlZdmN/eGHH2xWtC4px48fV2hoqHU7Ly9Pp06dsubywQcf6IcfftDWrVttVqn9+eefHcYryuJid9xxh+644w6dP39eu3bt0uzZszVgwACFh4erVatWqlSpkrKysuz2++GHHySpxN6P63Wca5W/cNIfFy26Fvkz53+clXIk/znhu3btuupq13/8DF/JlZ9hR221atWyaXP02QwMDJSvr6/DBbXy+/Nd7fPq4eGh8ePHa/z48fr555/13nvv6dFHH1XXrl117NgxBQQEyM3NrUiftYJynj9/vubPn6+jR4/qzTff1OTJk3Xy5MlrehKCm5ubHnjgAT366KN6/vnntWDBAnXs2NHh/0MKes+l//sMBAYGqnHjxnryyScdHu+PfzwaOnSohg4dqnPnzmnbtm2aPn26br/9dn3zzTeqUaOGw/1fffVVeXp66u2337b5w01xrgzLV6lSpULP7Vrlf38TExPtFh/M98f3e+jQoXrttde0ZcsWVa9eXXv27NHChQut/QEBAdYrJRz9cUSSIiIiCs2npD5LV/vZd3NzU0BAgE379ViMMjAwUBaLRdu3b3e4mOkf2xo1aqRXX31Vxhh99tlnWrFihWbNmiVfX19Nnjy5wGN89tln6tWrl9q1a6clS5Y4zMHZnwUAuN7+1jPdVzN06FB99NFHevXVV/XZZ5/prrvuUrdu3XTo0CFJ0ltvvaWbbrpJb7/9tiIiIhQeHq7hw4fr9OnTpZz5309iYqKMMYqPj9eFCxfs+i9evKi33npLkqyXvq5evdpmzJ49e/Tll1/aPSqlJKxZs8Zme+3atcrLy7MWdvm/FF35y8rLL79cYjl4e3urXbt21kuu85/33LFjRx08eFCffPKJzfhVq1bJYrEoJiamRI7fsWNH6x8XrjyOn5/fn+KxSp9++qmeeuophYeHKy4urkRi/vvf/5anp6fNLQqOJCQkqEyZMho9erTOnDlj12+MsT4yrFWrVvL19bX7DH///ffWy/hL2pWf4Y8//lhHjhxx6o8Tt99+u7799ltVqlTJ4RUJjp7DXtDn9Y8qVKigvn376oEHHtDp06eVkZGhMmXK6JZbbtH69ettZlcvX76s1atXq1q1akV+1nH16tU1ZswYde7c2e7npDiGDx8uLy8vDRw4UF9//bXGjBnjcNz7779vnbWVpEuXLiklJUU1a9a0/sHw9ttv14EDB1SzZk2H762jQqNMmTLq3r27HnvsMV24cEFffPFFgblaLBZ5eHjY3FKSm5urf//738U9fcXExBR4biWhTp06uvnmm/Xpp586fE+io6NVrlw56/guXbooNDRUSUlJSkpKko+Pj/r372/t9/PzU0xMjNLS0tS4cWOH8RzN8DtyrZ+lOnXqKDQ0VK+88orNrTDnzp3TunXrrCuaX2+33367jDHKzMx0+P40atTIbh+LxaImTZpo3rx5qlChQqHvx9GjR9W9e3fddNNNWrdunTw9PR3mUNSfBQC4Xv7WM92F+fbbb5WcnKzvv//e+g/1hAkTtHnzZiUlJempp57Sd999pyNHjui1116zXpqWkJCgvn372t0HC9dq1aqVFi5cqNGjR6tZs2YaNWqUGjRooIsXLyotLU2LFy9Ww4YNFRsbqzp16uj+++/Xv/71L7m5ual79+7KyMjQ1KlTFRYWpoSEhBLPb/369fLw8FDnzp31xRdfaOrUqWrSpIm1sGvdurUCAgI0cuRITZ8+XZ6enlqzZo0+/fTTazrutGnT9P3336tjx46qVq2afv75Z73wwgs294snJCRo1apVuu222zRr1izVqFFDGzZs0IIFCzRq1KgiFygFmT59uvWeu2nTpqlixYpas2aNNmzYoGeeecbhY7Jcad++ffL399fFixf1ww8/6P3339e///1vBQUF6a233rLeLuCsZ599VgcPHrS+1ydPntSyZcv07rvvasaMGVedfY6IiNCrr76qu+++W5GRkRozZoz1fuuDBw9q+fLlMsaod+/eqlChgqZOnapHH31UgwYNUv/+/XXq1CnNnDlTPj4+mj59erHfl4Ls3btXw4cP11133aVjx47pscceU2hoqPVy3cI89NBDWrdunf7xj38oISFBjRs31uXLl3X06FG9++67evjhh3XLLbc49XmNjY1Vw4YNFR0drcqVK+vIkSOaP3++atSooZtvvlmSNHv2bHXu3FkxMTGaMGGCvLy8tGDBAh04cEDJyclXnfk7c+aMYmJiNGDAANWtW1flypXTnj17tHnz5gJnTouiQoUKGjRokBYuXKgaNWooNjbW4bjAwEB16NBBU6dOVZkyZbRgwQJ99dVXNo8NmzVrlrZs2aLWrVtr7NixqlOnjn777TdlZGRo48aNWrRokapVq6b4+Hj5+vqqTZs2CgkJ0fHjxzV79mz5+/tb76V35LbbbtPcuXM1YMAA3X///Tp16pSee+45h7OZzpoyZYrefPNNdejQQdOmTZOfn59eeuklu8fHXc1bb71lUzzn69u3r15++WV1795dXbt21ZAhQxQaGqrTp0/ryy+/1CeffKLXXnvNOt7d3V2DBg3S3LlzVb58ed155512/x698MILuvXWW9W2bVuNGjVK4eHh+uWXX3T48GG99dZbBf4/v6Q/S25ubnrmmWc0cOBA3X777RoxYoTOnz+vZ599Vj///LP1UYDXW5s2bXT//fdr6NCh2rt3r/7xj3+oTJkyysrK0o4dO9SoUSONGjVKb7/9thYsWKBevXrppptukjFG69ev188//6zOnTsXGL979+76+eef9eKLL9r9kahmzZqqXLmy0z8LAFAqSmP1tj8jSeb111+3bq9du9ZIMmXKlLF5eXh4mLi4OGPM74/H0BWrnu7bt89IMl999dX1PgWY31cQHzx4sKlevbrx8vKyPppr2rRp5uTJk9Zxly5dMnPmzDG1a9c2np6eJjAw0Nxzzz3m2LFjNvHatWtnGjRoYHecGjVqmNtuu82uXVesup2/euy+fftMbGysKVu2rClXrpzp37+/OXHihM2+H3/8sWnVqpXx8/MzlStXNsOHDzeffPKJ3Uq4jlZE/mPfH1eUffvtt0337t1NaGio8fLyMkFBQaZHjx42j5UxxpgjR46YAQMGmEqVKhlPT09Tp04d8+yzz9qsjlvQyrb55z19+nSHOf3R559/bmJjY42/v7/x8vIyTZo0sTm3P8YryurlBY197bXXCly9PP/l7e1tQkJCTJcuXcwLL7xgzp49axensPc835tvvmluvfVWU7lyZePh4WHKlStn2rZte9VV3a/07bffmtGjR5tatWoZb29v4+vra+rXr2/Gjx9vt6rz0qVLTePGjY2Xl5fx9/c3d9xxh90KvQXl7uxnO3/l4nfffdfce++9pkKFCtaV0w8dOuRUTGN+f1TQlClTTJ06daz5NmrUyCQkJFhXsXbm8/r888+b1q1bm8DAQOPl5WWqV69u7rvvPpORkWFzvO3bt5sOHTqYMmXKGF9fX9OyZUvz1ltv2YzJP7crV1X/7bffzMiRI03jxo1N+fLlja+vr6lTp46ZPn26OXfunMPzc6Swz83WrVuNJPP000877M//XC9YsMDUrFnTeHp6mrp165o1a9bYjf3xxx/N2LFjTUREhPH09DQVK1Y0zZo1M4899pj59ddfjTHGrFy50sTExJgqVaoYLy8vU7VqVRMXF2c+++yzq57H8uXLTZ06dYy3t7e56aabzOzZs82yZcvsVrQu6N/Fdu3amXbt2tm0ffTRR9bHLAYHB5uJEyeaxYsXF2n18oJe+T799FPro788PT1NcHCw6dChg1m0aJFdzG+++ca6/5YtWxweNz093QwbNsyEhoYaT09PU7lyZdO6dWubFfyvXL38Wj5LjlYvz/fGG2+YW265xfj4+JgyZcqYjh07mo8++sjh+1TYKu9Xnp+jf+OdfWSYMb9/Vm655Rbrz13NmjXNoEGDrE8A+eqrr0z//v1NzZo1ja+vr/H39zctWrQwK1assIlz5erlhX2///j/EGd+FgCgNFiMKWCp3r8Zi8Wi119/Xb169ZL0+8InAwcO1BdffGFzWZ30+yqhwcHBmj59up566imbxT9yc3Pl5+end999t9C/2uLvYcaMGZo5c6Z+/PHHP809y0BRrFixQkOHDtWePXsUHR1d2un8ZTz88MNauHChjh075vDSZIvFogceeOCaFvoEAAB/DlxeXoCmTZvq0qVLOnnypNq2betwTJs2bZSXl6dvv/1WNWvWlCR98803klTgojQAgL+vXbt26ZtvvtGCBQs0YsQIp+8FBgAAN66/ddH966+/6vDhw9bt9PR07d+/XxUrVlTt2rU1cOBADRo0SM8//7yaNm2qn376SR988IEaNWqkHj16qFOnToqKitKwYcM0f/58Xb58WQ888IA6d+5cYvfBAgD+OvIXurr99tv1xBNPlHY6AADgOvhbX16+detWhyszDx48WCtWrNDFixf1xBNPaNWqVcrMzFSlSpXUqlUrzZw507oS5w8//KAHH3xQ7777rnVF2Oeff97h828BAAAAAH8vf+uiGwAAAAAAV+I53QAAAAAAuAhFNwAAAAAALvK3W0jt8uXL+uGHH1SuXDlZLJbSTgcAAABA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Fbcw3NMNAAAAAHCoadOmOnjwYInHXblypbKzs9WnT59ix0hLS5NkOxt+NW3atNEPP/ygX3/91dr2zTffyM3NTdWqVbO2HThwQJ6enmrQoEGx88tH0Q0AAAAAcKhr16764osvCpztdkZOTo6OHz+u77//Xv/73//0yCOPaOTIkRo1apRiYmKcirFz507NmzdP+/fvV3p6utauXasRI0aoZ8+eql69utO5DBgwQJUqVdLQoUN18OBBbdu2TRMnTtSwYcNsZum3b9+utm3bOj1zXxiKbgAAAACAQ40aNVJ0dLTWrl1b7BhLlixRSEiIatasqd69e+vgwYNKSUnRggULnI7h7e2tlJQUtW/fXvXr19e0adMUHx+v5ORkm3Hh4eGaMWNGgXHKli2rLVu26Oeff1Z0dLQGDhyo2NhY/fOf/7QZl5ycbPM88GvBPd0AAAAAUEqqPd22tFO4qqlTp2rChAmKj4+Xm5ubwsPDZYxxOHbr1q2FbhemoJiSFBUVpV27dhW6f25urk6cOKF27doVOq5u3brasmVLgf0bNmyQu7u7+vbtW3jCTqLoBgAAAAAUqEePHjp06JAyMzMVFhZW2ukUKDU1VR06dHD6kvWCnDt3TklJSfLwKJlymaIbAAAAAFCocePGlXYKV9WtWzd169btmuPExcWVQDb/h3u6AQAAAABwEYpuAAAAAABcpNSL7gULFigiIkI+Pj5q1qyZtm/fXuj4NWvWqEmTJvLz81NISIiGDh2qU6dOXadsAQAAAABwXqkW3SkpKXrooYf02GOPKS0tTW3btlX37t119OhRh+N37NihQYMG6b777tMXX3yh1157TXv27NHw4cOvc+YAAAAAAFxdqRbdc+fO1X333afhw4erXr16mj9/vsLCwrRw4UKH43ft2qXw8HCNHTtWERERuvXWWzVixAjt3bv3OmcOAAAAAMDVldrq5RcuXNC+ffs0efJkm/YuXbro448/drhP69at9dhjj2njxo3q3r27Tp48qf/85z+67bbbrkfKAEraDP/SzsCxGWdKOwMAAAD8RZTaTPdPP/2kS5cuqUqVKjbtVapU0fHjxx3u07p1a61Zs0Z33323vLy8FBwcrAoVKuhf//pXgcc5f/68zp49a/MCAAAAAOB6KPWF1CwWi822McauLd/Bgwc1duxYTZs2Tfv27dPmzZuVnp6ukSNH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ev3119WvXz8NGTJEixcvthmblJSkbt26WbevfDLWrFmzbNYRK1u2bJFyWbhwoRITE7VkyRI1b95cu3fvVnx8vAICAhQbGytJCgoKUpcuXbRo0SLNmTOnqKdrx+mi2xijjh07ysPj911ycnIUGxtrfRPy8vKuORkAAAAAwJ/Hpk2b5OHhoVatWhU7hp+fn4KDgyVJYWFhatmyperWrathw4YpLi5OnTp1so6tUKGCdawj5cqVK7T/av79739rxIgR1lulb7rpJu3atUtz5syxFt2S1LNnT02dOvX6Ft3Tp0+32b7jjjvsxvTp0+eaEwIAAAAA/Dls27ZN0dHRJR538ODBevjhh7V+/Xqbovtq5syZo8cff1xhYWG66667NHHiRLvZ8MKcP39ePj4+Nm2+vr7avXu3Ll68KE9PT0lSixYtdOzYMR05ckQ1atRwOr4jxS66AQAAAAB/bRkZGapatarDvtatW8vNzXaZsNzcXEVGRl41rpubm2rXrm23OFv//v3l7u5u3V69erV69eolSRo3bpyioqIUEBCg3bt3KzExUenp6Vq6dKnT59O1a1ctXbpUvXr1UlRUlPbt26fly5fr4sWL+umnnxQSEiJJCg0NlfT7+V+3ojvf6tWrdc899zjsmzhxop599tlrSggAAAAA8OeQm5trNzOcLyUlRfXq1bNpGzhwoNOxjTF264TNmzfPZuY7vwiWpISEBOvXjRs3VkBAgPr27as5c+aoUqVKTh1z6tSpOn78uFq2bCljjKpUqaIhQ4bomWeesSn2fX19JalEFgt3evXyfGPGjNHbb79t156QkKDVq1dfc0IAAAAAgD+HwMBAZWdnO+wLCwtTrVq1bF75xerVXLp0SYcOHVJERIRNe3BwsE28MmXKFBijZcuWkqTDhw87eTa/F9PLly9XTk6OMjIydPToUYWHh6tcuXIKDAy0jjt9+rQkqXLlyk7HLkiRi+5XX31V99xzj7Zt22Zte/DBB7V27Vp9+OGH15wQAAAAAODPoWnTpjp48GCJx125cqWys7OvaV2wtLQ0Sbaz4c7y9PRUtWrV5O7urldffVW33367zaXyBw4ckKenpxo0aFDs/PIV+fLybt26adGiRerVq5feffddLV++XP/973/14Ycfqnbt2tecEAAAAADgz6Fr165KTExUdna2AgICihUjJydHx48fV15enjIzM7V+/XrNmzdPo0aNUkxMjFMxdu7cqV27dikmJkb+/v7as2ePEhIS1LNnT1WvXt3pXL755hvt3r1bt9xyi7KzszV37lwdOHBAK1eutBm3fft2tW3b1umZ+8IUueiWpH79+ik7O1u33nqrKleurNTUVNWqVeuakwEAAAAA/Hk0atRI0dHRWrt2rUaMGFGsGEuWLNGSJUvk5eWlSpUqqVmzZkpJSVHv3r2djuHt7a2UlBTNnDlT58+fV40aNRQfH69JkybZjAsPD9eQIUM0Y8YMh3EuXbqk559/Xl9//bU8PT0VExOjjz/+WOHh4TbjkpOTNXPmzKKeqkNOFd3jx4932B4UFKSmTZtqwYIF1ra5c+eWSGIAAAAA8Fd3PCaytFO4qqlTp2rChAmKj4+Xm5ubwsPDZYxxOHbr1q2FbhemoJiSFBUVpV27dhW6f25urk6cOKF27doVOKZevXrWy9ILsmHDBrm7u6tv376FJ+wkp4rugpKqWbOmzp49a+2/cuU5AAAAAMCNrUePHjp06JAyMzMVFhZW2ukUKDU1VR06dHD6kvWCnDt3TklJSfLwKNaF4XacisICaQAAAADw9zVu3LjSTuGqunXrpm7dul1znLi4uBLI5v8UefVyAAAAAADgHKeK7pEjR+rYsWNOBUxJSdGaNWuuKSkAAAAAAP4KnLq8vHLlymrYsKFat26tnj17Kjo6WlWrVpWPj4+ys7N18OBB7dixQ6+++qpCQ0O1ePFiV+cNAAAAAMCfnlNF9+OPP64HH3xQy5Yt06JFi3TgwAGb/nLlyqlTp05aunSpunTp4pJEAQAAAOBGV9gK3bhxFOX76PRybEFBQUpMTFRiYqJ+/vlnHTlyRLm5uQoMDFTNmjVZuRwAAAAACuDu7i5JunDhgnx9fUs5G1yrnJwcSZKnp+dVxxZrDfQKFSqoQoUKxdkVAAAAAP52PDw85Ofnpx9//FGenp5yc2NN6xuRMUY5OTk6efKkKlSoYP1jSmFK5sFjAAAAAIACWSwWhYSEKD09XUeOHCntdHCNKlSooODgYKfGUnQDAAAAwHXg5eWlm2++WRcuXCjtVHANPD09nZrhzkfRDQAAAADXiZubm3x8fEo7DVxH3EgAAAAAAICLFKvozsvL03vvvaeXX35Zv/zyiyTphx9+0K+//lqiyQEAAAAAcCMr8uXlR44cUbdu3XT06FGdP39enTt3Vrly5fTMM8/ot99+06JFi1yRJwAAAAAAN5wiz3SPGzdO0dHRys7Otnm+XO/evfX++++XaHIAAAAAANzIijzTvWPHDn300Ufy8vKyaa9Ro4YyMzNLLDEAAAAAAG50RZ7pvnz5si5dumTX/v3336tcuXIlkhQAAAAAAH8FRS66O3furPnz51u3LRaLfv31V02fPl09evQoydwAAAAAALihFfny8nnz5ikmJkb169fXb7/9pgEDBujQoUMKDAxUcnKyK3IEAAAAAOCGVOSiu2rVqtq/f7+Sk5P1ySef6PLly7rvvvs0cOBAm4XVAAAAAAD4uyty0S1Jvr6+GjZsmIYNG1bS+QAAAAAA8JdR5Hu63d3dFRMTo9OnT9u0nzhxQu7u7iWWGAAAAAAAN7oiF93GGJ0/f17R0dE6cOCAXR8AAAAAAPhdkYtui8WidevWKTY2Vq1bt9Z///tfm76iWrBggSIiIuTj46NmzZpp+/bthY4/f/68HnvsMdWoUUPe3t6qWbOmli9fXuTjAgAAAADgakW+p9sYI3d3d73wwgtq0KCB7r77bk2ZMkXDhw8v8sFTUlL00EMPacGCBWrTpo1efvllde/eXQcPHlT16tUd7hMXF6cTJ05o2bJlqlWrlk6ePKm8vLwiHxsAAAAAAFcr1kJq+e6//37Vrl1bffv2VWpqapH3nzt3ru677z5rwT5//ny98847WrhwoWbPnm03fvPmzUpNTdV3332nihUrSpLCw8Ov5RQAAAAAAHCZIl9eXqNGDZsF09q3b69du3bp+++/L1KcCxcuaN++ferSpYtNe5cuXfTxxx873OfNN99UdHS0nnnmGYWGhqp27dqaMGGCcnNzi3oaAAAAAAC4XJFnutPT0+3aatWqpbS0NJ04ccLpOD/99JMuXbqkKlWq2LRXqVJFx48fd7jPd999px07dsjHx0evv/66fvrpJ40ePVqnT58u8L7u8+fP6/z589bts2fPOp0jAAAAAADXosgz3QXx8fFRjRo1irzflYuvGWMKXJDt8uXLslgsWrNmjVq0aKEePXpo7ty5WrFiRYGz3bNnz5a/v7/1FRYWVuQcAQAAAAAoDqeK7ooVK+qnn36SJAUEBKhixYoFvpwVGBgod3d3u1ntkydP2s1+5wsJCVFoaKj8/f2tbfXq1ZMxpsDL2xMTE3XmzBnr69ixY07nCAAAAADAtXDq8vJ58+apXLly1q+L82iwK3l5ealZs2basmWLevfubW3fsmWL7rjjDof7tGnTRq+99pp+/fVXlS1bVpL0zTffyM3NTdWqVXO4j7e3t7y9va85XwAAAAAAisqponvw4MHWr4cMGVJiBx8/frzuvfdeRUdHq1WrVlq8eLGOHj2qkSNHSvp9ljozM1OrVq2SJA0YMECPP/64hg4dqpkzZ+qnn37SxIkTNWzYMPn6+pZYXgAAAAAAlIQiL6T2ySefyNPTU40aNZIk/fe//1VSUpLq16+vGTNmyMvLy+lYd999t06dOqVZs2YpKytLDRs21MaNG633hmdlZeno0aPW8WXLltWWLVv04IMPKjo6WpUqVVJcXJyeeOKJop4GAAAAAAAuV+Sie8SIEZo8ebIaNWqk7777TnfffbfuvPNOvfbaa8rJydH8+fOLFG/06NEaPXq0w74VK1bYtdWtW1dbtmwpatoAAAAAAFx3RV69/JtvvlFkZKQk6bXXXlO7du30yiuvaMWKFVq3bl1J5wcAAAAAwA2ryEW3MUaXL1+WJL333nvq0aOHJCksLMy6wjkAAAAAAChG0R0dHa0nnnhC//73v5WamqrbbrtNkpSenl7go74AAAAAAPg7KnLRPX/+fH3yyScaM2aMHnvsMdWqVUuS9J///EetW7cu8QQBAAAAALhRFXkhtcaNG+vzzz+3a3/22Wfl7u5eIkkBAAAAAPBXUOSZbkn6+eeftXTpUiUmJur06dOSpIMHD+rkyZMlmhwAAAAAADeyIs90f/bZZ+rYsaMqVKigjIwMxcfHq2LFinr99dd15MgRrVq1yhV5AgAAAABwwynyTPf48eM1dOhQHTp0SD4+Ptb27t27a9u2bSWaHAAAAAAAN7IiF9179uzRiBEj7NpDQ0N1/PjxEkkKAAAAAIC/giIX3T4+Pjp79qxd+9dff63KlSuXSFIAAAAAAPwVFLnovuOOOzRr1ixdvHhRkmSxWHT06FFNnjxZffr0KfEEAQAAAAC4URW56H7uuef0448/KigoSLm5uWrXrp1q1aqlcuXK6cknn3RFjgAAAAAA3JCKvHp5+fLltWPHDn3wwQf65JNPdPnyZUVFRalTp06uyA8AAAAAgBtWkYvufB06dFCHDh1KMhcAAAAAAP5SnCq6//nPfzodcOzYscVOBgAAAACAvxKniu558+Y5FcxisVB0AwAAAADw/zlVdKenp7s6DwAAAAAA/nKKvHo5AAAAAABwjlMz3ePHj9fjjz+uMmXKaPz48YWOnTt3bokkBgAAAADAjc6pojstLU0XL160fl0Qi8VSMlkBAAAAAPAX4FTR/eGHH+q7776Tv7+/PvzwQ1fnBAAAAADAX4LT93TffPPN+vHHH63bd999t06cOOGSpAAAAAAA+Ctwuug2xthsb9y4UefOnSvxhAAAAAAA+Ktg9XIAAAAAAFzE6aLbYrHYLZTGwmkAAAAAABTMqYXUpN8vLx8yZIi8vb0lSb/99ptGjhypMmXK2Ixbv359yWYIAAAAAMANyumie/DgwTbb99xzT4knAwAAAADAX4nTRXdSUpIr8wAAAAAA4C+HhdQAAAAAAHARim4AAAAAAFyEohsAAAAAABeh6AYAAAAAwEUougEAAAAAcBGKbgAAAAAAXISiGwAAAAAAF6HoBgAAAADARSi6AQAAAABwEYpuAAAAAABchKIbAAAAAAAXoegGAAAAAMBFKLoBAAAAAHARim4AAAAAAFyEohsAAAAAABeh6AYAAAAAwEUougEAAAAAcBGKbgAAAAAAXISiGwAAAAAAF6HoBgAAAADARSi6AQAAAABwEYpuAAAAAABchKIbAAAAAAAXoegGAAAAAMBFKLoBAAAAAHARim4AAAAAAFyEohsAAAAAABeh6AYAAAAAwEUougEAAAAAcBGKbgAAAAAAXISiGwAAAAAAF6HoBgAAAADARSi6AQAAAABwEYpuAAAAAABchKIbAAAAAAAXoegGAAAAAMBFKLoBAAAAAHARim4AAAAAAFyEohsAAAAAABeh6AYAAAAAwEUougEAAAAAcBGKbgAAAAAAXISiGwAAAAAAFyn1onvBggWKiIiQj4+PmjVrpu3btzu130cffSQPDw9FRka6NkEAAAAAAIqpVIvulJQUPfTQQ3rssceUlpamtm3bqnv37jp69Gih+505c0aDBg1Sx44dr1OmAAAAAAAUXakW3XPnztV9992n4cOHq169epo/f77CwsK0cOHCQvcbMWKEBgwYoFatWl2nTAEAAAAAKLpSK7ovXLigffv2qUuXLjbtXbp00ccff1zgfklJSfr22281ffp0p45z/vx5nT171uYFAAAAAMD1UGpF908//aRLly6pSpUq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pMLCQm3atEnTpk3TG2+8oW3btlkfRFzrWP38/K75YUVD7r77bt11111asWKFEhMT9f3332vDhg0Njrn8elfOYUNzAAAAGifOdANAE9G6dWslJiZq0aJFunDhQp3tlx/aFRMTo+LiYpWUlFjbfvzxR50/f17R0dH/uo4rH9h2eb1r165X7R8SEqL27dvr8OHD6tSpk9MSERFh9QsMDNTYsWOVnZ2tVatWac2aNTpz5oykS6F5xIgRWrhwobZu3apdu3bp+++/V0xMjKqrq7Vnzx5rP6dPn9ZPP/10XY71SpMnT1Zubq5ycnKUkJDgdCWBdOnhdb/99pu1vmvXLnl4eKhLly5/eQ4AAEDjw5luAGhCFi9erL59+6p3796aPXu2YmNjVV1drcLCQi1ZskQOh0MJCQmKjY3VuHHjlJWVperqak2bNk0DBw50uuz7n1q9erV69eqle++9VytXrtTevXv1zjvvNDgmIyNDaWlpCgwMVFJSkioqKrRv3z6dPXtW6enpWrBggcLCwtSjRw95eHho9erVCg0NVVBQkPLy8lRTU6M+ffrI399f7733nvz8/NShQwcFBwcrOTlZqampWrZsmVq0aKEXXnhB7du3V3Jy8r8+1iuNGzdOzz77rLKzs7VixYo62319fTVhwgTNnTtXpaWlSktL05gxYxQaGvqX5gAAADROnOkGgCYkIiJC3377re6//34988wz6t69u4YMGaLNmzdryZIlki5dzrxu3Tq1atVKAwYMUEJCgiIjI7Vq1arrUkNmZqY++ugjxcbG6t1339XKlSsVExPT4JjJkyfr7bffVl5enu68804NHDhQeXl51lnegIAAvf766+rVq5fuueceFRUVKT8/Xx4eHgoKClJ2drb69eun2NhYbd68WRs2bFBwcLCkS/dXx8XFadiwYYqPj5cxRvn5+df9u8EDAwM1cuRIBQQE1Ht5f6dOnfTII4/ogQce0NChQ9W9e3enrwS71hwAAIDGyWaudkMbAADXmc1m09q1axu8p/xWNmTIEEVHR2vhwoVO7RkZGVq3bp0OHDjgnsIAAIDLcHk5AAAudubMGRUUFGjLli1666233F0OAAC4gQjdAAC4WM+ePXX27Fm9/vrrioqKcnc5AADgBuLycgAAAAAAXIQHqQEAAAAA4CKEbgAAAAAAXITQDQAAAACAixC6AQAAAABwEUI3AAAAAAAuQugGAAAAAMBFCN0AAAAAALgIoRsAAAAAABchdAMAAAAA4CL/B/YFs0q0MpOxAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot hdf5 filesize for each compressor and level\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "format = ['HDF5'] * 10 * len(hdf5_compressors)\n", - "\n", - "compressor = [n for n in hdf5_compressors for _ in range(10)]\n", - "\n", - "lvl = list(range(10)) * len(hdf5_compressors)\n", - "val = []\n", - "\n", - "for c in hdf5_compressors:\n", - " for i in range(10):\n", - " val.append(filesize(f'yiip_{c}_{i}_hdf5.h5'))\n", - "\n", - "\n", - "data = {\n", - " 'Format': format,\n", - " 'Compressor': compressor,\n", - " 'Level': lvl,\n", - " 'Filesize': val\n", - "}\n", - "\n", - "df = pd.DataFrame(data)\n", - "\n", - "pivot_df = df.pivot(index='Compressor', columns=['Format', 'Level'], values='Filesize')\n", - "\n", - "pivot_df.plot(kind='bar', figsize=(10, 6))\n", - "plt.title('Comparison of HDF5 Compressors Types and Levels for filesize')\n", - "plt.xlabel('Compressor Type')\n", - "plt.ylabel('Filesize (kB)')\n", - "plt.xticks(rotation=0)\n", - "plt.legend(title='Format, Level', bbox_to_anchor=(1.05, 1), loc='upper left')\n", - "plt.tight_layout()\n", - "plt.show()\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAJOCAYAAACqS2TfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAACRU0lEQVR4nOzdeVwVZf//8Tc7iIqAoiAkalEUaCRpuNziihuZS8tti1pqZuWW3UpqanZHRSVtuCeZhugdVppZ5gJ2p2mmpUndZhwp0lQwTSQBmd8f/jhfjwfwsBzRej0fj3k8PNdcM/M5hwF5c81c42AYhiEAAAAAAFDjHGu7AAAAAAAA/qoI3QAAAAAA2AmhGwAAAAAAOyF0AwAAAABgJ4RuAAAAAADshNANAAAAAICdELoBAAAAALATQjcAAAAAAHZC6AYAAAAAwE4I3fjb+/bbbzV8+HA1b95c7u7uqlu3rm655Ra9+OKLysvLq+3y7G7YsGEKDg6u7TKqbffu3ercubO8vLzk4OCgxMTEMvsNGzZMDg4OFS5XyuexZs0axcbGqnHjxnJ1dZWPj4+6deum5cuXq6ioqLbL+1symUyXPH9KF5PJVNvlXpFmzpwpBweHS/YbNmyY6tatexkqqrwtW7bIwcFBW7ZsqZH9vf7667r22mvl6uoqBwcH/f777zWy37IkJyeXe85OmjTJfI4nJydbbWOvc/qv8v8QAJTHubYLAGrTwoULNWbMGF1//fV68skndeONN6qoqEhfffWV5s2bp23btmn16tW1XaZdTZ8+XePGjavtMqrtwQcfVH5+vlasWCFvb+9yf4GbPn26Ro8eXea65ORkzZ8/XwMGDLBjpZdmGIYefPBBJScnq0+fPnrllVcUFBSkkydPavPmzRozZoyOHz/+l/i6XW38/f21bds2i7YxY8bo5MmTWr58uVVf4FL27NmjsWPHasSIERo6dKicnZ1Vr149ux93yZIluuGGGyzaAgIC1LhxY23btk0tW7a0ew2l/ir/DwFAeQjd+Nvatm2bHnnkEfXo0UPvv/++3NzczOt69OihJ554QuvXr6/FCu3rzJkzqlOnzmX9xcqe9u3bp5EjR6p3794V9mvZsmWZ73n79u1asmSJ/vGPfyghIaFGair9jMtSUFAgDw+PMtclJCQoOTlZs2bN0tNPP22xLjY2Vv/617/0448/1kiNl8u5c+dUXFxs8X12pSvr6+fm5qbbbrvNoq1+/foqLCy0agds8d1330mSRo4cqbZt29bIPiv62VMqLCxMkZGRZa673OfyX+X/IQAoD5eX42/rueeek4ODgxYsWFBmEHB1ddXtt99ufl1SUqIXX3xRN9xwg9zc3OTn56cHHnhAv/zyi8V20dHRCgsL07Zt29S+fXt5eHgoODhYS5YskSR99NFHuuWWW1SnTh2Fh4dbBfvSSy93796tgQMHqn79+vLy8tJ9992nY8eOWfRNTU1Vz5495e/vLw8PD4WGhmrKlCnKz8+36Fd6mebevXvVs2dP1atXT926dTOvu3hUeNWqVWrXrp28vLxUp04dtWjRQg8++KBFn+zsbN13333y8/OTm5ubQkND9fLLL6ukpMTcp/QyxZdeekmvvPKKmjdvrrp16yoqKkrbt2+v6Mtjtm/fPvXv31/e3t5yd3fXzTffrLffftu8vvSyx+LiYs2dO9d8mWRlHDlyRIMGDVKjRo20cuVKOTv/398jN2zYoP79+yswMFDu7u669tpr9fDDD+v48eMW+yj9un399dcaPHiwvL29zb9IBgcHq1+/fkpLS1NERITc3d01a9asMmspKirSCy+8oBtuuEHTp08vs0+TJk3UsWNH8+u8vDyNGTNGTZs2laurq1q0aKGpU6fq7NmzFts5ODjoscce05IlS3T99dfLw8NDkZGR2r59uwzDUEJCgvlr1LVrV6tgX3pub926Vbfddps8PDzUtGlTTZ8+XefOnTP3K/26v/jii3r22WfVvHlzubm5afPmzZKkr776Srfffrt8fHzk7u6uiIgIrVy50uJYZ86c0aRJk8y3ffj4+CgyMlIpKSnmPj/99JPuueceBQQEyM3NTY0bN1a3bt20Z88ec5/Kft9mZGSoffv2qlOnjtU5b6tu3brphhtukGEYFu2GYejaa69V3759rT6nf//737rmmmvk7u6uyMhIbdy40Wq/Bw4c0JAhQyy+5958802LPiUlJXr22WfNX98GDRqoVatWevXVVyus+c8//9QTTzyhm2++WV5eXvLx8VFUVJQ++OADq76l59E777yj0NBQ1alTR61bt9batWut+n700Ue6+eab5ebmpubNm+ull1665OdXWZ999pm6deum+vXrq06dOurQoYPF5/f+++/LwcGhzM+09GfGt99+a26z5fwsiy3n48Wio6N13333SZLatWsnBwcHDRs2zLz+rbfeUuvWrc3fAwMGDFBmZqbFPir6+V4VZV1eXp5LffaSdOzYMY0aNUpBQUFyc3NTo0aN1KFDB3322WcW7+HC/4dKf56WtVz4+RQWFurZZ581f383atRIw4cPt/q/EgBqnQH8DRUXFxt16tQx2rVrZ/M2o0aNMiQZjz32mLF+/Xpj3rx5RqNGjYygoCDj2LFj5n6dO3c2fH19jeuvv95YvHix8cknnxj9+vUzJBmzZs0ywsPDjZSUFGPdunXGbbfdZri5uRk5OTnm7WfMmGFIMpo1a2Y8+eSTxieffGK88sorhqenpxEREWEUFhaa+86ePduYM2eO8dFHHxlbtmwx5s2bZzRv3tzo0qWLRe1Dhw41XFxcjODgYCM+Pt7YuHGj8cknn5jXNWvWzNz3iy++MBwcHIx77rnHWLdunbFp0yZjyZIlxv3332/uc/ToUaNp06ZGo0aNjHnz5hnr1683HnvsMUOS8cgjj5j7ZWVlGZKM4OBgo1evXsb7779vvP/++0Z4eLjh7e1t/P777xV+5t9//71Rr149o2XLlsbSpUuNjz76yPjnP/9pSDJeeOEFcy3btm0zJBmDBw82tm3bZmzbts3mr2thYaHRsWNHw9XVtczt5s6da8THxxsffvihkZ6ebrz99ttG69atjeuvv97ia3Hh123y5MnGhg0bjPfff98wDMNo1qyZ4e/vb7Ro0cJ46623jM2bNxs7duwos54vvvjCkGRMnjzZpvoLCgqMVq1aGZ6ensZLL71kfPrpp8b06dMNZ2dno0+fPhZ9S+tr3769kZaWZqxevdoICQkxfHx8jAkTJhj9+/c31q5dayxfvtxo3Lix0apVK6OkpMS8fem5HRAQYLz22mvGJ598YowdO9aQZDz66KPmfqVf96ZNmxpdunQx/vOf/xiffvqpkZWVZWzatMlwdXU1OnXqZKSmphrr1683hg0bZkgylixZYt7Hww8/bNSpU8d45ZVXjM2bNxtr1641nn/+eeP1118397n++uuNa6+91njnnXeM9PR047333jOeeOIJY/PmzeY+lfm+9fHxMYKCgozXX3/d2Lx5s5Genm7T16Bz587GTTfdZH79wQcfGJKMDRs2WPT76KOPDEnGRx99ZPE5BQUFGR07djTee+89Y9WqVcatt95quLi4GF988YV52++++87w8vIywsPDjaVLlxqffvqp8cQTTxiOjo7GzJkzzf3i4+MNJycnY8aMGcbGjRuN9evXG4mJiRZ9yvL7778bw4YNM9555x1j06ZNxvr1641JkyYZjo6Oxttvv23Rt/R7um3btsbKlSuNdevWGdHR0Yazs7Nx8OBBc7/PPvvMcHJyMjp27GikpaWZ39s111xj2PLrx9ChQw1PT88K+7zzzjuGg4ODcccddxhpaWnGmjVrjH79+hlOTk7GZ599ZhiGYRQVFRl+fn7Gvffea7V927ZtjVtuucX82tbzc/PmzYYki3PNlvPxYt99950xbdo08/63bdtm/Pjjj4ZhGMZzzz1nSDL++c9/Gh999JGxdOlSo0WLFoaXl5fxv//9z+JzKu/ne1mWLFliSDK2b99uFBUVWSyG8X/n5YXvt3SbrKysSn32hmEYMTExRqNGjYwFCxYYW7ZsMd5//33j6aefNlasWGHxHi78f+jnn382/ywvXZ588klDkvHiiy8ahmEY586dM3r16mV4enoas2bNMjZs2GAsWrTIaNq0qXHjjTcaZ86cKfczAIDLjdCNv6UjR44Ykox77rnHpv6ZmZmGJGPMmDEW7V9++aUhyXjqqafMbZ07dzYkGV999ZW5LTc313BycjI8PDwsAvaePXsMScZrr71mbisNbxMmTLA41vLlyw1JxrJly8qssaSkxCgqKjLS09MNScY333xjXjd06FBDkvHWW29ZbXfxLzsvvfSSIanCQDxlyhRDkvHll19atD/yyCOGg4OD8cMPPxiG8X+/vIWHhxvFxcXmfjt27DAkGSkpKeUewzAM45577jHc3NyM7Oxsi/bevXsbderUsajx4uBnqzFjxhiSjHnz5l2yb+lnfOjQIUOS8cEHH5jXlX7dnn76aavtmjVrZjg5OZk/l4qsWLHC5noMwzDmzZtnSDJWrlxp0f7CCy8YkoxPP/3U3CbJaNKkiXH69Glz2/vvv29IMm6++WaLgJ2YmGhIMr799ltzW+m5feH7NgzDGDlypOHo6GgcOnTIMIz/+7q3bNnS4g8ThmEYN9xwgxEREWH+Bb9Uv379DH9/f+PcuXOGYRhGWFiYcccdd5T7vo8fP25IMhITE8vtU5Xv240bN5a7v/JcHLrPnTtntGjRwujfv79Fv969exstW7Y0f86ln1NAQIBRUFBg7nfq1CnDx8fH6N69u7ktJibGCAwMNE6ePGmxz8cee8xwd3c38vLyDMM4/znefPPNlX4PFysuLjaKioqMhx56yIiIiLBYJ8lo3LixcerUKXPbkSNHDEdHRyM+Pt7c1q5du3LfW02E7vz8fMPHx8eIjY21aD937pzRunVro23btua2iRMnGh4eHhY/M/bv329IsvhDjq3n58Wh25bzsTylgXbnzp3mthMnThgeHh5WfzjLzs423NzcjCFDhpjbKvr5XtHxylqKiopsCt2V+ezr1q1rjB8/vsKaLv5/6GJbt2413N3djXvvvdf8/ZOSkmJIMt577z2Lvjt37jQkGUlJSTZ8GgBwefytLy/PyMhQbGysAgIC5ODgoPfff7/S+zAMQy+99JJCQkLk5uamoKAgPffcczVfLGpV6WWxF17WJklt27ZVaGio1eV0/v7+atOmjfm1j4+P/Pz8dPPNNysgIMDcHhoaKkk6dOiQ1THvvfdei9d33XWXnJ2dzbVI5y9nHDJkiJo0aSInJye5uLioc+fOkmR1CaIkDRo06JLv9dZbbzUfb+XKlcrJybHqs2nTJt14441W9x8OGzZMhmFo06ZNFu19+/aVk5OT+XWrVq0klf2+Lz5Ot27dFBQUZHWcM2fOWE1oVVnJyclKSkrSgw8+qIcffrjMPkePHtXo0aMVFBQkZ2dnubi4qFmzZpIq9xm3atVKISEh1aq3LJs2bZKnp6cGDx5s0V56rl58bnbp0kWenp7m16XnYO/evS0uyy/v3KxXr57FbReSNGTIEJWUlCgjI8Oi/fbbb5eLi4v59Y8//qjvv//efG4XFxeblz59+ujw4cP64YcfJJ3/3vr44481ZcoUbdmyRQUFBRb79vHxUcuWLZWQkKBXXnlFu3fvtri1Qar89623t7e6du2q6nJ0dNRjjz2mtWvXKjs7W5J08OBBrV+/XmPGjLG6/WHgwIFyd3c3v65Xr55iY2OVkZGhc+fO6c8//9TGjRs1YMAA1alTx+pz+/PPP823a7Rt21bffPONxowZo08++USnTp2yue5Vq1apQ4cOqlu3rvlcX7x4cZnneZcuXSwm+2rcuLH8/PzM50t+fr527txZ7nurCV988YXy8vI0dOhQi8+kpKREvXr10s6dO8232jz44IMqKChQamqqefslS5bIzc1NQ4YMkVS58/NitpyPlbFt2zYVFBRYnbtBQUHq2rVrmZfK2/Lz/UJLly7Vzp07LZYLb62pSGU++7Zt2yo5OVnPPvustm/fXuknL2RmZur2229X+/bt9dZbb5m/f9auXasGDRooNjbWooabb75ZTZo0qbGZ5QGgJvytQ3d+fr5at26tN954o8r7GDdunBYtWqSXXnpJ33//vdasWVNjE6HAfho2bKg6deooKyvLpv65ubmSyp6NOCAgwLy+lI+Pj1W/0kc+Xdwmnb+f8mJNmjSxeO3s7CxfX1/zsU6fPq1OnTrpyy+/1LPPPqstW7Zo586dSktLkySrkFKnTh3Vr1+/wvcpSf/4xz/0/vvvq7i4WA888IACAwMVFhZmcS9tbm5uuZ9F6foL+fr6WrwuvYf+4hovVtnjVMZXX32lRx55RJGRkUpKSiqzT0lJiXr27Km0tDT961//0saNG7Vjxw5zwCmr/vJmrLZ1JutrrrlGkip1bjZp0sQqyPn5+cnZ2fmS52bpOWjrudm4cWOrGkrP1YuPdfF7/u233yRJkyZNkouLi8UyZswYSTLfK//aa69p8uTJev/999WlSxf5+Pjojjvu0IEDByTJfI9uTEyMXnzxRd1yyy1q1KiRxo4dqz/++MOiHlu/b2tytvEHH3xQHh4emjdvniTpzTfflIeHR5n3iV/8vV7aVlhYqNOnTys3N1fFxcV6/fXXrT63Pn36SPq/zy0uLk4vvfSStm/frt69e8vX11fdunXTV199VWG9aWlpuuuuu9S0aVMtW7ZM27Zt086dO/Xggw+W+fPp4u9p6fz3den3xIkTJ1RSUlLue6sJpefT4MGDrT6XF154QYZhmB/7eNNNN+nWW281z61x7tw5LVu2TP379zef+5U5Py9my/lYGZU9d239+X6h0NBQRUZGWiy2qsxnn5qaqqFDh2rRokWKioqSj4+PHnjgAR05cuSSx/n111/Vq1cvBQYGKi0tzfxzqbSG33//Xa6urlY1HDlypNyvFQDUhr/17OW9e/eucKbjwsJCTZs2TcuXL9fvv/+usLAwvfDCC4qOjpZ0/q+vc+fO1b59+3T99ddfpqpRE5ycnNStWzd9/PHH+uWXXxQYGFhh/9JfMA8fPmzV99dff1XDhg1rvMYjR46oadOm5tfFxcXKzc0117Jp0yb9+uuv2rJli3l0W1K5z3etzORi/fv3V//+/XX27Flt375d8fHxGjJkiIKDgxUVFSVfX18dPnzYartff/1Vkmrs87DXcY4dO6aBAweqbt26eu+998qdUXvfvn365ptvlJycrKFDh5rbK5o5vLzP2dbPPzIyUj4+Pvrggw8UHx9/ye18fX315ZdfyjAMi75Hjx5VcXFxjZ+bpb9sX6j0l+eLg9jFtZfWEhcXp4EDB5a5/9KfpZ6enpo1a5ZmzZql3377zTzqHRsbq++//16S1KxZMy1evFiS9L///U8rV67UzJkzVVhYqHnz5lX6+7ayE/BVxMvLyxw0Jk2apCVLlmjIkCFq0KCBVd+ywseRI0fk6uqqunXrysXFRU5OTrr//vv16KOPlnm85s2bSzr/x7mJEydq4sSJ+v333/XZZ5/pqaeeUkxMjH7++edyZ7RetmyZmjdvrtTUVIvP4eLJ+Gzl7e0tBweHct9bTSj9+r3++uvlzrZ94R+Jhg8frjFjxigzM1M//fSTDh8+rOHDh1vtz5bzsyyXOh8r48Jz92L2PndtUZnPvmHDhkpMTFRiYqKys7P14YcfasqUKTp69GiFTwg5deqU+vTpo5KSEq1bt05eXl5WNfj6+pa7j8vx2DUAsNXfeqT7UoYPH67//ve/WrFihb799lvdeeed6tWrl3mkZc2aNWrRooXWrl2r5s2bKzg4WCNGjDD/dRdXtri4OBmGoZEjR6qwsNBqfVFRkdasWSNJ5ktOly1bZtFn586dyszMrNZMseW5+Jm/K1euVHFxsfmPPqW/ZF0cGOfPn19jNbi5ualz58564YUXJEm7d++WdH525v379+vrr7+26L906VI5ODioS5cuNXL8bt26mf+4cPFx6tSpU6XH2hQXF+vOO+/Ur7/+qtTUVPPIclkux2d8MRcXF02ePFnff/+9Zs+eXWafo0eP6r///a+k85/R6dOnrW6PWbp0qXl9Tfrjjz/04YcfWrS9++67cnR01D/+8Y8Kt73++ut13XXX6ZtvvrEaYStdyvpFuXHjxho2bJj++c9/6ocfftCZM2es+oSEhGjatGkKDw83n5e18X17obFjx+r48eMaPHiwfv/9dz322GNl9ktLS7MYTf7jjz+0Zs0aderUSU5OTqpTp466dOmi3bt3q1WrVmV+bmWNPDdo0ECDBw/Wo48+qry8PJlMpnJrdXBwkKurq0V4O3LkSJmzl9vC09NTbdu2Lfe91YQOHTqoQYMG2r9/f7nn04Ujo//85z/l7u6u5ORkJScnq2nTpurZs6d5fVXPz7KUdT5WRlRUlDw8PKzO3V9++cV8201tquxnX+qaa67RY489ph49elT4uRQWFmrAgAEymUz6+OOPy/zDeL9+/ZSbm6tz586VeXwGQwBcSf7WI90VOXjwoFJSUvTLL7+YL2WdNGmS1q9fryVLlui5557TTz/9pEOHDmnVqlVaunSpzp07pwkTJmjw4MFW97TiyhMVFaW5c+dqzJgxatOmjR555BHddNNNKioq0u7du7VgwQKFhYUpNjZW119/vUaNGqXXX39djo6O6t27t0wmk6ZPn66goCBNmDChxutLS0uTs7OzevTooe+++07Tp09X69atddddd0mS2rdvL29vb40ePVozZsyQi4uLli9frm+++aZax3366af1yy+/qFu3bgoMDNTvv/+uV1991eJ+8QkTJmjp0qXq27evnnnmGTVr1kwfffSRkpKS9Mgjj9TYvcszZszQ2rVr1aVLFz399NPy8fHR8uXL9dFHH+nFF1+0GvmwxZNPPqn09HTde++9qlOnTrmPLrvtttt0ww03qGXLlpoyZYoMw5CPj4/WrFmjDRs2VPetXbLGzMxMzZgxQzt27NCQIUMUFBSkkydPKiMjQwsWLNCsWbPUoUMHPfDAA3rzzTc1dOhQmUwmhYeH6/PPP9dzzz2nPn36qHv37jVam6+vrx555BFlZ2crJCRE69at08KFC/XII49U+AeMUvPnz1fv3r0VExOjYcOGqWnTpsrLy1NmZqa+/vprrVq1StL5xyf169dPrVq1kre3tzIzM/XOO+8oKipKderU0bfffqvHHntMd955p6677jq5urpq06ZN+vbbbzVlyhRJqpXv2wuFhISoV69e+vjjj9WxY0e1bt26zH5OTk7q0aOHJk6cqJKSEr3wwgs6deqUxWPlXn31VXXs2FGdOnXSI488ouDgYP3xxx/68ccftWbNGvP/ObGxsebnLzdq1EiHDh1SYmKimjVrpuuuu67cWksfaTdmzBgNHjxYP//8s2bPni1/f3/zH5ora/bs2erVq5d69OihJ554QufOndMLL7wgT09Pm/84fe7cOf3nP/+xavf09FTv3r31+uuva+jQocrLy9PgwYPl5+enY8eO6ZtvvtGxY8c0d+5c8zYNGjTQ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JwAAAABwBTh37pwkydXVtZYrgS1K/zBSVFRUYT9CNwAAAABcQS51jzCuDLZ+nQjdAAAAAADYSa2G7oyMDMXGxiogIEAODg56//33K+yflpamHj16qFGjRqpfv76ioqL0ySefXJ5iAQAAAAB/eSaTSQ4ODtqzZ0+N7K9WQ3d+fr5at26tN954w6b+GRkZ6tGjh9atW6ddu3apS5cuio2N1e7du+1cKQAAAADUrmHDhsnBwcFq+fHHH2u7NCvVCa7R0dEaP358jddUW2p19vLevXurd+/eNvdPTEy0eP3cc8/pgw8+0Jo1axQREVHD1QEAAADAlaVXr15asmSJRVujRo2qtK/CwkImbbsMrup7uktKSvTHH3/Ix8en3D5nz57VqVOnLBYAAAAAuBq5ubmpSZMmFkvp46rS09PVtm1bubm5yd/fX1OmTFFxcbF52+joaD322GOaOHGiGjZsqB49emjLli1ycHDQJ598ooiICHl4eKhr1646evSoPv74Y4WGhqp+/fr65z//qTNnzpj3tX79enXs2FENGjSQr6+v+vXrp4MHD5rXN2/eXJIUEREhBwcHRUdH19hn8MUXX+gf//iHPDw8FBQUpLFjxyo/P1+SFBcXp9tuu81qm1atWmnGjBnm10uWLFFoaKjc3d11ww03KCkpqcbqu9hVHbpffvll5efn66677iq3T3x8vLy8vMxLUFDQZawQAAAAAOwvJydHffr00a233qpvvvlGc+fO1eLFi/Xss89a9Hv77bfl7Oys//73v5o/f765febMmXrjjTf0xRdf6Oeff9Zdd92lxMREvfvuu/roo4+0YcMGvf766+b++fn5mjhxonbu3KmNGzfK0dFRAwYMUElJiSRpx44dkqTPPvtMhw8fVlpaWo28z7179yomJkYDBw7Ut99+q9TUVH3++ed67LHHJEn33nuvvvzyS4s/AHz33Xfau3ev7r33XknSwoULNXXqVP373/9WZmamnnvuOU2fPl1vv/12jdRoxbhCSDJWr15tc/93333XqFOnjrFhw4YK+/3555/GyZMnzcvPP/9sSDJOnjxZzYoBAAAAXIlOnjx5Vf7OX1BQYOzfv98oKCgoc/3QoUMNJycnw9PT07wMHjzYMAzDeOqpp4zrr7/eKCkpMfd/8803jbp16xrnzp0zDMMwOnfubNx8880W+9y8ebMhyfjs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ateunb755hvt3r1bN998syQpPDxcbdu21Zw5czRt2rRqH4fQDQC4amTeEFruutDvMy9jJQAAoFRBQYEWL16sdevWmdvS0tJUWFho0a+wsFB9+/aVu7u72rVrV+XjFRUVycXFxWrfrq6uldrPv/71LwUEBOibb76xWjd8+HCNHj1acXFxcnJyqnKtEpeXAwAAAACq4eOPP5azs7OioqLMbT4+PmrSpInFMnv2bB07dkyrV6+Wu7u7JGn9+vXq2LGjGjRoIF9fX/Xr108HDx4078dkMsnBwUErV65UdHS03N3dtWzZMg0bNkx33HGH4uPjFRAQoJCQkErX/Omnn+qll14qc31MTIxyc3MrHK23FaEbAAAAAFBlGRkZioyMrLBPUlKSli5dqrS0NAUGBprb8/PzNXHiRO3cuVMbN26Uo6OjBgwYoJKSEovtJ0+erLFjxyozM1MxMTGSpI0bNyozM1MbNmzQ2rVrba73t99+08iRI/XOO++oTp06ZfZxdXVV69attXXrVpv3Wx4uLwcA/CVc6n63qtyfBgAALs1kMikgIKDc9RkZGRo/frySkpLUvn17i3WDBg2yeL148WL5+flp//79CgsLM7ePHz9eAwcOtOjr6empRYsWVeqycsMwNGzYMI0ePVqRkZEVTvzWtGnTGpkYjtANAPhbePnufhWufyLV9r+QAwCA/1NQUGC+XPxi2dnZGjx4sEaNGqURI0ZYrT948KCmT5+u7du36/jx4+YR7uzsbIvQXdZIenh4eKXv43799dd16tQpxcXFXbKvh4eHzpw5U6n9l4XLywEAAAAAVdawYUOdOHHCqr2goEADBgzQTTfdpMTExDK3jY2NVW5urhYuXKgvv/xSX375pSRZTcLm6elptW1ZbZeyadMmbd++XW5ubnJ2dta1114r6XyoHzp0qEXfvLw8NWrUqNLHuBgj3QAASPplSvn3bC1y31jhtjNnzqzhagAAuHpERERo2bJlVu0jRoxQXl6ePvnkEzk7W0fP3NxcZWZmav78+erUqZMk6fPPP7drra+99pqeffZZ8+tff/1VMTExSk1NtZpRfd++fRo8eHC1j0noBgCgmjZualnh+nsd3it33ZEuN9dwNQAAXF4xMTGKi4vTiRMn5O3tLUlKSEjQqlWrtGbNGhUXF+vIkSMW23h5ecnb21u+vr5asGCB/P39lZ2d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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot zarr filesize for each compressor and level\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "\n", - "format = ['Zarr'] * 10 * len(zarr_compressors)\n", - "compressor = [n for n in zarr_compressors for _ in range(10)]\n", - "lvl = list(range(10)) * len(zarr_compressors) \n", - "val = []\n", - "for c in zarr_compressors:\n", - " for i in range(10):\n", - " val.append(filesize(f'zarrfiles/yiip_{c}_{i}_zarr.zarr'))\n", - "\n", - "data = {\n", - " 'Format': format,\n", - " 'Compressor': compressor,\n", - " 'Level': lvl,\n", - " 'Filesize': val\n", - "}\n", - "\n", - "df = pd.DataFrame(data)\n", - "\n", - "pivot_df = df.pivot(index='Compressor', columns=['Format', 'Level'], values='Filesize')\n", - "\n", - "pivot_df.plot(kind='bar', figsize=(10, 6))\n", - "plt.title('Comparison of Zarr Compressor Types and Levels vs Filesize')\n", - "plt.xlabel('Compressor Type')\n", - "plt.ylabel('Filesize (kB)')\n", - "plt.xticks(rotation=0)\n", - "plt.legend(title='Format, Level', bbox_to_anchor=(1.05, 1), loc='upper left')\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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n58ftm3bBn9/f50ESkRERERERPS40SjpBv56PFh0dDSio6Px+++/o6CgAAqFAlZWVnB2dubO5UREREREREQP0TjpfpCZmRnMzMxaOBQiIiIiIiKivxfuXk5ERERERESkI0y6iYiIiIiIqF4lJSWwtraGXC5v61BaxeLFi7FgwYIW649JNxEREREREdUrLi4OQUFBkMlkAAC5XA6JRIILFy6o1PX19UVERITSsUQigUQigaGhIbp27YqgoCBkZmaqtK2r9+BryJAh4nmZTKZyPioqSuvrycrKQv/+/WFkZITu3btj06ZNSudfe+01JCcnIz8/X+u+1WnSPd1ERERERETUfLKor1p1PPmaMVrVVygUSEpKwr59+5o8Znh4OFauXInq6moUFRVh9+7deOaZZxAaGqryuOnk5GQEBgaKxwYGBkrnV65cifDwcPG4Q4cOWsWSn5+P0aNHIzw8HDt27MC3336L+fPno3Pnzpg0aRKAvzYR9/f3x6ZNm7B27VptL1dFk5LumpoaHD16FHl5eZg2bRo6duyIa9euoVOnTlpfNBERERERET2a9u/fD319fXh5eTW5j/bt28PGxgYA4ODggEGDBqFnz56YPXs2pkyZAj8/P7GumZmZWFedjh07Nni+MZs2bUK3bt2QkJAAAHB1dcXZs2exbt06MekGgHHjxiEmJqZFkm6tl5cXFBTA3d0d48ePx4svvohbt24BAN5++20sXry42QERERERERHRoyE7Oxuenp4t3u/MmTNhbm6udpl5Q9auXQtLS0v07dsXq1evRlVVlVbtT5w4AX9/f6WygIAAnD17FtXV1WLZgAEDcPXqVRQUFGjVvzpaJ90LFy6Ep6cnysrKYGxsLJYHBwfj0KFDzQ6IiIiIiIiIHg1yuRx2dnZqz3l7e6NDhw5Kr2PHjmnUr1QqhYuLi8rmbM8++6xSf59//rl4buHChdi1axeOHDmCl156CQkJCZg/f75W11NcXIwuXboolXXp0gU1NTW4ffu2WNa1a1cAaJHN47ReXn78+HF8++23KmvrHR0dUVRU1OyAiIiIiIiI6NGgUChgZGSk9lxaWhpcXV2VyqZPn65x34IgQCKRKJVt2LBBabm5ra2t+HNkZKT4c+/evWFubo6QkBBx9ltTD48pCIJKed0Ec0VFhcb91kfrpLu2thb3799XKf/tt9/QsWPHZgdEREREREREjwYrKyuUlZWpPefg4IAePXoolT24Groh9+/fx+XLl/HUU08pldvY2Kj0WZ9BgwYBAK5cuaJx0m1jY4Pi4mKlsps3b0JfX1+pj9LSUgBA586dNeq3IVovLx85cqR40znw118D7t27hzfeeAOjR49udkBERERERET0aPDw8EBOTk6L9/vxxx+jrKxMafMybZ0/fx6A8mx4Y7y8vHDw4EGlsm+++Qaenp5o166dWHbp0iW0a9cOvXr1anJ8dbSe6d6wYQOGDRuGJ598En/++SemTZuGy5cvw8rKCqmpqc0OiIiIiIiIiB4NAQEBiI6ORllZGczNzZvUR0VFBYqLi1FTU4OioiJkZmZiw4YNeOGFFzBs2DCN+jhx4gROnjyJYcOGwdTUFGfOnEFkZCTGjRuHbt26aRzLvHnz8MEHH2DRokUIDw/HiRMnkJSUpJLLHjt2DEOHDtV45r4hWs9029nZ4cKFC1i8eDHmzp0LDw8PrFmzBufPn4e1tXWzAyIiIiIiIqJHg7u7Ozw9PZGent7kPrZu3QpbW1s4OzsjODgYOTk5SEtLQ2JiosZ9GBoaIi0tDb6+vnjyySexfPlyhIeHqyTLMpkMsbGx9fbj5OSEffv24ejRo+jbty9WrVqF9957T2XGPTU1Vel54M3RpOd0GxsbY/bs2Zg9e3aLBEFERERERPRPJF8zpq1DaFRMTAwWL16M8PBwSKVSyGQycfOxhx09erTB44bU1ycA9OvXDydPnmywvUKhwI0bN+Dj49NgPR8fH3z//ff1nv/qq6+gp6eHkJCQhgPWkNYz3Xp6ehg2bJh4Y3mdGzduQE9Pr0WCIiIiIiIiokfD6NGjMXfu3Ef+aVVZWVkYPny4xkvW61NeXo7k5GTo6zdpjlqF1r0IgoDKykp4enriyy+/hJubm9I5IiIiIiIi+ntZuHBhW4fQqMDAQAQGBja7nylTprRANP9H65luiUSCzz77DEFBQfD29sYXX3yhdE5biYmJcHJygpGREfr379/ow9QrKyuxdOlSODo6wtDQEM7Ozvjoo4+0HpeIiIiIiIhI15o0062np4d3330XvXr1wtSpU7Fs2TKEhYVpPXhaWhoiIiKQmJiIwYMHY/PmzRg1ahRycnLq3YFuypQpuHHjBpKSktCjRw/cvHkTNTU1Wo9NREREREREpGvNWqQ+Z84cuLi4ICQkBFlZWVq3f+edd/D888+LCXtCQgK+/vprbNy4EXFxcSr1Dxw4gKysLPz666+wsLAA8NfudERERERERESPIq2Xlzs6OiptmObr64uTJ0/it99+06qfqqoqnDt3Dv7+/krl/v7++O6779S2+fLLL+Hp6Ym3334bXbt2hYuLCxYvXgyFQqHtZRARERERERHpnNYz3fn5+SplPXr0wPnz53Hjxg2N+7l9+zbu37+PLl26KJV36dIFxcXFatv8+uuvOH78OIyMjLB7927cvn0b8+fPR2lpab33dVdWVqKyslI8vnv3rsYxEhERERERETWH1jPd9TEyMoKjo6PW7R7efE0QhHo3ZKutrYVEIsHOnTsxYMAAjB49Gu+88w5SUlLqne2Oi4uDqamp+HJwcNA6RiIiIiIiIqKm0CjptrCwwO3btwEA5ubmsLCwqPelKSsrK+jp6anMat+8eVNl9ruOra0tunbtClNTU7HM1dUVgiDUu7w9Ojoad+7cEV9Xr17VOEYiIiIiIiKi5tBoefmGDRvQsWNH8eemPBrsYQYGBujfvz8OHjyI4OBgsfzgwYMYP3682jaDBw9GRkYG7t27hw4dOgAAfvnlF0ilUtjb26ttY2hoCENDw2bHS0RERERE9E9UUlICV1dXnD59+h+xkfXixYtRVVWF9957r0X60yjpnjlzpvhzaGhoiwwMAIsWLcK///1veHp6wsvLC1u2bEFhYSHmzZsH4K9Z6qKiImzfvh0AMG3aNKxatQqzZs3CihUrcPv2bbz66quYPXs2jI2NWywuIiIiIiKiVhFr2nidFh3vjtZN4uLiEBQUJCbccrkcTk5OOH/+PPr27atU19fXF3379kVCQoJ4XPekKwMDA1hZWaFfv36YNWsWJk6cqNRW3eTu4MGDcfz4cQB/PbmqoKBA6fySJUuwZs0aja/l+vXreOWVV3Du3DlcvnwZCxYsEGOt89prr8HZ2RmRkZFwcnLSuO/6aH1P9/fff4+LFy+Kx1988QUmTJiA119/HVVVVVr1NXXqVCQkJGDlypXo27cvsrOzsW/fPvHe8OvXr6OwsFCs36FDBxw8eBC///47PD09MX36dAQFBbXYXyCIiIiIiIjo/ygUCiQlJYmPeW6K8PBwXL9+HVeuXMFnn32GJ598Es888wzmzJmjUjc5ORnXr18XX19++aXS+ZUrVyqdX7ZsmVaxVFZWonPnzli6dCn69Omjto61tTX8/f2xadMmrfquj9a7l8+dOxdRUVFwd3fHr7/+iqlTp2LixInIyMhARUWFyl8JGjN//nzMnz9f7bmUlBSVsp49e+LgwYPahk1ERERERERa2r9/P/T19eHl5dXkPtq3bw8bGxsAgIODAwYNGoSePXti9uzZmDJlCvz8/MS6ZmZmYl11Onbs2OD5xshkMrz77rsAUO8TsABg3LhxiImJwdq1a5s8Vh2tZ7p/+eUXcQlBRkYGfHx88MknnyAlJQWfffZZswMiIiIiIiKiR0N2djY8PT1bvN+ZM2fC3NwcmZmZWrVbu3YtLC0t0bdvX6xevVrr1daaGjBgAK5evaqynL0ptJ7pFgQBtbW1AID//ve/GDt2LIC//mJRt8M5ERERERERPf7kcjns7OzUnvP29oZUqjyPq1AoVO7zVkcqlcLFxQVyuVyp/Nlnn4Wenp54vGPHDkyYMAEAsHDhQvTr1w/m5uY4ffo0oqOjkZ+fj23btml1TZro2rUrgL+uvymPxn6Q1km3p6cn3nzzTfj5+SErKwsbN24EAOTn59f7qC8iIiIiIiJ6/CgUChgZGak9l5aWBldXV6Wy6dOna9y3IAgqm6dt2LBBabm5ra2t+HNkZKT4c+/evWFubo6QkBBx9rsl1W3UXVFR0ey+tE66ExISMH36dHz++edYunQpevToAQD49NNP4e3t3eyAiIiIiIiI6NFgZWWFsrIyteccHBzEfLCOpk+Vun//Pi5fvoynnnpKqdzGxkalz/oMGjQIAHDlypUWT7pLS0sBAJ07d252X1on3b1791bavbxOfHy80jIAIiIiIiIierx5eHhgx44dLd7vxx9/jLKyMkyaNKnJfZw/fx6A8mx4S7l06RLatWuHXr16NbsvrZNuAPj999/x6aefIi8vD6+++iosLCyQk5ODLl26iGvfiYiIiIiI6PEWEBCA6OholJWVwdzcvEl9VFRUoLi4GDU1NSgqKkJmZiY2bNiAF154AcOGDdOojxMnTuDkyZMYNmwYTE1NcebMGURGRmLcuHHo1q2bVvFcuHABAHDv3j3cunULFy5cgIGBAZ588kmxzrFjxzB06FCNZ+4bonXS/cMPP2DEiBEwMzODXC5HeHg4LCwssHv3bhQUFGD79u3NDoqIiIiIiIjanru7Ozw9PZGeno65c+c2qY+tW7di69atMDAwgKWlJfr374+0tDQEBwdr3IehoSHS0tKwYsUKVFZWwtHREeHh4XjttdeU6slkMoSGhiI2Nrbevjw8PMSfz507h08++QSOjo5Km7qlpqZixYoVGsfXEK2T7kWLFmHWrFl4++230bFjR7F81KhRmDZtWosERURERERE9I8Qe6etI2hUTEwMFi9ejPDwcEilUshkMgiCoLbu0aNHGzxuSH19AkC/fv1w8uTJBtsrFArcuHEDPj4+TR4HAL766ivo6ekhJCSkwXqa0jrpPnPmDDZv3qxS3rVrVxQXF7dIUERERERERPRoGD16NC5fvoyioiI4ODi0dTj1ysrKwvDhwzVesl6f8vJyJCcnQ1+/SXdjq9C6FyMjI9y9e1el/Oeff26Rnd2IiIiIiIjo0bJw4cK2DqFRgYGBCAwMbHY/U6ZMaYFo/o+08SrKxo8fj5UrV6K6uhoAIJFIUFhYiKioqGbtPEdERERERET0d6N10r1u3TrcunUL1tbWUCgU8PHxQY8ePdCxY0esXr1aFzESERERERERPZa0Xl7eqVMnHD9+HIcPH8b333+P2tpa9OvXD35+frqIj4iIiIiIiOix1eQ7w4cPH47hw4e3ZCxEREREREREfysaJd3vvfeexh0uWLCgycEQERERERER/Z1olHRv2LBBo84kEgmTbiIiIiIiIqL/T6OkOz8/X9dxEBEREREREf3taL17OREREREREf1zlJSUwNraGnK5vK1DaRWLFy9u0RXcGs10L1q0CKtWrYKJiQkWLVrUYN133nmnRQIjIiIiIiL6u3P/2L1Vx7s486LWbeLi4hAUFASZTAYAkMvlcHJywvnz59G3b1+lur6+vujbty8SEhLE46ysLACAgYEBrKys0K9fP8yaNQsTJ05UaiuRSFTGHjx4MI4fPw4AkMlkKCgoUDq/ZMkSrFmzRuNryczMxMaNG3HhwgVUVlaiV69eiI2NRUBAgFjntddeg7OzMyIjI+Hk5KRx3/XRKOk+f/48qqurxZ/ro+5NIiIiIiIioseTQqFAUlIS9u3b1+Q+wsPDsXLlSlRXV6OoqAi7d+/GM888g9DQUGzZskWpbnJyMgIDA8VjAwMDpfMrV65EeHi4eNyhQwetYsnOzsbIkSPx1ltvwczMDMnJyQgKCsKpU6fg4eEBALC2toa/vz82bdqEtWvXanu5KjRKuo8cOYJff/0VpqamOHLkSLMHJSIiIiIiokff/v37oa+vDy8vryb30b59e9jY2AAAHBwcMGjQIPTs2ROzZ8/GlClT4OfnJ9Y1MzMT66rTsWPHBs83pm4Gvs5bb72FL774Anv27BGTbgAYN24cYmJiWiTp1vie7n/961+4deuWeDx16lTcuHGj2QEQERERERHRoyk7Oxuenp4t3u/MmTNhbm6OzMxMrdqtXbsWlpaW6Nu3L1avXo2qqqpmxVFbW4s//vgDFhYWSuUDBgzA1atXVZazN4XGSbcgCErH+/btQ3l5ebMDICIiIiIiokeTXC6HnZ2d2nPe3t7o0KGD0uvYsWMa9SuVSuHi4qKyOduzzz6r1N/nn38unlu4cCF27dqFI0eO4KWXXkJCQgLmz5/f1EsDAKxfvx7l5eWYMmWKUnnXrl0BoEU2j9NoeTkRERERERH98ygUChgZGak9l5aWBldXV6Wy6dOna9y3IAgq+4Jt2LBBabm5ra2t+HNkZKT4c+/evWFubo6QkBBx9ltbqampiI2NxRdffAFra2ulc8bGxgCAiooKrft9mMZJt0QiUXlDuHEaERERERHR35eVlRXKysrUnnNwcECPHj2UyuqS1cbcv38fly9fxlNPPaVUbmNjo9JnfQYNGgQAuHLlitZJd1paGp5//nlkZGQoJfl1SktLAQCdO3fWql91NE66BUFAaGgoDA0NAQB//vkn5s2bBxMTE6V62q7JJyIiIiIiokeTh4cHduzY0eL9fvzxxygrK8OkSZOa3Efdk7UenA3XRGpqKmbPno3U1FSMGTNGbZ1Lly6hXbt26NWrV5Pjq6Nx0j1z5kyl4+eee67ZgxMREREREdGjKyAgANHR0SgrK4O5uXmT+qioqEBxcTFqampQVFSEzMxMbNiwAS+88AKGDRumUR8nTpzAyZMnMWzYMJiamuLMmTOIjIzEuHHj0K1bN41jSU1NxYwZM/Duu+9i0KBBKC4uBvDXDL2pqalY79ixYxg6dKjGM/cN0TjpTk5ObvZgRERERERE9Phwd3eHp6cn0tPTMXfu3Cb1sXXrVmzduhUGBgawtLRE//79kZaWhuDgYI37MDQ0RFpaGlasWIHKyko4OjoiPDwcr732mlI9mUyG0NBQxMbGqu1n8+bNqKmpwYsvvogXX3xRLJ85cyZSUlLE49TUVKxYsUKr66wPN1IjIiIiIiJqIxdnXmzrEBoVExODxYsXIzw8HFKpFDKZTOXpVnWOHj3a4HFD6usTAPr164eTJ0822F6hUODGjRvw8fGpt44m8Xz11VfQ09NDSEhIo3U1waSbiIiIiIiI6jV69GhcvnwZRUVFcHBwaOtw6pWVlYXhw4drvGS9PuXl5UhOToa+fsuky0y6iYiIiIiIqEELFy5s6xAaFRgYiMDAwGb38/Azu5tL2qK9EREREREREZGISTcRERERERGRjjDpJiIiIiIiItIRJt1EREREREREOsKkm4iIiIiIiEhHmHQTERERERER6QiTbiIiIiIiIiIdYdJNRERERERE9SopKYG1tTXkcnlbh9IqFi9ejAULFrRYf/ot1hMRERERERFpJbena6uO5/pTrtZt4uLiEBQUBJlMBgCQy+VwcnLC+fPn0bdvX6W6vr6+6Nu3LxISEsTjrKwsAICBgQGsrKzQr18/zJo1CxMnTlRqK5FIVMYePHgwjh8/DgCQyWQoKChQOr9kyRKsWbNG42s5fvw4lixZgp9++gkVFRVwdHTE3LlzERkZKdZ57bXX4OzsjMjISDg5OWncd32YdBMREREREZFaCoUCSUlJ2LdvX5P7CA8Px8qVK1FdXY2ioiLs3r0bzzzzDEJDQ7FlyxalusnJyQgMDBSPDQwMlM6vXLkS4eHh4nGHDh20isXExAQvvfQSevfuDRMTExw/fhxz586FiYkJ5syZAwCwtraGv78/Nm3ahLVr12p7uSqYdBMREREREZFa+/fvh76+Pry8vJrcR/v27WFjYwMAcHBwwKBBg9CzZ0/Mnj0bU6ZMgZ+fn1jXzMxMrKtOx44dGzzfGA8PD3h4eIjHMpkMmZmZOHbsmJh0A8C4ceMQExPTIkk37+kmIiIiIiIitbKzs+Hp6dni/c6cORPm5ubIzMzUqt3atWthaWmJvn37YvXq1aiqqmpWHOfPn8d3330HHx8fpfIBAwbg6tWrKsvZm4Iz3URERERERKSWXC6HnZ2d2nPe3t6QSpXncRUKhcp93upIpVK4uLiobM727LPPQk9PTzzesWMHJkyYAABYuHAh+vXrB3Nzc5w+fRrR0dHIz8/Htm3btLomALC3t8etW7dQU1OD2NhYhIWFKZ3v2rUrgL+u39HRUev+H8Skm4iIiIiIiNRSKBQwMjJSey4tLQ2ursobwU2fPl3jvgVBUNk8bcOGDUrLzW1tbcWfH9zsrHfv3jA3N0dISIg4+62NY8eO4d69ezh58iSioqLQo0cPPPvss+J5Y2NjAEBFRYVW/arDpJuIiIiIiIjUsrKyQllZmdpzDg4O6NGjh1JZXbLamPv37+Py5ct46qmnlMptbGxU+qzPoEGDAABXrlzROumu25Xc3d0dN27cQGxsrFLSXVpaCgDo3LmzVv2qw3u6iYiIiIiISC0PDw/k5OS0eL8ff/wxysrKMGnSpCb3cf78eQDKs+FNIQgCKisrlcouXbqEdu3aoVevXs3qG+BMNxEREREREdUjICAA0dHRKCsrg7m5eZP6qKioQHFxMWpqalBUVITMzExs2LABL7zwAoYNG6ZRHydOnMDJkycxbNgwmJqa4syZM4iMjMS4cePQrVs3jWP58MMP0a1bN/Ts2RPAX8/tXrduHV5++WWleseOHcPQoUM1nrlvCJNuIiIiIiIiUsvd3R2enp5IT0/H3Llzm9TH1q1bsXXrVhgYGMDS0hL9+/dHWloagoODNe7D0NAQaWlpWLFiBSorK+Ho6Ijw8HC89tprSvVkMhlCQ0MRGxurtp/a2lpxAzZ9fX04OztjzZo1KteWmpqKFStWaH2t6jDpJiIiIiIiaiOuP+W2dQiNiomJweLFixEeHg6pVAqZTAZBENTWPXr0aIPHDamvTwDo168fTp482WB7hUKBGzduqDz+60Evv/yyyqz2w7766ivo6ekhJCSk4YA1xKSbiIiIiIiI6jV69GhcvnwZRUVFcHBwaOtw6pWVlYXhw4drvGS9PuXl5UhOToa+fsuky0y6iYiIiIiIqEELFy5s6xAaFRgYiMDAwGb3M2XKlBaI5v9w93IiIiIiIiIiHWHSTURERERERKQjTLqJiIiIiIiIdIRJNxEREREREZGOMOkmIiIiIiIi0hEm3UREREREREQ6wqSbiIiIiIiISEeYdBMREREREVG9SkpKYG1tDblc3tahtIrFixdjwYIFLdaffov1RERERERERFr5cN7hVh3vxU3DtW4TFxeHoKAgyGQyAIBcLoeTkxPOnz+Pvn37KtX19fVF3759kZCQIB5nZWUBAAwMDGBlZYV+/fph1qxZmDhxolJbiUSiMvbgwYNx/PhxAIBMJkNBQYHS+SVLlmDNmjVaXxMAfPvtt/Dx8YGbmxsuXLgglr/22mtwdnZGZGQknJycmtT3gzjTTURERERERGopFAokJSUhLCysyX2Eh4fj+vXruHLlCj777DM8+eSTeOaZZzBnzhyVusnJybh+/br4+vLLL5XOr1y5Uun8smXLmhTTnTt3MGPGDIwYMULlnLW1Nfz9/bFp06Ym9f0wznQTERERERGRWvv374e+vj68vLya3Ef79u1hY2MDAHBwcMCgQYPQs2dPzJ49G1OmTIGfn59Y18zMTKyrTseOHRs8r6m5c+di2rRp0NPTw+eff65yfty4cYiJicHatWubPRZnuomIiIiIiEit7OxseHp6tni/M2fOhLm5OTIzM7Vqt3btWlhaWqJv375YvXo1qqqqtB47OTkZeXl5eOONN+qtM2DAAFy9elVlOXtTcKabiIiIiIiI1JLL5bCzs1N7ztvbG1Kp8jyuQqFQuc9bHalUChcXF5XN2Z599lno6emJxzt27MCECRMAAAsXLkS/fv1gbm6O06dPIzo6Gvn5+di2bZvG13P58mVERUXh2LFj0NevPx3u2rUrgL+u39HRUeP+1WHSTURERERERGopFAoYGRmpPZeWlgZXV1elsunTp2vctyAIKpunbdiwQWm5ua2trfhzZGSk+HPv3r1hbm6OkJAQcfa7Mffv38e0adOwYsX/a+/e46Ks8///PznIwVBAEEEbHdRU8LCIaKJropmgm+SB6OAtz1NqpeGi5paGbK7ZlrDthuYJbS0WTetjq+7qVqKWZLa03wwrLFFjwVJJTVhRvH5/9HO2iQEGdJxaH/fbbW471/vwmtc12+2qF+/3dc1CderUqc6xvr6+kqSKigqHzqUuFN0AAAAAALuCg4NVXl5ut89kMqljx442bVeK1fpUV1erqKhIvXv3tmkPDQ2tEbM2ffv2lSQdPnzYoaL73LlzOnDggAoKCvTII49Iki5fvizDMOTp6akdO3Zo8ODvn+5++vRpSVLLli0dyqUuFN0AAAAAALt69uyp9evXX/O469atU3l5ucaMGdPoGAUFBZJsV8Pr0rx5c3388cc2bVlZWXr77bf12muv2fw82MGDB9WkSRN17dq10fldQdENAAAAALArPj5e8+bNU3l5uQIDAxsVo6KiQmVlZbp06ZJKSkq0efNmZWRkaNq0aRo0aJBDMfbt26f8/HwNGjRI/v7++uCDD5SS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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot zarr vs hdf5 for each compressor and level\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "\n", - "format = ['Zarr'] * 10 \n", - "format += ['HDF5'] * 10\n", - "compressor = ['zstd'] * 10 + ['gzip'] * 10\n", - "lvl = list(range(10)) * 2\n", - "val = []\n", - "\n", - "for i in range(10):\n", - " val.append(filesize(f'zarrfiles/yiip_zstd_{i}_zarr.zarr'))\n", - "for i in range(10):\n", - " val.append(filesize(f'h5files/yiip_gzip_{i}_hdf5.h5'))\n", - "\n", - "data = {\n", - " 'Format': format,\n", - " 'Compressor': compressor,\n", - " 'Level': lvl,\n", - " 'Filesize': val\n", - "}\n", - "\n", - "df = pd.DataFrame(data)\n", - "\n", - "pivot_df = df.pivot(index='Compressor', columns=['Format', 'Level'], values='Filesize')\n", - "\n", - "pivot_df.plot(kind='bar', figsize=(10, 6))\n", - "plt.title('Comparison of Zarr and HDF5 default compression types')\n", - "plt.xlabel('Compressor Type')\n", - "plt.ylabel('Filesize (kB)')\n", - "plt.xticks(rotation=0)\n", - "plt.legend(title='Format, Level', bbox_to_anchor=(1.05, 1), loc='upper left')\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[38], line 13\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m c \u001b[38;5;129;01min\u001b[39;00m zarr_compressors:\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m10\u001b[39m):\n\u001b[0;32m---> 13\u001b[0m val\u001b[38;5;241m.\u001b[39mappend(\u001b[43mzarr_iteration_time\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43mf\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mzarrfiles/yiip_\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mc\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[38;5;124;43m_\u001b[39;49m\u001b[38;5;132;43;01m{\u001b[39;49;00m\u001b[43mi\u001b[49m\u001b[38;5;132;43;01m}\u001b[39;49;00m\u001b[38;5;124;43m_zarr.zarr\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 15\u001b[0m data \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 16\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFormat\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;28mformat\u001b[39m,\n\u001b[1;32m 17\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mCompressor\u001b[39m\u001b[38;5;124m'\u001b[39m: compressor,\n\u001b[1;32m 18\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mLevel\u001b[39m\u001b[38;5;124m'\u001b[39m: lvl,\n\u001b[1;32m 19\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFilesize\u001b[39m\u001b[38;5;124m'\u001b[39m: val\n\u001b[1;32m 20\u001b[0m }\n\u001b[1;32m 22\u001b[0m df \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mDataFrame(data)\n", - "Cell \u001b[0;32mIn[34], line 14\u001b[0m, in \u001b[0;36mzarr_iteration_time\u001b[0;34m(filename)\u001b[0m\n\u001b[1;32m 11\u001b[0m num \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mlen\u001b[39m(pos_vals)):\n\u001b[1;32m 13\u001b[0m \u001b[38;5;66;03m# arbitrary task that requires accessing third dimension\u001b[39;00m\n\u001b[0;32m---> 14\u001b[0m num \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[43mpos_vals\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m]\n\u001b[1;32m 15\u001b[0m end_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[1;32m 16\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m end_time \u001b[38;5;241m-\u001b[39m start_time\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:844\u001b[0m, in \u001b[0;36mArray.__getitem__\u001b[0;34m(self, selection)\u001b[0m\n\u001b[1;32m 842\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_orthogonal_selection(pure_selection, fields\u001b[38;5;241m=\u001b[39mfields)\n\u001b[1;32m 843\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 844\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_basic_selection\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpure_selection\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfields\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 845\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:970\u001b[0m, in \u001b[0;36mArray.get_basic_selection\u001b[0;34m(self, selection, out, fields)\u001b[0m\n\u001b[1;32m 968\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_basic_selection_zd(selection\u001b[38;5;241m=\u001b[39mselection, out\u001b[38;5;241m=\u001b[39mout, fields\u001b[38;5;241m=\u001b[39mfields)\n\u001b[1;32m 969\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 970\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_basic_selection_nd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mselection\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mselection\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfields\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:1012\u001b[0m, in \u001b[0;36mArray._get_basic_selection_nd\u001b[0;34m(self, selection, out, fields)\u001b[0m\n\u001b[1;32m 1006\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_get_basic_selection_nd\u001b[39m(\u001b[38;5;28mself\u001b[39m, selection, out\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, fields\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 1007\u001b[0m \u001b[38;5;66;03m# implementation of basic selection for array with at least one dimension\u001b[39;00m\n\u001b[1;32m 1008\u001b[0m \n\u001b[1;32m 1009\u001b[0m \u001b[38;5;66;03m# setup indexer\u001b[39;00m\n\u001b[1;32m 1010\u001b[0m indexer \u001b[38;5;241m=\u001b[39m BasicIndexer(selection, \u001b[38;5;28mself\u001b[39m)\n\u001b[0;32m-> 1012\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_selection\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindexer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mindexer\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfields\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:1388\u001b[0m, in \u001b[0;36mArray._get_selection\u001b[0;34m(self, indexer, out, fields)\u001b[0m\n\u001b[1;32m 1385\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m math\u001b[38;5;241m.\u001b[39mprod(out_shape) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 1386\u001b[0m \u001b[38;5;66;03m# allow storage to get multiple items at once\u001b[39;00m\n\u001b[1;32m 1387\u001b[0m lchunk_coords, lchunk_selection, lout_selection \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mzip\u001b[39m(\u001b[38;5;241m*\u001b[39mindexer)\n\u001b[0;32m-> 1388\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_chunk_getitems\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1389\u001b[0m \u001b[43m \u001b[49m\u001b[43mlchunk_coords\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1390\u001b[0m \u001b[43m \u001b[49m\u001b[43mlchunk_selection\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1391\u001b[0m \u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1392\u001b[0m \u001b[43m \u001b[49m\u001b[43mlout_selection\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1393\u001b[0m \u001b[43m \u001b[49m\u001b[43mdrop_axes\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mindexer\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdrop_axes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1394\u001b[0m \u001b[43m \u001b[49m\u001b[43mfields\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfields\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1395\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1396\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m out\u001b[38;5;241m.\u001b[39mshape:\n\u001b[1;32m 1397\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m out\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:2228\u001b[0m, in \u001b[0;36mArray._chunk_getitems\u001b[0;34m(self, lchunk_coords, lchunk_selection, out, lout_selection, drop_axes, fields)\u001b[0m\n\u001b[1;32m 2226\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m ckey, chunk_select, out_select \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(ckeys, lchunk_selection, lout_selection):\n\u001b[1;32m 2227\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ckey \u001b[38;5;129;01min\u001b[39;00m cdatas:\n\u001b[0;32m-> 2228\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_chunk\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2229\u001b[0m \u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2230\u001b[0m \u001b[43m \u001b[49m\u001b[43mcdatas\u001b[49m\u001b[43m[\u001b[49m\u001b[43mckey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2231\u001b[0m \u001b[43m \u001b[49m\u001b[43mchunk_select\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2232\u001b[0m \u001b[43m \u001b[49m\u001b[43mdrop_axes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2233\u001b[0m \u001b[43m \u001b[49m\u001b[43mout_is_ndarray\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2234\u001b[0m \u001b[43m \u001b[49m\u001b[43mfields\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2235\u001b[0m \u001b[43m \u001b[49m\u001b[43mout_select\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2236\u001b[0m \u001b[43m \u001b[49m\u001b[43mpartial_read_decode\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpartial_read_decode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2237\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2238\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2239\u001b[0m \u001b[38;5;66;03m# check exception type\u001b[39;00m\n\u001b[1;32m 2240\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_fill_value \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:2141\u001b[0m, in \u001b[0;36mArray._process_chunk\u001b[0;34m(self, out, cdata, chunk_selection, drop_axes, out_is_ndarray, fields, out_selection, partial_read_decode)\u001b[0m\n\u001b[1;32m 2139\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m ArrayIndexError:\n\u001b[1;32m 2140\u001b[0m cdata \u001b[38;5;241m=\u001b[39m cdata\u001b[38;5;241m.\u001b[39mread_full()\n\u001b[0;32m-> 2141\u001b[0m chunk \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_decode_chunk\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcdata\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2143\u001b[0m \u001b[38;5;66;03m# select data from chunk\u001b[39;00m\n\u001b[1;32m 2144\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m fields:\n", - "File \u001b[0;32m~/anaconda3/envs/zarrtraj/lib/python3.10/site-packages/zarr/core.py:2402\u001b[0m, in \u001b[0;36mArray._decode_chunk\u001b[0;34m(self, cdata, start, nitems, expected_shape)\u001b[0m\n\u001b[1;32m 2400\u001b[0m chunk \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compressor\u001b[38;5;241m.\u001b[39mdecode_partial(cdata, start, nitems)\n\u001b[1;32m 2401\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2402\u001b[0m chunk \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_compressor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdecode\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcdata\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2403\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2404\u001b[0m chunk \u001b[38;5;241m=\u001b[39m cdata\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "# Plot zarr filesize for each compressor and level\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "\n", - "format = ['Zarr'] * 10 * len(zarr_compressors)\n", - "compressor = [n for n in zarr_compressors for _ in range(10)]\n", - "lvl = list(range(10)) * len(zarr_compressors) \n", - "val = []\n", - "for c in zarr_compressors:\n", - " for i in range(10):\n", - " val.append(zarr_iteration_time(f'zarrfiles/yiip_{c}_{i}_zarr.zarr'))\n", - "\n", - "data = {\n", - " 'Format': format,\n", - " 'Compressor': compressor,\n", - " 'Level': lvl,\n", - " 'Filesize': val\n", - "}\n", - "\n", - "df = pd.DataFrame(data)\n", - "\n", - "pivot_df = df.pivot(index='Compressor', columns=['Format', 'Level'], values='Filesize')\n", - "\n", - "pivot_df.plot(kind='bar', figsize=(10, 6))\n", - "plt.title('Comparison of Zarr Compressor Types and Levels for Filesize')\n", - "plt.xlabel('Compressor Type')\n", - "plt.ylabel('Filesize (kB)')\n", - "plt.xticks(rotation=0)\n", - "plt.legend(title='Format, Level', bbox_to_anchor=(1.05, 1), loc='upper left')\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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vLwUFRWlWbNmqbi42GbcggUL1K5dO9WsWVP+/v5q3ry57r333grznjVrlq688krVqVNHtWrVUkxMjBYvXixjjM24yMhIXXPNNXr33XcVExMjX19fNW/eXC+88EKpmJs3b9ZVV10lHx8fNWjQQKmpqTp16lSFuVTG559/rv79+6tOnTry8fFR+/bttWzZMmv/V199JYvFosWLF5fad82aNbJYLFq5cqW1bdeuXRo+fLjN/yefeeaZCvOoyrU0atQoXX311ZKk66+/XhaLxeYW6pUrV6pz587y8/OTv7+/evXqVepOi5KfP19++aWSkpIUGBhYqT/MpqWl6e6775YkRUVF2X08IisrS507d1aNGjVUs2ZN9enTp9TdOOX9zFq7dq2uvfZaNWzYUD4+PmrSpInGjh1r8+hARXnYu738yJEjuu222xQWFiYvLy9ddtllmj59uoqKimzGlfw7+89//qMWLVrIz89P7dq1s3ls6HzZu738fH+3kKp+PQL4GzJANSguLjZ+fn7myiuvdHifW2+91UgyEyZMMO+++65ZuHChqVevngkPDze//vqrdVy3bt1M3bp1TbNmzczixYvNe++9Z6655hojycyaNcu0adPGZGZmmtWrV5tOnToZb29vs3//fuv+999/v5FkIiIizN13323ee+8988QTT5gaNWqY9u3bm5MnT1rHPvDAA2bu3Llm1apVZt26dWbhwoUmKirKxMfH2+Q+cuRI4+npaSIjI016err58MMPzXvvvWfti4iIsI799NNPjcViMUOHDjWrV682H330kcnIyDA33nijdcyhQ4dMWFiYqVevnlm4cKF59913zYQJE4wkM378eOu4nJwcI8lERkaahIQEs2LFCrNixQrTpk0bExgYaH777bdy3/P//ve/xt/f3zRu3Ni89NJLZtWqVWbYsGFGkpkzZ441l02bNhlJJikpyWzatMls2rSp3LiSzG233WZOnTpV6pWVlWUkmY8//rjU9+Ts7/O5eUoyN998s817XqNGjVLxi4uLS+USGBhofHx8jJeXl4mJiTEvvPBCufmXaNq0qalfv75DY40x5uGHHzaSzLBhw8yqVavMSy+9ZC677DITEBBgfvjhB5vcvby8TIsWLcyTTz5p1q5da0aPHm0kmdTUVNO0adNS1/bnn39u3T8jI8NIMuHh4WbMmDFmzZo15rnn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evfdd8ucOa2M2rVr66abbtKCBQsUERGhxMREu+OCgoLUvXt3zZgxQzVq1ND8+fP13//+1+Zjw2bPnq21a9eqS5cumjhxopo1a6Y//vhDubm5Wr16tRYuXKiGDRsqOTlZvr6+uuqqqxQaGqq8vDylp6crICDA+iy9Pf/85z/1xBNPaPjw4br11lt1+PBhPf7443Y/mtFR9913n1auXKnu3btr5syZ8vPz0zPPPFPq4+Mq8vbbb9sUzyWSkpL07LPPqm/fvurTp49GjRqlsLAwHTlyRN99952+/PJLvfbaa9bx7u7uuummm/TEE0+oVq1aGjRoUKn/Hz355JO6+uqr1bVrV40fP16RkZH6/ffftXv3br399tul1r4oUd3Xkpubmx599FGNGDFC11xzjcaOHauioiI99thj+u2336wfBVhd2rRpI+nP8x85cqQ8PT3VrFkzRUZGavbs2Zo+fbp++uknJSQkKDAwUAcPHtSWLVtUo0YNzZo1q9zYzZs3V+PGjTVt2jQZY1SnTh29/fbbdh95KCsPe9//m266Sc8884xGjhyp3NxctWnTRhs3btTDDz+sfv36qWfPntXwzrhWVa9HAH9TLlrADX9h27dvNyNHjjSNGjUyXl5e1o/mmjlzpjl06JB13OnTp82cOXNM06ZNjaenpwkKCjI33HCD2bdvn028bt26mVatWpU6TkREhPnnP/9Zql3nrLpdsnrsF198YRITE03NmjWNv7+/GTZsmDl48KDNvp9++qnp3Lmz8fPzM/Xq1TO33HKL+fLLL0uthGtvReSz+85evfydd94xffv2NWFhYcbLy8sEBwebfv362XysjDHG7NmzxwwfPtzUrVvXeHp6mmbNmpnHHnvMZnXcklV5H3vsMbvnff/999vN6WzffPONSUxMNAEBAcbLy8u0a9fO5tzOjleZ1cvLGvvaa6+VuXp5ycvb29uEhoaa3r17myeffNJmFdsS5b3nJVauXGmuvvpqU69ePePh4WH8/f1N165dK1zV/Vw//vijue2220yTJk2Mt7e38fX1NS1btjSTJ08utXLv888/b9q2bWu8vLxMQECAufbaa20+qqe83B29tktW3n3//ffNjTfeaGrXrm1dOX3Xrl0OxTTGmOPHj5v77rvPNGvWzJpvmzZtTEpKinUVa0eu13/961+mS5cuJigoyHh5eZlGjRqZm2++2eTm5tocb8OGDaZ79+6mRo0axtfX13Tq1Mm8/fbbNmPKWnH4jz/+MOPGjTNt27Y1tWrVMr6+vqZZs2bm/vvvNydOnLB7fvaUd92sW7fOSDKPPPKI3f6S63r+/PmmcePGxtPT0zRv3ty8/PLLpcb++uuvZuLEiSYqKsp4enqaOnXqmCuuuMJMnz7dHD9+3BhjzJIlS0x8fLypX7++8fLyMg0aNDBDhgwxX3/9dYXn8cILL5hmzZoZb29vc9lll5n09HSzePHiUisyl/X/xXNXlzbmz9XvSz4KKSQkxNx9993mueeeq9Tq5WW9Snz11VfWj/7y9PQ0ISEhpnv37mbhwoWlYv7www/W/deuXWv3uDk5OWbMmDEmLCzMeHp6mnr16pkuXbrYrOB/7url53Mt2VtNvMSKFSvMlVdeaXx8fEyNGjVMjx49zCeffGL3fSpvlXdHjpeammoaNGhg3NzcSv3/dMWKFSY+Pt7UqlXLeHt7m4iICJOUlGQ++OAD65jy/h3s3LnT9OrVy/j7+5vAwEBz3XXXmb1799r9mVJWHvaur8OHD5tx48aZ0NBQ4+HhYSIiIkxqaqr5448/bMaV9fMjIiLCjBw5svw37CxVWb38fH63MMax6xEAjDHGYkwZywQDfxFpaWmaNWuWfv3110v+OTL8Pb344osaPXq0tm7d6tAto3DMXXfdpQULFmjfvn12bwW1WCy6/fbb9fTTT7sgOwAA8FfB7eUAgL+VzZs364cfftD8+fM1duxYnr0EAABORdENAPhbKVno6pprrtGDDz7o6nQAAMBfHLeXAwAAAADgJHxkGAAAAAAATkLRDQAAAACAk1B0AwAAAADgJH/5hdTOnDmjX375Rf7+/rJYLK5OBwAAAMB5Msbo999/V4MGDeTmxjwiLm5/+aL7l19+UXh4uKvTAAAAAFDN9u3bp4YNG7o6DaBcf/mi29/fX9Kf/yBr1arl4mwAAAAAnK9jx44pPDzc+rs+cDH7yxfdJbeU16pVi6IbAAAA+Avh8VFcCngAAgAAAAAAJ6HoBgAAAADASSi6AQAAAABwkr/8M90AAAAAcDE5ffq0Tp065eo0cB68vLwc/rg6im4AAAAAuACMMcrLy9Nvv/3m6lRwntzc3BQVFSUvL68Kx1J0AwAAAMAFUFJwBwcHy8/Pj9XXL1FnzpzRL7/8ogMHDqhRo0YVfh8pugEAAADAyU6fPm0tuOvWrevqdHCe6tWrp19++UXFxcXy9PQsdywLqQEAAACAk5U8w+3n5+fiTFAdSm4rP336dIVjKboBAAAA4ALhlvK/hsp8Hym6AQAAAABwEopuAAAAAMDfVm5uriwWi7Zv3+6U+BTdAAAAAHARGjVqlCwWS6nX7t27XZ1aKedTuMbFxenOO++s9pwuFqxeDgAAAAAXqYSEBGVkZNi01atXr0qxTp486dDnSqN6MdMNAAAAABcpb29vhYSE2Lzc3d0lSdnZ2erYsaO8vb0VGhqqadOmqbi42LpvXFycJkyYoMmTJysoKEi9evXSunXrZLFY9N5776l9+/by9fVV9+7ddejQIa1Zs0YtWrRQrVq1NGzYMBUUFFhjvfvuu7r66qtVu3Zt1a1bV9dcc41+/PFHa39UVJQkqX379rJYLIqLi6u29+DTTz/VP/7xD/n6+io8PFwTJ07UiRMnJEmpqanq1KlTqX3atm2r+++/37qdkZGhFi1ayMfHR82bN9f8+fOrLb+KUHQDAAAAwCVm//796tevnzp06KCvvvpKCxYs0OLFi/Xggw/ajFuyZIk8PDz0ySef6Nlnn7W2p6Wl6emnn9ann36qffv2aciQIZo3b55eeeUVrVq1SmvXrtW///1v6/gTJ05o8uTJ2rp1qz788EO5ublp4MCBOnPmjCRpy5YtkqQPPvhABw4c0PLly6vlPL/55hv16dNHgwYN0tdff62srCxt3LhREyZMkCSNGDFCn332mc0fAL799lt98803GjFihCRp0aJFmj59uh566CF99913evjhhzVjxgwtWbKkWnKsCLeXAwAAAMBF6p133lHNmjWt23379tVrr72m+fPnKzw8XE8//bQsFouaN2+uX375Rffcc49mzpwpN7c/51ebNGmiRx991Lp/Xl6eJOnBBx/UVVddJUm6+eablZqaqh9//FGXXXaZJCkpKUkff/yx7rnnHknS4MGDbfJavHixgoODtXPnTrVu3dp6y3vdunUVEhJSbef/2GOPafjw4dZnvi+//HI99dRT6tatmxYsWKDWrVurbdu2euWVVzRjxgxJ0ssvv6wOHTqoadOmkqQHHnhA//rXvzRo0CBJf87K79y5U88++6xGjhxZbbmWhZluAAAAALhIxcfHa/v27dbXU089JUn67rvv1LlzZ5vPi77qqqt0/Phx/fzzz9a22NhYu3Hbtm1r/bp+/fry8/OzFtwlbYcOHbJu//jjjxo+fLguu+wy1apVy3o7+d69e6vnRMvwxRdf6MUXX1TNmjWtrz59+ujMmTPKycmR9Ods98svvyxJMsYoMzPTOsv966+/at++fbr55pttYjz44IM2s+POxEw3AAAAAFykatSooSZNmpRqN8bYFNwlbZJs2mvUqGE3rqenp/Vri8Vis13SVnLruCQlJiYqPDxcixYtUoMGDXTmzBm1bt1aJ0+erPxJVcKZM2c0duxYTZw4sVRfo0aNJEnDhw/XtGnT9OWXX6qwsFD79u3T0KFDrftLf95ifuWVV9rsX/JsvLNRdAMAAADAJaZly5Z64403bIrvTz/9VP7+/goLC6vWYx0+fFjfffednn32WXXt2lWStHHjRpsxJauinz59ulqPHRMTo2+//dbuHx5KNGzYUP/4xz/08ssvq7CwUD179lT9+vUl/TljHxYWpp9++sk6+32hUXQDAAAAwCXmtttu07x583THHXdowoQJ+v7773X//fdr8uTJ1ue5q0tgYKDq1q2r5557TqGhodq7d6+mTZtmMyY4OFi+vr5699131bBhQ/n4+CggIMDhY/z666+lPuM7JCRE99xzjzp16qTbb79dycnJqlGjhr777rtSC72NGDFCaWlpOnnypObOnWsTJy0tTRMnTlStWrXUt29fFRUV6fPPP1d+fr4mT55c+TekknimGwAAAAAuMWFhYVq9erW2bNmidu3aady4cbr55pt13333Vfux3Nzc9Oqrr+qLL75Q69atlZKSoscee8xmjIeHh5566ik9++yzatCgga699lpJsn5EWW5ubrnHeOWVV9S+fXub18KFC9W2bVtlZ2dr165d6tq1q9q3b68ZM2YoNDTUZv/rrrtOhw8fVkFBgQYMGGDTd8stt+j555/Xiy++qDZt2qhbt2568cUXrc+lO5vFlNz4/xd17NgxBQQE6OjRo6pVq5ar0wEumMhpq1ydgl25j/zT1SkAAIBL3KX4O/4ff/yhnJwcRUVFycfHx9XpXDAvvviiHnroIe3cubPUc+OXssp8P5npBgAAAAA4xbvvvquHH374L1VwVxbPdAMAAAAAnOLVV191dQoux0w3AAAAAABOQtENAAAAAICTUHQDAAAAAOAkLi26FyxYoLZt26pW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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot hdf5 iteration time for each compressor and level\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "format = ['HDF5'] * 10 * len(hdf5_compressors)\n", - "\n", - "compressor = [n for n in hdf5_compressors for _ in range(10)]\n", - "\n", - "lvl = list(range(10)) * len(hdf5_compressors)\n", - "val = []\n", - "\n", - "for c in hdf5_compressors:\n", - " for i in range(10):\n", - " val.append(h5_iteration_time(f'h5files/yiip_{c}_{i}_hdf5.h5'))\n", - "\n", - "\n", - "data = {\n", - " 'Format': format,\n", - " 'Compressor': compressor,\n", - " 'Level': lvl,\n", - " 'Filesize': val\n", - "}\n", - "\n", - "df = pd.DataFrame(data)\n", - "\n", - "pivot_df = df.pivot(index='Compressor', columns=['Format', 'Level'], values='Filesize')\n", - "\n", - "pivot_df.plot(kind='bar', figsize=(10, 6))\n", - "plt.title('Comparison of HDF5 Compressors Types and Levels for Iteration Time')\n", - "plt.xlabel('Compressor Type')\n", - "plt.ylabel('Filesize (kB)')\n", - "plt.xticks(rotation=0)\n", - "plt.legend(title='Format, Level', bbox_to_anchor=(1.05, 1), loc='upper left')\n", - "plt.tight_layout()\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/zarrtraj_benchmarks/align_setup.ipynb b/notebooks/zarrtraj_benchmarks/align_setup.ipynb deleted file mode 100644 index acb312a..0000000 --- a/notebooks/zarrtraj_benchmarks/align_setup.ipynb +++ /dev/null @@ -1,153 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This notebook demonstrates how to write a zarrtraj trajectory to disk and AWS S3 using the `ZarrTrajWriter`. This will serve as setup code for RMSF and RMSD\n", - "benchmarking notebooks as well.\n", - "\n", - "Prerequisites: \n", - "- `write_benchmark_setup.ipynb`\n", - "\n", - "Steps:\n", - "\n", - "1. Align the `.xtc` trajectory using `MDAnalysis.analysis.align`\n", - "2. Write the aligned trajectory to the local filesystem in `.xtc` format\n", - "3. Load the aligned trajectory into a universe and write it again in the local filesystem in `.zarrtraj` format\n", - "4. Write the loaded trajectory into an AWS S3 bucket" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from MDAnalysis.analysis import rms, align\n", - "import MDAnalysis as mda\n", - "\n", - "# 1, 2\n", - "\n", - "u = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\",\n", - " \"notebook_data_tmp/yiip_equilibrium/yiip.xtc\")\n", - "\n", - "average = align.AverageStructure(u, u, select=\"protein and name CA\",\n", - " ref_frame=0).run()\n", - "ref = average.results.universe\n", - "aligner = align.AlignTraj(u, ref,\n", - " select='protein and name CA',\n", - " filename='notebook_data_tmp/yiip_aligned.xtc',\n", - " in_memory=False).run()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "importing zarrtraj...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - } - ], - "source": [ - "import zarrtraj\n", - "import zarr\n", - "import MDAnalysis as mda\n", - "\n", - "# 3\n", - "\n", - "u = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\",\n", - " \"notebook_data_tmp/yiip_aligned.xtc\")\n", - "\n", - "zHDD = zarr.open_group(\"notebook_data_tmp/yiip_aligned.zarrtraj\", 'w')\n", - "\n", - "with mda.Writer(zHDD, u.atoms.n_atoms,\n", - " format='ZARRTRAJ') as W:\n", - " for ts in u.trajectory:\n", - " W.write(u.atoms)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os \n", - "import s3fs\n", - "import zarrtraj\n", - "import zarr\n", - "import MDAnalysis as mda\n", - "\n", - "# 4\n", - "# Use your own bucket here\n", - "\n", - "u = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\",\n", - " \"notebook_data_tmp/yiip_aligned.xtc\")\n", - "\n", - "s3_fs = s3fs.S3FileSystem(\n", - " # anon must be false to allow authentication\n", - " anon=False,\n", - " profile='sample_profile',\n", - " client_kwargs=dict(\n", - " region_name='us-east-1',\n", - " )\n", - ")\n", - "\n", - "cloud_store = s3fs.S3Map(\n", - " root=f'zarrtraj-test-data/yiip_aligned.zarrtraj',\n", - " s3=s3_fs,\n", - " check=False\n", - ")\n", - "\n", - "zS3 = zarr.open_group(cloud_store, 'w')\n", - "\n", - "with mda.Writer(zS3, u.atoms.n_atoms,\n", - " n_frames=u.trajectory.n_frames,\n", - " format='ZARRTRAJ') as W:\n", - " for ts in u.trajectory:\n", - " W.write(u.atoms)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/zarrtraj_benchmarks/calculated_density_benchmark.ipynb b/notebooks/zarrtraj_benchmarks/calculated_density_benchmark.ipynb deleted file mode 100644 index 3e7bf7c..0000000 --- a/notebooks/zarrtraj_benchmarks/calculated_density_benchmark.ipynb +++ /dev/null @@ -1,77 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import zarrtraj\n", - "import MDAnalysis as mda\n", - "import zarr\n", - "from zarr.storage import LRUStoreCache\n", - "import s3fs\n", - "import os\n", - "\n", - "# 1\n", - "yiipHDD = zarr.open_group(\"notebook_data_tmp/yiip.zarrtraj\")\n", - "\n", - "# 2\n", - "AWS_ACCESS_KEY_ID = os.getenv(\"AWS_ACCESS_KEY_ID\")\n", - "AWS_SECRET_ACCESS_KEY = os.getenv(\"AWS_SECRET_ACCESS_KEY\")\n", - "BUCKET_NAME = os.getenv(\"BUCKET_NAME\")\n", - "\n", - "s3 = s3fs.S3FileSystem(key=AWS_ACCESS_KEY_ID, secret=AWS_SECRET_ACCESS_KEY)\n", - "store = s3fs.S3Map(root='zarrtraj-test-data/yiip.zarrtraj', s3=s3, check=False)\n", - "# Select max_size value in bytes based on chunking of zarrtraj data\n", - "# At least one chunk must fit in the cache\n", - "cache = LRUStoreCache(store, max_size=2**25)\n", - "yiipS3 = zarr.open_group(store=cache)\n", - "\n", - "# 3\n", - "uHDD = mda.Universe(\"notebook_data_tmp/YiiP_system.pdb\", yiipHDD)\n", - "uS3 = mda.Universe(\"notebook_data_tmp/YiiP_system.pdb\", yiipS3)\n", - "uXTC = mda.Universe(\"notebook_data_tmp/YiiP_system.pdb\", \"YiiP_system_90ns_center.xtc\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from MDAnalysis import transformations as trans\n", - "\n", - "\n", - "\n", - "protein = u.select_atoms('protein')\n", - "water = u.select_atoms('resname SOL')\n", - "\n", - "workflow = [trans.unwrap(u.atoms), # unwrap all fragments\n", - " trans.center_in_box(protein, # move atoms so protein\n", - " center='geometry'), # is centered\n", - " trans.wrap(water, # wrap water back into box\n", - " compound='residues'), # keep each water whole\n", - " trans.fit_rot_trans(protein, # align protein to first frame\n", - " protein,\n", - " weights='mass'),\n", - " ]\n", - "\n", - "u.trajectory.add_transformations(*workflow)\n", - "\n", - "ow = u.select_atoms('name OW')\n", - "dens = density.DensityAnalysis(ow,\n", - " delta=4.0,\n", - " padding=2)\n", - "dens.run()" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/zarrtraj_benchmarks/pca_benchmark.ipynb b/notebooks/zarrtraj_benchmarks/pca_benchmark.ipynb deleted file mode 100644 index f3d6408..0000000 --- a/notebooks/zarrtraj_benchmarks/pca_benchmark.ipynb +++ /dev/null @@ -1,178 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - } - ], - "source": [ - "import zarrtraj\n", - "import MDAnalysis as mda\n", - "import zarr\n", - "from zarr.storage import LRUStoreCache\n", - "import s3fs\n", - "import os\n", - "\n", - "# 1\n", - "yiipHDD = zarr.open_group(\"notebook_data_tmp/yiip.zarrtraj\", mode='r')\n", - "\n", - "# 2\n", - "# Use your own bucket here\n", - "\n", - "s3_fs = s3fs.S3FileSystem(\n", - " # anon must be false to allow authentication\n", - " anon=False,\n", - " # use profiles defined in a .aws/credentials file to store secret keys\n", - " # docs: \n", - " profile='sample_profile',\n", - " client_kwargs=dict(\n", - " region_name='us-west-1',\n", - " )\n", - ")\n", - "store = s3fs.S3Map(root=f'zarrtraj-test-data/yiip.zarrtraj',\n", - " s3=s3_fs,\n", - " check=False)\n", - "# Select max_size value in bytes based on chunking of zarrtraj data\n", - "# At least one chunk must fit in the cache\n", - "cache = LRUStoreCache(store, max_size=10485760)\n", - "yiipS3 = zarr.open_group(store=cache, mode='r')\n", - "\n", - "# 3\n", - "uHDD = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", yiipHDD)\n", - "uS3 = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", yiipS3)\n", - "uXTC = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", \"notebook_data_tmp/yiip.xtc\")" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/Bio/Application/__init__.py:40: BiopythonDeprecationWarning: The Bio.Application modules and modules relying on it have been deprecated.\n", - "\n", - "Due to the on going maintenance burden of keeping command line application\n", - "wrappers up to date, we have decided to deprecate and eventually remove these\n", - "modules.\n", - "\n", - "We instead now recommend building your command line and invoking it directly\n", - "with the subprocess module.\n", - " warnings.warn(\n" - ] - } - ], - "source": [ - "import MDAnalysis as mda\n", - "import MDAnalysis.analysis.pca as pca\n", - "import time\n", - "import json\n", - "\n", - "# 4\n", - "\n", - "universes = dict()\n", - "universes[\"uHDD\"] = dict()\n", - "universes[\"uHDD\"][\"ref\"] = uHDD\n", - "universes[\"uS3\"] = dict()\n", - "universes[\"uS3\"][\"ref\"] = uS3\n", - "universes[\"uXTC\"] = dict()\n", - "universes[\"uXTC\"][\"ref\"] = uXTC\n", - "\n", - "\n", - "for name in (\"uHDD\", \"uS3\", \"uXTC\"):\n", - " start = time.time()\n", - " PSF_pca = pca.PCA(universes[name][\"ref\"], select='backbone')\n", - " PSF_pca.run()\n", - " stop = time.time()\n", - " universes[name][\"PCA\"] = stop - start\n", - "\n", - "pca_speeds = dict()\n", - "pca_speeds[\"uXTC\"] = universes[\"uXTC\"][\"PCA\"]\n", - "pca_speeds[\"uS3\"] = universes[\"uS3\"][\"PCA\"]\n", - "pca_speeds[\"uHDD\"] = universes[\"uHDD\"][\"PCA\"]\n", - "with open('notebook_data_tmp/pca_speeds.json', 'w') as j:\n", - " json.dump(pca_speeds, j)" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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P/6IzZs3l/rslyZNmuDw4cPYvHkzwsLCXrje2oLH5osdm71798auXbsQGBgINzc3BAcHo2nTpti/fz90df8dbnz37l0EBQWhSZMm6NGjB06dOoWoqCj4+vq+0LZfFjKhzRebiUgrrVy5ErNnz8atW7dquhQiJTw2aw7PEBGRVrl58yb27NnzajxZl14pPDZrFm+7JyKt0rZtWzRo0AARERE1XQqREh6bNYuXzIiIiEjr8ZIZERERaT0GIiIiItJ6DERERESk9RiIiIiISOsxEBFRreLt7a30FGYnJycsXry4xuoholcDAxERvXRGjhwJmUymMl29ehXbt2/H7NmzNbat1NRUyGQyJCQkaGydRFT78DlERPRS8vPzQ3h4uFKblZUVdHR0aqgiInqV8QwREb2UDAwMYGtrqzTp6OioXDJ7lkKhwAcffABra2uYmZmhe/fuOH/+fJn9nZ2dAQBt2rSBTCaDt7c3jh07Bj09PaSnpyv1DQsLQ9euXQEAERERqFevHnbu3Ak3NzcYGhrC19cXN2/eVFpm165daNeuHQwNDeHi4oJZs2ahsLBQzXeFiKoKAxERvTKEEOjbty/S09OxZ88exMfHo23btujRowcePnxY6jKnT58GABw8eBBpaWnYvn07unbtChcXF6xfv17qV1hYiA0bNuC9996T2h4/foxvvvkGa9euxR9//IGsrCwMGzZMmr9v3z68++67mDhxIi5duoSVK1ciIiIC33zzTRW9A0SkLgYiInop7d69G3Xr1pWmwYMHP3eZI0eOIDExEb/++ivat28PV1dX/Pe//0W9evXwv//9r9RlrKysAAD169eHra0tLCwsAACjRo1SumQXGRmJx48fY8iQIVJbQUEBli1bBk9PT7Rr1w5r165FTEyMFLK++eYbfPrppwgODoaLiwt8fX0xe/ZsrFy5Uu33hYiqBscQEdFLycfHBytWrJBem5iYPHeZ+Ph45OTkoH79+krtubm5+Pvvvyu1/ZEjR+KLL77AyZMn4eHhgTVr1mDIkCFKdejq6qJ9+/bS66ZNm6JevXq4fPkyOnbsiPj4eMTFxSmdESoqKsKTJ0/w+PFjGBsbV6omIqo6DERE9FIyMTFB48aNK7VMcXEx7OzscPToUZV59erVq9S6rK2tERgYiPDwcLi4uGDPnj2lrlcmk5XZVlxcjFmzZmHgwIEqfQwNDStVDxFVLQYiInpltG3bFunp6dDV1YWTk1OFltHX1wfw75mbZ73//vsYNmwYGjZsiNdeew2dO3dWml9YWIgzZ86gY8eOAIDk5GRkZmaiadOmUj3JycmVDnZEVP04hoiIXhk9e/aEp6cnBgwYgH379iE1NRUxMTH44osvcObMmVKXsba2hpGREaKionD37l0oFAppXu/evSGXy/Gf//xHaTB1CT09PUyYMAGnTp3C2bNn8d5778HDw0MKSF999RXWrVuHmTNn4uLFi7h8+TK2bt2KL774omreACJSGwMREb0yZDIZ9uzZg65duyIkJARubm4YNmwYUlNTYWNjU+oyurq6WLJkCVauXAl7e3v0799fmlenTh2MHDkSRUVFGDFihMqyxsbG+OSTTzB8+HB4enrCyMgIW7Zskeb37t0bu3fvxoEDB9ChQwd4eHhg4cKFcHR01PzOE9ELkQkhRE0XQUT0sho9ejTu3r2L33//Xak9IiICkydPRmZmZs0URkQaxTFERESlUCgUiIuLw8aNG/Hbb7/VdDlEVMUYiIiIStG/f3+cPn0aY8aMga+vb02XQ0RVjJfMiIiISOtxUDURERFpPQYiIiIi0noMRERERKT1GIiIiIhI6zEQERERkdZjICIiIiKtx0BEREREWo+BiIiIiLQeAxERERFpvf8Hh10jirjhHVgAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "import json\n", - "\n", - "# 5. Graph performance.\n", - "\n", - "with open('notebook_data_tmp/pca_speeds.json', 'r') as j:\n", - " data = json.load(j)\n", - "\n", - "time_vals = [data[\"uXTC\"], data[\"uHDD\"], data[\"uS3\"]]\n", - "filenames = [\"XTC\", \"Zarrtraj on Disk\", \"Zarrtraj on S3\"]\n", - "\n", - "plt.bar(filenames, time_vals)\n", - "plt.title('YiiP Trajectory PCA Calculation Time Comparison')\n", - "plt.xlabel('File type')\n", - "plt.ylabel('Total PCA Calculation Time (s)')\n", - "\n", - "plt.savefig(\"pca_speeds.svg\", format='svg')\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/zarrtraj_benchmarks/rmsd.ipynb b/notebooks/zarrtraj_benchmarks/rmsd.ipynb deleted file mode 100644 index 21da578..0000000 --- a/notebooks/zarrtraj_benchmarks/rmsd.ipynb +++ /dev/null @@ -1,204 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Benchmarking RMSD analysis speed using cloud & disk reading\n", - "\n", - "Prerequisites:\n", - "- `write_benchmark_setup.ipynb`\n", - "- `align_setup.ipynb`\n", - "\n", - "Steps:\n", - "\n", - "1. Open a `zarr.Group` object from the aligned trajectory stored on disk\n", - "2. Open a group from the trajectory uploaded to an AWS S3 bucket\n", - "3. Create an `mda.Universe` object for both zarr groups and one for the original .xtc trajectory\n", - "4. Perform the RMSD analysis for each `mda.Universe`, time, and record results\n", - "5. Graph results" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element Z found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/PDBParser.py:348: UserWarning: Unknown element D found for some atoms. These have been given an empty element record. If needed they can be guessed using MDAnalysis.topology.guessers.\n", - " warnings.warn(wmsg)\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: D\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n", - "/nfs/homes3/ljwoods2/.conda/envs/zarrtraj/lib/python3.11/site-packages/MDAnalysis/topology/guessers.py:146: UserWarning: Failed to guess the mass for the following atom types: Z\n", - " warnings.warn(\"Failed to guess the mass for the following atom types: {}\".format(atom_type))\n" - ] - } - ], - "source": [ - "import zarrtraj\n", - "import MDAnalysis as mda\n", - "import zarr\n", - "from zarr.storage import LRUStoreCache\n", - "import s3fs\n", - "import os\n", - "\n", - "# 1\n", - "yiipHDD = zarr.open_group(\"notebook_data_tmp/yiip_aligned.zarrtraj\", mode='r')\n", - "\n", - "# 2\n", - "# Use your own bucket here\n", - "\n", - "s3_fs = s3fs.S3FileSystem(\n", - " # anon must be false to allow authentication\n", - " anon=False,\n", - " profile='sample_profile',# use profiles defined in a .aws/credentials file to store secret keys\n", - " client_kwargs=dict(\n", - " region_name='us-west-1',\n", - " )\n", - ")\n", - "store = s3fs.S3Map(root=f'zarrtraj-test-data/yiip_aligned.zarrtraj',\n", - " s3=s3_fs,\n", - " check=False)\n", - "# Select max_size value in bytes based on chunking of zarrtraj data\n", - "# At least one chunk must fit in the cache\n", - "cache = LRUStoreCache(store, max_size=10485760)\n", - "yiipS3 = zarr.open_group(store=cache, mode='r')\n", - "\n", - "# 3\n", - "uHDD = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", yiipHDD)\n", - "uS3 = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", yiipS3)\n", - "uXTC = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", \"notebook_data_tmp/yiip_aligned.xtc\")" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "from MDAnalysis.analysis import rms\n", - "import time\n", - "import json\n", - "\n", - "# 5\n", - "\n", - "universes = dict()\n", - "universes[\"uHDD\"] = dict()\n", - "universes[\"uHDD\"][\"ref\"] = uHDD\n", - "universes[\"uS3\"] = dict()\n", - "universes[\"uS3\"][\"ref\"] = uS3\n", - "universes[\"uXTC\"] = dict()\n", - "universes[\"uXTC\"][\"ref\"] = uXTC\n", - "\n", - "\n", - "for name in (\"uHDD\", \"uS3\", \"uXTC\"):\n", - " start = time.time()\n", - " R = rms.RMSD(universes[name][\"ref\"],\n", - " universes[name][\"ref\"],\n", - " select='backbone',\n", - " ref_frame=0).run()\n", - " stop = time.time()\n", - " universes[name][\"RMSD\"] = stop - start\n", - "\n", - "rmsd_speeds = dict()\n", - "rmsd_speeds[\"uXTC\"] = universes[\"uXTC\"][\"RMSD\"]\n", - "rmsd_speeds[\"uS3\"] = universes[\"uS3\"][\"RMSD\"]\n", - "rmsd_speeds[\"uHDD\"] = universes[\"uHDD\"][\"RMSD\"]\n", - "with open('notebook_data_tmp/RMSD_speeds.json', 'w') as j:\n", - " json.dump(rmsd_speeds, j)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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UkIUffVZWFiYGDZsmGjQoIEwMTER2trawsbGRvTu3VtcuHBBbvqCK3AKHvr6+qJWrVrCy8tLbN68WWRlZSm8fkIIERERIT7//HNhY2MjdHR0hLGxsWjTpo1YsmSJ3E0ODxw4IBo3biz09PREjRo1xDfffCOOHDlS5BVC799UMC8vTyxbtky4uLgIXV1dYWJiItq0aSP3e8zKyhJTpkwRdnZ2Ql9fX7Rv315ER0crdDXW06dPRZ8+fYSpqakwMjISXbt2FTdv3iw0rRBvr+pxdHQUWlpacu/FourOzMwUU6dOFfb29kJHR0fY2NiI0aNHF7oKz97eXnTv3r3Qa/v+e+lDSnM1VlHbW0mfR+/X+fz5czFhwgTh6OgodHR0hJmZmWjevLmYMWOGSEtL+2DNubm5YsuWLaJDhw7CzMxMaGtrCwsLC9GtWzexY8cOuauNHj16JAYOHCiqV68udHR0RN26dcWSJUvkxhR83ixZskSh16ao937Bev7666/i448/Frq6usLBwUEsXbq0UP0LFy4UDg4OQiqVivr164v//e9/siug3gVAjB07tsjX4P3387Rp00SLFi2EqampkEqlonbt2mLixInixYsXctPt27dPuLq6Cj09PWFoaCg6duwozp07JzemoJbnz58Xud6xsbFF1lRZSIRQ0yUVREr6448/0KRJExw4cAA9evQo73JK7fr162jcuDHWrFmDMWPGlHc5RKQmDg4OcHFxwcGDB8u7FPoAHsaiCuHkyZPYuHEjdHV1Zce5K5sHDx7g0aNH+Pbbb2FjY1PmL0YlIiLV4AnKVCF4enri8uXLCAoKUvgk2Ypm7ty58PT0RFpaGn755Zd/zYl/REQVHQ9jERERkUbjnh0iIiLSaAw7REREpNEYdoiIiEij8WosvL1x2t9//w0jIyOlbh5HRERE5UcIgdevX8PW1lbuy07fx7CDt7fKt7OzK+8yiIiIqBSePHlS4l24GXYAGBkZAXj7YhkbG5dzNURERKSI1NRU2NnZyf6OF4dhB//35YPGxsYMO0RERJXMh05B4QnKREREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk07fIugIiINJ/DtEPlXQKVo7iF3ct1+dyzQ0RERBqNYYeIiIg0GsMOERERaTSGHSIiItJoPEGZSMPxxFAq75NDicob9+wQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaOUadhYsWICWLVvCyMgIlpaW8PHxwZ07d+TG+Pn5QSKRyD1at24tNyYrKwvjx4+Hubk5DA0N4e3tjadPn/6Tq0JEREQVVLmGnYiICIwdOxYXL17E8ePHkZubi86dOyM9PV1uXNeuXREfHy97HD58WK7f398fe/fuxa5du3D27FmkpaWhR48eyMvL+ydXh4iIiCog7fJc+NGjR+WeBwUFwdLSElevXkW7du1k7VKpFNbW1kXOIyUlBZs2bcK2bdvQqVMnAMD27dthZ2eH33//HV26dFHfChAREVGFV6HO2UlJSQEAmJmZybWfOnUKlpaWcHZ2xogRI5CYmCjru3r1KnJyctC5c2dZm62tLVxcXHD+/Pkil5OVlYXU1FS5BxEREWmmChN2hBCYNGkSPvnkE7i4uMjau3Xrhp9//hknTpzAjz/+iMjISHTo0AFZWVkAgISEBOjq6sLU1FRuflZWVkhISChyWQsWLICJiYnsYWdnp74VIyIionJVroex3jVu3Dhcv34dZ8+elWvv37+/7GcXFxe0aNEC9vb2OHToEHr37l3s/IQQkEgkRfZNnz4dkyZNkj1PTU1l4CEiItJQFWLPzvjx47F//36cPHkSNWvWLHGsjY0N7O3tce/ePQCAtbU1srOz8erVK7lxiYmJsLKyKnIeUqkUxsbGcg8iIiLSTOUadoQQGDduHEJDQ3HixAk4Ojp+cJqkpCQ8efIENjY2AIDmzZtDR0cHx48fl42Jj4/HzZs34ebmprbaiYiIqHIo18NYY8eOxY4dO/Dbb7/ByMhIdo6NiYkJ9PX1kZaWhsDAQPTp0wc2NjaIi4vDt99+C3Nzc/Tq1Us2dvjw4QgICED16tVhZmaGyZMno2HDhrKrs4iIiOjfq1zDzrp16wAA7u7ucu1BQUHw8/ODlpYWbty4ga1btyI5ORk2Njbw8PBASEgIjIyMZOOXLVsGbW1t9OvXD5mZmejYsSOCg4OhpaX1T64OERERVUDlGnaEECX26+vrIyws7IPz0dPTw6pVq7Bq1SpVlUZEREQaokKcoExERESkLgw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijaZdmopycHCQkJCAjIwMWFhYwMzNTdV1EREREKqHwnp20tDRs2LAB7u7uMDExgYODAxo0aAALCwvY29tjxIgRiIyMVGetREREREpTKOwsW7YMDg4O+N///ocOHTogNDQU0dHRuHPnDi5cuIBZs2YhNzcXnp6e6Nq1K+7du6fuuomIiIgUotBhrPPnz+PkyZNo2LBhkf2tWrXCsGHDsH79emzatAkRERFwcnJSaaFEREREpaFQ2Pnll18UmplUKsWYMWPKVBARERGRKpX5aqzU1FTs27cPMTExqqiHiIiISKWUDjv9+vXD6tWrAQCZmZlo0aIF+vXrh0aNGmHPnj0qL5CIiIioLJQOO6dPn8ann34KANi7dy+EEEhOTsbKlSvxww8/qLxAIiIiorJQOuykpKTI7qtz9OhR9OnTBwYGBujevTuvwiIiIqIKR+mwY2dnhwsXLiA9PR1Hjx5F586dAQCvXr2Cnp6eygskIiIiKgul76Ds7++PQYMGoWrVqrC3t4e7uzuAt4e3irs0nYiIiKi8KB12xowZA1dXVzx+/Bienp6oUuXtzqHatWvznB0iIiKqcEr13VjNmzdH8+bN5dq6d++ukoKIiIiIVEmhc3YWLlyIjIwMhWZ46dIlHDp0qExFEREREamKQmHn9u3bqFWrFkaPHo0jR47g+fPnsr7c3Fxcv34da9euhZubGwYMGABjY2O1FUxERESkDIUOY23duhXXr1/HmjVrMGjQIKSkpEBLSwtSqVS2x6dp06b4z3/+A19fX0ilUrUWTURERKQohc/ZadSoETZs2ID169fj+vXriIuLQ2ZmJszNzdGkSROYm5urs04iIiKiUlH6BGWJRILGjRujcePG6qiHiIiISKXK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AwNha2sLfX19uLu749atW+VYMREREVU0FTrsAMDHH3+M+Ph42ePGjRuyvsWLF2Pp0qVYvXo1IiMjYW1tDU9PT7x+/bocKyYiIqKKpMKHHW1tbVhbW8seFhYWAN7u1Vm+fDlmzJiB3r17w8XFBVu2bEFGRgZ27NhRzlUTERFRRVHhw869e/dga2sLR0dHDBgwAA8fPgQAxMbGIiEhAZ07d5aNlUqlaN++Pc6fP1/iPLOyspCamir3ICIiIs1UocOOq6srtm7dirCwMPzvf/9DQkIC3NzckJSUhISEBACAlZWV3DRWVlayvuIsWLAAJiYmsoednZ3a1oGIiIjKV4UOO926dUOfPn3QsGFDdOrUCYcOHQIAbNmyRTbm/Ts7CyE+eLfn6dOnIyUlRfZ48uSJ6osnIiKiCqFCh533GRoaomHDhrh3757sqqz39+IkJiYW2tvzPqlUCmNjY7kHERERaaZKFXaysrIQExMDGxsbODo6wtraGsePH5f1Z2dnIyIiAm5ubuVYJREREVUkSn3r+T9t8uTJ8PLyQq1atZCYmIgffvgBqamp8PX1hUQigb+/P+bPnw8nJyc4OTlh/vz5MDAwwMCBA8u7dCIiIqogKnTYefr0Kb744gu8ePECFhYWaN26NS5evAh7e3sAwJQpU5CZmYkxY8bg1atXcHV1xbFjx2BkZFTOlRMREVFFUaHDzq5du0rsl0gkCAwMRGBg4D9TEBEREVU6leqcHSIiIiJlMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiIiEijMewQERGRRmPYISIiIo3GsENEREQajWGHiIiINBrDDhEREWk0hh0iIiLSaAw7REREpNEYdoiI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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "import json\n", - "\n", - "# 5. Graph performance.\n", - "\n", - "with open('notebook_data_tmp/RMSD_speeds.json', 'r') as j:\n", - " data = json.load(j)\n", - "\n", - "time_vals = [data[\"uXTC\"], data[\"uHDD\"], data[\"uS3\"]]\n", - "filenames = [\"XTC\", \"Zarrtraj on Disk\", \"Zarrtraj on S3\"]\n", - "\n", - "plt.bar(filenames, time_vals)\n", - "plt.title('YiiP Trajectory RMSD Calculation Time Comparison')\n", - "plt.xlabel('File type')\n", - "plt.ylabel('Total RMSD Calculation Time (s)')\n", - "\n", - "plt.savefig(\"RMSD_speeds.svg\", format='svg')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[-48.996128 84.863785 0. ]\n", - "[-4.899613 8.486379 0. ]\n" - ] - } - ], - "source": [ - "for zGroup in (yiipHDD, yiipS3):\n", - " print(zGroup[\"particles\"][\"trajectory\"][\"box\"][\"edges\"][\"value\"][0][1])\n", - " zGroup.store.close()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\"\"" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/zarrtraj_benchmarks/rmsf.ipynb b/notebooks/zarrtraj_benchmarks/rmsf.ipynb deleted file mode 100644 index e800741..0000000 --- a/notebooks/zarrtraj_benchmarks/rmsf.ipynb +++ /dev/null @@ -1,159 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Benchmarking RMSF analysis speed using cloud & disk reading\n", - "\n", - "Prerequisites:\n", - "- `write_benchmark_setup.ipynb`\n", - "- `align_setup.ipynb`\n", - "\n", - "Steps:\n", - "\n", - "1. Open a `zarr.Group` object from the aligned trajectory stored on disk\n", - "2. Open a group from the trajectory uploaded to an AWS S3 bucket\n", - "3. Create an `mda.Universe` object for both zarr groups and one for the original .xtc trajectory\n", - "4. Perform the RMSF analysis for each `mda.Universe`, time, and record results\n", - "5. Graph results" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "import zarrtraj\n", - "import MDAnalysis as mda\n", - "import zarr\n", - "from zarr.storage import LRUStoreCache\n", - "import s3fs\n", - "import os\n", - "\n", - "# 1\n", - "yiipHDD = zarr.open_group(\"notebook_data_tmp/yiip_aligned.zarrtraj\", mode='r')\n", - "\n", - "# 2\n", - "# Use your own bucket here\n", - "\n", - "s3_fs = s3fs.S3FileSystem(\n", - " # anon must be false to allow authentication\n", - " anon=False,\n", - " profile='sample_profile',\n", - " client_kwargs=dict(\n", - " region_name='us-west-1',\n", - " )\n", - ")\n", - "store = s3fs.S3Map(root=f'zarrtraj-test-data/yiip_aligned.zarrtraj',\n", - " s3=s3_fs,\n", - " check=False)\n", - "# Select max_size value in bytes based on chunking of zarrtraj data\n", - "# At least one chunk must fit in the cache\n", - "cache = LRUStoreCache(store, max_size=10485760)\n", - "yiipS3 = zarr.open_group(store=cache, mode='r')\n", - "\n", - "# 3\n", - "uHDD = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", yiipHDD)\n", - "uS3 = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", yiipS3)\n", - "uXTC = mda.Universe(\"notebook_data_tmp/yiip_equilibrium/YiiP_system.pdb\", \"notebook_data_tmp/yiip_aligned.xtc\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "from MDAnalysis.analysis import rms\n", - "import json\n", - "\n", - "#4\n", - "\n", - "universes = dict()\n", - "universes[\"uHDD\"] = dict()\n", - "universes[\"uHDD\"][\"ref\"] = uHDD\n", - "universes[\"uS3\"] = dict()\n", - "universes[\"uS3\"][\"ref\"] = uS3\n", - "universes[\"uXTC\"] = dict()\n", - "universes[\"uXTC\"][\"ref\"] = uXTC\n", - "\n", - "for name in (\"uHDD\", \"uS3\", \"uXTC\"):\n", - " c_alphas = universes[name][\"ref\"].select_atoms(\"protein and name CA\")\n", - "\n", - " start = time.time()\n", - " R = rms.RMSF(c_alphas).run()\n", - " stop = time.time()\n", - "\n", - " universes[name][\"RMSF_time\"] = stop - start\n", - "\n", - "rmsf_speeds = dict()\n", - "rmsf_speeds[\"uXTC\"] = universes[\"uXTC\"][\"RMSF_time\"]\n", - "rmsf_speeds[\"uS3\"] = universes[\"uS3\"][\"RMSF_time\"]\n", - "rmsf_speeds[\"uHDD\"] = universes[\"uHDD\"][\"RMSF_time\"]\n", - "with open('notebook_data_tmp/RMSF_speeds.json', 'w') as j:\n", - " json.dump(rmsf_speeds, j)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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4EDlf9or6SUen7rDW8+JSG80a9YMNWrUQFRUlK5LISqCx6fu8DIWERER6TVexiIiIiK9xrBDREREeo1hh4iIiPQaww4RERHpNYYdIqpQvL29lZ4Q7OLigoiICJ3VQ0SVH8MOEf3rBg8eDIlEUmT6448/sHPnTsyZM0dj20pISIBEIsHVq1c1tk4iqlz4nB0i0okuXbogMjJSqc3W1hYGBgY6qoiI9BXP7BCRTkilUsjlcqXJwMCgyGWs16WlpeHTTz+FnZ0dLC0t4evri19//bXE/q6urgCApk2bQiKRwNvbG6dPn4aRkRGSkpKU+o4fPx7t27cHAERFRaFatWrYvXs33N3dYWJiAn9/f9y/f19pmb1796J58+YwMTFB7dq1MWvWLOTl5ZXxXSEibWDYIaJKQwiBwMBAJCUl4cCBA4iNjUWzZs3g5+eHZ8+eFbvMhQsXAADHjh1DYmIidu7cifbt26N27drYuHGjol9eXh42bdqEIUOGKNpevHiBuXPnYv369Th79izS09MxYMAAxfzDhw/jo48+wueff46bN2/i22+/RVRUFObOnauld4CIyoJhh4h0Yt++fahatapi6tu37xuXOXnyJK5du4YffvgBLVq0gJubG/773/+iWrVq+PHHH4tdxtbWFgBgY2MDuVwOa2trAMDQoUOVLqPt378fL168QL9+/RRtubm5WLFiBdq2bYvmzZtj/fr1iImJUQSouXPnYvLkyQgODkbt2rXh7++POXPm4Ntvvy3z+0JEmscxO0SkEz4+Pli9erXitbm5+RuXiY2NRWZmJmxsbJTas7Ky8Oeff6q1/cGDB2P69Ok4f/482rRpg++++w79+vVTqsPQ0BAtWrRQvK5Xrx6qVauGW7duoVWrVoiNjcXFixeVzuTk5+fj5cuXePHiBczMzNSqiYi0g2GHiHTC3NwcderUUWuZgoICODg44NSpU0XmVatWTa112dnZISgoCJGRkahduzYOHDhQ7HolEkmJbQUFBZg1axZ69epVpI+JiYla9RCR9jDsEFGl0axZMyQlJcHQ0BAuLi4qLWNsbAzg1RmX133yyScYMGAAatasiXfeeQft2rVTmp+Xl4dLly6hVatWAIDbt28jNTUV9erVU9Rz+/ZttUMbEf27OGaHiCqNjh07om3btujRowcOHz6MhIQExMTEYPr06bh06VKxy9jZ2cHU1BSHDh3Co0ePkJaWppjXuXNnyGQy/Oc//1EamFzIyMgIY8aMwS+//ILLly9jyJAhaNOmjSL8fPXVV9iwYQPCwsJw48YN3Lp1C9u2bcP06dO18wYQUZkw7BBRpSGRSHDgwAG0b98eISEhcHd3x4ABA5CQkAB7e/tilzE0NMSyZcvw7bffwtHREd27d1fMq1KlCgYPHoz8/Hx8/PHHRZY1MzPDpEmTMHDgQLRt2xampqbYunWrYn7nzp2xb98+HD16FC1btkSbNm2wePFiODs7a37niajMJEIIoesiiIh0ZdiwYXj06BH27Nmj1B4VFYWxY8ciNTVVN4URkcZwzA4RvZXS0tJw8eJFfP/99/jpp590XQ4RaRHDDhG9lbp3744LFy5g+PDh8Pf313U5RKRFvIxFREREeo0DlImIiEivMewQERGRXmPYISIiIr3GsENERER6jWGHiIiI9BrDDhEREek1hh0iIiLSaww7REREpNcYdoiIiEiv/T93ZPtmI1CRPQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "import json\n", - "\n", - "# 5. Graph performance.\n", - "\n", - "with open('notebook_data_tmp/RMSF_speeds.json', 'r') as j:\n", - " data = json.load(j)\n", - "\n", - "time_vals = [data[\"uXTC\"], data[\"uHDD\"], data[\"uS3\"]]\n", - "filenames = [\"XTC\", \"Zarrtraj on Disk\", \"Zarrtraj on S3\"]\n", - "\n", - "plt.bar(filenames, time_vals)\n", - "plt.title('YiiP Trajectory RMSF Calculation Time Comparison')\n", - "plt.xlabel('File type')\n", - "plt.ylabel('Total RMSF Calculation Time (s)')\n", - "\n", - "plt.savefig(\"RMSF_speeds.svg\", format='svg')\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/notebooks/zarrtraj_benchmarks/write_benchmark_setup.ipynb b/notebooks/zarrtraj_benchmarks/write_benchmark_setup.ipynb deleted file mode 100644 index 7954ff4..0000000 --- a/notebooks/zarrtraj_benchmarks/write_benchmark_setup.ipynb +++ /dev/null @@ -1,151 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This notebook demonstrates how to write a `.zarrtraj` trajectory\n", - "to disk and to an S3 bucket using `s3fs` while benchmarking writing performance.\n", - "\n", - "This notebooks will also act as setup code for other benchmarks.\n", - "\n", - "1. Download the 90ns YiiP trajectory to the local filesystem\n", - "2. Write it into the xtc format on disk (for benchmarking comparative speed)\n", - "3. Write it into the zarrtraj format on disk\n", - "4. Write it into the zarrtraj format on an accessible AWS S3 bucket\n", - "5. Load results and graph performance." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "import zarrtraj\n", - "import MDAnalysis as mda\n", - "import MDAnalysisData\n", - "import zarr\n", - "import os \n", - "import s3fs\n", - "import time\n", - "import json\n", - "\n", - "# Setup benchmarking\n", - "write_speeds = dict()\n", - "\n", - "# 1. Download the 90ns YiiP trajectory to the local filesystem\n", - "yiip = MDAnalysisData.yiip_equilibrium.fetch_yiip_equilibrium_long(data_home='notebook_data_tmp')\n", - "u = mda.Universe(yiip.topology, yiip.trajectory)\n", - "\n", - "# 2. Write it into the xtc format on disk (for benchmarking comparative speed)\n", - "start = time.time()\n", - "with mda.Writer(\"notebook_data_tmp/yiip.xtc\", u.atoms.n_atoms) as W:\n", - " for ts in u.trajectory:\n", - " W.write(u.atoms)\n", - "stop = time.time()\n", - "write_speeds[\"XTC\"] = stop - start\n", - "\n", - "# 3. Write it into the zarrtraj format on disk\n", - "zHDD = zarr.open_group(\"notebook_data_tmp/yiip.zarrtraj\", mode = 'w')\n", - "\n", - "start = time.time()\n", - "with mda.Writer(zHDD, u.atoms.n_atoms,\n", - " format='ZARRTRAJ') as W:\n", - " for ts in u.trajectory:\n", - " W.write(u.atoms)\n", - "stop = time.time()\n", - "write_speeds[\"Zarrtraj_Disk\"] = stop - start\n", - "\n", - "# 4. Write it into the zarrtraj format on an accessible AWS S3 bucket\n", - "# Use your own bucket here\n", - "\n", - "s3_fs = s3fs.S3FileSystem(\n", - " # anon must be false to allow authentication\n", - " anon=False,\n", - " profile='sample_profile',\n", - " client_kwargs=dict(\n", - " region_name='us-east-1',\n", - " )\n", - ")\n", - "\n", - "cloud_store = s3fs.S3Map(\n", - " root=f'zarrtraj-test-data/yiip.zarrtraj',\n", - " s3=s3_fs,\n", - " check=False\n", - ")\n", - "\n", - "zS3 = zarr.open_group(store=cloud_store, mode='w')\n", - "\n", - "start = time.time()\n", - "with mda.Writer(zS3, u.atoms.n_atoms,\n", - " n_frames=u.trajectory.n_frames,\n", - " format='ZARRTRAJ') as W:\n", - " for ts in u.trajectory:\n", - " W.write(u.atoms)\n", - "stop = time.time()\n", - "write_speeds[\"Zarrtraj_S3\"] = stop - start\n", - "\n", - "with open('notebook_data_tmp/write_speeds.json', 'w') as j:\n", - " json.dump(write_speeds, j)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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ObV8+vRpAUBMnTq1Qse1b98+AUAsWLBApb1kanv16tVSm7OzszA2NhY3b96U2uLi4gQA4ejoqDJVtWPHDgFA7Ny5U2or+XtdsmSJynvNnTtXABDR0dFl1lhUVCQKCgrE+vXrhZ6envTvRAghvLy8BABx+PDhUtt5eXkJLy8v6fXHH38sLCwsnvp59O/fXxgZGYnr16+rtHfv3l2YmJiI9PR0IcT//7nx1ltvqfQrma48derUU9+HKhenzKhK6969O9q3bw83Nze8//77z72f9u3bw8DAAGZmZvD394eDgwN+++032Nvbv3CN77zzTqm2wsJChIWFoUmTJjA0NIS+vj4MDQ3x119/4cqVK+Xu69GjRzh8+DDefvttmJiYoLCwUFreeustPHr0CKdPnwYA/Pbbb2jQoAE6d+6sds3Z2dk4c+YMevfujVq1akntenp6GDhwIG7evFlqSL+s43z33XdhZ2enMp33zTffwNbWttQI05MUCgW8vLxw4sQJFBQUIC4uDunp6dL0hZeXFyIjIyGEwOnTp5Gbm6tyQfvT6lLH7t274ePjAycnJ5XPu3v37gAej6Rpk7+/v8rrxo0bAwB69OhRqv2/U7y7d++GhYUFAgICVOpu3ry5NLqmKUeOHAGAUndV9unTB6ampjh8+LBKe/PmzfHKK6+UOiZvb2+VEamS9rKmrt977z2V1wMGDADweKSwxIULFxAYGAhra2vo6enBwMAAgwYNQlFREf7880+V7S0tLfHmm28+81jbtm2L9PR0vPvuu/j1119x7969Un2OHDkCX19f1KlTR6V98ODByMnJwalTp1TaAwMDVV43bdoUwItN2ZPmMRBRlWdkZARDQ8MX2sf69esRExODCxcu4N9//8WlS5fQsWNHjdTn6OhYqm3ChAmYPn06evbsiV27duHMmTOIiYlBs2bNkJubW+6+7t+/j8LCQnzzzTcwMDBQWd566y0AkH5A371797nvWEpLS4MQoszanZycpFqedZxGRkYYMWIENm7ciPT0dNy9exf/+9//8MEHH6hMoZTHx8cH2dnZiImJwdGjR2Fvby9NJ3p5eeHevXtISEiQfgk+GYhMTEykqa/ndfv2bezatavU5/3aa68BQJm/EDXJyspK5XXJuV5W+6NHj1TqTk9Ph6GhYanaU1NTn1r3q6++CgBITEysUI3379+Hvr5+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Dg4OyM/PR1pa2lP73L59u9T+7969W2r06b+MjIxgbm6ushAREdHLqcoGIldXVzg4OODgwYNSW35+PqKiouDp6QkAaNWqFQwMDFT6pKSkID4+XurToUMHZGRk4OzZs1KfM2fOICMjQ+pDRERE8qavyzfPysrC33//Lb1OTExEXFwcrKys8OqrryIkJARhYWFwc3ODm5sbwsLCYGJiggEDBgAAlEolhg0bhokTJ8La2hpWVlaYNGkSPDw80LlzZwBA48aN0a1bNwwfPhyrVq0CAHz44Yfw9/ev8B1mRERE9HLTaSA6d+4cfHx8pNcTJkwAAAQHByMiIgKTJ09Gbm4uRo0ahbS0NLRr1w4HDhyAmZmZtM2iRYugr6+Pvn37Ijc3F76+voiIiICenp7U56effsLYsWOlu9ECAwPLffYRERERyU+VeQ5RVcfnEBERaQ+fQ0R8DhERERGRjjEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkexV6UBUWFiIzz77DK6urjA2NkbdunUxe/ZsFBcXS32EEJg5cyacnJxgbGwMb29vJCQkqOwnLy8PY8aMgY2NDUxNTREYGIibN29W9uEQERFRFfVCgSgvL09TdZRp/vz5+Pbbb7Fs2TJcuXIFCxYswJdffolvvvlG6rNgwQIsXLgQy5YtQ0xMDBwcHODn54eHDx9KfUJCQrB9+3Zs3rwZ0dHRyMrKgr+/P4qKirRaPxEREVUPagWi/fv3Y/DgwahXrx4MDAxgYmICMzMzeHl5Ye7cufj3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wtraWmoPCQlBWFgY3Nzc4ObmhrCwMJiYmEjfqaZUKjFs2DBMnDgR1tbWsLKywqRJk+Dh4VHqIm0iIiKSJ7W/3LWqmTx5MnJzczFq1CikpaWhXbt2OHDgAMzMzKQ+ixYtgr6+Pvr27Yvc3Fz4+voiIiICenp6OqyciIiIqgqF0MVcWDWUmZkJpVKJjIwMXk9ELx2XqXt0XQLpWNK8Hjp9f56DpK1zsKK/v9X+clciIiKilw0DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREckeAxERERHJHgMRERERyR4DEREREclelQ5E4eHhaNOmDczMzGBnZ4eePXvi6tWrKn2EEJg5cyacnJxgbGwMb29vJCQkqPTJy8vDmDFjYGNjA1NTUwQGBuLmzZuVeShERERUhVXpQBQVFYXRo0fj9OnTOHjwIAoLC9GlSxdkZ2dLfRYsWICFCxdi2bJliImJgYODA/z8/PDw4UOpT0hICLZv347NmzcjOjoaWVlZ8Pf3R1FRkS4Oi4iIiKoYfV0X8DT79u1Teb127VrY2dkhNjYWnTp1ghACixcvxrRp09CrVy8AwLp162Bvb4+NGzdixIgRyMjIwJo1a/Djjz+ic+fOAIANGzagTp06OHToELp27Vrpx0VERERVS5UeIXpSRkYGAMDKygoAkJiYiNTUVHTp0kXqY2RkBC8vL5w8eRIAEBsbi4KCApU+Tk5OcHd3l/qUJS8vD5mZmSoLERERvZyq9AjRfwkhMGHCBLz++utwd3cHAKSmpgIA7O3tVfra29sjOTlZ6mNoaAhLS8tSfUq2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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "# 5. Graph performance.\n", - "\n", - "with open('notebook_data_tmp/write_speeds.json', 'r') as j:\n", - " data = json.load(j)\n", - "\n", - "time_vals = [data[\"XTC\"], data[\"Zarrtraj_Disk\"], data[\"Zarrtraj_S3\"]]\n", - "filenames = [\"XTC\", \"Zarrtraj on Disk\", \"Zarrtraj on S3\"]\n", - "\n", - "plt.bar(filenames, time_vals)\n", - "plt.title('YiiP Trajectory Write Time Comparison')\n", - "plt.xlabel('File type')\n", - "plt.ylabel('Total write time (s)')\n", - "\n", - "plt.savefig(\"write_speeds.svg\", format='svg')\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "zarrtraj", - "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.11.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/pyproject.toml b/pyproject.toml index e5853ec..7faa64d 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,10 +21,11 @@ dependencies = [ "MDAnalysis>=2.7.0", # Earliest zarr version where BaseStore has close() method "zarr>=2.11.0", - "dask>=2023.11.0", + # Earliest version with preserved_linked_dsets "kerchunk>=0.2.6", + # Earliest version with visititems_links "h5py>=3.11.0", - "s3fs==2024.3.0", + "s3fs>=2024.3.0", ] keywords = [ "molecular simulations", diff --git a/zarrtraj/ZARR.py b/zarrtraj/ZARR.py index ab0a2a1..da7dfc6 100644 --- a/zarrtraj/ZARR.py +++ b/zarrtraj/ZARR.py @@ -1,28 +1,30 @@ """ -Example: Loading a .zarrmd file from disk +Example: Loading a .h5md file from disk ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``zarrmd`` files are H5MD-formatted files stored in the Zarr format. -To learn more, see the `H5MD documentation `_, -the `Zarr documentation `_, -and the :ref:`zarrmd format page `. - -To load a simulation from a ``.zarrmd`` trajectory file, pass a +To load a simulation from a ``.h5md`` trajectory file, pass a topology file and a path to the ``.zarrmd`` file to a :class:`~MDAnalysis.core.universe.Universe`:: import zarrtraj import MDAnalysis as mda - u = mda.Universe("topology.tpr", "trajectory.zarrmd") + u = mda.Universe("topology.tpr", "trajectory.h5md") -The reader can also handle reading from a .h5md file. +The reader can also handle reading from a ``.zarrmd`` file. + +``zarrmd`` files are H5MD-formatted files stored in the Zarr format. +To learn more, see the `H5MD documentation `_, +the `Zarr documentation `_, +and the :ref:`zarrmd format page `. Example: Reading from cloud services ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Zarrtraj currently supports reading from .h5md and .zarrmd files stored in -AWS, Google Cloud, and Azure Block Storage. +Zarrtraj currently supports reading from ``.h5md`` and ``.zarrmd`` files stored in +AWS S3 buckets. If you are interested in streaming from and writing to other +cloud service storage options, please raise an issue on the +`zarrtraj GitHub `_. To read from AWS S3, pass the S3 url path to the file as the trajectory argument:: @@ -71,10 +73,6 @@ for ts in u.trajectory: w.write(u.atoms) -Note that the `n_frames` argument is required. This is because the writer needs to know -the number of frames in the output trajectory in order to determine the number of frames per chunk -for each dataset. - Classes ^^^^^^^ @@ -92,13 +90,13 @@ from MDAnalysis.exceptions import NoDataError from MDAnalysis.due import due, Doi from MDAnalysis.lib.util import store_init_arguments -import dask.array as da from enum import Enum from .utils import * -from .cache import FrameCache, AsyncFrameCache +from .cache import FrameCache import collections import numbers import logging +import warnings try: @@ -435,9 +433,8 @@ def _determine_protocol(self): """Prepares the correct method for managing the file given the protocol""" self._protocol = get_protocol(self.filename) - if self._protocol == "s3": + if self._protocol in ZARRTRAJ_NETWORK_PROTOCOLS: self._cache_type = ZarrLRUCache - # NOTE: Import correct packages elif self._protocol == "file": self._cache_type = ZarrNoCache else: @@ -464,12 +461,8 @@ def _open_trajectory(self): raise NoDataError("H5MD file must contain an 'h5md' group") if self._group is None: - # NOTE: we do this because running moto on gh actions - # duplicates all keys in the zarr file when reading traj_keys = list(self._file["particles"].group_keys()) - if len(traj_keys) == 1 or all( - traj_key == traj_keys[0] for traj_key in traj_keys - ): + if len(traj_keys) == 1: self._group = traj_keys[0] else: raise NoDataError( @@ -564,7 +557,7 @@ def _read_frame(self, frame): if self.convert_units: self._convert_units() - # frame seq update case 1: read called from __getitem__-like context + # frame seq update case 2: read called from __getitem__-like context if len(self._frame_seq) == 0: self._frame_seq = None self._cache.update_frame_seq(self._frame_seq) @@ -776,9 +769,7 @@ def parse_n_atoms(filename, group=None, so=None): if group is None: traj_keys = list(file["particles"].group_keys()) - if len(traj_keys) == 1 or all( - traj_key == traj_keys[0] for traj_key in traj_keys - ): + if len(traj_keys) == 1: group = traj_keys[0] else: raise NoDataError( @@ -823,7 +814,7 @@ def __init__( # to get buffer indices, do i.e. _val_idx % _val_frames_per_chunk self._val_idx = 0 self._t_idx = 0 - self._n_frames = n_frames + self._n_frames = n_frames if n_frames is not None else np.inf val_filter = None time_filter = None @@ -903,7 +894,7 @@ def write( *self._val_chunks[1:], ) - if self._t_idx % self._t_frames_per_chunk == 0: + if self._t_idx != 0 and self._t_idx % self._t_frames_per_chunk == 0: self._t[self._t_idx - self._t_frames_per_chunk :] = self._t_buf[:] self._s[self._t_idx - self._t_frames_per_chunk :] = self._s_buf[:] self._t.resize(self._t.shape[0] + self._t_frames_per_chunk) @@ -919,21 +910,28 @@ def flush(self): """Write everything remaining in the buffers to the zarr datasets and shink the zarr datasets to the correct size. """ - self._val[ - self._val_idx - - (self._val_idx % (self._val_frames_per_chunk + 1)) : self._val_idx - ] = self._val_buf[: (self._val_idx % (self._val_frames_per_chunk + 1))] + num_v_frames = self._val_idx % self._val_frames_per_chunk + if num_v_frames == 0: + num_v_frames = self._val_frames_per_chunk + + self._val[self._val_idx - num_v_frames : self._val_idx] = self._val_buf[ + :num_v_frames + ] self._val.resize(self._val_idx, *self._val_chunks[1:]) - self._t[ - self._t_idx - - (self._t_idx % (self._t_frames_per_chunk + 1)) : self._t_idx - ] = self._t_buf[: (self._t_idx % (self._t_frames_per_chunk + 1))] + num_t_frames = self._t_idx % self._t_frames_per_chunk + if num_t_frames == 0: + num_t_frames = self._t_frames_per_chunk + + self._t[self._t_idx - num_t_frames : self._t_idx] = self._t_buf[ + :num_t_frames + ] + self._t.resize(self._t_idx) - self._s[ - self._t_idx - - (self._t_idx % (self._t_frames_per_chunk + 1)) : self._t_idx - ] = self._s_buf[: (self._t_idx % (self._t_frames_per_chunk + 1))] + + self._s[self._t_idx - num_t_frames : self._t_idx] = self._s_buf[ + :num_t_frames + ] self._s.resize(self._t_idx) @@ -947,8 +945,10 @@ class ZARRMDWriter(base.WriterBase): filename or URL to write to n_atoms : int number of atoms in the system - n_frames : int - number of frames to be written in the output trajectory + n_frames : int (optional) + number of frames to be written in the output trajectory. If not + provided, the trajectory will allocate more memory than necessary + which may slow down trajectory write speed. compressor : numcodecs.Codec (optional) compressor to use for the Zarr datasets. Will be applied to all datasets precision : int (optional) @@ -993,7 +993,7 @@ class ZARRMDWriter(base.WriterBase): ValueError when ``n_atoms`` is 0 ValueError - when ``n_frames`` is not provided or negative + when ``n_frames`` is provided and not positive ValueError when ``precision`` is less than 0 ValueError @@ -1115,9 +1115,9 @@ def __init__( raise ValueError("H5MDWriter: no atoms in output trajectory") self.n_atoms = n_atoms - if n_frames is None or n_frames < 0: + if n_frames is not None and n_frames <= 0: raise ValueError( - "H5MDWriter: Please provide a non-negative value for 'n_frames' kwarg" + "H5MDWriter: Please provide a positive value for 'n_frames' kwarg" ) self.n_frames = n_frames self.storage_options = storage_options @@ -1249,10 +1249,12 @@ def _open_file(self): self._file["h5md/creator"].attrs["name"] = self.creator self._file["h5md/creator"].attrs["version"] = self.creator_version - def _initialize_zarrmd_file(self, ts): - # for keeping track of where to write in the dataset + self._curr_time = None + self._curr_step = None + # for keeping track of num frames written self._counter = 0 + def _initialize_zarrmd_file(self, ts): # initialize trajectory group self._file.require_group("particles").require_group("trajectory") self._traj = self._file["particles/trajectory"] @@ -1404,19 +1406,26 @@ def _write_next_timestep(self, ts): violates the rules of the step dataset in the H5MD standard. """ - - i = self._counter - self._allocate_buffers(ts) - curr_time = ( + prev_time = self._curr_time + self._curr_time = ( ts.time if self.units["time"] is None else self.convert_time_to_native(ts.time) ) - curr_step = ts.data["step"] if "step" in ts.data else ts.frame - - # NOTE: check monotinic increasing + if prev_time is not None and self._curr_time < prev_time: + raise ValueError( + "The H5MD standard dictates that the time values " + + "must increase monotonically" + ) + prev_step = self._curr_step + self._curr_step = ts.data["step"] if "step" in ts.data else ts.frame + if prev_step is not None and self._curr_step < prev_step: + raise ValueError( + "The H5MD standard dictates that the step values " + + "must increase monotonically" + ) if ts.dimensions is not None and "box/edges" in self._elements: @@ -1425,7 +1434,9 @@ def _write_next_timestep(self, ts): if self.units["length"] is None else self.convert_pos_to_native(ts.triclinic_dimensions) ) - self._elements["box/edges"].write(box, curr_step, curr_time) + self._elements["box/edges"].write( + box, self._curr_step, self._curr_time + ) if not ts.has_positions and "position" in self._elements: raise NoDataError( @@ -1439,7 +1450,9 @@ def _write_next_timestep(self, ts): if self.units["length"] is None else self.convert_pos_to_native(ts.positions) ) - self._elements["position"].write(pos, curr_step, curr_time) + self._elements["position"].write( + pos, self._curr_step, self._curr_time + ) if ts.dimensions is None and "box/edges" in self._elements: raise NoDataError( @@ -1453,7 +1466,9 @@ def _write_next_timestep(self, ts): if self.units["velocity"] is None else self.convert_velocities_to_native(ts.velocities) ) - self._elements["velocity"].write(vel, curr_step, curr_time) + self._elements["velocity"].write( + vel, self._curr_step, self._curr_time + ) if ts.has_forces and "force" in self._elements: force = ( @@ -1461,7 +1476,9 @@ def _write_next_timestep(self, ts): if self.units["force"] is None else self.convert_forces_to_native(ts.forces) ) - self._elements["force"].write(force, curr_step, curr_time) + self._elements["force"].write( + force, self._curr_step, self._curr_time + ) for obsv, value in ts.data.items(): if ( @@ -1469,7 +1486,9 @@ def _write_next_timestep(self, ts): and obsv not in self.data_blacklist and obsv in self._elements ): - self._elements[obsv].write(value, curr_step, curr_time) + self._elements[obsv].write( + value, self._curr_step, self._curr_time + ) self._counter += 1 @@ -1480,6 +1499,22 @@ def close(self): elembuffer.flush() # To ensure idempotency: self._elements = dict() + if hasattr(self, "_counter"): + if self.n_frames is not None: + # issue a warning if counter is less or more than n_frames + if self._counter < self.n_frames: + warnings.warn( + f"H5MDWriter: `n_frames` kwarg set to {self.n_frames} but " + f"only {self._counter} frame(s) were written to the trajectory.", + RuntimeWarning, + ) + if self._counter >= self.n_frames: + warnings.warn( + f"H5MDWriter: `n_frames` kwarg set to {self.n_frames} but " + f"{self._counter} frame(s) were written to the trajectory.", + RuntimeWarning, + ) + del self._counter if hasattr(self, "_file") and self._file is not None: self._file.store.close() self._file = None diff --git a/zarrtraj/__init__.py b/zarrtraj/__init__.py index 1e5efe0..2d2b624 100755 --- a/zarrtraj/__init__.py +++ b/zarrtraj/__init__.py @@ -1,9 +1,8 @@ """ zarrtraj -This is a kit that provides the ability to read and write trajectory data in the Zarr file format +This is a kit that provides the ability to read H5MD trajectory data into MDAnalysis using Zarr """ -# Add imports here from importlib.metadata import version from .ZARR import ZARRH5MDReader, ZARRMDWriter diff --git a/zarrtraj/cache.py b/zarrtraj/cache.py index 1090c12..f426ba1 100644 --- a/zarrtraj/cache.py +++ b/zarrtraj/cache.py @@ -43,6 +43,7 @@ def cleanup(self, *args, **kwargs): """Call this in the reader's close() method""" +# Not yet implemented class AsyncFrameCache(FrameCache, threading.Thread): def __init__(self): diff --git a/zarrtraj/data/write_aligned_yiip_xtc.py b/zarrtraj/data/write_aligned_yiip_xtc.py new file mode 100644 index 0000000..b92c9ac --- /dev/null +++ b/zarrtraj/data/write_aligned_yiip_xtc.py @@ -0,0 +1,25 @@ +import zarrtraj +import zarr +from numcodecs import Blosc, Quantize +import MDAnalysis as mda +from MDAnalysis.analysis import rms, align +import numcodecs + +# This requires MDAnalysis >= 2.8.0 + +u = mda.Universe( + "zarrtraj/data/yiip_equilibrium/YiiP_system.pdb", + "zarrtraj/data/yiip_equilibrium/YiiP_system_90ns_center.xtc", +) + +average = align.AverageStructure( + u, u, select="protein and name CA", ref_frame=0 +).run() +ref = average.results.universe + +aligner = align.AlignTraj( + u, + ref, + select="protein and name CA", + filename="zarrtraj/data/yiip_equilibrium/YiiP_system_90ns_center_aligned.xtc", +).run() diff --git a/zarrtraj/tests/test_zarrtraj.py b/zarrtraj/tests/test_zarrtraj.py index d287e40..8444254 100644 --- a/zarrtraj/tests/test_zarrtraj.py +++ b/zarrtraj/tests/test_zarrtraj.py @@ -122,23 +122,6 @@ def ref(request): class TestH5MDFmtReaderBaseAPI(MultiframeReaderTest): """Tests ZarrTrajReader with with synthetic trajectory.""" - # Override get_writer tests to provide n_frames kwarg - @pytest.mark.skip(reason="Not implemented") - def test_get_writer_1(self, ref, reader, tmpdir): - with tmpdir.as_cwd(): - outfile = "test-writer." + ref.ext - with reader.Writer(outfile, n_frames=1) as W: - assert_equal(isinstance(W, ref.writer), True) - assert_equal(W.n_atoms, reader.n_atoms) - - @pytest.mark.skip(reason="Not implemented") - def test_get_writer_2(self, ref, reader, tmpdir): - with tmpdir.as_cwd(): - outfile = "test-writer." + ref.ext - with reader.Writer(outfile, n_atoms=100, n_frames=1) as W: - assert_equal(isinstance(W, ref.writer), True) - assert_equal(W.n_atoms, 100) - # H5MD Format Reader Tests # Only test these with disk to avoid excessive test length @@ -368,7 +351,7 @@ def test_write_none(self, ref, tmpdir, prefix): outfile = prefix + "write-none." + ref.ext with tmpdir.as_cwd(): with pytest.raises(TypeError): - with ref.writer(outfile, 42, n_frames=1) as w: + with ref.writer(outfile, 42) as w: w.write(None) def test_no_container(self, ref, tmpdir, prefix): @@ -428,3 +411,55 @@ def test_write_compressor_filters(self, universe, tmpdir): assert written[h5mdelem_path][ "step" ].compressor == numcodecs.Blosc(cname="zstd", clevel=7) + + +class TestH5MDFmtWriterNFrames: + @pytest.fixture() + def universe(self): + return mda.Universe(TPR_xvf, H5MD_xvf) + + def test_write_below_n_frames(self, universe, tmpdir): + """Writing below n_frames should issue a warning but still write + the correct number of frames""" + + with tmpdir.as_cwd(): + with pytest.warns( + RuntimeWarning, + ): + with mda.Writer( + "foo.zarrmd", + universe.atoms.n_atoms, + n_frames=2, + ) as w: + w.write(universe) + + written = mda.Universe(TPR_xvf, "foo.zarrmd") + for i in range(len(written.trajectory)): + assert_timestep_almost_equal( + written.trajectory[i], universe.trajectory[i] + ) + + assert len(written.trajectory) == 1 + + def test_write_above_n_frames(self, universe, tmpdir): + """Writing above n_frames should issue a warning but still write + the correct number of frames""" + with tmpdir.as_cwd(): + with pytest.warns( + RuntimeWarning, + ): + with mda.Writer( + "foo.zarrmd", + universe.atoms.n_atoms, + n_frames=2, + ) as w: + for ts in universe.trajectory: + w.write(universe) + + written = mda.Universe(TPR_xvf, "foo.zarrmd") + for i in range(len(written.trajectory)): + assert_timestep_almost_equal( + written.trajectory[i], universe.trajectory[i] + ) + + assert len(written.trajectory) == 3 diff --git a/zarrtraj/utils.py b/zarrtraj/utils.py index f411ad2..23e7d0c 100644 --- a/zarrtraj/utils.py +++ b/zarrtraj/utils.py @@ -7,6 +7,8 @@ import numpy as np from kerchunk.hdf import SingleHdf5ToZarr +ZARRTRAJ_NETWORK_PROTOCOLS = ["s3", "http", "https"] + class H5MDElement: """Convenience class for representing elements in an H5MD @@ -150,11 +152,12 @@ def get_h5_zarr_mapping( h5chunks = SingleHdf5ToZarr(inf, url, inline_threshold=100) fo = h5chunks.translate(preserve_linked_dsets=True) - if protocol == "s3": + # Currently supported + if protocol in ZARRTRAJ_NETWORK_PROTOCOLS: fs = fsspec.filesystem( "reference", fo=fo, - remote_protocol="s3", + remote_protocol=protocol, remote_options=so, skip_instance_cache=True, ) @@ -172,7 +175,8 @@ def get_h5_zarr_mapping( def get_mapping_for(filename, protocol, ext, so): if ext == ".zarr" or ext == ".zarrmd": - mapping = zarr.storage.FSStore(filename, mode="r", **so) + fs = fsspec.filesystem(protocol, **so) + mapping = fs.get_mapper(filename) elif ext == ".h5md" or ext == ".h5": mapping = get_h5_zarr_mapping(filename, protocol, so) else: