From 77e11c269c12e77770c22323468c6a964452a2fd Mon Sep 17 00:00:00 2001 From: betolink Date: Sun, 28 Jan 2024 20:25:09 -0600 Subject: [PATCH 01/11] refactoring tests to log io behavior --- h5tests/h5py_arr_mean.py | 32 +- h5tests/h5test.py | 88 +++++- h5tests/single-test.ipynb | 44 +-- h5tests/xarray_arr_mean.py | 49 +++- helpers/links-old.json | 53 ++++ helpers/links.py | 2 +- helpers/s3filelinks.json | 103 ++++--- notebooks/logs-fsspec.ipynb | 568 ++++++++++++++++++++++++++++++++++++ 8 files changed, 822 insertions(+), 117 deletions(-) create mode 100644 helpers/links-old.json create mode 100644 notebooks/logs-fsspec.ipynb diff --git a/h5tests/h5py_arr_mean.py b/h5tests/h5py_arr_mean.py index 7c35407..1d5a01c 100644 --- a/h5tests/h5py_arr_mean.py +++ b/h5tests/h5py_arr_mean.py @@ -1,21 +1,27 @@ -from .h5test import H5Test, timer_decorator import h5py import numpy as np +from .h5test import H5Test, timer_decorator + + class H5pyArrMean(H5Test): @timer_decorator - def run(self): - final_h5py_array = [] + def run(self, io_params={}): + final_h5py_array = [] # TODO: Do we need to make this configurable or consistent? - group = '/gt1l/heights' - variable = 'h_ph' + group = "/gt1l/heights" + variable = "h_ph" + fsspec_params = {} + h5py_params = {} + if "fsspec_params" in io_params: + fsspec_params = io_params["fsspec_params"] + if "h5py_params" in io_params: + h5py_params = io_params["h5py_params"] for file in self.files: - with h5py.File(self.s3_fs.open(file, 'rb')) as f: - data = f[f'{group}/{variable}'][:] - # Need to test if using concatenate is faster - final_h5py_array = np.insert( - final_h5py_array, - len(final_h5py_array), - data, axis=None - ) + with self.s3_fs.open(file, mode="rb", **fsspec_params) as fo: + with h5py.File(fo, **h5py_params) as f: + data = f[f"{group}/{variable}"][:] + final_h5py_array = np.insert( + final_h5py_array, len(final_h5py_array), data, axis=None + ) return np.mean(final_h5py_array) diff --git a/h5tests/h5test.py b/h5tests/h5test.py index 74bb4de..60f7ac7 100644 --- a/h5tests/h5test.py +++ b/h5tests/h5test.py @@ -1,52 +1,109 @@ -import boto3 import csv -from io import StringIO +import logging +import os +import re +import sys import time from datetime import datetime -import os +from io import StringIO + +import boto3 import s3fs -import sys -current = os.path.abspath('..') +current = os.path.abspath("..") sys.path.append(current) + from helpers.links import S3Links -def generate_timestamp(): - return datetime.now().strftime('%Y-%m-%d-%H%M%S') + +class RegexFilter(logging.Filter): + """ + This class will filter a logstream based on a regex expression + The idea is to target a particular library as they usually have a consistent signature. + """ + + def __init__(self, regex_pattern): + super(RegexFilter, self).__init__() + self.regex_pattern = re.compile(regex_pattern) + + def filter(self, record): + # Apply the regex pattern to the log message + return not bool(self.regex_pattern.search(record.msg)) + def timer_decorator(func): """ A decorator to measure the execution time of the wrapped function. + It also writes logs to local disk if a regex expression is used in the + subclass instance. """ + + def __setup_logging(self, tstamp): + log_filename = f"logs/{self.data_format}-{tstamp}.log" + logger = logging.getLogger("fsspec") + logger.setLevel(logging.DEBUG) + self.regex_filter = RegexFilter(self.logs_regex) + # add regerx to root logger + logging.getLogger().addFilter(self.regex_filter) + self._file_handler = logging.FileHandler(log_filename) + self._file_handler.setLevel(logging.DEBUG) + # Add the handler to the root logger + logging.getLogger().addHandler(self._file_handler) + + def __turnoff_logging(self): + logging.getLogger().removeFilter(self.regex_filter) + logging.getLogger().removeHandler(self._file_handler) + self._file_handler.close() + def wrapper(self, *args, **kwargs): + tstamp = datetime.now().strftime("%Y-%m-%d-%H%M%S") + if self.logs_regex: + __setup_logging(self, tstamp) start_time = time.time() result = func(self, *args, **kwargs) end_time = time.time() + if self.logs_regex: + __turnoff_logging(self) execution_time = end_time - start_time # Call the store method here if self.store_results: - results_key = f"{generate_timestamp()}_{self.name}_{self.data_format}_results.csv" + results_key = f"{tstamp}_{self.name}_{self.data_format}_results.csv" s3_key = f"{self.results_directory}/{results_key}" - self.store(run_time=execution_time, result=result, bucket=self.bucket, s3_key=s3_key) + self.store( + run_time=execution_time, + result=result, + bucket=self.bucket, + s3_key=s3_key, + ) return result, execution_time + return wrapper + class H5Test: - def __init__(self, data_format: str, files=None, store_results=True): + def __init__( + self, data_format: str, files=None, store_results=True, logs_regex=None + ): self.name = self.__class__.__name__ self.data_format = data_format + self.logs_regex = logs_regex if files: self.files = files else: self.files = S3Links().get_links_by_format(data_format) - self.s3_client = boto3.client('s3') # Ensure AWS credentials are configured + self.s3_client = boto3.client("s3") # Ensure AWS credentials are configured self.s3_fs = s3fs.S3FileSystem(anon=False) self.store_results = store_results - self.bucket = "nasa-cryo-scratch" - self.results_directory = "h5cloud/benchmark_results" + self.bucket = "nasa-cryo-persistent" + self.results_directory = "h5cloud/benchmark_results" @timer_decorator - def run(self): + def run(self, io_params={}): + """ + When implemented we can pass io_params as runtime tweaks to the underlying + libraries e.g. fsspec. + """ + raise NotImplementedError("The run method has not been implemented") def store(self, run_time: float, result: str, bucket: str, s3_key: str): @@ -61,7 +118,7 @@ def store(self, run_time: float, result: str, bucket: str, s3_key: str): # Create a CSV in-memory csv_buffer = StringIO() csv_writer = csv.writer(csv_buffer) - csv_writer.writerow(['Name', 'Data Format', 'Run Time', 'Result']) # Headers + csv_writer.writerow(["Name", "Data Format", "Run Time", "Result"]) # Headers csv_writer.writerow([self.name, self.data_format, run_time, result]) # Reset the buffer's position to the beginning @@ -70,6 +127,7 @@ def store(self, run_time: float, result: str, bucket: str, s3_key: str): # Upload the CSV to S3 self.s3_client.put_object(Bucket=bucket, Key=s3_key, Body=csv_buffer.getvalue()) + ## Example subclass # class SampleTest(H5Test): # @timer_decorator diff --git a/h5tests/single-test.ipynb b/h5tests/single-test.ipynb index 1ea5439..ee4e966 100644 --- a/h5tests/single-test.ipynb +++ b/h5tests/single-test.ipynb @@ -2,21 +2,12 @@ "cells": [ { "cell_type": "code", - "execution_count": 73, + "execution_count": null, "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - } - ], + "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload \n", @@ -25,44 +16,41 @@ "import os\n", "current = os.path.abspath('..')\n", "sys.path.append(current)\n", - "from h5tests.xarray_arr_len import XarrayArrLen\n", + "from xarray_arr_mean import XarrayArrMean\n", "from helpers.links import S3Links" ] }, { "cell_type": "code", - "execution_count": 74, + "execution_count": null, "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", "metadata": { "tags": [] }, "outputs": [], "source": [ - "test = XarrayArrLen('kerchunk-repacked', store_results=False)" + "test = XarrayArrMean('atl03-midsize-original', store_results=False)" ] }, { "cell_type": "code", - "execution_count": 75, + "execution_count": null, "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", "metadata": { "tags": [] }, - "outputs": [ - { - "data": { - "text/plain": [ - "(338294671, 69.48884391784668)" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "test.run()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -81,7 +69,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/h5tests/xarray_arr_mean.py b/h5tests/xarray_arr_mean.py index 0c1fc92..0341210 100644 --- a/h5tests/xarray_arr_mean.py +++ b/h5tests/xarray_arr_mean.py @@ -1,31 +1,48 @@ -from .h5test import H5Test, timer_decorator import fsspec -import xarray as xr import numpy as np +import xarray as xr +from h5test import H5Test, timer_decorator + class XarrayArrMean(H5Test): def open_reference_ds(self, file): fs = fsspec.filesystem( - 'reference', - fo=file, - remote_protocol='s3', - remote_options=dict(anon=False), - skip_instance_cache=True + "reference", + fo=file, + remote_protocol="s3", + remote_options=dict(anon=False), + skip_instance_cache=True, + ) + return xr.open_dataset( + fs.get_mapper(""), engine="zarr", consolidated=False, group="gt1l/heights" ) - return xr.open_dataset(fs.get_mapper(""), engine='zarr', consolidated=False, group='gt1l/heights') @timer_decorator - def run(self): - group = '/gt1l/heights' - variable = 'h_ph' - if 'kerchunk' in self.data_format: + def run(self, io_params={}): + group = "/gt1l/heights" + variable = "h_ph" + + if "kerchunk" in self.data_format: datasets = [self.open_reference_ds(file) for file in self.files] h_ph_values = [] for dataset in datasets: - h_ph_values = np.append(h_ph_values, dataset['h_ph'].values) + h_ph_values = np.append(h_ph_values, dataset["h_ph"].values) return np.mean(h_ph_values) else: - s3_fileset = [self.s3_fs.open(file) for file in self.files] - xrds = xr.open_mfdataset(s3_fileset, group=group, combine='by_coords', engine='h5netcdf') - h_ph_values = xrds['h_ph'] + fsspec_params = {} + h5py_params = {} + if "fsspec_params" in io_params: + fsspec_params = io_params["fsspec_params"] + if "h5py_params" in io_params: + h5py_params = io_params["h5py_params"] + + s3_fileset = [self.s3_fs.open(file, **fsspec_params) for file in self.files] + xrds = xr.open_mfdataset( + s3_fileset, + group=group, + combine="by_coords", + engine="h5netcdf", + **h5py_params + ) + h_ph_values = xrds["h_ph"] return float(np.mean(h_ph_values).values) diff --git a/helpers/links-old.json b/helpers/links-old.json new file mode 100644 index 0000000..1f0b836 --- /dev/null +++ b/helpers/links-old.json @@ -0,0 +1,53 @@ +{ + "flatgeobuf": { + "ATL03_20181120182818_08110112_006_02.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20181120182818_08110112_006_02.fgb", + "ATL03_20190219140808_08110212_006_02.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20190219140808_08110212_006_02.fgb", + "ATL03_20200217204710_08110612_006_01.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20200217204710_08110612_006_01.fgb", + "ATL03_20211114142614_08111312_006_01.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20211114142614_08111312_006_01.fgb", + "ATL03_20230211164520_08111812_006_01.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20230211164520_08111812_006_01.fgb" + }, + "flatgeobuf_no_sindex": { + "ATL03_20181120182818_08110112_006_02_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20181120182818_08110112_006_02_no_sindex.fgb", + "ATL03_20190219140808_08110212_006_02_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20190219140808_08110212_006_02_no_sindex.fgb", + "ATL03_20200217204710_08110612_006_01_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20200217204710_08110612_006_01_no_sindex.fgb", + "ATL03_20211114142614_08111312_006_01_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20211114142614_08111312_006_01_no_sindex.fgb", + "ATL03_20230211164520_08111812_006_01_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20230211164520_08111812_006_01_no_sindex.fgb" + }, + "geoparquet": { + "ATL03_20181120182818_08110112_006_02.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20181120182818_08110112_006_02.h5.gpq", + "ATL03_20190219140808_08110212_006_02.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20190219140808_08110212_006_02.h5.gpq", + "ATL03_20200217204710_08110612_006_01.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20200217204710_08110612_006_01.h5.gpq", + "ATL03_20211114142614_08111312_006_01.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20211114142614_08111312_006_01.h5.gpq", + "ATL03_20230211164520_08111812_006_01.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20230211164520_08111812_006_01.h5.gpq", + "['ATL03_20200217204710_08110612_006_01.h5'].gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/['ATL03_20200217204710_08110612_006_01.h5'].gpq" + }, + + "h5repack": { + "ATL03_20181120182818_08110112_006_02_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20181120182818_08110112_006_02_repacked.h5", + "ATL03_20190219140808_08110212_006_02_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20190219140808_08110212_006_02_repacked.h5", + "ATL03_20200217204710_08110612_006_01_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20200217204710_08110612_006_01_repacked.h5", + "ATL03_20211114142614_08111312_006_01_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20211114142614_08111312_006_01_repacked.h5", + "ATL03_20230211164520_08111812_006_01_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20230211164520_08111812_006_01_repacked.h5" + }, + "kerchunk-original": { + "original_ATL03_20181120182818_08110112_006_02.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20181120182818_08110112_006_02.json", + "original_ATL03_20190219140808_08110212_006_02.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20190219140808_08110212_006_02.json", + "original_ATL03_20200217204710_08110612_006_01.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20200217204710_08110612_006_01.json", + "original_ATL03_20211114142614_08111312_006_01.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20211114142614_08111312_006_01.json", + "original_ATL03_20230211164520_08111812_006_01.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20230211164520_08111812_006_01.json" + }, + "kerchunk-repacked": { + "h5repack_ATL03_20181120182818_08110112_006_02_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20181120182818_08110112_006_02_repacked.json", + "h5repack_ATL03_20190219140808_08110212_006_02_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20190219140808_08110212_006_02_repacked.json", + "h5repack_ATL03_20200217204710_08110612_006_01_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20200217204710_08110612_006_01_repacked.json", + "h5repack_ATL03_20211114142614_08111312_006_01_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20211114142614_08111312_006_01_repacked.json", + "h5repack_ATL03_20230211164520_08111812_006_01_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20230211164520_08111812_006_01_repacked.json" + }, + "original": { + "ATL03_20181120182818_08110112_006_02.h5": "s3://nasa-cryo-permanent/h5cloud/original/ATL03_20181120182818_08110112_006_02.h5", + "ATL03_20190219140808_08110212_006_02.h5": "s3://nasa-cryo-permanent/h5cloud/original/ATL03_20190219140808_08110212_006_02.h5", + "ATL03_20200217204710_08110612_006_01.h5": "s3://nasa-cryo-permanent/h5cloud/original/ATL03_20200217204710_08110612_006_01.h5", + "ATL03_20211114142614_08111312_006_01.h5": "s3://nasa-cryo-permanent/h5cloud/original/ATL03_20211114142614_08111312_006_01.h5", + "ATL03_20230211164520_08111812_006_01.h5": "s3://nasa-cryo-permanent/h5cloud/original/ATL03_20230211164520_08111812_006_01.h5" + } +} \ No newline at end of file diff --git a/helpers/links.py b/helpers/links.py index 5590042..c56e285 100644 --- a/helpers/links.py +++ b/helpers/links.py @@ -4,7 +4,7 @@ import s3fs -S3LINK = "s3://nasa-cryo-scratch/h5cloud/" +S3LINK = "s3://nasa-cryo-permanent/h5cloud/" S3FILELINKS = Path("../helpers/s3filelinks.json") diff --git a/helpers/s3filelinks.json b/helpers/s3filelinks.json index 2a4ab87..2818b4b 100644 --- a/helpers/s3filelinks.json +++ b/helpers/s3filelinks.json @@ -1,52 +1,67 @@ { "flatgeobuf": { - "ATL03_20181120182818_08110112_006_02.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20181120182818_08110112_006_02.fgb", - "ATL03_20190219140808_08110212_006_02.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20190219140808_08110212_006_02.fgb", - "ATL03_20200217204710_08110612_006_01.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20200217204710_08110612_006_01.fgb", - "ATL03_20211114142614_08111312_006_01.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20211114142614_08111312_006_01.fgb", - "ATL03_20230211164520_08111812_006_01.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf/ATL03_20230211164520_08111812_006_01.fgb" + }, "flatgeobuf_no_sindex": { - "ATL03_20181120182818_08110112_006_02_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20181120182818_08110112_006_02_no_sindex.fgb", - "ATL03_20190219140808_08110212_006_02_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20190219140808_08110212_006_02_no_sindex.fgb", - "ATL03_20200217204710_08110612_006_01_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20200217204710_08110612_006_01_no_sindex.fgb", - "ATL03_20211114142614_08111312_006_01_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20211114142614_08111312_006_01_no_sindex.fgb", - "ATL03_20230211164520_08111812_006_01_no_sindex.fgb": "s3://nasa-cryo-scratch/h5cloud/flatgeobuf_no_sindex/ATL03_20230211164520_08111812_006_01_no_sindex.fgb" + }, "geoparquet": { - "ATL03_20181120182818_08110112_006_02.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20181120182818_08110112_006_02.h5.gpq", - "ATL03_20190219140808_08110212_006_02.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20190219140808_08110212_006_02.h5.gpq", - "ATL03_20200217204710_08110612_006_01.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20200217204710_08110612_006_01.h5.gpq", - "ATL03_20211114142614_08111312_006_01.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20211114142614_08111312_006_01.h5.gpq", - "ATL03_20230211164520_08111812_006_01.h5.gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/ATL03_20230211164520_08111812_006_01.h5.gpq", - "['ATL03_20200217204710_08110612_006_01.h5'].gpq": "s3://nasa-cryo-scratch/h5cloud/geoparquet/['ATL03_20200217204710_08110612_006_01.h5'].gpq" - }, - "h5repack": { - "ATL03_20181120182818_08110112_006_02_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20181120182818_08110112_006_02_repacked.h5", - "ATL03_20190219140808_08110212_006_02_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20190219140808_08110212_006_02_repacked.h5", - "ATL03_20200217204710_08110612_006_01_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20200217204710_08110612_006_01_repacked.h5", - "ATL03_20211114142614_08111312_006_01_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20211114142614_08111312_006_01_repacked.h5", - "ATL03_20230211164520_08111812_006_01_repacked.h5": "s3://nasa-cryo-scratch/h5cloud/h5repack/ATL03_20230211164520_08111812_006_01_repacked.h5" - }, - "kerchunk-original": { - "original_ATL03_20181120182818_08110112_006_02.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20181120182818_08110112_006_02.json", - "original_ATL03_20190219140808_08110212_006_02.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20190219140808_08110212_006_02.json", - "original_ATL03_20200217204710_08110612_006_01.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20200217204710_08110612_006_01.json", - "original_ATL03_20211114142614_08111312_006_01.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20211114142614_08111312_006_01.json", - "original_ATL03_20230211164520_08111812_006_01.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-original/original_ATL03_20230211164520_08111812_006_01.json" - }, - "kerchunk-repacked": { - "h5repack_ATL03_20181120182818_08110112_006_02_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20181120182818_08110112_006_02_repacked.json", - "h5repack_ATL03_20190219140808_08110212_006_02_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20190219140808_08110212_006_02_repacked.json", - "h5repack_ATL03_20200217204710_08110612_006_01_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20200217204710_08110612_006_01_repacked.json", - "h5repack_ATL03_20211114142614_08111312_006_01_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20211114142614_08111312_006_01_repacked.json", - "h5repack_ATL03_20230211164520_08111812_006_01_repacked.json": "s3://nasa-cryo-scratch/h5cloud/kerchunk-repacked/h5repack_ATL03_20230211164520_08111812_006_01_repacked.json" - }, - "original": { - "ATL03_20181120182818_08110112_006_02.h5": "s3://nasa-cryo-scratch/h5cloud/original/ATL03_20181120182818_08110112_006_02.h5", - "ATL03_20190219140808_08110212_006_02.h5": "s3://nasa-cryo-scratch/h5cloud/original/ATL03_20190219140808_08110212_006_02.h5", - "ATL03_20200217204710_08110612_006_01.h5": "s3://nasa-cryo-scratch/h5cloud/original/ATL03_20200217204710_08110612_006_01.h5", - "ATL03_20211114142614_08111312_006_01.h5": "s3://nasa-cryo-scratch/h5cloud/original/ATL03_20211114142614_08111312_006_01.h5", - "ATL03_20230211164520_08111812_006_01.h5": "s3://nasa-cryo-scratch/h5cloud/original/ATL03_20230211164520_08111812_006_01.h5" + + }, + "atl03-bigsize-original": { + "ATL03_20181120182818_08110112_006_02.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5", + "ATL03_20190219140808_08110212_006_02.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5", + "ATL03_20200217204710_08110612_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20200217204710_08110612_006_01.h5", + "ATL03_20211114142614_08111312_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20211114142614_08111312_006_01.h5", + "ATL03_20230211164520_08111812_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20230211164520_08111812_006_01.h5" + }, + "atl03-bigsize-h5repack": { + "ATL03_20181120182818_08110112_006_02_repacked.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5", + "ATL03_20190219140808_08110212_006_02_repacked.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5", + "ATL03_20200217204710_08110612_006_01_repacked.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20200217204710_08110612_006_01_repacked.h5", + "ATL03_20211114142614_08111312_006_01_repacked.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20211114142614_08111312_006_01_repacked.h5", + "ATL03_20230211164520_08111812_006_01_repacked.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20230211164520_08111812_006_01_repacked.h5" + }, + "atl03-kerchunk-bigsize-original": { + "atl03_ATL03_20190219140808_08110212_006_02.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20190219140808_08110212_006_02.json", + "atl03_ATL03_20230211164520_08111812_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20230211164520_08111812_006_01.json", + "atl03_ATL03_20200217204710_08110612_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20200217204710_08110612_006_01.json", + "atl03_ATL03_20181120182818_08110112_006_02.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json", + "atl03_ATL03_20211114142614_08111312_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20211114142614_08111312_006_01.json" + }, + "atl03-kerchunk-bigsize-repacked": { + "atl03_ATL03_20181120182818_08110112_006_02_repacked.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json", + "atl03_ATL03_20190219140808_08110212_006_02_repacked.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20190219140808_08110212_006_02_repacked.json", + "atl03_ATL03_20211114142614_08111312_006_01_repacked.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20211114142614_08111312_006_01_repacked.json", + "atl03_ATL03_20200217204710_08110612_006_01_repacked.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20200217204710_08110612_006_01_repacked.json", + "atl03_ATL03_20230211164520_08111812_006_01_repacked.json": "s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20230211164520_08111812_006_01_repacked.json" + }, + "atl03-midsize-original": { + "ATL03_20191225111315_13680501_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20191225111315_13680501_006_01.h5", + "ATL03_20200922221235_13680801_006_02.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20200922221235_13680801_006_02.h5", + "ATL03_20220620155150_13681501_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20220620155150_13681501_006_01.h5", + "ATL03_20220919113142_13681601_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20220919113142_13681601_006_01.h5", + "ATL03_20230618223036_13681901_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5" + }, + "atl03-midsize-h5repack":{ + "ATL03_20191225111315_13680501_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20191225111315_13680501_006_01.h5", + "ATL03_20200922221235_13680801_006_02.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20200922221235_13680801_006_02.h5", + "ATL03_20220620155150_13681501_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20220620155150_13681501_006_01.h5", + "ATL03_20220919113142_13681601_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20220919113142_13681601_006_01.h5", + "ATL03_20230618223036_13681901_006_01.h5": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5" + }, + "atl03-kerchunk-midsize-original": { + "atl03_ATL03_20220919113142_13681601_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/kerchunk/atl03_ATL03_20220919113142_13681601_006_01.json", + "atl03_ATL03_20191225111315_13680501_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/kerchunk/atl03_ATL03_20191225111315_13680501_006_01.json", + "atl03_ATL03_20220620155150_13681501_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/kerchunk/atl03_ATL03_20220620155150_13681501_006_01.json", + "atl03_ATL03_20200922221235_13680801_006_02.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/kerchunk/atl03_ATL03_20200922221235_13680801_006_02.json", + "atl03_ATL03_20230618223036_13681901_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/original/kerchunk/atl03_ATL03_20230618223036_13681901_006_01.json" + }, + "atl03-kerchunk-midsize-repacked": { + "atl03_ATL03_20220620155150_13681501_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/kerchunk/atl03_ATL03_20220620155150_13681501_006_01.json", + "atl03_ATL03_20191225111315_13680501_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/kerchunk/atl03_ATL03_20191225111315_13680501_006_01.json", + "atl03_ATL03_20220919113142_13681601_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/kerchunk/atl03_ATL03_20220919113142_13681601_006_01.json", + "atl03_ATL03_20200922221235_13680801_006_02.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/kerchunk/atl03_ATL03_20200922221235_13680801_006_02.json", + "atl03_ATL03_20230618223036_13681901_006_01.json": "s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/kerchunk/atl03_ATL03_20230618223036_13681901_006_01.json" } } \ No newline at end of file diff --git a/notebooks/logs-fsspec.ipynb b/notebooks/logs-fsspec.ipynb new file mode 100644 index 0000000..fa25aa4 --- /dev/null +++ b/notebooks/logs-fsspec.ipynb @@ -0,0 +1,568 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6c9b37e2-2daa-4283-a228-ea581498de0c", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## AB testing access time for ICESat-2 HDF5 files on the cloud.\n", + "\n", + "This notebook requires that we have 2 versions of the same file:\n", + " * Original A: The original file with no modifications on a S3 location.\n", + " * Test Case B: A modified version of the orignal file to test for metadata consolidation, rechunking and other strategies to speed up access to the data in the file.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3b78fb94-10ae-48cb-8e30-521b2c8b7822", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "xarray v2023.12.0\n", + "h5py v3.10.0\n", + "fsspec v2023.6.0\n" + ] + } + ], + "source": [ + "import xarray as xr\n", + "import h5py\n", + "import fsspec\n", + "import s3fs\n", + "import boto3\n", + "import logging\n", + "import re\n", + "import time\n", + "from datetime import datetime\n", + "import pandas as pd\n", + "import numpy as np\n", + "import os\n", + "\n", + "class RegexFilter(logging.Filter):\n", + " def __init__(self, regex_pattern):\n", + " super(RegexFilter, self).__init__()\n", + " self.regex_pattern = re.compile(regex_pattern)\n", + "\n", + " def filter(self, record):\n", + " # Apply the regex pattern to the log message\n", + " return not bool(self.regex_pattern.search(record.msg))\n", + "\n", + " \n", + "def timer_decorator(func):\n", + " \"\"\"\n", + " A decorator to measure the execution time of the wrapped function.\n", + " \"\"\"\n", + " def __setup_logging(self, tstamp):\n", + " log_filename = f\"logs/{self.data_format}-{tstamp}.log\"\n", + " logger = logging.getLogger(\"fsspec\")\n", + " logger.setLevel(logging.DEBUG)\n", + " self.regex_filter = RegexFilter(self.logs_regex)\n", + " # add regerx to root logger\n", + " logging.getLogger().addFilter(self.regex_filter )\n", + " self._file_handler = logging.FileHandler(log_filename)\n", + " self._file_handler.setLevel(logging.DEBUG)\n", + " # Add the handler to the root logger\n", + " logging.getLogger().addHandler(self._file_handler)\n", + " \n", + " def __turnoff_logging(self):\n", + " logging.getLogger().removeFilter(self.regex_filter)\n", + " logging.getLogger().removeHandler(self._file_handler)\n", + " self._file_handler.close()\n", + " \n", + " def wrapper(self, *args, **kwargs):\n", + " tstamp = datetime.now().strftime('%Y-%m-%d-%H%M%S')\n", + " if self.logs_regex:\n", + " __setup_logging(self, tstamp)\n", + " start_time = time.time()\n", + " result = func(self, *args, **kwargs)\n", + " end_time = time.time()\n", + " if self.logs_regex:\n", + " __turnoff_logging(self)\n", + " execution_time = end_time - start_time\n", + " # Call the store method here\n", + " if self.store_results:\n", + " results_key = f\"{tstamp}_{self.name}_{self.data_format}_results.csv\"\n", + " s3_key = f\"{self.results_directory}/{results_key}\"\n", + " self.store(run_time=execution_time, result=result, bucket=self.bucket, s3_key=s3_key)\n", + " return result, execution_time\n", + " return wrapper \n", + "\n", + "\n", + " \n", + "class H5Test:\n", + " def __init__(self,\n", + " data_format: str,\n", + " files=None,\n", + " store_results=True,\n", + " logs_regex=None):\n", + " self.name = self.__class__.__name__\n", + " self.data_format = data_format\n", + " self.logs_regex = logs_regex\n", + " if files:\n", + " self.files = files\n", + " else:\n", + " self.files = S3Links().get_links_by_format(data_format)\n", + " self.s3_client = boto3.client('s3') # Ensure AWS credentials are configured\n", + " self.s3_fs = s3fs.S3FileSystem(anon=False)\n", + " self.store_results = store_results\n", + " self.bucket = \"nasa-cryo-persistent\"\n", + " self.results_directory = \"h5cloud/benchmark_results\"\n", + " \n", + " \n", + "\n", + " @timer_decorator\n", + " def run(self, io_params):\n", + " raise NotImplementedError(\"The run method has not been implemented\")\n", + "\n", + " def store(self, run_time: float, result: str, bucket: str, s3_key: str):\n", + " \"\"\"\n", + " Store test results to an S3 bucket as a CSV file.\n", + "\n", + " :param run_time: The runtime of the test\n", + " :param result: The result of the test\n", + " :param bucket: The name of the S3 bucket where the CSV will be uploaded\n", + " :param s3_key: The S3 key (filename) where the CSV will be stored\n", + " \"\"\"\n", + " # Create a CSV in-memory\n", + " csv_buffer = StringIO()\n", + " csv_writer = csv.writer(csv_buffer)\n", + " csv_writer.writerow(['Name', 'Data Format', 'Run Time', 'Result']) # Headers\n", + " csv_writer.writerow([self.name, self.data_format, run_time, result])\n", + "\n", + " # Reset the buffer's position to the beginning\n", + " csv_buffer.seek(0)\n", + "\n", + " # Upload the CSV to S3\n", + " self.s3_client.put_object(Bucket=bucket, Key=s3_key, Body=csv_buffer.getvalue())\n", + "\n", + "for library in (xr, h5py, fsspec):\n", + " print(f'{library.__name__} v{library.__version__}')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d6ed86c7-a919-4532-b7d3-1ca3cf4e25d1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "class H5pyArrMean(H5Test):\n", + " \n", + " @timer_decorator\n", + " def run(self, io_params):\n", + " final_h5py_array = [] \n", + " # TODO: Do we need to make this configurable or consistent?\n", + " group = '/gt1l/heights'\n", + " variable = 'h_ph'\n", + " fsspec_params = io_params[\"fsspec_params\"]\n", + " h5py_params = io_params[\"h5py_params\"]\n", + " for file in self.files:\n", + " with self.s3_fs.open(file, mode=\"rb\", **fsspec_params) as fo:\n", + " with h5py.File(fo, **h5py_params) as f:\n", + " data = f[f\"{group}/{variable}\"][:]\n", + " final_h5py_array = np.insert(\n", + " final_h5py_array,\n", + " len(final_h5py_array),\n", + " data, axis=None\n", + " )\n", + " return np.mean(final_h5py_array)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7db7c600-d362-45c2-bb9f-3670de9ddf4d", + "metadata": {}, + "outputs": [], + "source": [ + "class H5pyROS3ArrMean(H5Test):\n", + " \"\"\"\n", + " This will only work for public buckets for now\n", + " \"\"\"\n", + " \n", + " @timer_decorator\n", + " def run(self, io_params):\n", + " final_h5py_array = [] \n", + " # TODO: Do we need to make this configurable or consistent?\n", + " group = '/gt1l/heights'\n", + " variable = 'h_ph'\n", + " h5py_params = io_params[\"h5py_params\"]\n", + " for file in self.files:\n", + " with h5py.File(file, driver=\"ros3\", **h5py_params) as f:\n", + " data = f[f\"{group}/{variable}\"][:]\n", + " final_h5py_array = np.insert(\n", + " final_h5py_array,\n", + " len(final_h5py_array),\n", + " data, axis=None\n", + " )\n", + " return np.mean(final_h5py_array)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "621f6014-fda5-40a4-be23-dcaed47b6fbd", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "class XarrayArrMean(H5Test):\n", + " def open_reference_ds(self, file):\n", + " fs = fsspec.filesystem(\n", + " 'reference', \n", + " fo=file, \n", + " remote_protocol='s3', \n", + " remote_options=dict(anon=False), \n", + " skip_instance_cache=True\n", + " )\n", + " return xr.open_dataset(fs.get_mapper(\"\"), engine='zarr', consolidated=False, group='gt1l/heights')\n", + "\n", + " @timer_decorator\n", + " def run(self, io_params):\n", + " group = '/gt1l/heights'\n", + " variable = 'h_ph'\n", + "\n", + " if 'kerchunk' in self.data_format: \n", + " datasets = [self.open_reference_ds(file) for file in self.files]\n", + " h_ph_values = []\n", + " for dataset in datasets:\n", + " h_ph_values = np.append(h_ph_values, dataset['h_ph'].values)\n", + " return np.mean(h_ph_values)\n", + " else:\n", + " if \"repacked\" in self.data_format:\n", + " fsspec_params = {\n", + " # \"skip_instance_cache\": True\n", + " \"cache_type\": \"first\",\n", + " \"block_size\": 16*1024*1024\n", + " }\n", + " h5py_params = {\n", + " \"driver_kwds\" :{\n", + " \"page_buf_size\": 32*1024*1024,\n", + " \"rdcc_nbytes\": 8*1024*1024\n", + " }\n", + " } \n", + " s3_fileset = [self.s3_fs.open(file, **fsspec_params) for file in self.files]\n", + " xrds = xr.open_mfdataset(s3_fileset, group=group, combine='by_coords', engine='h5netcdf', **h5py_params)\n", + " h_ph_values = xrds['h_ph']\n", + " return float(np.mean(h_ph_values).values)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "a6d4b6ce-10f1-4031-987d-fcfd43422ae6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "repacked_granules = [\n", + " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", + " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", + "]\n", + "test_cloud = H5pyArrMean('atl03-bigsize-repacked',\n", + " files=repacked_granules,\n", + " store_results=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "4dfe5ab6-2e88-46d3-bb19-d6ebcec2d341", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "\n", + "original_granules = [\n", + " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", + " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + "]\n", + "\n", + "logs_regex = r\"\\s*(read: \\d+ - \\d+)\"\n", + "\n", + "test_original = H5pyArrMean('atl03-bigsize-original',\n", + " files=original_granules,\n", + " store_results=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "40ef2c85-f4d2-4a03-9839-bc192dda0c02", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1032.9840463639412, 12.149354219436646)\n", + "(1032.9840463639412, 12.194729566574097)\n", + "(1032.9840463639412, 12.10885739326477)\n", + "(1032.9840463639412, 11.940461874008179)\n", + "(1032.9840463639412, 12.063915252685547)\n" + ] + } + ], + "source": [ + "# logger = logging.getLogger()\n", + "# logger.setLevel(logging.DEBUG)\n", + "io_params ={\n", + " \"fsspec_params\": {\n", + " \"skip_instance_cache\": True\n", + " # \"cache_type\": \"blockcache\",\n", + " # \"block_size\": 4*1024*1024\n", + " },\n", + " \"h5py_params\": {\n", + " # \"rdcc_nbytes\": 2*1024*1024 \n", + " }\n", + "}\n", + "for runs in range(5):\n", + " print(test_original.run(io_params))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb2f92bf-4b1f-4bfe-a037-8061bfa9b127", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1032.9840463639412, 34.1772985458374)\n", + "(1032.9840463639412, 30.96499228477478)\n", + "(1032.9840463639412, 31.00865602493286)\n", + "(1032.9840463639412, 31.207276821136475)\n" + ] + } + ], + "source": [ + "io_params ={\n", + " \"fsspec_params\": {\n", + " # \"skip_instance_cache\": True\n", + " # \"cache_type\": \"blockcache\",\n", + " # \"block_size\": 4*1024*1024\n", + " },\n", + " \"h5py_params\": {\n", + " # \"page_buf_size\": 32*1024*1024,\n", + " # \"rdcc_nbytes\": 2*1024*1024\n", + " }\n", + "}\n", + "for runs in range(5):\n", + " print(test_cloud.run(io_params))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "262a6b25-8b23-46bb-8301-8965aaf155d2", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Registered drivers: frozenset({'mpio', 'family', 'ros3', 'split', 'core', 'sec2', 'fileobj', 'direct', 'stdio'})\n" + ] + } + ], + "source": [ + "print(f'Registered drivers: {h5py.registered_drivers()}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02258a85-4951-48c2-a295-75a47c0e38c1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "df = pd.DataFrame.from_dict(benchmarks)\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "for name, group in df.groupby(['tool', 'dataset', 'format']):\n", + " tool, dataset, formated = name\n", + " x = f'{tool}, {dataset}, {formated}'\n", + " y = group['time'].mean()\n", + " ax.bar(f'{tool}, {dataset}, {formated}', group['time'].mean(), label=f'{tool}, {dataset}, {formated}', align='center')\n", + " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=8)\n", + "\n", + "# Set labels and title\n", + "ax.set_xlabel('Combination')\n", + "ax.set_ylabel('Time in Seconds')\n", + "ax.set_title('mean() on photon data for a single IS2 track, less is better')\n", + "\n", + "# Rotate x-axis labels for better readability\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "# # Show legend\n", + "# ax.legend()\n", + "\n", + "# Show the plot\n", + "with plt.xkcd():\n", + " # This figure will be in XKCD-style\n", + " fig1 = plt.figure()\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1d5d779b-5bc6-4208-ae26-05c5a473d9b9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64bcc5de-aae3-46aa-9474-1c90b9ff20a9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "df = pd.DataFrame.from_dict(benchmarks)\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "for name, group in df.groupby(['tool', 'dataset', 'format']):\n", + " tool, dataset, formated = name\n", + " x = f'{tool}, {dataset}, {formated}'\n", + " y = group['time'].mean()\n", + " ax.bar(f'{tool}, {dataset}, {formated}', group['time'].mean(), label=f'{tool}, {dataset}, {formated}', align='center')\n", + " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=8)\n", + "\n", + "# Set labels and title\n", + "ax.set_xlabel('Combination')\n", + "ax.set_ylabel('Time in Seconds')\n", + "ax.set_title('mean() on photon data for a single IS2 track, less is better')\n", + "\n", + "# Rotate x-axis labels for better readability\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "# # Show legend\n", + "# ax.legend()\n", + "\n", + "# Show the plot\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b2871e1-d700-4d22-b01f-5e5a9acd1006", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89aabece-d942-418c-b387-77ea2de1e561", + "metadata": {}, + "outputs": [], + "source": [ + "# def normalize_log(log_file):\n", + "# with open(log_file, 'r') as input_file:\n", + "# # Open the output file in write mode\n", + "# with open(f'{log_file.replace(\".log\", \"-ros-compatible.log\")}', 'w') as output_file:\n", + "# # Iterate through each line in the input file\n", + "# for line in input_file:\n", + "# # Strip leading and trailing whitespaces from the line\n", + "# stripped_line = line.strip()\n", + "\n", + "# # Write the stripped line to the output file\n", + "# output_file.write(stripped_line + '\\n') " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8411f4a8-22b4-424e-b817-0d31e7ac9e93", + "metadata": {}, + "outputs": [], + "source": [ + " # \"ATL08\": {\n", + " # \"links\": {\n", + " # \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl08/original/ATL08_20200404075919_01340707_006_03.h5\",\n", + " # \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl08/repacked/ATL08_20200404075919_01340707_006_03_repacked.h5\",\n", + " # },\n", + " # \"group\": \"/gt1l/signal_photons\",\n", + " # \"variable\": \"ph_h\",\n", + " # \"processing\": [\n", + " # \"h5repack -S PAGE -G 4000000\"\n", + " # ]\n", + " # },\n", + " # \"ATL03\": {\n", + " # \"links\": {\n", + " # \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\",\n", + " # \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\"\n", + " # },\n", + " # \"group\": \"/gt1l/heights\",\n", + " # \"variable\": \"h_ph\",\n", + " # \"processing\": [\n", + " # \"h5repack -S PAGE -G 4000000\"\n", + " # ]\n", + " # }," + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 5c0482717ecc5cd07f3332254100e34230cb8d97 Mon Sep 17 00:00:00 2001 From: betolink Date: Tue, 30 Jan 2024 14:41:51 -0600 Subject: [PATCH 02/11] testing with out of region access --- environment.yml | 21 + h5tests/h5test.py | 14 +- h5tests/single-test.ipynb | 54 +- h5tests/xarray_arr_mean.py | 11 +- helpers/links.py | 13 +- helpers/s3itslive.json | 50 ++ notebooks/cloud-optimized-hdf5.ipynb | 1062 ++++++++++++++++++++++++++ notebooks/fsspec-logs.ipynb | 2 +- notebooks/logs-fsspec.ipynb | 2 +- 9 files changed, 1201 insertions(+), 28 deletions(-) create mode 100644 helpers/s3itslive.json create mode 100644 notebooks/cloud-optimized-hdf5.ipynb diff --git a/environment.yml b/environment.yml index e69de29..05d9104 100644 --- a/environment.yml +++ b/environment.yml @@ -0,0 +1,21 @@ +name: h5cloud +channels: + - conda-forge +dependencies: + - jupyterlab + - matplotlib-base + - pandas + - numpy + - s3fs + - xarray + - fsspec + - dask + - distributed + - geopandas + - h5py>3.9 + - zarr + - kerchunk + - h5netcdf + - pip + - pip: + - h5coro diff --git a/h5tests/h5test.py b/h5tests/h5test.py index 60f7ac7..3be885b 100644 --- a/h5tests/h5test.py +++ b/h5tests/h5test.py @@ -82,7 +82,7 @@ def wrapper(self, *args, **kwargs): class H5Test: def __init__( - self, data_format: str, files=None, store_results=True, logs_regex=None + self, data_format: str, files=None, store_results=True, logs_regex=None, anon_access=False, source="cryocloud" ): self.name = self.__class__.__name__ self.data_format = data_format @@ -90,9 +90,13 @@ def __init__( if files: self.files = files else: - self.files = S3Links().get_links_by_format(data_format) - self.s3_client = boto3.client("s3") # Ensure AWS credentials are configured - self.s3_fs = s3fs.S3FileSystem(anon=False) + if source == "cryocloud": + links = "../helpers/s3filelinks.json" + else: + links = "../helpers/itslivelinks.json" + self.files = S3Links(links).get_links_by_format(data_format) + self.s3_fs = s3fs.S3FileSystem(anon=anon_access) + self.store_results = store_results self.bucket = "nasa-cryo-persistent" self.results_directory = "h5cloud/benchmark_results" @@ -115,6 +119,8 @@ def store(self, run_time: float, result: str, bucket: str, s3_key: str): :param bucket: The name of the S3 bucket where the CSV will be uploaded :param s3_key: The S3 key (filename) where the CSV will be stored """ + self.s3_client = boto3.client("s3") # Ensure AWS credentials are configured + # Create a CSV in-memory csv_buffer = StringIO() csv_writer = csv.writer(csv_buffer) diff --git a/h5tests/single-test.ipynb b/h5tests/single-test.ipynb index ee4e966..be39a69 100644 --- a/h5tests/single-test.ipynb +++ b/h5tests/single-test.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", "metadata": { "tags": [] @@ -16,20 +16,23 @@ "import os\n", "current = os.path.abspath('..')\n", "sys.path.append(current)\n", - "from xarray_arr_mean import XarrayArrMean\n", - "from helpers.links import S3Links" + "from xarray_arr_mean import XarrayArrMean" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", "metadata": { "tags": [] }, "outputs": [], "source": [ - "test = XarrayArrMean('atl03-midsize-original', store_results=False)" + "files = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + "]\n", + "test_original = XarrayArrMean('atl03-bigsize-original', files=files, store_results=False, anon_access=True)" ] }, { @@ -41,7 +44,12 @@ }, "outputs": [], "source": [ - "test.run()" + "# don't even try this out of region.... more than 30 minutes \n", + "io_params ={\n", + " \"fsspec_params\": {},\n", + " \"h5py_params\" : {}\n", + "}\n", + "test_original.run(io_params)" ] }, { @@ -50,7 +58,37 @@ "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "files = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", + "]\n", + "test_cloud = XarrayArrMean('atl03-bigsize-repacked', files=files, store_results=False, anon_access=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfd4e404-0412-4d2f-8eba-ca39a670e369", + "metadata": {}, + "outputs": [], + "source": [ + "io_params ={\n", + " \"fsspec_params\": {\n", + " # \"skip_instance_cache\": True\n", + " \"cache_type\": \"blockcache\",\n", + " \"block_size\": 8*1024*1024\n", + " },\n", + " \"h5py_params\" : {\n", + " \"driver_kwds\": {\n", + " \"page_buf_size\": 32*1024*1024,\n", + " \"rdcc_nbytes\": 8*1024*1024\n", + " }\n", + "\n", + " }\n", + "}\n", + "test_cloud.run(io_params)" + ] } ], "metadata": { @@ -69,7 +107,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.18" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/h5tests/xarray_arr_mean.py b/h5tests/xarray_arr_mean.py index 0341210..8bee141 100644 --- a/h5tests/xarray_arr_mean.py +++ b/h5tests/xarray_arr_mean.py @@ -35,14 +35,9 @@ def run(self, io_params={}): fsspec_params = io_params["fsspec_params"] if "h5py_params" in io_params: h5py_params = io_params["h5py_params"] + print(h5py_params) s3_fileset = [self.s3_fs.open(file, **fsspec_params) for file in self.files] - xrds = xr.open_mfdataset( - s3_fileset, - group=group, - combine="by_coords", - engine="h5netcdf", - **h5py_params - ) - h_ph_values = xrds["h_ph"] + xrds = xr.open_mfdataset(s3_fileset, group=group, combine='by_coords', engine='h5netcdf', **h5py_params) + h_ph_values = xrds['h_ph'] return float(np.mean(h_ph_values).values) diff --git a/helpers/links.py b/helpers/links.py index c56e285..e212ef0 100644 --- a/helpers/links.py +++ b/helpers/links.py @@ -5,7 +5,6 @@ import s3fs S3LINK = "s3://nasa-cryo-permanent/h5cloud/" -S3FILELINKS = Path("../helpers/s3filelinks.json") class S3Links: @@ -41,9 +40,11 @@ class S3Links: 'h5cloud/original/ATL03_20181120182818_08110112_006_02.h5' """ - def __init__(self): - self.json_file = S3FILELINKS - self.table = load_s3testfile(S3FILELINKS) + def __init__(self, file="../helpers/s3filelinks.json"): + self.S3FILELINKS = Path(file) + + self.json_file = self.S3FILELINKS + self.table = load_s3testfile(self.S3FILELINKS) self.formats = list(self.table.keys()) def get_links_by_format(self, file_format): @@ -86,9 +87,9 @@ def update_links(self, write_to_file=True): print("Differences between self.table and S3 buckets: updating self.table") self.table = filelinks self.formats = list(self.table.keys()) - response = input(f"Update {S3FILELINKS} (y or n)?") + response = input(f"Update {self.S3FILELINKS} (y or n)?") if response.lower() == "y": - print(f"Updating {S3FILELINKS}") + print(f"Updating {self.S3FILELINKS}") write_s3links(filelinks) diff --git a/helpers/s3itslive.json b/helpers/s3itslive.json new file mode 100644 index 0000000..4f0a16d --- /dev/null +++ b/helpers/s3itslive.json @@ -0,0 +1,50 @@ +{ + "flatgeobuf": { + + }, + "flatgeobuf_no_sindex": { + + }, + "geoparquet": { + + }, + "atl03-bigsize-original": { + "ATL03_20181120182818_08110112_006_02.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5", + "ATL03_20190219140808_08110212_006_02.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5", + "ATL03_20200217204710_08110612_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20200217204710_08110612_006_01.h5", + "ATL03_20211114142614_08111312_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20211114142614_08111312_006_01.h5", + "ATL03_20230211164520_08111812_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20230211164520_08111812_006_01.h5" + }, + "atl03-bigsize-h5repack": { + "ATL03_20181120182818_08110112_006_02_repacked.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5", + "ATL03_20190219140808_08110212_006_02_repacked.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5", + "ATL03_20200217204710_08110612_006_01_repacked.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20200217204710_08110612_006_01_repacked.h5", + "ATL03_20211114142614_08111312_006_01_repacked.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20211114142614_08111312_006_01_repacked.h5", + "ATL03_20230211164520_08111812_006_01_repacked.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20230211164520_08111812_006_01_repacked.h5" + }, + "atl03-kerchunk-bigsize-original": { + + }, + "atl03-kerchunk-bigsize-repacked": { + }, + "atl03-midsize-original": { + "ATL03_20191225111315_13680501_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20191225111315_13680501_006_01.h5", + "ATL03_20200922221235_13680801_006_02.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20200922221235_13680801_006_02.h5", + "ATL03_20220620155150_13681501_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20220620155150_13681501_006_01.h5", + "ATL03_20220919113142_13681601_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20220919113142_13681601_006_01.h5", + "ATL03_20230618223036_13681901_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5" + }, + "atl03-midsize-h5repack":{ + "ATL03_20191225111315_13680501_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/repacked/ATL03_20191225111315_13680501_006_01.h5", + "ATL03_20200922221235_13680801_006_02.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/repacked/ATL03_20200922221235_13680801_006_02.h5", + "ATL03_20220620155150_13681501_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/repacked/ATL03_20220620155150_13681501_006_01.h5", + "ATL03_20220919113142_13681601_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/repacked/ATL03_20220919113142_13681601_006_01.h5", + "ATL03_20230618223036_13681901_006_01.h5": "s3://its-live-data/cloud-experiments/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5" + }, + "atl03-kerchunk-midsize-original": { + + }, + "atl03-kerchunk-midsize-repacked": { + + } +} \ No newline at end of file diff --git a/notebooks/cloud-optimized-hdf5.ipynb b/notebooks/cloud-optimized-hdf5.ipynb new file mode 100644 index 0000000..98eaa91 --- /dev/null +++ b/notebooks/cloud-optimized-hdf5.ipynb @@ -0,0 +1,1062 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "11f9a9cb-c049-461e-8578-7090a644508e", + "metadata": {}, + "source": [ + "# Cloud Optimized HDF: or How I Learned to Stop Worrying and Love the Format\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "6332a484-8fd6-4448-827f-aa48e6322f8f", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "id": "2d37475f-42b0-4105-b34c-529f627d9066", + "metadata": {}, + "source": [ + "## The big ol list of \"ifs\"\n", + "\n", + "* We use the most recent versions of h5py, xarray and fsspec\n", + "* We create the HDF5 files with [cloud optimized flags](https://www.youtube.com/watch?v=rcS5vt-mKok)\n", + " * if the files are out there we can repack them, consolidating the metadata and perhaps incresing the chunk sizes\n", + "* We know how to \"tweak the nobs\" (or a fair understanding of what the I/O libraries are doing)." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "736bb5fb-c5cd-42bf-be4e-6b81ae6eb865", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "xarray v2024.1.1\n", + "h5py v3.10.0\n", + "s3fs v2023.12.2\n" + ] + } + ], + "source": [ + "import xarray as xr\n", + "import h5py\n", + "import s3fs\n", + "\n", + "fs = s3fs.S3FileSystem(anon=True)\n", + "\n", + "for library in (xr, h5py, s3fs):\n", + " print(f'{library.__name__} v{library.__version__}')" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "78d6697b-9f84-4edf-b426-fde27560bc68", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ETag': '\"237bbd5828745b9e1a1e0ba88486e43c-835\"',\n", + " 'LastModified': datetime.datetime(2024, 1, 29, 4, 48, 24, tzinfo=tzutc()),\n", + " 'size': 6997123664,\n", + " 'name': 'its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5',\n", + " 'type': 'file',\n", + " 'StorageClass': 'INTELLIGENT_TIERING',\n", + " 'VersionId': None,\n", + " 'ContentType': 'application/x-hdf5'}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# a \"big\" ATL03 file from the ICESat-2 mission\n", + "original_granule = \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\"\n", + "# the same \"big\" ATL03 file from the ICESat-2 mission, metadata consolidated in 8MB-size pages.\n", + "cloud_optimized = \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\"\n", + "\n", + "fs.info(original_granule)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "e94bb01e-a325-4ab3-8f6a-ac5799d14f02", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ETag': '\"08af0688f787f10eee1ccfb13f7eb66d-836\"',\n", + " 'LastModified': datetime.datetime(2024, 1, 29, 4, 52, 44, tzinfo=tzutc()),\n", + " 'size': 7008000000,\n", + " 'name': 'its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5',\n", + " 'type': 'file',\n", + " 'StorageClass': 'INTELLIGENT_TIERING',\n", + " 'VersionId': None,\n", + " 'ContentType': 'application/x-hdf5'}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fs.info(cloud_optimized)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec2bce8f-bcf4-4982-8556-d3a71209af74", + "metadata": {}, + "outputs": [], + "source": [ + "# don't even try this out of region (us-west-2) will take forever, forever >= 30 minutes\n", + "ds = xr.open_dataset(fs.open(original_granule),\n", + " group=\"/gt1l/heights\",\n", + " engine=\"h5netcdf\")\n", + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9b5701b-6a8b-41ac-a56a-34a4f42125e1", + "metadata": {}, + "outputs": [], + "source": [ + "# again... don't even try this out of region (us-west-2) will take forever, forever >= 30 minutes\n", + "ds = xr.open_dataset(fs.open(cloud_optimized),\n", + " group=\"/gt1l/heights\",\n", + " engine=\"h5netcdf\")\n", + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "0def8b43-7616-4e01-a502-3f44811ae47e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 4.16 s, sys: 3.04 s, total: 7.2 s\n", + "Wall time: 20.6 s\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset>\n",
+       "Dimensions:         (delta_time: 73765028, ds_surf_type: 5)\n",
+       "Coordinates:\n",
+       "  * delta_time      (delta_time) datetime64[ns] 2019-02-19T14:08:08.557345384...\n",
+       "    lat_ph          (delta_time) float64 ...\n",
+       "    lon_ph          (delta_time) float64 ...\n",
+       "Dimensions without coordinates: ds_surf_type\n",
+       "Data variables:\n",
+       "    dist_ph_across  (delta_time) float32 ...\n",
+       "    dist_ph_along   (delta_time) float32 ...\n",
+       "    h_ph            (delta_time) float32 ...\n",
+       "    pce_mframe_cnt  (delta_time) uint32 ...\n",
+       "    ph_id_channel   (delta_time) uint8 ...\n",
+       "    ph_id_count     (delta_time) uint8 ...\n",
+       "    ph_id_pulse     (delta_time) uint8 ...\n",
+       "    quality_ph      (delta_time) int8 ...\n",
+       "    signal_conf_ph  (delta_time, ds_surf_type) int8 ...\n",
+       "    weight_ph       (delta_time) uint8 ...\n",
+       "Attributes:\n",
+       "    Description:  Contains arrays of the parameters for each received photon.\n",
+       "    data_rate:    Data are stored at the photon detection rate.
" + ], + "text/plain": [ + "\n", + "Dimensions: (delta_time: 73765028, ds_surf_type: 5)\n", + "Coordinates:\n", + " * delta_time (delta_time) datetime64[ns] 2019-02-19T14:08:08.557345384...\n", + " lat_ph (delta_time) float64 ...\n", + " lon_ph (delta_time) float64 ...\n", + "Dimensions without coordinates: ds_surf_type\n", + "Data variables:\n", + " dist_ph_across (delta_time) float32 ...\n", + " dist_ph_along (delta_time) float32 ...\n", + " h_ph (delta_time) float32 ...\n", + " pce_mframe_cnt (delta_time) uint32 ...\n", + " ph_id_channel (delta_time) uint8 ...\n", + " ph_id_count (delta_time) uint8 ...\n", + " ph_id_pulse (delta_time) uint8 ...\n", + " quality_ph (delta_time) int8 ...\n", + " signal_conf_ph (delta_time, ds_surf_type) int8 ...\n", + " weight_ph (delta_time) uint8 ...\n", + "Attributes:\n", + " Description: Contains arrays of the parameters for each received photon.\n", + " data_rate: Data are stored at the photon detection rate." + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "\n", + "# this one is different! you can try this at home (cloud otpmized HDF5!)\n", + "\n", + "io_params ={\n", + " \"fsspec_params\": {\n", + " # \"skip_instance_cache\": True\n", + " \"cache_type\": \"blockcache\", # or \"first\" with enough space\n", + " \"block_size\": 8*1024*1024 # could be bigger\n", + " },\n", + " \"h5py_params\" : {\n", + " \"driver_kwds\": { # only recent versions of xarray and h5netcdf allow this correctly\n", + " \"page_buf_size\": 32*1024*1024, # this one only works in repacked files\n", + " \"rdcc_nbytes\": 8*1024*1024 # this one is to read the chunks \n", + " }\n", + "\n", + " }\n", + "}\n", + "ds = xr.open_dataset(fs.open(cloud_optimized, **io_params[\"fsspec_params\"]),\n", + " group=\"/gt1l/heights\",\n", + " engine=\"h5netcdf\",\n", + " **io_params[\"h5py_params\"])\n", + "ds" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "da959721-2f9d-4151-b361-6f9f38fa5b8c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 11 s, sys: 2.02 s, total: 13 s\n", + "Wall time: 1min 25s\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'h_ph' ()>\n",
+       "array(1031.6101, dtype=float32)
" + ], + "text/plain": [ + "\n", + "array(1031.6101, dtype=float32)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%time\n", + "\n", + "# takes about ~2 minutes\n", + "ds.h_ph.mean()" + ] + }, + { + "cell_type": "markdown", + "id": "35caf411-afe7-44f7-9264-5e7b892456d0", + "metadata": {}, + "source": [ + "
" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/fsspec-logs.ipynb b/notebooks/fsspec-logs.ipynb index 96bfe63..87d7f05 100644 --- a/notebooks/fsspec-logs.ipynb +++ b/notebooks/fsspec-logs.ipynb @@ -317,7 +317,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.1" } }, "nbformat": 4, diff --git a/notebooks/logs-fsspec.ipynb b/notebooks/logs-fsspec.ipynb index fa25aa4..768cf69 100644 --- a/notebooks/logs-fsspec.ipynb +++ b/notebooks/logs-fsspec.ipynb @@ -560,7 +560,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.18" + "version": "3.12.1" } }, "nbformat": 4, From 80b035356c2814b91326a2bca327b88375c5cb02 Mon Sep 17 00:00:00 2001 From: betolink Date: Mon, 5 Feb 2024 19:31:02 -0600 Subject: [PATCH 03/11] updating notebooks, portable can quickly test and visualize results by access pattern --- .gitignore | 4 + environment.yml | 2 + h5tests/h5py_arr_mean.py | 10 +- h5tests/h5test.py | 156 +++++--- h5tests/single-test.ipynb | 239 ++++++++++- h5tests/xarray_arr_mean.py | 33 +- notebooks/logs-fsspec.ipynb | 568 --------------------------- notebooks/portable-h5py-test.ipynb | 329 ++++++++++++++++ notebooks/portable-xarray-test.ipynb | 305 ++++++++++++++ 9 files changed, 995 insertions(+), 651 deletions(-) delete mode 100644 notebooks/logs-fsspec.ipynb create mode 100644 notebooks/portable-h5py-test.ipynb create mode 100644 notebooks/portable-xarray-test.ipynb diff --git a/.gitignore b/.gitignore index ee11d40..97e5249 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,7 @@ venv.bak/ *.hdf5 *.nc *.tif + +*.log +notebooks/logs +notebooks/results diff --git a/environment.yml b/environment.yml index 05d9104..0c9d76a 100644 --- a/environment.yml +++ b/environment.yml @@ -3,6 +3,8 @@ channels: - conda-forge dependencies: - jupyterlab + - boto3 + - tqdm - matplotlib-base - pandas - numpy diff --git a/h5tests/h5py_arr_mean.py b/h5tests/h5py_arr_mean.py index 1d5a01c..d49431f 100644 --- a/h5tests/h5py_arr_mean.py +++ b/h5tests/h5py_arr_mean.py @@ -1,16 +1,13 @@ import h5py import numpy as np -from .h5test import H5Test, timer_decorator +from h5test import H5Test, timer_decorator class H5pyArrMean(H5Test): @timer_decorator - def run(self, io_params={}): + def run(self, io_params={}, dataset="/gt1l/heights", variable="h_ph"): final_h5py_array = [] - # TODO: Do we need to make this configurable or consistent? - group = "/gt1l/heights" - variable = "h_ph" fsspec_params = {} h5py_params = {} if "fsspec_params" in io_params: @@ -19,8 +16,9 @@ def run(self, io_params={}): h5py_params = io_params["h5py_params"] for file in self.files: with self.s3_fs.open(file, mode="rb", **fsspec_params) as fo: + print("h5py params: ", h5py_params) with h5py.File(fo, **h5py_params) as f: - data = f[f"{group}/{variable}"][:] + data = f[f"{dataset}/{variable}"][:] final_h5py_array = np.insert( final_h5py_array, len(final_h5py_array), data, axis=None ) diff --git a/h5tests/h5test.py b/h5tests/h5test.py index 3be885b..e7310cc 100644 --- a/h5tests/h5test.py +++ b/h5tests/h5test.py @@ -13,15 +13,27 @@ current = os.path.abspath("..") sys.path.append(current) -from helpers.links import S3Links +import csv +import logging +import os +import pathlib +import re +import time +from datetime import datetime +from io import StringIO + +import boto3 +import fsspec +import h5py +import numpy as np +import pandas as pd +import s3fs +import xarray as xr +from tqdm import tqdm -class RegexFilter(logging.Filter): - """ - This class will filter a logstream based on a regex expression - The idea is to target a particular library as they usually have a consistent signature. - """ +class RegexFilter(logging.Filter): def __init__(self, regex_pattern): super(RegexFilter, self).__init__() self.regex_pattern = re.compile(regex_pattern) @@ -34,25 +46,45 @@ def filter(self, record): def timer_decorator(func): """ A decorator to measure the execution time of the wrapped function. - It also writes logs to local disk if a regex expression is used in the - subclass instance. """ + def fsspec_stats(log_file): + with open(log_file, "r") as input_file: + num_requests = 0 + total_requested_bytes = 0 + for line in input_file: + # Strip leading and trailing whitespaces from the line + + try: + read_range = line.split("read:")[1].split(" - ") + request_size = int(read_range[1]) - int(read_range[0]) + total_requested_bytes += request_size + num_requests += 1 + except Exception: + pass + stats = { + "total_reqs": num_requests, + "total_reqs_bytes": total_requested_bytes, + "avg_req_size": int(round(total_requested_bytes / num_requests, 2)), + } + return stats + def __setup_logging(self, tstamp): - log_filename = f"logs/{self.data_format}-{tstamp}.log" + pathlib.Path(f"./logs").mkdir(exist_ok=True) + self.log_filename = f"logs/{self.data_format}-{tstamp}.log" logger = logging.getLogger("fsspec") logger.setLevel(logging.DEBUG) self.regex_filter = RegexFilter(self.logs_regex) # add regerx to root logger - logging.getLogger().addFilter(self.regex_filter) - self._file_handler = logging.FileHandler(log_filename) + logging.getLogger("fsspec").addFilter(self.regex_filter) + self._file_handler = logging.FileHandler(self.log_filename) self._file_handler.setLevel(logging.DEBUG) # Add the handler to the root logger - logging.getLogger().addHandler(self._file_handler) + logging.getLogger("fsspec").addHandler(self._file_handler) def __turnoff_logging(self): - logging.getLogger().removeFilter(self.regex_filter) - logging.getLogger().removeHandler(self._file_handler) + logging.getLogger("fsspec").removeFilter(self.regex_filter) + logging.getLogger("fsspec").removeHandler(self._file_handler) self._file_handler.close() def wrapper(self, *args, **kwargs): @@ -66,72 +98,100 @@ def wrapper(self, *args, **kwargs): __turnoff_logging(self) execution_time = end_time - start_time # Call the store method here + self.io_stats = fsspec_stats(self.log_filename) if self.store_results: results_key = f"{tstamp}_{self.name}_{self.data_format}_results.csv" - s3_key = f"{self.results_directory}/{results_key}" - self.store( - run_time=execution_time, - result=result, - bucket=self.bucket, - s3_key=s3_key, - ) - return result, execution_time + self.store(run_time=execution_time, result=result, file_name=results_key) + return result, execution_time, self.log_filename, self.io_stats return wrapper class H5Test: def __init__( - self, data_format: str, files=None, store_results=True, logs_regex=None, anon_access=False, source="cryocloud" + self, + data_format: str, + files=[], + store_results=True, + logs_regex=r"\s*(read: \d+ - \d+)", ): self.name = self.__class__.__name__ + self.io_stats = {} + self.log_filename = "" self.data_format = data_format self.logs_regex = logs_regex - if files: + if len(files) > 0: self.files = files else: - if source == "cryocloud": - links = "../helpers/s3filelinks.json" - else: - links = "../helpers/itslivelinks.json" - self.files = S3Links(links).get_links_by_format(data_format) - self.s3_fs = s3fs.S3FileSystem(anon=anon_access) - + raise ValueError("We need at least 1 ATL03 granule URL hosted in S3") + self.store_results = store_results - self.bucket = "nasa-cryo-persistent" - self.results_directory = "h5cloud/benchmark_results" - @timer_decorator - def run(self, io_params={}): - """ - When implemented we can pass io_params as runtime tweaks to the underlying - libraries e.g. fsspec. - """ + if files[0].startswith("s3://nasa-cryo-persistent"): + self.s3_client = boto3.client("s3") # + self.annon_access = False + self.results_bucket = "s3://nasa-cryo-persistent/" + self.results_directory = "h5cloud/benchmark_results" + self.results_store_type = "S3" + else: + self.annon_access = True + self.results_path = "results" + pathlib.Path(f"./{self.results_path}").mkdir(exist_ok=True) + self.results_store_type = "Local" + self.s3_fs = s3fs.S3FileSystem(anon=self.annon_access) + + @timer_decorator + def run(self, io_params, dataset, variable): raise NotImplementedError("The run method has not been implemented") - def store(self, run_time: float, result: str, bucket: str, s3_key: str): + def store(self, run_time: float, result: str, file_name: str): """ Store test results to an S3 bucket as a CSV file. - :param run_time: The runtime of the test :param result: The result of the test - :param bucket: The name of the S3 bucket where the CSV will be uploaded - :param s3_key: The S3 key (filename) where the CSV will be stored + :param file_name: file to store the results """ - self.s3_client = boto3.client("s3") # Ensure AWS credentials are configured - # Create a CSV in-memory csv_buffer = StringIO() csv_writer = csv.writer(csv_buffer) - csv_writer.writerow(["Name", "Data Format", "Run Time", "Result"]) # Headers - csv_writer.writerow([self.name, self.data_format, run_time, result]) + csv_writer.writerow( + [ + "Name", + "Data Format", + "Run Time", + "Result", + "Access Log", + "Total Bytes Tranferred", + "Total Requests", + ] + ) # Headers + csv_writer.writerow( + [ + self.name, + self.data_format, + run_time, + result, + self.log_filename, + self.io_stats["total_reqs_bytes"], + self.io_stats["total_reqs"], + ] + ) # Reset the buffer's position to the beginning csv_buffer.seek(0) # Upload the CSV to S3 - self.s3_client.put_object(Bucket=bucket, Key=s3_key, Body=csv_buffer.getvalue()) + if self.results_store_type == "S3": + # assumes s3 can write to bucket + self.s3_client.put_object( + Bucket=self.results_bucket, + Key=f"{self.results_directory}/{file_name}", + Body=csv_buffer.getvalue(), + ) + else: + with open(f"{self.results_path}/{file_name}", "w", newline="") as csv_file: + csv_file.write(csv_buffer.getvalue()) ## Example subclass diff --git a/h5tests/single-test.ipynb b/h5tests/single-test.ipynb index be39a69..165aabc 100644 --- a/h5tests/single-test.ipynb +++ b/h5tests/single-test.ipynb @@ -2,12 +2,21 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 10, "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n" + ] + } + ], "source": [ "%load_ext autoreload\n", "%autoreload \n", @@ -16,12 +25,15 @@ "import os\n", "current = os.path.abspath('..')\n", "sys.path.append(current)\n", - "from xarray_arr_mean import XarrayArrMean" + "from xarray_arr_mean import XarrayArrMean\n", + "import pandas as pd\n", + "\n", + "benchmarks = []" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 11, "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", "metadata": { "tags": [] @@ -32,29 +44,62 @@ " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", "]\n", - "test_original = XarrayArrMean('atl03-bigsize-original', files=files, store_results=False, anon_access=True)" + "xarray_original = XarrayArrMean('atl03-bigsize-original', files=files, store_results=True)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'library': 'xarray',\n", + " 'format': 'cloud',\n", + " 'mean': 1032.984130859375,\n", + " 'time': 176.90762186050415,\n", + " 'total_requested_bytes': 720001152,\n", + " 'total_requests': 100,\n", + " 'avg_req_size': 7200011},\n", + " {'library': 'xarray',\n", + " 'format': 'original',\n", + " 'mean': 1032.984130859375,\n", + " 'time': 1456.8166418075562,\n", + " 'total_requested_bytes': 438520591,\n", + " 'total_requests': 26988,\n", + " 'avg_req_size': 16248}]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# don't even try this out of region.... more than 30 minutes \n", + "# don't even try this out of region...\n", + "# takes about ~10 minutes per granule out of region (6+ GB granules)\n", "io_params ={\n", " \"fsspec_params\": {},\n", " \"h5py_params\" : {}\n", "}\n", - "test_original.run(io_params)" + "results = xarray_original.run(io_params)\n", + "benchmarks.append({\"library\": \"xarray\",\n", + " \"format\": \"original\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", "metadata": {}, "outputs": [], @@ -63,16 +108,34 @@ " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", "]\n", - "test_cloud = XarrayArrMean('atl03-bigsize-repacked', files=files, store_results=False, anon_access=True)" + "xarray_cloud = XarrayArrMean('atl03-bigsize-repacked', files=files, store_results=True)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "dfd4e404-0412-4d2f-8eba-ca39a670e369", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'library': 'xarray',\n", + " 'format': 'cloud',\n", + " 'mean': 1032.984130859375,\n", + " 'time': 176.90762186050415,\n", + " 'total_requested_bytes': 720001152,\n", + " 'total_requests': 100,\n", + " 'avg_req_size': 7200011}]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ + "# takes about ~90 seconds per granule out of region\n", "io_params ={\n", " \"fsspec_params\": {\n", " # \"skip_instance_cache\": True\n", @@ -87,7 +150,155 @@ "\n", " }\n", "}\n", - "test_cloud.run(io_params)" + "\n", + "results = xarray_cloud.run(io_params)\n", + "\n", + "benchmarks.append({\"library\": \"xarray\",\n", + " \"format\": \"cloud\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "9d30d92b-4192-4da1-8b60-41cc94ca2db1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
libraryformatmeantimetotal_requested_bytestotal_requestsavg_req_size
0xarraycloud1032.984131176.9076227200011521007200011
1xarrayoriginal1032.9841311456.8166424385205912698816248
\n", + "
" + ], + "text/plain": [ + " library format mean time total_requested_bytes \\\n", + "0 xarray cloud 1032.984131 176.907622 720001152 \n", + "1 xarray original 1032.984131 1456.816642 438520591 \n", + "\n", + " total_requests avg_req_size \n", + "0 100 7200011 \n", + "1 26988 16248 " + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_dict(benchmarks)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "3ff4c22f-7f77-4c69-a84c-f13b0fbba1f2", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1sAAAJoCAYAAACQpfuyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACZ+UlEQVR4nOzdeZyN5f/H8feZObObOcyMmTGMXfYtIlTImi1JKiXKl8qWUkqrNkqSikLJLiL5KUvIUkJZExXJHmMsYzaznnP9/pjm5DRjzGhOY3g9H4/z4Nz3dd/35z5nlvOe67qv22KMMQIAAAAAFCiPwi4AAAAAAK5GhC0AAAAAcAPCFgAAAAC4AWELAAAAANyAsAUAAAAAbkDYAgAAAAA3IGwBAAAAgBsQtgAAAADADQhbAAAAAOAGhC0ABe67776Tj4+PDh8+7Fx2yy23aOjQoYVX1L/Up08fFStWrED3OWrUKC1evLhA91kQRo4cKYvFclnbzp07V+PHjy/Ygv7y/vvvq3LlyvL29pbFYtG5c+fcchzkrlu3brJYLBo0aJBz2aFDh2SxWPL0OHTokNatWyeLxaKFCxde8njz5s1TvXr15Ovrq8jISA0dOlSJiYkubXbu3KmOHTuqbNmy8vPzU3BwsJo0aaLZs2df9nlmndP06dMvex/uMH36dOfr+G+1aNFCtWrV+vdFXeCDDz7I8TU7fvy4Ro4cqZ07dxbo8YArHWELQIEyxmjo0KHq16+fypUr51z+6quv6oMPPtDevXsLsbory5Uatv4Nd4WtnTt3asiQIWrZsqXWrFmjTZs2KTAwsMCPg9zFxMToq6++kiTNmTNHKSkpkqRSpUpp06ZNLo/69eurYsWK2ZaXKlUqz8ebM2eO7r33Xt1www1avny5XnrpJU2fPl3dunVzaXfu3DlFRUVp1KhRWrZsmWbOnKny5curV69eeu211wruBbgCdOzYMd+v438pt7D18ssvE7ZwzbEWdgEAri4rVqzQ9u3bNXfuXJflzZs3V9WqVfX2229rypQphVQdiqo9e/ZIkvr166dGjRoVyD7Pnz8vf39/t7W/Gs2cOVPp6enq2LGjli5dqkWLFqlnz57y8fHRjTfe6NI2KChIaWlp2Zbnld1u11NPPaW2bdvqo48+kiS1bNlSgYGBuu+++7R8+XLddtttkjJ7aFq0aOGyfadOnXTw4EFNmTJFzz///GXVcCUqWbKkSpYsWdhlXDGSk5Pl6+t72b3xgLvRswVcYbKGcO3atUt33XWXbDabgoOD9cQTTygjI0N79+5V+/btFRgYqPLly2vMmDHZ9hEfH68nn3xSFSpUkLe3t0qXLq2hQ4cqKSnJpd3EiRN1yy23KCwsTAEBAapdu7bGjBmj9PR0l3ZZQ022bNmim2++Wf7+/qpYsaLeeOMNORwOl7YffvihbrjhBlWtWjVbXb169dLcuXOVkJBwydfh7NmzGjBggEqXLi1vb29VrFhRzz33nFJTU13aZQ1nmjVrlqpXry5/f3/VrVvX+df33GQNZZo9e7aeeOIJRUREyM/PT82bN9eOHTty3Gb//v3q0KGDihUrpqioKA0bNixbTXmp3WKxKCkpSTNmzHAOr7rww+Lu3bt1++23q0SJEvL19VW9evU0Y8aMHOv/9NNP9dxzzykyMlJBQUFq3bp1nnsQly5dqnr16snHx0cVKlTQ2LFjc2yXl6+VFi1aaOnSpTp8+LDLsLEsL7/8sho3bqzg4GAFBQXp+uuv19SpU2WMybXGFi1a6P7775ckNW7cWBaLRX369HGu/+STT1S3bl35+voqODhYd9xxh3799VeXfWQNA/3555/Vtm1bBQYGqlWrVhc9Ztb34fbt29W9e3eVKFFClSpVctbzzw/2WccoX76883nWMLSxY8dq3LhxqlChgooVK6YmTZpo8+bNLtseOHBA99xzjyIjI+Xj46Pw8HC1atUqT70AS5YsUZMmTeTv76/AwEC1adNGmzZtyvF89uzZo3vvvVc2m03h4eF66KGHFBcXd8ljZPnkk08UHh6uGTNmyM/PT5988kmet82vzZs368SJE3rwwQddlt91110qVqyYvvjii0vuIzQ0VFZrwf5d+ffff1fPnj0VFhYmHx8fVa9eXRMnTnRp43A49Nprr6lq1ary8/NT8eLFVadOHb377rvONqdOnVL//v0VFRUlHx8flSxZUs2aNdPq1atzPX5Owwh37NihTp06OWuKjIxUx44ddezYsTyd03fffacbb7xRfn5+Kl26tF544QXZ7XaXNmlpaXrttddUrVo1Z70PPvigTp065WxTvnx57dmzR+vXr3d+/5cvX17r1q3TDTfcIEl68MEHnetGjhzp3Hbr1q3q0qWLgoOD5evrq/r16+uzzz7L8dxXrlyphx56SCVLlpS/v3+2n8HAFcUAuKK89NJLRpKpWrWqefXVV82qVavM8OHDjSQzaNAgU61aNfPee++ZVatWmQcffNBIMp9//rlz+6SkJFOvXj0TGhpqxo0bZ1avXm3effddY7PZzK233mocDoez7eOPP24+/PBDs2LFCrNmzRrzzjvvmNDQUPPggw+61NS8eXMTEhJiqlSpYiZNmmRWrVplBgwYYCSZGTNmONulpqYaPz8/M3z48BzP7YcffjCSzJIlS3J9DZKTk02dOnVMQECAGTt2rFm5cqV54YUXjNVqNR06dHBpK8mUL1/eNGrUyHz22Wdm2bJlpkWLFsZqtZo//vgj1+OsXbvWSDJRUVHm9ttvN19++aWZPXu2qVy5sgkKCnLZvnfv3sbb29tUr17djB071qxevdq8+OKLxmKxmJdffjnftW/atMn4+fmZDh06mE2bNplNmzaZPXv2GGOM+e2330xgYKCpVKmSmTlzplm6dKm59957jSTz5ptvZqu/fPny5r777jNLly41n376qSlbtqypUqWKycjIyPX8V69ebTw9Pc1NN91kFi1aZBYsWGBuuOEGU7ZsWfPPXw95+VrZs2ePadasmYmIiHCe06ZNm5zr+/TpY6ZOnWpWrVplVq1aZV599VXj5+fn8vrlZM+ePeb55583ksy0adPMpk2bzP79+40xxowaNcpIMvfee69ZunSpmTlzpqlYsaKx2Wxm3759Lu+fl5eXKV++vBk9erT55ptvzNdff33RY2Z9H5YrV848/fTTZtWqVWbx4sXGmMzvh+bNm2fbpnfv3qZcuXLO5wcPHnS+P+3btzeLFy82ixcvNrVr1zYlSpQw586dc7atWrWqqVy5spk1a5ZZv369+fzzz82wYcPM2rVrc31t5syZYySZtm3bmsWLF5v58+ebBg0aGG9vb/Pdd99lO5+qVauaF1980axatcqMGzfO+Pj4ZPt+v5jvv//eSDJPPfWUMcaY+++/31gsFnPgwIEc2zdv3tzUrFkzx3VZX7sLFiy46PEmTZpkJDm/Ly7UsGFD06RJk2zL7Xa7SU9PNzExMWbixInGarWaSZMm5eX0ssl6/6ZNm+ZctmfPHmOz2Uzt2rXNzJkzzcqVK82wYcOMh4eHGTlypLPd6NGjjaenp3nppZfMN998Y1asWGHGjx/v0qZdu3amZMmSZsqUKWbdunVm8eLF5sUXXzTz5s3Lta5p06YZSebgwYPGGGMSExNNSEiIadiwofnss8/M+vXrzfz5880jjzxifvnll1z3lfWzPTIy0rz33nvm66+/NkOGDDGSzMCBA53t7Ha7ad++vQkICDAvv/yyWbVqlfn4449N6dKlTY0aNcz58+eNMcZs377dVKxY0dSvX9/5/b99+3YTFxfnrPv55593rjt69Kgxxpg1a9YYb29vc/PNN5v58+ebFStWmD59+mR7/bP2Ubp0adO/f3+zfPlys3Dhwkv+rAMKE2ELuMJkfSh6++23XZbXq1fPSDKLFi1yLktPTzclS5Y03bp1cy4bPXq08fDwMFu2bHHZfuHChUaSWbZsWY7HzfqQMnPmTOPp6WnOnj3rXNe8eXMjyfzwww8u29SoUcO0a9fO+TwrTF3sw0JaWpqxWCzm6aefzvU1yPqQ9dlnn7ksf/PNN40ks3LlSucySSY8PNzEx8c7l0VHRxsPDw8zevToXI+T9YHv+uuvdwmhhw4dMl5eXuZ///ufc1nv3r1zrKlDhw6matWql1V7QECA6d27d7a67rnnHuPj42OOHDnisvy2224z/v7+zg/pWfX/M4B+9tlnRpJL0MlJ48aNTWRkpElOTnYui4+PN8HBwdnC1oVy+1rp2LGjS+C41D5eeeUVExIS4vL65yTrQ9aFX9exsbHOwHqhI0eOGB8fH9OzZ0/nsqz375NPPrlkbcb8/X344osvZluX37BVu3Ztlw+DP/74o5FkPv30U2OMMadPnzaSzPjx4/NUWxa73W4iIyNN7dq1jd1udy5PSEgwYWFhpmnTptnOZ8yYMS77GDBggPH19b3k62+MMQ899JCRZH799VdjzN9ffy+88EKO7f9t2Hr99deNJHPixIls69q2bWuuu+66bMsffvhhI8lIMt7e3uaDDz645HldTE5hq127dqZMmTImLi7Ope2gQYOMr6+v83uhU6dOpl69ernuv1ixYmbo0KH5ruufYWvr1q1GkvOPAfmR9bP9//7v/1yW9+vXz3h4eJjDhw8bY4z59NNPs/1hzxhjtmzZYiS5vM41a9bM8fsjq+2Fr2eWatWqmfr165v09HSX5Z06dTKlSpVyfn1nnfsDDzyQ73MFCgvDCIErVKdOnVyeV69eXRaLxXmNgiRZrVZVrlzZZda/r776SrVq1VK9evWUkZHhfLRr104Wi0Xr1q1ztt2xY4e6dOmikJAQeXp6ysvLSw888IDsdrv27dvncvyIiIhs18rUqVPH5djHjx+XJIWFheV4Tl5eXipevLj+/PPPXM99zZo1CggIUPfu3V2WZw0d++abb1yWZ13HkSU8PFxhYWEuteWmZ8+eLsPdypUrp6ZNm2rt2rUu7SwWizp37uyy7J+vQX5rz8maNWvUqlUrRUVFZdvH+fPnsw0R69KlS7aaJOV6/klJSdqyZYu6desmX19f5/LAwMBs5yjl72slt/Nq3bq1bDabcx8vvviizpw5o5iYmDzt40KbNm1ScnKyy5BCSYqKitKtt96a42t955135usY+W2fk44dO8rT09P5/J/vT3BwsCpVqqS33npL48aN044dO7INz83J3r17dfz4cfXq1UseHn//Oi9WrJjuvPNObd68WefPn3fZJqevlZSUlEu+/omJifrss8/UtGlTVatWTVLmdZiVKlXS9OnT81Tv5brYtTg5LX/22We1ZcsWLV26VA899JAGDRp00aGx+ZWSkqJvvvlGd9xxh/z9/V1+vnbo0EEpKSnO4aGNGjXSTz/9pAEDBujrr79WfHx8tv01atRI06dP12uvvabNmzdnG76dV5UrV1aJEiX09NNPa9KkSfrll1/ytX1gYGC2r4uePXvK4XDo22+/lZT5e6V48eLq3Lmzy3nXq1dPERERLr9X8mv//v367bffdN9990lSttf1xIkT2YZFF8T3JfBfIWwBV6jg4GCX597e3vL393f5YJy1PGtGMEk6efKkdu3aJS8vL5dHYGCgjDE6ffq0JOnIkSO6+eab9eeff+rdd9/Vd999py1btjivPUhOTnY5TkhISLYafXx8XNpl/f+fNV7I19c3277/6cyZM4qIiMj2YSosLExWq1VnzpzJd225iYiIyHHZP4+T0+vv4+Pj8vrnt/acnDlzJseZxiIjI53rL/TP8/fx8ZGU/T28UGxsrBwOx0XP/UL5/VrJyY8//qi2bdtKkj766CN9//332rJli5577rk87+Ofsl6Hi71WOb1/QUFB+TpGQcz4dqn3x2Kx6JtvvlG7du00ZswYXX/99SpZsqSGDBmS6/WNlzp/h8Oh2NjYfNVyMfPnz1diYqJ69Oihc+fO6dy5c4qLi1OPHj109OhRrVq1KtftL0dWrTl9z5w9ezbbz0hJKlu2rBo2bKgOHTroww8/VP/+/TVixAiX64ou15kzZ5SRkaH3338/28/XDh06SJLz5+uIESM0duxYbd68WbfddptCQkLUqlUrbd261bm/+fPnq3fv3vr444/VpEkTBQcH64EHHlB0dHS+6rLZbFq/fr3q1aunZ599VjVr1lRkZKReeumlPAW48PDwbMuyfgZkvfYnT57UuXPn5O3tne3co6Ojned9OU6ePClJevLJJ7Pte8CAAZKUbf9X6kyMQE6YjRC4yoSGhuZ64XpoaKgkafHixUpKStKiRYtcpmj/N9PyZu377NmzF20TGxvrbHcxISEh+uGHH2SMcQktMTExysjIuOT2+ZXTh5vo6OgcQ9ylFETtISEhOnHiRLblWT2HBXH+JUqUkMViuei5X6ggvlbmzZsnLy8vffXVVy6B9d9MfZ/1/lzstfrn63Q5s5XltI2vr2+Ok0r8mw+c5cqV09SpUyVJ+/bt02effaaRI0cqLS1NkyZNynGbS52/h4eHSpQocdk1XSirtqFDh+Z4v7ypU6eqXbt2BXKsLLVr15Yk/fzzz6pRo4ZzeUZGhn777Tfde++9l9xHo0aNNGnSJB04cOBfz+BXokQJeXp6qlevXho4cGCObSpUqCApc9TBE088oSeeeELnzp3T6tWr9eyzz6pdu3Y6evSo/P39FRoaqvHjx2v8+PE6cuSIlixZomeeeUYxMTFasWJFvmqrXbu25s2bJ2OMdu3apenTp+uVV16Rn5+fnnnmmVy3zQo7F8r6GZD1NRYaGqqQkJCL1vVvbsOQ9X06YsSIbFP6Z/nnhEvMPIiihJ4t4CrTqVMn/fHHHwoJCVHDhg2zPbJmS8v6ZZX1l20p8x5ZWVMsX47q1atLkv74448c1x8/flwpKSkuH5xy0qpVKyUmJmb7ID5z5kzn+oL06aefusyId/jwYW3cuDHHGecuJT+1X6z3rVWrVlqzZo0zXF24D39//8ueSvtCAQEBatSokRYtWuTSM5eQkKAvv/zSpW1+vlYudk4Wi0VWq9VlOF1ycrJmzZp12efQpEkT+fn5Zbtx7bFjx5xDMd2hfPny2rdvn8sMaGfOnNHGjRsLZP/XXXednn/+edWuXVvbt2+/aLuqVauqdOnSmjt3rsvXb1JSkj7//HPnDIX/1q+//qpNmzbpzjvv1Nq1a7M9WrVqpf/7v//LU69tfjRu3FilSpXKds+mhQsXKjEx8aIfzC+0du1aeXh4qGLFiv+6Hn9/f7Vs2VI7duxQnTp1cvz5mtMfaIoXL67u3btr4MCBOnv2bI43Iy5btqwGDRqkNm3a5PqeX4rFYlHdunX1zjvvqHjx4nnaV0JCgpYsWeKybO7cufLw8NAtt9wiKfP3ypkzZ2S323M87wvD0MV+BlysF7Vq1aqqUqWKfvrppxz33bBhQ+6phyKNni3gKjN06FB9/vnnuuWWW/T444+rTp06cjgcOnLkiFauXKlhw4apcePGatOmjby9vXXvvfdq+PDhSklJ0Ycffpht2FF+lClTRhUrVtTmzZs1ZMiQbOuzrmdo2bJlrvt54IEHNHHiRPXu3VuHDh1S7dq1tWHDBo0aNUodOnRQ69atL7vGnMTExOiOO+5Qv379FBcXp5deekm+vr4aMWJEvveVn9pr166tdevW6csvv1SpUqUUGBioqlWr6qWXXtJXX32lli1b6sUXX1RwcLDmzJmjpUuXasyYMbLZbAVy3q+++qrat2+vNm3aaNiwYbLb7XrzzTcVEBDg0juZn6+V2rVra9GiRfrwww/VoEEDeXh4qGHDhurYsaPGjRunnj17qn///jpz5ozGjh3rEuDyq3jx4nrhhRf07LPP6oEHHtC9996rM2fO6OWXX5avr69eeumly953bnr16qXJkyfr/vvvV79+/XTmzBmNGTMm30MUs+zatUuDBg3SXXfdpSpVqsjb21tr1qzRrl27cu2V8PDw0JgxY3TfffepU6dOevjhh5Wamqq33npL586d0xtvvHG5p+giq1dr+PDhOd7jLCEhQd98841mz56txx57LF/7/ucU+FmaN2+ukiVLasyYMerVq5cefvhh3Xvvvfr99981fPhwtWnTRu3bt3e279+/v4KCgtSoUSOFh4fr9OnTWrBggebPn6+nnnrKpVdr+vTpevDBBzVt2rRs1/tdyrvvvqubbrpJN998sx599FGVL19eCQkJ2r9/v7788kutWbNGktS5c2fVqlVLDRs2VMmSJXX48GGNHz9e5cqVU5UqVRQXF6eWLVuqZ8+eqlatmgIDA7VlyxatWLEiTyHyQl999ZU++OADde3aVRUrVpQxRosWLdK5c+fUpk2bS24fEhKiRx99VEeOHNF1112nZcuW6aOPPtKjjz6qsmXLSpLuuecezZkz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Xq5cOf35558FVhgAAAAAFGX57tlyOByy2+3Zlh87dkyBgYEFUhQAAAAAFHX5Dltt2rTR+PHjnc8tFosSExP10ksvqUOHDgVZGwAAAAAUWfkeRvjOO++oZcuWqlGjhlJSUtSzZ0/9/vvvCg0N1aeffuqOGgEAAACgyMl32IqMjNTOnTv16aefavv27XI4HOrbt6/uu+8+lwkzAAAAAOBalu+wJUl+fn566KGH9NBDDxV0PQAAAABwVbissPXnn3/q+++/V0xMjBwOh8u6IUOGFEhhAAAAAFCU5TtsTZs2TY888oi8vb0VEhIii8XiXGexWAhbAAAAAKDLCFsvvviiXnzxRY0YMUIeHvmezBAAAAAArgn5Tkvnz5/XPffcQ9ACAAAAgFzkOzH17dtXCxYscEctAAAAAHDVyPcwwtGjR6tTp05asWKFateuLS8vL5f148aNK7DiAAAAAKCoynfYGjVqlL7++mtVrVpVkrJNkAEAAAAAuIywNW7cOH3yySfq06ePG8oBAAAAgKtDvq/Z8vHxUbNmzdxRCwAAAABcNfIdth577DG9//777qgFAAAAAK4a+R5G+OOPP2rNmjX66quvVLNmzWwTZCxatKjAigMAAACAoirfYat48eLq1q2bO2oBAAAAgKtGvsPWtGnT3FEHAAAAAFxV8n3N1n/tzz//1P3336+QkBD5+/urXr162rZtm3O9MUYjR45UZGSk/Pz81KJFC+3Zs8dlH6mpqRo8eLBCQ0MVEBCgLl266NixY//1qQAAAAC4huSpZ+v666/XN998oxIlSqh+/fq53k9r+/btBVZcbGysmjVrppYtW2r58uUKCwvTH3/8oeLFizvbjBkzRuPGjdP06dN13XXX6bXXXlObNm20d+9eBQYGSpKGDh2qL7/8UvPmzVNISIiGDRumTp06adu2bfL09CywegEAAAAgS57C1u233y4fHx9JUteuXd1Zj4s333xTUVFRLkMXy5cv7/y/MUbjx4/Xc88957yObMaMGQoPD9fcuXP18MMPKy4uTlOnTtWsWbPUunVrSdLs2bMVFRWl1atXq127dv/Z+QAAAAC4dliMMSYvDR966CG9++67zt6i/0KNGjXUrl07HTt2TOvXr1fp0qU1YMAA9evXT5J04MABVapUSdu3b1f9+vWd291+++0qXry4ZsyYoTVr1qhVq1Y6e/as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stlscjgcqlevngYPHqwmTZooIyNDQ4YM0fbt29WmTRs999xz8vX1LeTqgaKDYYTANSJrqEj9+vUVEhKiTz/91LnO09NT9evXV5UqVbRq1SoNHjy4sMoEAPwHsoLW22+/rTlz5mjevHnavXu37rjjDn355ZcaOXKkvv32W1mtVr333nuqUKGCTpw4IR8fn0KuHChaCFvANWD06NF69913lZKSIm9vb3Xu3FkrV67UzJkznW28vLxUq1Ytbdy4UdOmTSvEagEA/4WYmBht3LhRr7zyipo1a6avvvpKEydO1P33369Tp07plVde0aZNm2S1WjV79mxNmTKF63qBfCJsAdeA+Ph4DRs2TNOnT5eXl5eGDRumsLAwvfvuu+rVq5cmTZqk22+/XUePHlWjRo3k4eEhu91e2GUDANwoLCxMw4cPV/v27bVz504NHDhQr732mj788EPdeeed2rx5swYPHqytW7fK09NTHh4ecjgcXM8L5IO1sAsAULAuvOA5y+jRoxUYGKiBAwfKbrdr4MCBeuedd7Ro0SLNnDlT+/fvV2hoqBYtWuT8ZZo1KxUAoOjL6XeDJF1//fXy8vLSjBkzVKdOHfXr10+SFBwcrBtvvFE333yzrr/+emf7nPYB4OIIW8BVJusX4f79+1W5cmXn8meffVYOh0NDhgyRxWLRgAEDNHjwYA0ePFgJCQkKDAyUJGVkZMhq5UcDAFwtjDHO3w1Tp07VsWPH5OnpqREjRsjLy0uSlJqaqmPHjunQoUOqWrWqVq5cqS5dumjw4MGyWCwXDWsAcsd3DXAVWr58ua677jp9+eWXLsuff/55PfPMM3ryySc1ffp0JSYmSpIzaBljCFoAcBW5cNbB5557To8//rg2bdqkt956S7fccov27t0rSWrYsKG8vLzUuXNn1axZU3v37tWAAQOc12gRtIDLw9TvwFXqf//7nxYuXKjZs2erU6dOzl+4P//8sxo3bqyUlBQtWrRIXbt2LexSAQBudvLkSfXv318jR45U7dq1debMGd16663y8fHRZ599psqVK2vZsmXat2+fkpKS9PTTT8tqtcputzOsHPgXCFtAEZfb0I7//e9/mjdvnubNm6dOnTpJkvbu3atZs2apUqVK6tWrFz1ZAHCVWblypVq0aCFvb29J0vjx4zV58mSVKVNGM2fOVKlSpSRJsbGxuummm+Tt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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "for name, group in df.groupby(['library', 'format']):\n", + " library, format = name\n", + " x = f'{library}, {format}'\n", + " y = group['time'].mean()\n", + " ax.bar(f'{library}, {format}', group['time'].mean(), label=f'{library}, {format}', align='center')\n", + " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=12)\n", + " ax.text(x, y - (y/2) - 10, f'Total Requests: {group[\"total_requests\"].mean()}', ha='center', va='bottom', color='black', fontsize=8)\n", + " ax.text(x, y - (y/2.5), f'Total Req Bytes (MB): {round(group[\"total_requested_bytes\"].mean() / (1024*1024) , 2)}', ha='center', va='bottom', color='black', fontsize=8)\n", + "\n", + "# Set labels and title\n", + "ax.set_xlabel('Access Pattern')\n", + "ax.set_ylabel('Time in Seconds')\n", + "ax.set_title(f'mean() on photon data for runs on ATL03, less is better ')\n", + "\n", + "# Rotate x-axis labels for better readability\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "# # Show legend\n", + "# ax.legend()\n", + "\n", + "# Show the plot\n", + "with plt.xkcd():\n", + " # This figure will be in XKCD-style\n", + " fig1 = plt.figure()" ] } ], diff --git a/h5tests/xarray_arr_mean.py b/h5tests/xarray_arr_mean.py index 8bee141..59d636d 100644 --- a/h5tests/xarray_arr_mean.py +++ b/h5tests/xarray_arr_mean.py @@ -1,43 +1,46 @@ import fsspec import numpy as np import xarray as xr + from h5test import H5Test, timer_decorator class XarrayArrMean(H5Test): - def open_reference_ds(self, file): + def open_reference_ds(self, file: str, dataset: str): fs = fsspec.filesystem( "reference", fo=file, remote_protocol="s3", - remote_options=dict(anon=False), + remote_options=dict(anon=self.anon_access), skip_instance_cache=True, ) return xr.open_dataset( - fs.get_mapper(""), engine="zarr", consolidated=False, group="gt1l/heights" + fs.get_mapper(""), engine="zarr", consolidated=False, group=dataset ) @timer_decorator - def run(self, io_params={}): - group = "/gt1l/heights" - variable = "h_ph" - + def run(self, io_params={}, dataset="/gt1l/heights", variable="h_ph"): if "kerchunk" in self.data_format: - datasets = [self.open_reference_ds(file) for file in self.files] + datasets_ref = [ + self.open_reference_ds(file, dataset) for file in self.files + ] h_ph_values = [] - for dataset in datasets: - h_ph_values = np.append(h_ph_values, dataset["h_ph"].values) + for ds in datasets_ref: + h_ph_values = np.append(h_ph_values, ds[variable].values) return np.mean(h_ph_values) else: - fsspec_params = {} - h5py_params = {} if "fsspec_params" in io_params: fsspec_params = io_params["fsspec_params"] if "h5py_params" in io_params: h5py_params = io_params["h5py_params"] - print(h5py_params) s3_fileset = [self.s3_fs.open(file, **fsspec_params) for file in self.files] - xrds = xr.open_mfdataset(s3_fileset, group=group, combine='by_coords', engine='h5netcdf', **h5py_params) - h_ph_values = xrds['h_ph'] + xrds = xr.open_mfdataset( + s3_fileset, + group=dataset, + combine="by_coords", + engine="h5netcdf", + **h5py_params + ) + h_ph_values = xrds[variable] return float(np.mean(h_ph_values).values) diff --git a/notebooks/logs-fsspec.ipynb b/notebooks/logs-fsspec.ipynb deleted file mode 100644 index 768cf69..0000000 --- a/notebooks/logs-fsspec.ipynb +++ /dev/null @@ -1,568 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6c9b37e2-2daa-4283-a228-ea581498de0c", - "metadata": { - "tags": [], - "user_expressions": [] - }, - "source": [ - "## AB testing access time for ICESat-2 HDF5 files on the cloud.\n", - "\n", - "This notebook requires that we have 2 versions of the same file:\n", - " * Original A: The original file with no modifications on a S3 location.\n", - " * Test Case B: A modified version of the orignal file to test for metadata consolidation, rechunking and other strategies to speed up access to the data in the file.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "3b78fb94-10ae-48cb-8e30-521b2c8b7822", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "xarray v2023.12.0\n", - "h5py v3.10.0\n", - "fsspec v2023.6.0\n" - ] - } - ], - "source": [ - "import xarray as xr\n", - "import h5py\n", - "import fsspec\n", - "import s3fs\n", - "import boto3\n", - "import logging\n", - "import re\n", - "import time\n", - "from datetime import datetime\n", - "import pandas as pd\n", - "import numpy as np\n", - "import os\n", - "\n", - "class RegexFilter(logging.Filter):\n", - " def __init__(self, regex_pattern):\n", - " super(RegexFilter, self).__init__()\n", - " self.regex_pattern = re.compile(regex_pattern)\n", - "\n", - " def filter(self, record):\n", - " # Apply the regex pattern to the log message\n", - " return not bool(self.regex_pattern.search(record.msg))\n", - "\n", - " \n", - "def timer_decorator(func):\n", - " \"\"\"\n", - " A decorator to measure the execution time of the wrapped function.\n", - " \"\"\"\n", - " def __setup_logging(self, tstamp):\n", - " log_filename = f\"logs/{self.data_format}-{tstamp}.log\"\n", - " logger = logging.getLogger(\"fsspec\")\n", - " logger.setLevel(logging.DEBUG)\n", - " self.regex_filter = RegexFilter(self.logs_regex)\n", - " # add regerx to root logger\n", - " logging.getLogger().addFilter(self.regex_filter )\n", - " self._file_handler = logging.FileHandler(log_filename)\n", - " self._file_handler.setLevel(logging.DEBUG)\n", - " # Add the handler to the root logger\n", - " logging.getLogger().addHandler(self._file_handler)\n", - " \n", - " def __turnoff_logging(self):\n", - " logging.getLogger().removeFilter(self.regex_filter)\n", - " logging.getLogger().removeHandler(self._file_handler)\n", - " self._file_handler.close()\n", - " \n", - " def wrapper(self, *args, **kwargs):\n", - " tstamp = datetime.now().strftime('%Y-%m-%d-%H%M%S')\n", - " if self.logs_regex:\n", - " __setup_logging(self, tstamp)\n", - " start_time = time.time()\n", - " result = func(self, *args, **kwargs)\n", - " end_time = time.time()\n", - " if self.logs_regex:\n", - " __turnoff_logging(self)\n", - " execution_time = end_time - start_time\n", - " # Call the store method here\n", - " if self.store_results:\n", - " results_key = f\"{tstamp}_{self.name}_{self.data_format}_results.csv\"\n", - " s3_key = f\"{self.results_directory}/{results_key}\"\n", - " self.store(run_time=execution_time, result=result, bucket=self.bucket, s3_key=s3_key)\n", - " return result, execution_time\n", - " return wrapper \n", - "\n", - "\n", - " \n", - "class H5Test:\n", - " def __init__(self,\n", - " data_format: str,\n", - " files=None,\n", - " store_results=True,\n", - " logs_regex=None):\n", - " self.name = self.__class__.__name__\n", - " self.data_format = data_format\n", - " self.logs_regex = logs_regex\n", - " if files:\n", - " self.files = files\n", - " else:\n", - " self.files = S3Links().get_links_by_format(data_format)\n", - " self.s3_client = boto3.client('s3') # Ensure AWS credentials are configured\n", - " self.s3_fs = s3fs.S3FileSystem(anon=False)\n", - " self.store_results = store_results\n", - " self.bucket = \"nasa-cryo-persistent\"\n", - " self.results_directory = \"h5cloud/benchmark_results\"\n", - " \n", - " \n", - "\n", - " @timer_decorator\n", - " def run(self, io_params):\n", - " raise NotImplementedError(\"The run method has not been implemented\")\n", - "\n", - " def store(self, run_time: float, result: str, bucket: str, s3_key: str):\n", - " \"\"\"\n", - " Store test results to an S3 bucket as a CSV file.\n", - "\n", - " :param run_time: The runtime of the test\n", - " :param result: The result of the test\n", - " :param bucket: The name of the S3 bucket where the CSV will be uploaded\n", - " :param s3_key: The S3 key (filename) where the CSV will be stored\n", - " \"\"\"\n", - " # Create a CSV in-memory\n", - " csv_buffer = StringIO()\n", - " csv_writer = csv.writer(csv_buffer)\n", - " csv_writer.writerow(['Name', 'Data Format', 'Run Time', 'Result']) # Headers\n", - " csv_writer.writerow([self.name, self.data_format, run_time, result])\n", - "\n", - " # Reset the buffer's position to the beginning\n", - " csv_buffer.seek(0)\n", - "\n", - " # Upload the CSV to S3\n", - " self.s3_client.put_object(Bucket=bucket, Key=s3_key, Body=csv_buffer.getvalue())\n", - "\n", - "for library in (xr, h5py, fsspec):\n", - " print(f'{library.__name__} v{library.__version__}')" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d6ed86c7-a919-4532-b7d3-1ca3cf4e25d1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "class H5pyArrMean(H5Test):\n", - " \n", - " @timer_decorator\n", - " def run(self, io_params):\n", - " final_h5py_array = [] \n", - " # TODO: Do we need to make this configurable or consistent?\n", - " group = '/gt1l/heights'\n", - " variable = 'h_ph'\n", - " fsspec_params = io_params[\"fsspec_params\"]\n", - " h5py_params = io_params[\"h5py_params\"]\n", - " for file in self.files:\n", - " with self.s3_fs.open(file, mode=\"rb\", **fsspec_params) as fo:\n", - " with h5py.File(fo, **h5py_params) as f:\n", - " data = f[f\"{group}/{variable}\"][:]\n", - " final_h5py_array = np.insert(\n", - " final_h5py_array,\n", - " len(final_h5py_array),\n", - " data, axis=None\n", - " )\n", - " return np.mean(final_h5py_array)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7db7c600-d362-45c2-bb9f-3670de9ddf4d", - "metadata": {}, - "outputs": [], - "source": [ - "class H5pyROS3ArrMean(H5Test):\n", - " \"\"\"\n", - " This will only work for public buckets for now\n", - " \"\"\"\n", - " \n", - " @timer_decorator\n", - " def run(self, io_params):\n", - " final_h5py_array = [] \n", - " # TODO: Do we need to make this configurable or consistent?\n", - " group = '/gt1l/heights'\n", - " variable = 'h_ph'\n", - " h5py_params = io_params[\"h5py_params\"]\n", - " for file in self.files:\n", - " with h5py.File(file, driver=\"ros3\", **h5py_params) as f:\n", - " data = f[f\"{group}/{variable}\"][:]\n", - " final_h5py_array = np.insert(\n", - " final_h5py_array,\n", - " len(final_h5py_array),\n", - " data, axis=None\n", - " )\n", - " return np.mean(final_h5py_array)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "621f6014-fda5-40a4-be23-dcaed47b6fbd", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "class XarrayArrMean(H5Test):\n", - " def open_reference_ds(self, file):\n", - " fs = fsspec.filesystem(\n", - " 'reference', \n", - " fo=file, \n", - " remote_protocol='s3', \n", - " remote_options=dict(anon=False), \n", - " skip_instance_cache=True\n", - " )\n", - " return xr.open_dataset(fs.get_mapper(\"\"), engine='zarr', consolidated=False, group='gt1l/heights')\n", - "\n", - " @timer_decorator\n", - " def run(self, io_params):\n", - " group = '/gt1l/heights'\n", - " variable = 'h_ph'\n", - "\n", - " if 'kerchunk' in self.data_format: \n", - " datasets = [self.open_reference_ds(file) for file in self.files]\n", - " h_ph_values = []\n", - " for dataset in datasets:\n", - " h_ph_values = np.append(h_ph_values, dataset['h_ph'].values)\n", - " return np.mean(h_ph_values)\n", - " else:\n", - " if \"repacked\" in self.data_format:\n", - " fsspec_params = {\n", - " # \"skip_instance_cache\": True\n", - " \"cache_type\": \"first\",\n", - " \"block_size\": 16*1024*1024\n", - " }\n", - " h5py_params = {\n", - " \"driver_kwds\" :{\n", - " \"page_buf_size\": 32*1024*1024,\n", - " \"rdcc_nbytes\": 8*1024*1024\n", - " }\n", - " } \n", - " s3_fileset = [self.s3_fs.open(file, **fsspec_params) for file in self.files]\n", - " xrds = xr.open_mfdataset(s3_fileset, group=group, combine='by_coords', engine='h5netcdf', **h5py_params)\n", - " h_ph_values = xrds['h_ph']\n", - " return float(np.mean(h_ph_values).values)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "a6d4b6ce-10f1-4031-987d-fcfd43422ae6", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "repacked_granules = [\n", - " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", - " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", - "]\n", - "test_cloud = H5pyArrMean('atl03-bigsize-repacked',\n", - " files=repacked_granules,\n", - " store_results=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "4dfe5ab6-2e88-46d3-bb19-d6ebcec2d341", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "\n", - "original_granules = [\n", - " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", - " \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", - "]\n", - "\n", - "logs_regex = r\"\\s*(read: \\d+ - \\d+)\"\n", - "\n", - "test_original = H5pyArrMean('atl03-bigsize-original',\n", - " files=original_granules,\n", - " store_results=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "40ef2c85-f4d2-4a03-9839-bc192dda0c02", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1032.9840463639412, 12.149354219436646)\n", - "(1032.9840463639412, 12.194729566574097)\n", - "(1032.9840463639412, 12.10885739326477)\n", - "(1032.9840463639412, 11.940461874008179)\n", - "(1032.9840463639412, 12.063915252685547)\n" - ] - } - ], - "source": [ - "# logger = logging.getLogger()\n", - "# logger.setLevel(logging.DEBUG)\n", - "io_params ={\n", - " \"fsspec_params\": {\n", - " \"skip_instance_cache\": True\n", - " # \"cache_type\": \"blockcache\",\n", - " # \"block_size\": 4*1024*1024\n", - " },\n", - " \"h5py_params\": {\n", - " # \"rdcc_nbytes\": 2*1024*1024 \n", - " }\n", - "}\n", - "for runs in range(5):\n", - " print(test_original.run(io_params))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb2f92bf-4b1f-4bfe-a037-8061bfa9b127", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1032.9840463639412, 34.1772985458374)\n", - "(1032.9840463639412, 30.96499228477478)\n", - "(1032.9840463639412, 31.00865602493286)\n", - "(1032.9840463639412, 31.207276821136475)\n" - ] - } - ], - "source": [ - "io_params ={\n", - " \"fsspec_params\": {\n", - " # \"skip_instance_cache\": True\n", - " # \"cache_type\": \"blockcache\",\n", - " # \"block_size\": 4*1024*1024\n", - " },\n", - " \"h5py_params\": {\n", - " # \"page_buf_size\": 32*1024*1024,\n", - " # \"rdcc_nbytes\": 2*1024*1024\n", - " }\n", - "}\n", - "for runs in range(5):\n", - " print(test_cloud.run(io_params))" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "262a6b25-8b23-46bb-8301-8965aaf155d2", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Registered drivers: frozenset({'mpio', 'family', 'ros3', 'split', 'core', 'sec2', 'fileobj', 'direct', 'stdio'})\n" - ] - } - ], - "source": [ - "print(f'Registered drivers: {h5py.registered_drivers()}')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02258a85-4951-48c2-a295-75a47c0e38c1", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "df = pd.DataFrame.from_dict(benchmarks)\n", - "\n", - "fig, ax = plt.subplots(figsize=(10, 6))\n", - "\n", - "for name, group in df.groupby(['tool', 'dataset', 'format']):\n", - " tool, dataset, formated = name\n", - " x = f'{tool}, {dataset}, {formated}'\n", - " y = group['time'].mean()\n", - " ax.bar(f'{tool}, {dataset}, {formated}', group['time'].mean(), label=f'{tool}, {dataset}, {formated}', align='center')\n", - " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=8)\n", - "\n", - "# Set labels and title\n", - "ax.set_xlabel('Combination')\n", - "ax.set_ylabel('Time in Seconds')\n", - "ax.set_title('mean() on photon data for a single IS2 track, less is better')\n", - "\n", - "# Rotate x-axis labels for better readability\n", - "plt.xticks(rotation=45, ha='right')\n", - "\n", - "# # Show legend\n", - "# ax.legend()\n", - "\n", - "# Show the plot\n", - "with plt.xkcd():\n", - " # This figure will be in XKCD-style\n", - " fig1 = plt.figure()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1d5d779b-5bc6-4208-ae26-05c5a473d9b9", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "64bcc5de-aae3-46aa-9474-1c90b9ff20a9", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "df = pd.DataFrame.from_dict(benchmarks)\n", - "\n", - "fig, ax = plt.subplots(figsize=(10, 6))\n", - "\n", - "for name, group in df.groupby(['tool', 'dataset', 'format']):\n", - " tool, dataset, formated = name\n", - " x = f'{tool}, {dataset}, {formated}'\n", - " y = group['time'].mean()\n", - " ax.bar(f'{tool}, {dataset}, {formated}', group['time'].mean(), label=f'{tool}, {dataset}, {formated}', align='center')\n", - " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=8)\n", - "\n", - "# Set labels and title\n", - "ax.set_xlabel('Combination')\n", - "ax.set_ylabel('Time in Seconds')\n", - "ax.set_title('mean() on photon data for a single IS2 track, less is better')\n", - "\n", - "# Rotate x-axis labels for better readability\n", - "plt.xticks(rotation=45, ha='right')\n", - "\n", - "# # Show legend\n", - "# ax.legend()\n", - "\n", - "# Show the plot\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b2871e1-d700-4d22-b01f-5e5a9acd1006", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "89aabece-d942-418c-b387-77ea2de1e561", - "metadata": {}, - "outputs": [], - "source": [ - "# def normalize_log(log_file):\n", - "# with open(log_file, 'r') as input_file:\n", - "# # Open the output file in write mode\n", - "# with open(f'{log_file.replace(\".log\", \"-ros-compatible.log\")}', 'w') as output_file:\n", - "# # Iterate through each line in the input file\n", - "# for line in input_file:\n", - "# # Strip leading and trailing whitespaces from the line\n", - "# stripped_line = line.strip()\n", - "\n", - "# # Write the stripped line to the output file\n", - "# output_file.write(stripped_line + '\\n') " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8411f4a8-22b4-424e-b817-0d31e7ac9e93", - "metadata": {}, - "outputs": [], - "source": [ - " # \"ATL08\": {\n", - " # \"links\": {\n", - " # \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl08/original/ATL08_20200404075919_01340707_006_03.h5\",\n", - " # \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl08/repacked/ATL08_20200404075919_01340707_006_03_repacked.h5\",\n", - " # },\n", - " # \"group\": \"/gt1l/signal_photons\",\n", - " # \"variable\": \"ph_h\",\n", - " # \"processing\": [\n", - " # \"h5repack -S PAGE -G 4000000\"\n", - " # ]\n", - " # },\n", - " # \"ATL03\": {\n", - " # \"links\": {\n", - " # \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\",\n", - " # \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\"\n", - " # },\n", - " # \"group\": \"/gt1l/heights\",\n", - " # \"variable\": \"h_ph\",\n", - " # \"processing\": [\n", - " # \"h5repack -S PAGE -G 4000000\"\n", - " # ]\n", - " # }," - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/portable-h5py-test.ipynb b/notebooks/portable-h5py-test.ipynb new file mode 100644 index 0000000..82d88f5 --- /dev/null +++ b/notebooks/portable-h5py-test.ipynb @@ -0,0 +1,329 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload \n", + "\n", + "import sys\n", + "import os\n", + "classes_path = os.path.abspath('../h5tests/')\n", + "sys.path.append(classes_path)\n", + "from h5py_arr_mean import H5pyArrMean\n", + "import pandas as pd\n", + "\n", + "benchmarks = []" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "original_granules = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + "]\n", + "h5py_original = H5pyArrMean('atl03-bigsize-original', files=original_granules, store_results=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "h5py params: {}\n", + "h5py params: {}\n" + ] + }, + { + "data": { + "text/plain": [ + "[{'library': 'h5py',\n", + " 'format': 'original',\n", + " 'mean': 1032.9840463639412,\n", + " 'time': 51.46329092979431,\n", + " 'total_requested_bytes': 414028873,\n", + " 'total_requests': 12295,\n", + " 'avg_req_size': 33674}]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# takes about ~30 seconds per granule out of region (6+ GB granules)\n", + "io_params ={\n", + " \"fsspec_params\": {},\n", + " \"h5py_params\" : {}\n", + "}\n", + "results = h5py_original.run(io_params)\n", + "benchmarks.append({\"library\": \"h5py\",\n", + " \"format\": \"original\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", + "metadata": {}, + "outputs": [], + "source": [ + "cloud_optimized_granules = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", + "]\n", + "h5py_cloud = H5pyArrMean('atl03-bigsize-repacked', files=cloud_optimized_granules, store_results=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dfd4e404-0412-4d2f-8eba-ca39a670e369", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "h5py params: {'page_buf_size': 33554432, 'rdcc_nbytes': 1048576}\n", + "h5py params: {'page_buf_size': 33554432, 'rdcc_nbytes': 1048576}\n" + ] + }, + { + "data": { + "text/plain": [ + "[{'library': 'h5py',\n", + " 'format': 'original',\n", + " 'mean': 1032.9840463639412,\n", + " 'time': 51.46329092979431,\n", + " 'total_requested_bytes': 414028873,\n", + " 'total_requests': 12295,\n", + " 'avg_req_size': 33674},\n", + " {'library': 'h5py',\n", + " 'format': 'cloud',\n", + " 'mean': 1032.9840463639412,\n", + " 'time': 42.97014808654785,\n", + " 'total_requested_bytes': 560001136,\n", + " 'total_requests': 78,\n", + " 'avg_req_size': 7179501}]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# takes about ~30 seconds per granule out of region\n", + "io_params ={\n", + " \"fsspec_params\": {\n", + " # \"skip_instance_cache\": True\n", + " \"cache_type\": \"first\",\n", + " \"block_size\": 16*1024*1024\n", + " },\n", + " \"h5py_params\" : {\n", + " \"page_buf_size\": 32*1024*1024,\n", + " \"rdcc_nbytes\": 1024*1024\n", + " }\n", + "}\n", + "\n", + "results = h5py_cloud.run(io_params)\n", + "\n", + "benchmarks.append({\"library\": \"h5py\",\n", + " \"format\": \"cloud\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9d30d92b-4192-4da1-8b60-41cc94ca2db1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
libraryformatmeantimetotal_requested_bytestotal_requestsavg_req_size
0h5pyoriginal1032.98404651.4632914140288731229533674
1h5pycloud1032.98404642.970148560001136787179501
\n", + "
" + ], + "text/plain": [ + " library format mean time total_requested_bytes \\\n", + "0 h5py original 1032.984046 51.463291 414028873 \n", + "1 h5py cloud 1032.984046 42.970148 560001136 \n", + "\n", + " total_requests avg_req_size \n", + "0 12295 33674 \n", + "1 78 7179501 " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_dict(benchmarks)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "3ff4c22f-7f77-4c69-a84c-f13b0fbba1f2", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0oAAAJhCAYAAAB/xkCsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMq0lEQVR4nOzdd3RU1d7G8WcmZdJDQhJC6E2KVEUQLIAQkGZHBUQUGwIiV68FUYpyQRERFRAVqQqiwouIgIRqoQtIsSDSe03vM/v9I2ZgJoUEAwnw/ayVtZh9ztnndyYhmWf2PnssxhgjAAAAAICTtbgLAAAAAICShqAEAAAAAG4ISgAAAADghqAEAAAAAG4ISgAAAADghqAEAAAAAG4ISgAAAADghqAEAAAAAG4ISgAAAADghqAEwOnHH3+UzWbTvn37nG233nqrBgwYUHxF/UuPPPKIAgICirTPESNGaN68eUXaZ1EYOnSoLBbLBR07c+ZMjR07tmgL+scHH3yg6tWry9vbWxaLRbGxsRflPMjfPffcI4vFon79+jnb9u7dK4vFUqCvvXv3auXKlbJYLPr666/Pe74vvvhCDRs2lI+Pj6KiojRgwAAlJia67LNlyxZ17NhRFStWlK+vr0JDQ9WsWTN99tlnF3yd2dc0derUC+7jYpg6darzefy3WrZsqbp16/77os4xYcKEXJ+zw4cPa+jQodqyZUuRng+4HBCUAEiSjDEaMGCAnnjiCVWqVMnZ/sYbb2jChAn6888/i7G6kqWkBqV/42IFpS1btqh///5q1aqVli9frjVr1igwMLDIz4P8HT9+XAsWLJAkff7550pNTZUklS1bVmvWrHH5atSokapWrZqjvWzZsgU+3+eff66uXbvqhhtu0KJFizRkyBBNnTpV99xzj8t+sbGxqlChgkaMGKGFCxdq+vTpqly5snr06KHhw4cX3RNQAnTs2LHQz+OllF9QGjZsGEEJVyXP4i4AQMmwePFibdq0STNnznRpb9GihWrWrKl33nlHH3/8cTFVh8vVjh07JElPPPGEmjRpUiR9Jicny8/P76LtfyWaPn26MjIy1LFjR3333XeaO3euunXrJpvNphtvvNFl36CgIKWnp+doLyi73a4XXnhBbdu21SeffCJJatWqlQIDA9W9e3ctWrRI7du3l5Q1MtKyZUuX4zt16qQ9e/bo448/1quvvnpBNZRE4eHhCg8PL+4ySoyUlBT5+Phc8Cg4cCkwogQUkexpT1u3blWXLl0UHBys0NBQPffcc8rMzNSff/6p22+/XYGBgapcubJGjRqVo4/4+Hj997//VZUqVeTt7a1y5cppwIABSkpKctlv/PjxuvXWWxURESF/f3/Vq1dPo0aNUkZGhst+2dMzNmzYoFtuuUV+fn6qWrWq3nzzTTkcDpd9P/zwQ91www2qWbNmjrp69OihmTNnKiEh4bzPw+nTp9WnTx+VK1dO3t7eqlq1qgYNGqS0tDSX/bKnAM2YMUO1a9eWn5+fGjRo4HzXOz/Z038+++wzPffcc4qMjJSvr69atGihzZs353rMrl271KFDBwUEBKhChQp6/vnnc9RUkNotFouSkpI0bdo055Skc1/obd++XXfeeadCQkLk4+Ojhg0batq0abnWP2vWLA0aNEhRUVEKCgpSmzZtCjxy991336lhw4ay2WyqUqWKRo8enet+BflZadmypb777jvt27fPZapVtmHDhqlp06YKDQ1VUFCQrrvuOn366acyxuRbY8uWLfXQQw9Jkpo2bSqLxaJHHnnEuX3y5Mlq0KCBfHx8FBoaqrvvvlu///67Sx/ZUye3bdumtm3bKjAwUK1bt87znNn/Dzdt2qT77rtPISEhqlatmrMe9xfl2eeoXLmy83H21K3Ro0drzJgxqlKligICAtSsWTOtXbvW5djdu3frwQcfVFRUlGw2m8qUKaPWrVsX6N33+fPnq1mzZvLz81NgYKCio6O1Zs2aXK9nx44d6tq1q4KDg1WmTBn16tVLcXFx5z1HtsmTJ6tMmTKaNm2afH19NXny5AIfW1hr167VkSNH9Oijj7q0d+nSRQEBAfq///u/8/YRFhYmT8+ifS/3r7/+Urdu3RQRESGbzabatWtr/PjxLvs4HA4NHz5cNWvWlK+vr0qVKqX69evrvffec+5z4sQJPfnkk6pQoYJsNpvCw8N10003aenSpfmeP7epd5s3b1anTp2cNUVFRaljx446ePBgga7pxx9/1I033ihfX1+VK1dOr732mux2u8s+6enpGj58uGrVquWs99FHH9WJEyec+1SuXFk7duzQqlWrnP//K1eurJUrV+qGG26QJD366KPObUOHDnUeu3HjRt1xxx0KDQ2Vj4+PGjVqpC+//DLXa1+yZIl69eql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X1Sfa8WKFbJarapateq/rsfPz0+tWrXS5s2bVb9+/Vx/v+b25kqpUqV03333qW/fvjp9+nSuHxRbsWJF9evXT9HR0fl+z8/HYrGoQYMGevfdd1WqVKkC9ZWQkKD58+e7tM2cOVNWq1W33nqrpKy/K6dOnZLdbs/1us8NMnn9Dshr9LJmzZqqUaOGfv3111z7bty4MZ+ZhsseI0pACTFgwADNmTNHt956q/7zn/+ofv36cjgc2r9/v5YsWaLnn39eTZs2VXR0tLy9vdW1a1e9+OKLSk1N1Ycffphjqk5hlC9fXlWrVtXatWvVv3//HNuz5++3atUq334efvhhjR8/Xj179tTevXtVr149/fTTTxoxYoQ6dOigNm3aXHCNuTl+/LjuvvtuPfHEE4qLi9OQIUPk4+OjgQMHFrqvwtRer149rVy5Ut9++63Kli2rwMBA1axZU0OGDNGCBQvUqlUrDR48WKGhofr888/13XffadSoUQoODi6S637jjTd0++23Kzo6Ws8//7zsdrveeust+fv7u4wKFuZnpV69epo7d64+/PBDXX/99bJarWrcuLE6duyoMWPGqFu3bnryySd16tQpjR492iV8FVapUqX02muv6ZVXXtHDDz+srl276tSpUxo2bJh8fHw0ZMiQC+47Pz169NBHH32khx56SE888YROnTqlUaNGFXpaX7atW7eqX79+6tKli2rUqCFvb28tX75cW7duzXc0wGq1atSoUerevbs6deqkp556SmlpaXr77bcVGxurN99880Iv0UX2aNKLL76Y62dYJSQkaNmyZfrss8/07LPPFqpv92XSs7Vo0ULh4eEaNWqUevTooaeeekpdu3bVX3/9pRdffFHR0dG6/fbbnfs/+eSTCgoKUpMmTVSmTBmdPHlSX331lWbPnq0XXnjBZTRp6tSpevTRRzVlypQc97edz3vvvaebb75Zt9xyi55++mlVrlxZCQkJ2rVrl7799lstX75cktS5c2fVrVtXjRs3Vnh4uPbt26exY8eqUqVKqlGjhuLi4tSqVSt169ZNtWrVUmBgoDZs2KDFixcXKACea8GCBZowYYLuuusuVa1aVcYYzZ07V7GxsYqOjj7v8aVLl9bTTz+t/fv365prrtHChQv1ySef6Omnn1bFihUlSQ8++KA+//xzdejQQc8++6yaNGkiLy8vHTx4UCtWrNCdd96pu+++W9LZ0a3Zs2eratWq8vHxUb169VStWjX5+vrq888/V+3atRUQEKCoqChFRUXpo48+Uvv27dWuXTs98sgjKleunE6fPq3ff/9dmzZt0ldffVWo5wQocYptGQngCpO9OtWJEydc2nv27Gn8/f1z7J/bylKJiYnm1VdfNTVr1jTe3t7O5Wz/85//mKNHjzr3+/bbb02DBg2Mj4+PKVeunHnhhRfMokWLjCSXZYnzWr3KfZUvY4x57bXXTEhIiElNTc2xf48ePUy9evUK8jSYU6dOmd69e5uyZcsaT09PU6lSJTNw4MAc/cptGdtslSpVynVFuXNlr7w1Y8YM079/fxMeHm5sNpu55ZZbzMaNG3Nca27Pf/b360Jq37Jli7npppuMn5+fkeSyUtS2bdtM586dTXBwsPH29jYNGjTIsVpUXiuH5bZaV17mz59v6tevb7y9vU3FihXNm2++mes1FfRn5fTp0+a+++4zpUqVMhaLxaWfyZMnm5o1axqbzWaqVq1qRo4caT799FOXFbzyktuqd9kmTZrkvIbg4GBz55135lhSOq/vX17y+n+Ybdq0aaZ27drGx8fH1KlTx8yePTvPVe/efvvtHMdLMkOGDDHGGHPs2DHzyCOPmFq1ahl/f38TEBBg6tevb959990CLXs8b94807RpU+Pj42P8/f1N69atzc8//1yg63FfQc1denq6iYiIyHcFt8zMTFO+fPkc/7cLsupdXl/n/kzNnDnT+f2NjIw0/fv3NwkJCS79TZ482dxyyy0mLCzMeHp6mlKlSpkWLVqYGTNm5Dj3Bx98YCSZxYsX53lNxuT9/2jPnj2mV69eply5csbLy8uEh4eb5s2bm+HDhzv3eeedd0zz5s1NWFiY8//WY489Zvbu3WuMMSY1NdX07t3b1K9f3wQFBRlfX19Ts2ZNM2TIEJOUlJRvXe7fsz/++MN07drVVKtWzfj6+prg4GDTpEkTM3Xq1Hz7Mebs92jlypWmcePGxmazmbJly5pXXnklxwp0GRkZZvTo0c7fAwEBAaZWrVrmqaeeMn/99Zdzv71795q2bduawMBA5xL72WbNmmVq1aplvLy8XP4PGGPMr7/+au6//34TERFhvLy8TGRkpLnttttclnfP7/cAUJJZjDnPJwYCuCocPnxYVapU0fTp0/XAAw842+Pj4xUVFaV3331XTzzxRDFWeNbKlSvVqlUrffXVVzlWqQNwZbr//vu1Z88ebdiwobhLAXCV4B4lAJKyVtsaMGCA/ve//7ksGfzuu++qYsWKevTRR4uxOgBXM2OMVq5cqf/973/FXQqAqwj3KAFwevXVV+Xn56dDhw45PwsoKChIU6dOlacnvy4AFA+LxXJBn9kFAP8GU+8AAAAAwA1T7wAAAADADUEJAAAAANwQlAAAAADAzRV/d7bD4dDhw4cVGBjo/JR6AAAAAFcfY4wSEhIUFRUlqzX/MaMrPigdPnzYuXoXAAAAABw4cEDly5fPd58rPigFBgZKynoygoKCirkaAAAAAMUlPj5eFSpUcGaE/FzxQSl7ul1QUBBBCQAAAECBbslhMQcAAAAAcENQAgAAAAA3BCUAAAAAcENQAgAAAAA3BCUAAIASauXKlbJYLLl+rV271rnfTz/9pMcff1zXX3+9bDabLBaL9u7de0HnTElJ0TXXXCOLxaLRo0fnus/27dvVpUsXhYeHy2azqXLlyurTp88FnQ8oqa74Ve8AAAAudyNGjFCrVq1c2urWrev897Jly7R06VI1atRIQUFBWrly5QWf67XXXlNSUlKe21esWKGOHTvqlltu0cSJExUWFqb9+/dr8+bNF3xOoCQiKAEAAJRwNWrU0I033pjn9tdee01DhgyRJI0ePfqCg9L69ev1wQcf6PPPP1eXLl1ybE9OTlb37t1122236dtvv3VZYrlHjx4XdE6gpGLqHQAAwGXOav33L+nS09PVq1cv9e3bV40bN851n6+++kpHjhzRCy+8UKDPoQEuZwQlAACAEq5v377y9PRUUFCQ2rVrp59++qnIz/H6668rKSlJb7zxRp77/PDDD5Iku92um2++Wd7e3goJCVHXrl11+PDhIq8JKE4EJQAAgBIqODhYzz77rD766COtWLFC7733ng4cOKCWLVvq+++/L7LzbNmyRaNGjdLEiRPl7++f536HDh2SJN1777266aab9P333+vNN99UTEyMWrRooeTk5CKrCShu3KMEAABQQjVq1EiNGjVyPr7lllt09913q169enrxxRfVrl27f32OzMxM9erVSw888MB5+3M4HJKkBx54QG+99ZYkqVWrVoqMjNRdd92lmTNn6vHHH//XNQElASNKAAAAl5FSpUqpU6dO2rp1q1JSUv51f2PHjtXu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AADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADATaGD0rRp0/Tdd985H7/44osqVaqUmjdvrn379hVpcQAAAABQHAodlEaMGCFfX19J0po1azRu3DiNGjVKYWFh+s9//lPkBQIAAADApeZZ2AMOHDig6tWrS5LmzZun++67T08++aRuuukmtWzZsqjrAwAAAIBLrtAjSgEBATp16pQkacmSJWrTpo0kycfHRykpKUVbHQAAAAAUg0KPKEVHR+vxxx9Xo0aNtHPnTnXs2FGStGPHDlWuXLmo6wMAAACAS67QI0rjx49Xs2bNdOLECc2ZM0elS5eWJP3yyy/q2rVrkRcIAAAAAJdaoUeUSpUqpXHjxuVoHzZsWJEUBAAAAADFrUBBaevWrQXusH79+hdcDAAAAACUBAUKSg0bNpTFYpExRhaLJd997XZ7kRQGAAAAAMWlQPco7dmzR7t379aePXs0Z84cValSRRMmTNDmzZu1efNmTZgwQdWqVdOcOXMudr0AAAAAcNEVaESpUqVKzn936dJF77//vjp06OBsq1+/vipUqKDXXntNd911V5EXCQAAAACXUqFXvdu2bZuqVKmSo71KlSr67bffiqQoAAAAAChOhV71rnbt2ho+fLg+/fRT+fj4SJLS0tI0fPhw1a5du8gLBAAAcNdwYqIkKd0u7TzlUN2IrPd+a4ZZNfs+vxz7bzlq185TDt1/rdd5+165N1P/XZKqjU8G5Ng2dGWqJmzIUFSgRel2qXqoVZ909lGZgEK/95ynymMT5ONpkY+nlGaXGkVa9UlnX/l753+f+NQt6WpewUPXlPYoslqSM4xumpykHx7xV6DNopZTk7T6gF0HnwtQhH/WNe8+41D19xN1T21PfX2/n/bGZj3O/p6k2aXu9bz06q02SdIH69KVmG408Bbbec+flG502/QkpWZmPS4bYNHETr6qXCqr78W7MvXq8lSl2yU/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8YeqVq0qb29v5+/6/fv3a9q0aRoyZIjGjh2r/v37O/dPTk7WxIkTNW/ePK1atYrV7YAiRlACLoEZM2Y43ynMng7xn//8R7t379Y333zjXBJ8y5Yt6tevn6655hpNnjw5Rz+EJAC48k2YMEFjx47Vtm3bZLPZdPjwYX300UcaM2aMRo4cqX79+jn3TU1Nlc1mc65uR1gCig53+AEX2cyZMzVkyBANHjzYZc64h4eHkpOTnTftOhwONWzYUH369NHMmTN16NChHH0RkgDgymO3210e33DDDcrMzNRtt92mtLQ0RUVF6cknn9Rzzz2nQYMGacKECc59fXx8CEnARUJQAi6yzp07q3v37lq1apVeffVVZWRkSJKaNWumZcuWae7cubJYLM77lkqVKqW6devKZrMVZ9kAgEsk+02wbdu2ScoKSnPnztWJEyd06623Ki0tTeXKlXOGpX79+mnOnDkufRCSgKLH1DvgIsqeKpeYmKiRI0dq6dKlatGihYYPHy5vb289//zzmjBhgj788EPdeOONKlWqlB555BEZY7R48WL+8AHAFezcFVDXrFmjm266STNnztSDDz4oSdq8ebMeeOABhYSE6IcffpDNZtP+/fsVExOjnj17smADcJERlICLxP3zK5KSkjRy5EjFxMSoRYsWGjFihDw9PfXaa69p7NixCgoKUmBgoAICArRmzRp5eXnxGRgAcIU6d6rc+++/L7vdrueff17BwcF6//331aNHD0lZYalr164KDQ3VihUrXGYbsAQ4cHERlICL4NyAM2nSJAUFBalLly5KTk7WiBEjtHTpUrVq1UpvvPGGvLy8tHHjRsXFxSkjI0PR0dHy8PDgDyAAXAUGDx6siRMnaty4cTp9+rTWrFmjWbNmadKkSXr44YclSVu2bFHLli3VpUsXffLJJ8VcMXD14FUYcBFkh6QXX3xRM2bM0EsvvaQTJ04oIiJCAwcOlMViUUxMjAYNGqT//e9/aty4scvxdrudkAQAV5gjR46obNmyzsenTp3S/Pnz9frrr+v++++XJD322GOKiIjQ448/Lk9PT3Xr1k0NGzbU+vXrVa1ateIqHbgqMacHuEimTp2q6dOna9GiRXr22WcVEREhh8OhgIAAvfzyy4qOjtZPP/2k/v3751jxiNXtAODK0qZNG40ePdqlLS0tTQcPHlRgYKCkrNkInp6e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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "for name, group in df.groupby(['library', 'format']):\n", + " library, format = name\n", + " x = f'{library}, {format}'\n", + " y = group['time'].mean()\n", + " ax.bar(f'{library}, {format}', group['time'].mean(), label=f'{library}, {format}', align='center')\n", + " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=12)\n", + " ax.text(x, y - (y/2) - 10, f'Total Requests: {group[\"total_requests\"].mean()}', ha='center', va='bottom', color='black', fontsize=8)\n", + " ax.text(x, y - (y/2.5), f'Total Req Bytes (MB): {round(group[\"total_requested_bytes\"].mean() / (1024*1024) , 2)}', ha='center', va='bottom', color='black', fontsize=8)\n", + "\n", + "# Set labels and title\n", + "ax.set_xlabel('Access Pattern')\n", + "ax.set_ylabel('Time in Seconds')\n", + "ax.set_title(f'mean() on photon data for runs on ATL03, less is better ')\n", + "\n", + "# Rotate x-axis labels for better readability\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "# # Show legend\n", + "# ax.legend()\n", + "\n", + "# Show the plot\n", + "with plt.xkcd():\n", + " # This figure will be in XKCD-style\n", + " fig1 = plt.figure()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/portable-xarray-test.ipynb b/notebooks/portable-xarray-test.ipynb new file mode 100644 index 0000000..4e67969 --- /dev/null +++ b/notebooks/portable-xarray-test.ipynb @@ -0,0 +1,305 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n", + "xarray v2024.1.1\n", + "h5py v3.10.0\n", + "s3fs v2024.2.0\n" + ] + } + ], + "source": [ + "%load_ext autoreload\n", + "%autoreload \n", + "\n", + "import sys\n", + "import os\n", + "classes_path = os.path.abspath('../h5tests/')\n", + "sys.path.append(classes_path)\n", + "from xarray_arr_mean import XarrayArrMean\n", + "import pandas as pd\n", + "\n", + "import xarray as xr\n", + "import h5py\n", + "import s3fs\n", + "\n", + "benchmarks = []\n", + "\n", + "for library in (xr, h5py, s3fs):\n", + " print(f'{library.__name__} v{library.__version__}')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "files = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + "]\n", + "xarray_original = XarrayArrMean('atl03-bigsize-original', files=files, store_results=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'library': 'xarray',\n", + " 'format': 'cloud',\n", + " 'mean': 1032.984130859375,\n", + " 'time': 176.90762186050415,\n", + " 'total_requested_bytes': 720001152,\n", + " 'total_requests': 100,\n", + " 'avg_req_size': 7200011},\n", + " {'library': 'xarray',\n", + " 'format': 'original',\n", + " 'mean': 1032.984130859375,\n", + " 'time': 1456.8166418075562,\n", + " 'total_requested_bytes': 438520591,\n", + " 'total_requests': 26988,\n", + " 'avg_req_size': 16248}]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# don't even try this out of region...\n", + "# takes about ~10 minutes per granule out of region (6+ GB granules)\n", + "io_params ={\n", + " \"fsspec_params\": {},\n", + " \"h5py_params\" : {}\n", + "}\n", + "results = xarray_original.run(io_params)\n", + "benchmarks.append({\"library\": \"xarray\",\n", + " \"format\": \"original\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", + "metadata": {}, + "outputs": [], + "source": [ + "files = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", + "]\n", + "xarray_cloud = XarrayArrMean('atl03-bigsize-repacked', files=files, store_results=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "dfd4e404-0412-4d2f-8eba-ca39a670e369", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'library': 'xarray',\n", + " 'format': 'cloud',\n", + " 'mean': 1032.984130859375,\n", + " 'time': 176.90762186050415,\n", + " 'total_requested_bytes': 720001152,\n", + " 'total_requests': 100,\n", + " 'avg_req_size': 7200011}]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# takes about ~90 seconds per granule out of region\n", + "io_params ={\n", + " \"fsspec_params\": {\n", + " # \"skip_instance_cache\": True\n", + " \"cache_type\": \"blockcache\",\n", + " \"block_size\": 8*1024*1024\n", + " },\n", + " \"h5py_params\" : {\n", + " \"driver_kwds\": {\n", + " \"page_buf_size\": 32*1024*1024,\n", + " \"rdcc_nbytes\": 8*1024*1024\n", + " }\n", + "\n", + " }\n", + "}\n", + "\n", + "results = xarray_cloud.run(io_params)\n", + "\n", + "benchmarks.append({\"library\": \"xarray\",\n", + " \"format\": \"cloud\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9d30d92b-4192-4da1-8b60-41cc94ca2db1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: []" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_dict(benchmarks)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "3ff4c22f-7f77-4c69-a84c-f13b0fbba1f2", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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kZHhfLRr104Wi0Xr1q1ztt2xY4e6dOmikJAQeXp6ysvLSw888IDsdrv27dvncvyIiIhs18rUqVPH5djHjx+XJIWFheV4Tl5eXipevLj+/PPPXM99zZo1CggIUPfu3V2WZw0d++abb1yWZ13HkSU8PFxhYWEuteWmZ8+eLsPdypUrp6ZNm2rt2rUu7SwWizp37uyy7J+vQX5rz8maNWvUqlUrRUVFZdvH+fPnsw0R69KlS7aaJOV6/klJSdqyZYu6desmX19f5/LAwMBs5yjl72slt/Nq3bq1bDabcx8vvviizpw5o5iYmDzt40KbNm1ScnKyy5BCSYqKitKtt96a42t955135usY+W2fk44dO8rT09P5/J/vT3BwsCpVqqS33npL48aN044dO7INz83J3r17dfz4cfXq1UseHn//Oi9WrJjuvPNObd68WefPn3fZJqevlZSUlEu+/omJifrss8/UtGlTVatWTVLmdZiVKlXS9OnT81Tv5brYtTg5LX/22We1ZcsWLV26VA899JAGDRp00aGx+ZWSkqJvvvlGd9xxh/z9/V1+vnbo0EEpKSnO4aGNGjXSTz/9pAEDBujrr79WfHx8tv01atRI06dP12uvvabNmzdnG76dV5UrV1aJEiX09NNPa9KkSfrll1/ytX1gYGC2r4uePXvK4XDo22+/lZT5e6V48eLq3Lmzy3nXq1dPERERLr9X8mv//v367bffdN9990lSttf1xIkT2YZFF8T3JfBfIWwBV6jg4GCX597e3vL393f5YJy1PGtGMEk6efKkdu3aJS8vL5dHYGCgjDE6ffq0JOnIkSO6+eab9eeff+rdd9/Vd999py1btjivPUhOTnY5TkhISLYafXx8XNpl/f+fNV7I19c3277/6cyZM4qIiMj2YSosLExWq1VnzpzJd225iYiIyHHZP4+T0+vv4+Pj8vrnt/acnDlzJseZxiIjI53rL/TP8/fx8ZGU/T28UGxsrBwOx0XP/UL5/VrJyY8//qi2bdtKkj766CN9//332rJli5577rk87+Ofsl6Hi71WOb1/QUFB+TpGQcz4dqn3x2Kx6JtvvlG7du00ZswYXX/99SpZsqSGDBmS6/WNlzp/h8Oh2NjYfNVyMfPnz1diYqJ69Oihc+fO6dy5c4qLi1OPHj109OhRrVq1KtftL0dWrTl9z5w9ezbbz0hJKlu2rBo2bKgOHTroww8/VP/+/TVixAiX64ou15kzZ5SRkaH3338/28/XDh06SJLz5+uIESM0duxYbd68WbfddptCQkLUqlUrbd261bm/+fPnq3fv3vr444/VpEkTBQcH64EHHlB0dHS+6rLZbFq/fr3q1aunZ599VjVr1lRkZKReeumlPAW48PDwbMuyfgZkvfYnT57UuXPn5O3tne3co6Ojned9OU6ePClJevLJJ7Pte8CAAZKUbf9X6kyMQE6YjRC4yoSGhuZ64XpoaKgkafHixUpKStKiRYtcpmj/N9PyZu377NmzF20TGxvrbHcxISEh+uGHH2SMcQktMTExysjIuOT2+ZXTh5vo6OgcQ9ylFETtISEhOnHiRLblWT2HBXH+JUqUkMViuei5X6ggvlbmzZsnLy8vffXVVy6B9d9MfZ/1/lzstfrn63Q5s5XltI2vr2+Ok0r8mw+c5cqV09SpUyVJ+/bt02effaaRI0cqLS1NkyZNynGbS52/h4eHSpQocdk1XSirtqFDh+Z4v7ypU6eqXbt2BXKsLLVr15Yk/fzzz6pRo4ZzeUZGhn777Tfde++9l9xHo0aNNGnSJB04cOBfz+BXokQJeXp6qlevXho4cGCObSpUqCApc9TBE088oSeeeELnzp3T6tWr9eyzz6pdu3Y6evSo/P39FRoaqvHjx2v8+PE6cuSIlixZomeeeUYxMTFasWJFvmqrXbu25s2bJ2OMdu3apenTp+uVV16Rn5+fnnnmmVy3zQo7F8r6GZD1NRYaGqqQkJCL1vVvbsOQ9X06YsSIbFP6Z/nnhEvMPIiihJ4t4CrTqVMn/fHHHwoJCVHDhg2zPbJmS8v6ZZX1l20p8x5ZWVMsX47q1atLkv74448c1x8/flwpKSkuH5xy0qpVKyUmJmb7ID5z5kzn+oL06aefusyId/jwYW3cuDHHGecuJT+1X6z3rVWrVlqzZo0zXF24D39//8ueSvtCAQEBatSokRYtWuTSM5eQkKAvv/zSpW1+vlYudk4Wi0VWq9VlOF1ycrJmzZp12efQpEkT+fn5Zbtx7bFjx5xDMd2hfPny2rdvn8sMaGfOnNHGjRsLZP/XXXednn/+edWuXVvbt2+/aLuqVauqdOnSmjt3rsvXb1JSkj7//HPnDIX/1q+//qpNmzbpzjvv1Nq1a7M9WrVqpf/7v//LU69tfjRu3FilSpXKds+mhQsXKjEx8aIfzC+0du1aeXh4qGLFiv+6Hn9/f7Vs2VI7duxQnTp1cvz5mtMfaIoXL67u3btr4MCBOnv2bI43Iy5btqwGDRqkNm3a5PqeX4rFYlHdunX1zjvvqHjx4nnaV0JCgpYsWeKybO7cufLw8NAtt9wiKfP3ypkzZ2S323M87wvD0MV+BlysF7Vq1aqqUqWKfvrppxz33bBhQ+6phyKNni3gKjN06FB9/vnnuuWWW/T444+rTp06cjgcOnLkiFauXKlhw4apcePGatOmjby9vXXvvfdq+PDhSklJ0Ycffpht2FF+lClTRhUrVtTmzZs1ZMiQbOuzrmdo2bJlrvt54IEHNHHiRPXu3VuHDh1S7dq1tWHDBo0aNUodOnRQ69atL7vGnMTExOiOO+5Qv379FBcXp5deekm+vr4aMWJEvveVn9pr166tdevW6csvv1SpUqUUGBioqlWr6qWXXtJXX32lli1b6sUXX1RwcLDmzJmjpUuXasyYMbLZbAVy3q+++qrat2+vNm3aaNiwYbLb7XrzzTcVEBDg0juZn6+V2rVra9GiRfrwww/VoEEDeXh4qGHDhurYsaPGjRunnj17qn///jpz5ozGjh3rEuDyq3jx4nrhhRf07LPP6oEHHtC9996rM2fO6OWXX5avr69eeumly953bnr16qXJkyfr/vvvV79+/XTmzBmNGTMm30MUs+zatUuDBg3SXXfdpSpVqsjb21tr1qzRrl27cu2V8PDw0JgxY3TfffepU6dOevjhh5Wamqq33npL586d0xtvvHG5p+giq1dr+PDhOd7jLCEhQd98841mz56txx57LF/7/ucU+FmaN2+ukiVLasyYMerVq5cefvhh3Xvvvfr99981fPhwtWnTRu3bt3e279+/v4KCgtSoUSOFh4fr9OnTWrBggebPn6+nnnrKpVdr+vTpevDBBzVt2rRs1/tdyrvvvqubbrpJN998sx599FGVL19eCQkJ2r9/v7788kutWbNGktS5c2fVqlVLDRs2VMmSJXX48GGNHz9e5cqVU5UqVRQXF6eWLVuqZ8+eqlatmgIDA7VlyxatWLEiTyHyQl999ZU++OADde3aVRUrVpQxRosWLdK5c+fUpk2bS24fEhKiRx99VEeOHNF1112nZcuW6aOPPtKjjz6qsmXLSpLuuecezZkz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Xq5cOf35558FVhgAAAAAFGX57tlyOByy2+3Zlh87dkyBgYEFUhQAAAAAFHX5Dltt2rTR+PHjnc8tFosSExP10ksvqUOHDgVZGwAAAAAUWfkeRvjOO++oZcuWqlGjhlJSUtSzZ0/9/vvvCg0N1aeffuqOGgEAAACgyMl32IqMjNTOnTv16aefavv27XI4HOrbt6/uu+8+lwkzAAAAAOBalu+wJUl+fn566KGH9NBDDxV0PQAAAABwVbissPXnn3/q+++/V0xMjBwOh8u6IUOGFEhhAAAAAFCU5TtsTZs2TY888oi8vb0VEhIii8XiXGexWAhbAAAAAKDLCFsvvviiXnzxRY0YMUIeHvmezBAAAAAArgn5Tkvnz5/XPffcQ9ACAAAAgFzkOzH17dtXCxYscEctAAAAAHDVyPcwwtGjR6tTp05asWKFateuLS8vL5f148aNK7DiAAAAAKCoynfYGjVqlL7++mtVrVpVkrJNkAEAAAAAuIywNW7cOH3yySfq06ePG8oBAAAAgKtDvq/Z8vHxUbNmzdxRCwAAAABcNfIdth577DG9//777qgFAAAAAK4a+R5G+OOPP2rNmjX66quvVLNmzWwTZCxatKjAigMAAACAoirfYat48eLq1q2bO2oBAAAAgKtGvsPWtGnT3FEHAAAAAFxV8n3N1n/tzz//1P3336+QkBD5+/urXr162rZtm3O9MUYjR45UZGSk/Pz81KJFC+3Zs8dlH6mpqRo8eLBCQ0MVEBCgLl266NixY//1qQAAAAC4huSpZ+v666/XN998oxIlSqh+/fq53k9r+/btBVZcbGysmjVrppYtW2r58uUKCwvTH3/8oeLFizvbjBkzRuPGjdP06dN13XXX6bXXXlObNm20d+9eBQYGSpKGDh2qL7/8UvPmzVNISIiGDRumTp06adu2bfL09CywegEAAAAgS57C1u233y4fHx9JUteuXd1Zj4s333xTUVFRLkMXy5cv7/y/MUbjx4/Xc88957yObMaMGQoPD9fcuXP18MMPKy4uTlOnTtWsWbPUunVrSdLs2bMVFRWl1atXq127dv/Z+QAAAAC4dliMMSYvDR966CG9++67zt6i/0KNGjXUrl07HTt2TOvXr1fp0qU1YMAA9evXT5J04MABVapUSdu3b1f9+vWd291+++0qXry4ZsyYoTVr1qhVq1Y6e/as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stlscjgcqlevngYPHqwmTZooIyNDQ4YM0fbt29WmTRs999xz8vX1LeTqgaKDYYTANSJrqEj9+vUVEhKiTz/91LnO09NT9evXV5UqVbRq1SoNHjy4sMoEAPwHsoLW22+/rTlz5mjevHnavXu37rjjDn355ZcaOXKkvv32W1mtVr333nuqUKGCTpw4IR8fn0KuHChaCFvANWD06NF69913lZKSIm9vb3Xu3FkrV67UzJkznW28vLxUq1Ytbdy4UdOmTSvEagEA/4WYmBht3LhRr7zyipo1a6avvvpKEydO1P33369Tp07plVde0aZNm2S1WjV79mxNmTKF63qBfCJsAdeA+Ph4DRs2TNOnT5eXl5eGDRumsLAwvfvuu+rVq5cmTZqk22+/XUePHlWjRo3k4eEhu91e2GUDANwoLCxMw4cPV/v27bVz504NHDhQr732mj788EPdeeed2rx5swYPHqytW7fK09NTHh4ecjgcXM8L5IO1sAsAULAuvOA5y+jRoxUYGKiBAwfKbrdr4MCBeuedd7Ro0SLNnDlT+/fvV2hoqBYtWuT8ZZo1KxUAoOjL6XeDJF1//fXy8vLSjBkzVKdOHfXr10+SFBwcrBtvvFE333yzrr/+emf7nPYB4OIIW8BVJusX4f79+1W5cmXn8meffVYOh0NDhgyRxWLRgAEDNHjwYA0ePFgJCQkKDAyUJGVkZMhq5UcDAFwtjDHO3w1Tp07VsWPH5OnpqREjRsjLy0uSlJqaqmPHjunQoUOqWrWqVq5cqS5dumjw4MGyWCwXDWsAcsd3DXAVWr58ua677jp9+eWXLsuff/55PfPMM3ryySc1ffp0JSYmSpIzaBljCFoAcBW5cNbB5557To8//rg2bdqkt956S7fccov27t0rSWrYsKG8vLzUuXNn1axZU3v37tWAAQOc12gRtIDLw9TvwFXqf//7nxYuXKjZs2erU6dOzl+4P//8sxo3bqyUlBQtWrRIXbt2LexSAQBudvLkSfXv318jR45U7dq1debMGd16663y8fHRZ599psqVK2vZsmXat2+fkpKS9PTTT8tqtcputzOsHPgXCFtAEZfb0I7//e9/mjdvnubNm6dOnTpJkvbu3atZs2apUqVK6tWrFz1ZAHCVWblypVq0aCFvb29J0vjx4zV58mSVKVNGM2fOVKlSpSRJsbGxuummm+Tt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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "for name, group in df.groupby(['library', 'format']):\n", + " library, format = name\n", + " x = f'{library}, {format}'\n", + " y = group['time'].mean()\n", + " ax.bar(f'{library}, {format}', group['time'].mean(), label=f'{library}, {format}', align='center')\n", + " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=12)\n", + " ax.text(x, y - (y/2) - 10, f'Total Requests: {group[\"total_requests\"].mean()}', ha='center', va='bottom', color='black', fontsize=8)\n", + " ax.text(x, y - (y/2.5), f'Total Req Bytes (MB): {round(group[\"total_requested_bytes\"].mean() / (1024*1024) , 2)}', ha='center', va='bottom', color='black', fontsize=8)\n", + "\n", + "# Set labels and title\n", + "ax.set_xlabel('Access Pattern')\n", + "ax.set_ylabel('Time in Seconds')\n", + "ax.set_title(f'mean() on photon data for runs on ATL03, less is better ')\n", + "\n", + "# Rotate x-axis labels for better readability\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "# # Show legend\n", + "# ax.legend()\n", + "\n", + "# Show the plot\n", + "with plt.xkcd():\n", + " # This figure will be in XKCD-style\n", + " fig1 = plt.figure()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a5fe2e281fcf84156d76a8ffbfd112acb428ad0e Mon Sep 17 00:00:00 2001 From: betolink Date: Mon, 5 Feb 2024 19:57:25 -0600 Subject: [PATCH 04/11] h5coro needs some upstream changes to work with annon=True access --- h5tests/h5coro_arr_mean.py | 17 ++- notebooks/portable-h5coro-test.ipynb | 162 +++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 notebooks/portable-h5coro-test.ipynb diff --git a/h5tests/h5coro_arr_mean.py b/h5tests/h5coro_arr_mean.py index 58b3f76..5f93fcc 100644 --- a/h5tests/h5coro_arr_mean.py +++ b/h5tests/h5coro_arr_mean.py @@ -1,4 +1,4 @@ -from .h5test import H5Test, timer_decorator +from h5test import H5Test, timer_decorator import numpy as np import subprocess @@ -12,15 +12,22 @@ from h5coro import h5coro, s3driver, filedriver h5coro.config(errorChecking=True, verbose=False, enableAttributes=False) + +driver = s3driver.S3Driver class H5CoroArrMean(H5Test): @timer_decorator - def run(self): - group = '/gt1l/heights' - variable = 'h_ph' + def run(self, dataset="/gt1l/heights", variable="h_ph"): + group = dataset + variable = variable final_h5coro_array = [] + if self.files[0].startswith("s3://cryo"): + credentials = {} + else: + credentials = {"region_name": "us-west-2", + "anon": True} for file in self.files: - h5obj = h5coro.H5Coro(file.replace("s3://", ""), s3driver.S3Driver) + h5obj = h5coro.H5Coro(file.replace("s3://", ""), s3driver.S3Driver, credentials=credentials) output = h5obj.readDatasets(datasets=[f'{group}/{variable}'], block=True) data = h5obj[f'{group}/{variable}'].values final_h5coro_array = np.insert(final_h5coro_array, len(final_h5coro_array), data, axis=None) diff --git a/notebooks/portable-h5coro-test.ipynb b/notebooks/portable-h5coro-test.ipynb new file mode 100644 index 0000000..df2394f --- /dev/null +++ b/notebooks/portable-h5coro-test.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload \n", + "\n", + "import sys\n", + "import os\n", + "classes_path = os.path.abspath('../h5tests/')\n", + "sys.path.append(classes_path)\n", + "from h5coro_arr_mean import H5CoroArrMean\n", + "import pandas as pd\n", + "\n", + "benchmarks = []" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "original_granules = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + "]\n", + "h5coro_original = H5CoroArrMean('atl03-bigsize-original', files=original_granules, store_results=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "ename": "FatalError", + "evalue": "invalid credential keys provided, looking for: aws_access_key_id, aws_secret_access_key, and aws_session_token", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mFatalError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[3], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# takes about ~30 seconds per granule out of region (6+ GB granules)\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[43mh5coro_original\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3\u001b[0m benchmarks\u001b[38;5;241m.\u001b[39mappend({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlibrary\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mh5coro\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 4\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mformat\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124moriginal\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 5\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmean\u001b[39m\u001b[38;5;124m\"\u001b[39m: results[\u001b[38;5;241m0\u001b[39m],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtotal_requests\u001b[39m\u001b[38;5;124m\"\u001b[39m: results[\u001b[38;5;241m3\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtotal_reqs\u001b[39m\u001b[38;5;124m\"\u001b[39m],\n\u001b[1;32m 9\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mavg_req_size\u001b[39m\u001b[38;5;124m\"\u001b[39m: results[\u001b[38;5;241m3\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mavg_req_size\u001b[39m\u001b[38;5;124m\"\u001b[39m]})\n\u001b[1;32m 10\u001b[0m benchmarks\n", + "File \u001b[0;32m~/work/openscapes/h5cloud/h5tests/h5test.py:95\u001b[0m, in \u001b[0;36mtimer_decorator..wrapper\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 93\u001b[0m __setup_logging(\u001b[38;5;28mself\u001b[39m, tstamp)\n\u001b[1;32m 94\u001b[0m start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[0;32m---> 95\u001b[0m result \u001b[38;5;241m=\u001b[39m \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\u001b[1;32m 96\u001b[0m end_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[1;32m 97\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlogs_regex:\n", + "File \u001b[0;32m~/work/openscapes/h5cloud/h5tests/h5coro_arr_mean.py:30\u001b[0m, in \u001b[0;36mH5CoroArrMean.run\u001b[0;34m(self, dataset, variable)\u001b[0m\n\u001b[1;32m 27\u001b[0m credentials \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mregion_name\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mus-west-2\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 28\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manon\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28;01mTrue\u001b[39;00m}\n\u001b[1;32m 29\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m file \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfiles:\n\u001b[0;32m---> 30\u001b[0m h5obj \u001b[38;5;241m=\u001b[39m \u001b[43mh5coro\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mH5Coro\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfile\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreplace\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43ms3://\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43ms3driver\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mS3Driver\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcredentials\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcredentials\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 31\u001b[0m output \u001b[38;5;241m=\u001b[39m h5obj\u001b[38;5;241m.\u001b[39mreadDatasets(datasets\u001b[38;5;241m=\u001b[39m[\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgroup\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mvariable\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m], block\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m 32\u001b[0m data \u001b[38;5;241m=\u001b[39m h5obj[\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgroup\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mvariable\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mvalues\n", + "File \u001b[0;32m~/.pyenv/versions/mambaforge/envs/h5cloud/lib/python3.12/site-packages/h5coro/h5coro.py:2020\u001b[0m, in \u001b[0;36mH5Coro.__init__\u001b[0;34m(self, resource, driver_class, credentials, datasets, block)\u001b[0m\n\u001b[1;32m 2018\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__init__\u001b[39m(\u001b[38;5;28mself\u001b[39m, resource, driver_class, credentials\u001b[38;5;241m=\u001b[39m{}, datasets\u001b[38;5;241m=\u001b[39m[], block\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m):\n\u001b[1;32m 2019\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mresource \u001b[38;5;241m=\u001b[39m resource\n\u001b[0;32m-> 2020\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdriver \u001b[38;5;241m=\u001b[39m \u001b[43mdriver_class\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresource\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcredentials\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2022\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcache \u001b[38;5;241m=\u001b[39m {}\n\u001b[1;32m 2023\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmetaDataTable \u001b[38;5;241m=\u001b[39m {}\n", + "File \u001b[0;32m~/.pyenv/versions/mambaforge/envs/h5cloud/lib/python3.12/site-packages/h5coro/s3driver.py:43\u001b[0m, in \u001b[0;36mS3Driver.__init__\u001b[0;34m(self, resource, credentials)\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msession \u001b[38;5;241m=\u001b[39m boto3\u001b[38;5;241m.\u001b[39mSession()\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 43\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m FatalError(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minvalid credential keys provided, looking for: aws_access_key_id, aws_secret_access_key, and aws_session_token\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 45\u001b[0m \u001b[38;5;66;03m# open resource\u001b[39;00m\n\u001b[1;32m 46\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mobj \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msession\u001b[38;5;241m.\u001b[39mresource(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ms3\u001b[39m\u001b[38;5;124m'\u001b[39m)\u001b[38;5;241m.\u001b[39mObject(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mresourcePath[\u001b[38;5;241m0\u001b[39m], \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;241m.\u001b[39mjoin(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mresourcePath[\u001b[38;5;241m1\u001b[39m:]))\n", + "\u001b[0;31mFatalError\u001b[0m: invalid credential keys provided, looking for: aws_access_key_id, aws_secret_access_key, and aws_session_token" + ] + } + ], + "source": [ + "# takes about ~30 seconds per granule out of region (6+ GB granules)\n", + "results = h5coro_original.run()\n", + "benchmarks.append({\"library\": \"h5coro\",\n", + " \"format\": \"original\",\n", + " \"mean\": results[0],\n", + " \"time\": results[1],\n", + " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", + " \"total_requests\": results[3][\"total_reqs\"],\n", + " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", + "benchmarks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", + "metadata": {}, + "outputs": [], + "source": [ + "cloud_optimized_granules = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", + "]\n", + "h5py_cloud = H5pyArrMean('atl03-bigsize-repacked', files=cloud_optimized_granules, store_results=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d30d92b-4192-4da1-8b60-41cc94ca2db1", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(benchmarks)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ff4c22f-7f77-4c69-a84c-f13b0fbba1f2", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "\n", + "for name, group in df.groupby(['library', 'format']):\n", + " library, format = name\n", + " x = f'{library}, {format}'\n", + " y = group['time'].mean()\n", + " ax.bar(f'{library}, {format}', group['time'].mean(), label=f'{library}, {format}', align='center')\n", + " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=12)\n", + " ax.text(x, y - (y/2) - 10, f'Total Requests: {group[\"total_requests\"].mean()}', ha='center', va='bottom', color='black', fontsize=8)\n", + " ax.text(x, y - (y/2.5), f'Total Req Bytes (MB): {round(group[\"total_requested_bytes\"].mean() / (1024*1024) , 2)}', ha='center', va='bottom', color='black', fontsize=8)\n", + "\n", + "# Set labels and title\n", + "ax.set_xlabel('Access Pattern')\n", + "ax.set_ylabel('Time in Seconds')\n", + "ax.set_title(f'mean() on photon data for runs on ATL03, less is better ')\n", + "\n", + "# Rotate x-axis labels for better readability\n", + "plt.xticks(rotation=45, ha='right')\n", + "\n", + "# # Show legend\n", + "# ax.legend()\n", + "\n", + "# Show the plot\n", + "with plt.xkcd():\n", + " # This figure will be in XKCD-style\n", + " fig1 = plt.figure()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a7a891dbf5002028dbdea8d39c5610a3a259d907 Mon Sep 17 00:00:00 2001 From: betolink Date: Mon, 12 Feb 2024 10:19:30 -0600 Subject: [PATCH 05/11] refactoring the whole thing --- h5tests/h5coro_arr_mean.py | 44 ++- h5tests/h5py_arr_mean.py | 5 +- h5tests/h5py_arr_subset_mean.py | 44 +-- h5tests/h5test.py | 191 +++++----- h5tests/single-test.ipynb | 249 +++++-------- h5tests/xarray_arr_mean.py | 4 +- .../01_data-selection.ipynb | 0 .../arr_mean_bar_plot.png | Bin .../benchmark-h5repack.ipynb | 0 .../benchmark-small-file-h5repack.ipynb | 0 .../benchmarks-outline.ipynb | 0 .../cloud-optimized-hdf5.ipynb | 0 .../convert_h5dataframe2flatgeobuf.ipynb | 0 .../example-list-test-files.ipynb | 0 .../format-preprocessing-times.ipynb | 0 .../{ => data-wrangling}/fsspec-logs.ipynb | 0 .../h5coro_benchmarks.ipynb | 0 ...ng_original_repacked_with_subsetting.ipynb | 0 .../{ => data-wrangling}/kerchunker.ipynb | 0 .../{ => data-wrangling}/read-results.ipynb | 0 .../data-wrangling/ros3vfd-log-info.ipynb | 344 ++++++++++++++++++ .../{ => data-wrangling}/run-tests.ipynb | 0 .../sliderule2geoparquet.ipynb | 0 .../xarray-h5coro-backend.ipynb | 0 notebooks/portable-full-comparison.ipynb | 1 + notebooks/portable-h5py-test.ipynb | 192 ++-------- 26 files changed, 628 insertions(+), 446 deletions(-) rename notebooks/{ => data-wrangling}/01_data-selection.ipynb (100%) rename notebooks/{ => data-wrangling}/arr_mean_bar_plot.png (100%) rename notebooks/{ => data-wrangling}/benchmark-h5repack.ipynb (100%) rename notebooks/{ => data-wrangling}/benchmark-small-file-h5repack.ipynb (100%) rename notebooks/{ => data-wrangling}/benchmarks-outline.ipynb (100%) rename notebooks/{ => data-wrangling}/cloud-optimized-hdf5.ipynb (100%) rename notebooks/{ => data-wrangling}/convert_h5dataframe2flatgeobuf.ipynb (100%) rename notebooks/{ => data-wrangling}/example-list-test-files.ipynb (100%) rename notebooks/{ => data-wrangling}/format-preprocessing-times.ipynb (100%) rename notebooks/{ => data-wrangling}/fsspec-logs.ipynb (100%) rename notebooks/{ => data-wrangling}/h5coro_benchmarks.ipynb (100%) rename notebooks/{ => data-wrangling}/h5py_testing_original_repacked_with_subsetting.ipynb (100%) rename notebooks/{ => data-wrangling}/kerchunker.ipynb (100%) rename notebooks/{ => data-wrangling}/read-results.ipynb (100%) create mode 100644 notebooks/data-wrangling/ros3vfd-log-info.ipynb rename notebooks/{ => data-wrangling}/run-tests.ipynb (100%) rename notebooks/{ => data-wrangling}/sliderule2geoparquet.ipynb (100%) rename notebooks/{ => data-wrangling}/xarray-h5coro-backend.ipynb (100%) create mode 100644 notebooks/portable-full-comparison.ipynb diff --git a/h5tests/h5coro_arr_mean.py b/h5tests/h5coro_arr_mean.py index 5f93fcc..6969c4a 100644 --- a/h5tests/h5coro_arr_mean.py +++ b/h5tests/h5coro_arr_mean.py @@ -1,34 +1,40 @@ -from h5test import H5Test, timer_decorator -import numpy as np import subprocess +import numpy as np +from h5test import H5Test, timer_decorator + try: import h5coro except: - completed_process = subprocess.run([ - 'mamba', 'install', '-c', 'conda-forge', 'h5coro', '--yes' - ]) + completed_process = subprocess.run( + ["pip", "install", "git+https://github.com/ICESat2-SlideRule/h5coro.git@main"] + ) import h5coro -from h5coro import h5coro, s3driver, filedriver -h5coro.config(errorChecking=True, verbose=False, enableAttributes=False) +from h5coro import h5coro, s3driver + +driver = s3driver.S3Driver + -driver = s3driver.S3Driver - class H5CoroArrMean(H5Test): @timer_decorator def run(self, dataset="/gt1l/heights", variable="h_ph"): group = dataset - variable = variable + variable = variable final_h5coro_array = [] - if self.files[0].startswith("s3://cryo"): - credentials = {} - else: - credentials = {"region_name": "us-west-2", - "anon": True} + for file in self.files: - h5obj = h5coro.H5Coro(file.replace("s3://", ""), s3driver.S3Driver, credentials=credentials) - output = h5obj.readDatasets(datasets=[f'{group}/{variable}'], block=True) - data = h5obj[f'{group}/{variable}'].values - final_h5coro_array = np.insert(final_h5coro_array, len(final_h5coro_array), data, axis=None) + if link.startswith("s3://nasa-cryo-persistent/"): + h5obj = h5coro.H5Coro(link.replace("s3://", ""), s3driver.S3Driver) + else: + h5obj = h5coro.H5Coro( + link.replace("s3://", ""), + s3driver.S3Driver, + credentials={"annon": True}, + ) + ds = h5obj.readDatasets(datasets=[f"{group}/{variable}"], block=True) + data = ds[f"{group}/{variable}"][:] + final_h5coro_array = np.insert( + final_h5coro_array, len(final_h5coro_array), data, axis=None + ) return np.mean(final_h5coro_array) diff --git a/h5tests/h5py_arr_mean.py b/h5tests/h5py_arr_mean.py index d49431f..8e059cf 100644 --- a/h5tests/h5py_arr_mean.py +++ b/h5tests/h5py_arr_mean.py @@ -1,11 +1,11 @@ import h5py import numpy as np - -from h5test import H5Test, timer_decorator +from h5test import H5Test, fsspec_logging_decorator, timer_decorator class H5pyArrMean(H5Test): @timer_decorator + @fsspec_logging_decorator def run(self, io_params={}, dataset="/gt1l/heights", variable="h_ph"): final_h5py_array = [] fsspec_params = {} @@ -14,6 +14,7 @@ def run(self, io_params={}, dataset="/gt1l/heights", variable="h_ph"): fsspec_params = io_params["fsspec_params"] if "h5py_params" in io_params: h5py_params = io_params["h5py_params"] + self.file_sizes = [self.s3_fs.info(file)["size"] for file in self.files] for file in self.files: with self.s3_fs.open(file, mode="rb", **fsspec_params) as fo: print("h5py params: ", h5py_params) diff --git a/h5tests/h5py_arr_subset_mean.py b/h5tests/h5py_arr_subset_mean.py index e8ceeea..f2c2629 100644 --- a/h5tests/h5py_arr_subset_mean.py +++ b/h5tests/h5py_arr_subset_mean.py @@ -1,16 +1,16 @@ import os import sys -from .h5test import H5Test, timer_decorator import h5py import numpy as np +from h5test import H5Test, fsspec_logging_decorator, timer_decorator -current = os.path.abspath('..') +current = os.path.abspath("..") sys.path.append(current) -from helpers.geospatial import get_subset_region, get_subset_indices +from helpers.geospatial import get_subset_indices, get_subset_region + class H5pyArrSubsetMean(H5Test): - def __init__(self, data_format, geometry=None): """ geometry : path to geojson file containing geometry @@ -18,32 +18,34 @@ def __init__(self, data_format, geometry=None): """ super().__init__(data_format) self.bounds = get_subset_region(geometry) - + @timer_decorator - def run(self): - final_h5py_array = [] + @fsspec_logging_decorator + def run(self, io_params={}, dataset="/gt1l/heights", variable="h_ph"): + final_h5py_array = [] # TODO: Do we need to make this configurable or consistent? - group = '/gt1l/heights' - variable = 'h_ph' + if "fsspec_params" in io_params: + fsspec_params = io_params["fsspec_params"] + if "h5py_params" in io_params: + h5py_params = io_params["h5py_params"] for file in self.files: - with h5py.File(self.s3_fs.open(file, 'rb')) as f: - - lat = f[f'{group}/lat_ph'][:] - lon = f[f'{group}/lon_ph'][:] - + with h5py.File( + self.s3_fs.open(file, "rb", **fsspec_params), **h5py_params + ) as f: + lat = f[f"{dataset}/lat_ph"][:] + lon = f[f"{dataset}/lon_ph"][:] + idx_start, idx_end = get_subset_indices(lat, lon, self.bounds) - + # Leaving this code here so that we can create a DataFrame or - # Dataset at a later date. Suggest creating dict which can be + # Dataset at a later date. Suggest creating dict which can be # passsed to xarray or (geo)pandas # lat[idx_start:idx_end]) # lon[idx_start:idx_end]) - data = f[f'{group}/{variable}'][idx_start:idx_end] + data = f[f"{dataset}/{variable}"][idx_start:idx_end] # Need to test if using concatenate is faster final_h5py_array = np.insert( - final_h5py_array, - len(final_h5py_array), - data, axis=None + final_h5py_array, len(final_h5py_array), data, axis=None ) - return np.mean(final_h5py_array) \ No newline at end of file + return np.mean(final_h5py_array) diff --git a/h5tests/h5test.py b/h5tests/h5test.py index e7310cc..b77e81c 100644 --- a/h5tests/h5test.py +++ b/h5tests/h5test.py @@ -1,7 +1,7 @@ import csv import logging import os -import re +import pathlib import sys import time from datetime import datetime @@ -14,47 +14,34 @@ sys.path.append(current) -import csv -import logging -import os -import pathlib -import re -import time -from datetime import datetime -from io import StringIO - -import boto3 -import fsspec -import h5py -import numpy as np -import pandas as pd -import s3fs -import xarray as xr -from tqdm import tqdm - - -class RegexFilter(logging.Filter): - def __init__(self, regex_pattern): - super(RegexFilter, self).__init__() - self.regex_pattern = re.compile(regex_pattern) - - def filter(self, record): - # Apply the regex pattern to the log message - return not bool(self.regex_pattern.search(record.msg)) - - -def timer_decorator(func): +def fsspec_logging_decorator(func): """ - A decorator to measure the execution time of the wrapped function. + It will store the fsspec logs inside ./logs and will get some stats from file access + Will pass values to timer_decorator """ + def __setup_logging(self): + pathlib.Path(f"./logs").mkdir(exist_ok=True) + logger = logging.getLogger("fsspec") + logger.setLevel(logging.DEBUG) + self._file_handler = logging.FileHandler(self.log_filename) + self._file_handler.setLevel(logging.DEBUG) + logging.getLogger("fsspec").addHandler(self._file_handler) + + def __turnoff_logging(self): + [ + logging.getLogger("fsspec").debug(f"FileSize: {size}") + for size in self.file_sizes + ] + logging.getLogger("fsspec").removeHandler(self._file_handler) + self._file_handler.close() + def fsspec_stats(log_file): + stats = None with open(log_file, "r") as input_file: num_requests = 0 total_requested_bytes = 0 for line in input_file: - # Strip leading and trailing whitespaces from the line - try: read_range = line.split("read:")[1].split(" - ") request_size = int(read_range[1]) - int(read_range[0]) @@ -62,47 +49,57 @@ def fsspec_stats(log_file): num_requests += 1 except Exception: pass - stats = { - "total_reqs": num_requests, - "total_reqs_bytes": total_requested_bytes, - "avg_req_size": int(round(total_requested_bytes / num_requests, 2)), - } + if total_requested_bytes > 0: + stats = { + "total_reqs": num_requests, + "total_reqs_bytes": total_requested_bytes, + "avg_req_size": int(round(total_requested_bytes / num_requests, 2)), + } return stats - def __setup_logging(self, tstamp): - pathlib.Path(f"./logs").mkdir(exist_ok=True) + def wrapper(self, *args, **kwargs): + tstamp = datetime.now().strftime("%Y-%m-%d-%H%M%S") self.log_filename = f"logs/{self.data_format}-{tstamp}.log" - logger = logging.getLogger("fsspec") - logger.setLevel(logging.DEBUG) - self.regex_filter = RegexFilter(self.logs_regex) - # add regerx to root logger - logging.getLogger("fsspec").addFilter(self.regex_filter) - self._file_handler = logging.FileHandler(self.log_filename) - self._file_handler.setLevel(logging.DEBUG) - # Add the handler to the root logger - logging.getLogger("fsspec").addHandler(self._file_handler) - def __turnoff_logging(self): - logging.getLogger("fsspec").removeFilter(self.regex_filter) - logging.getLogger("fsspec").removeHandler(self._file_handler) - self._file_handler.close() + __setup_logging(self) + result = func(self, *args, **kwargs) + __turnoff_logging(self) + + self.io_stats = fsspec_stats(self.log_filename) + return result, {"logs": self.log_filename, "io_stats": self.io_stats} + + return wrapper + + +def timer_decorator(func): + """ + A decorator to measure the execution time of the wrapped function. + """ def wrapper(self, *args, **kwargs): tstamp = datetime.now().strftime("%Y-%m-%d-%H%M%S") - if self.logs_regex: - __setup_logging(self, tstamp) + start_time = time.time() result = func(self, *args, **kwargs) end_time = time.time() - if self.logs_regex: - __turnoff_logging(self) execution_time = end_time - start_time + if "io_params" in kwargs: + self.runtime_params = kwargs["io_params"] + if len(args) > 0: + self.runtime_params = args[0] + # Call the store method here - self.io_stats = fsspec_stats(self.log_filename) if self.store_results: + if type(result) in [list, dict, tuple]: + # unpack + func_result, _ = result + else: + func_result = result results_key = f"{tstamp}_{self.name}_{self.data_format}_results.csv" - self.store(run_time=execution_time, result=result, file_name=results_key) - return result, execution_time, self.log_filename, self.io_stats + self.store( + run_time=execution_time, result=func_result, file_name=results_key + ) + return result, {"execution_time": execution_time} return wrapper @@ -113,13 +110,12 @@ def __init__( data_format: str, files=[], store_results=True, - logs_regex=r"\s*(read: \d+ - \d+)", ): self.name = self.__class__.__name__ - self.io_stats = {} + self.io_stats = None + self.runtime_params = None self.log_filename = "" self.data_format = data_format - self.logs_regex = logs_regex if len(files) > 0: self.files = files else: @@ -140,6 +136,7 @@ def __init__( self.results_store_type = "Local" self.s3_fs = s3fs.S3FileSystem(anon=self.annon_access) + self.file_sizes = [self.s3_fs.info(file)["size"] for file in self.files] @timer_decorator def run(self, io_params, dataset, variable): @@ -155,28 +152,50 @@ def store(self, run_time: float, result: str, file_name: str): # Create a CSV in-memory csv_buffer = StringIO() csv_writer = csv.writer(csv_buffer) - csv_writer.writerow( - [ - "Name", - "Data Format", - "Run Time", - "Result", - "Access Log", - "Total Bytes Tranferred", - "Total Requests", - ] - ) # Headers - csv_writer.writerow( - [ - self.name, - self.data_format, - run_time, - result, - self.log_filename, - self.io_stats["total_reqs_bytes"], - self.io_stats["total_reqs"], - ] - ) + if self.io_stats: # if we are using the fsspec logger decorator + csv_writer.writerow( + [ + "Name", + "Data Format", + "Run Time", + "Result", + "Runtime Params", + "Access Log", + "Total Bytes Tranferred", + "Total Requests", + "Average Request Size", + ] + ) # Headers + csv_writer.writerow( + [ + self.name, + self.data_format, + run_time, + result, + self.runtime_params, + self.log_filename, + self.io_stats["total_reqs_bytes"], + self.io_stats["total_reqs"], + self.io_stats["avg_req_size"], + ] + ) + else: + csv_writer.writerow( + [ + "Name", + "Data Format", + "Run Time", + "Result", + ] + ) # Headers + csv_writer.writerow( + [ + self.name, + self.data_format, + run_time, + result, + ] + ) # Reset the buffer's position to the beginning csv_buffer.seek(0) diff --git a/h5tests/single-test.ipynb b/h5tests/single-test.ipynb index 165aabc..cd7a3e0 100644 --- a/h5tests/single-test.ipynb +++ b/h5tests/single-test.ipynb @@ -1,22 +1,27 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "a1039b23-f008-4740-adbd-bafb8eaccfd2", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Testing access time on ICESat-2 ATL03 HDF5 files in AWS S3.\n", + "\n", + "This notebook runs a single test from the different access patterns and stores the results in `results/` and `logs/`\n", + "If we use files in the CryoCloud the results will be send to the S3 bucket `s3://nasa-cryo-persistent/h5cloud/benchmark_results/`\n" + ] + }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - } - ], + "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload \n", @@ -33,141 +38,50 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 2, "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", "metadata": { "tags": [] }, "outputs": [], "source": [ - "files = [\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + "granules = [\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20200922221235_13680801_006_02.h5\",\n", + " # \"s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20191225111315_13680501_006_01.h5\",\n", "]\n", - "xarray_original = XarrayArrMean('atl03-bigsize-original', files=files, store_results=True)" + "\n", + "# We create the test cases for each kind of granule.\n", + "xarray_test = XarrayArrMean('atl03-xarray-original', files=granules, store_results=True)" ] }, { - "cell_type": "code", - "execution_count": 24, - "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", + "cell_type": "markdown", + "id": "33dcde98-df71-4e49-b051-f67c865981c6", "metadata": { - "tags": [] + "tags": [], + "user_expressions": [] }, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'library': 'xarray',\n", - " 'format': 'cloud',\n", - " 'mean': 1032.984130859375,\n", - " 'time': 176.90762186050415,\n", - " 'total_requested_bytes': 720001152,\n", - " 'total_requests': 100,\n", - " 'avg_req_size': 7200011},\n", - " {'library': 'xarray',\n", - " 'format': 'original',\n", - " 'mean': 1032.984130859375,\n", - " 'time': 1456.8166418075562,\n", - " 'total_requested_bytes': 438520591,\n", - " 'total_requests': 26988,\n", - " 'avg_req_size': 16248}]" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# don't even try this out of region...\n", - "# takes about ~10 minutes per granule out of region (6+ GB granules)\n", - "io_params ={\n", - " \"fsspec_params\": {},\n", - " \"h5py_params\" : {}\n", - "}\n", - "results = xarray_original.run(io_params)\n", - "benchmarks.append({\"library\": \"xarray\",\n", - " \"format\": \"original\",\n", - " \"mean\": results[0],\n", - " \"time\": results[1],\n", - " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", - " \"total_requests\": results[3][\"total_reqs\"],\n", - " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", - "benchmarks" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", - "metadata": {}, - "outputs": [], "source": [ - "files = [\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", - "]\n", - "xarray_cloud = XarrayArrMean('atl03-bigsize-repacked', files=files, store_results=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "dfd4e404-0412-4d2f-8eba-ca39a670e369", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'library': 'xarray',\n", - " 'format': 'cloud',\n", - " 'mean': 1032.984130859375,\n", - " 'time': 176.90762186050415,\n", - " 'total_requested_bytes': 720001152,\n", - " 'total_requests': 100,\n", - " 'avg_req_size': 7200011}]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# takes about ~90 seconds per granule out of region\n", - "io_params ={\n", - " \"fsspec_params\": {\n", - " # \"skip_instance_cache\": True\n", - " \"cache_type\": \"blockcache\",\n", - " \"block_size\": 8*1024*1024\n", - " },\n", - " \"h5py_params\" : {\n", - " \"driver_kwds\": {\n", - " \"page_buf_size\": 32*1024*1024,\n", - " \"rdcc_nbytes\": 8*1024*1024\n", - " }\n", + "### Benchmarking access patterns \n", "\n", - " }\n", + "```python\n", + "io_params ={\n", + " \"fsspec_params\": {}, # if we use fsspec we can pass io params here\n", + " \"h5py_params\" : {} # if we use h5py we can pass io params here\n", "}\n", + "```\n", "\n", - "results = xarray_cloud.run(io_params)\n", - "\n", - "benchmarks.append({\"library\": \"xarray\",\n", - " \"format\": \"cloud\",\n", - " \"mean\": results[0],\n", - " \"time\": results[1],\n", - " \"total_requested_bytes\": results[3][\"total_reqs_bytes\"],\n", - " \"total_requests\": results[3][\"total_reqs\"],\n", - " \"avg_req_size\": results[3][\"avg_req_size\"]})\n", - "benchmarks" + "Accesing ATL03 with Xarray takes considerably longer than using h5py directly, this is mainly due the decoding and metadata that Xarray uses to represent the data.\n", + "Using Xarray it takes approx ~10 minutes per granule out of region (6+ GB granules) and ~2 minutes per granule in-region (6+ GB granules) when we access the non optimized granules.\n" ] }, { "cell_type": "code", - "execution_count": 25, - "id": "9d30d92b-4192-4da1-8b60-41cc94ca2db1", - "metadata": {}, + "execution_count": 3, + "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", + "metadata": { + "tags": [] + }, "outputs": [ { "data": { @@ -203,56 +117,85 @@ " \n", " 0\n", " xarray\n", - " cloud\n", - " 1032.984131\n", - " 176.907622\n", - " 720001152\n", - " 100\n", - " 7200011\n", - " \n", - " \n", - " 1\n", - " xarray\n", " original\n", - " 1032.984131\n", - " 1456.816642\n", - " 438520591\n", - " 26988\n", - " 16248\n", + " 18.128136\n", + " 70.16828\n", + " 50852992\n", + " 3828\n", + " 13284\n", " \n", " \n", "\n", "" ], "text/plain": [ - " library format mean time total_requested_bytes \\\n", - "0 xarray cloud 1032.984131 176.907622 720001152 \n", - "1 xarray original 1032.984131 1456.816642 438520591 \n", + " library format mean time total_requested_bytes \\\n", + "0 xarray original 18.128136 70.16828 50852992 \n", "\n", " total_requests avg_req_size \n", - "0 100 7200011 \n", - "1 26988 16248 " + "0 3828 13284 " ] }, - "execution_count": 25, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "# we don't need this when using the original granules.\n", + "io_params ={\n", + " \"fsspec_params\": {\n", + " # \"cache_type\": \"blockcache\",\n", + " # \"block_size\": 8*1024*1024\n", + " },\n", + " \"h5py_params\" : {\n", + "# \"driver_kwds\": {\n", + "# \"page_buf_size\": 64*1024*1024,\n", + "# \"rdcc_nbytes\": 8*1024*1024\n", + "# }\n", + "\n", + " }\n", + "}\n", + "\n", + "# this info gets stored in logs and csv files as usual but we want to plot them here too.\n", + "execution_info, execution_time = xarray_test.run(io_params)\n", + "\n", + "io_stats = execution_info[1][\"io_stats\"]\n", + "\n", + "benchmarks.append({\"library\": \"xarray\",\n", + " \"format\": \"original\",\n", + " \"mean\": execution_info[0],\n", + " \"time\": execution_time[\"execution_time\"],\n", + " \"total_requested_bytes\": io_stats[\"total_reqs_bytes\"],\n", + " \"total_requests\": io_stats[\"total_reqs\"],\n", + " \"avg_req_size\": io_stats[\"avg_req_size\"]})\n", + "\n", "df = pd.DataFrame.from_dict(benchmarks)\n", "df" ] }, + { + "cell_type": "markdown", + "id": "3d41bada-8735-4973-8536-bd9050b2e31f", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Plotting the resuls\n" + ] + }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 4, "id": "3ff4c22f-7f77-4c69-a84c-f13b0fbba1f2", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [ { "data": { - "image/png": "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kZHhfLRr104Wi0Xr1q1ztt2xY4e6dOmikJAQeXp6ysvLSw888IDsdrv27dvncvyIiIhs18rUqVPH5djHjx+XJIWFheV4Tl5eXipevLj+/PPPXM99zZo1CggIUPfu3V2WZw0d++abb1yWZ13HkSU8PFxhYWEuteWmZ8+eLsPdypUrp6ZNm2rt2rUu7SwWizp37uyy7J+vQX5rz8maNWvUqlUrRUVFZdvH+fPnsw0R69KlS7aaJOV6/klJSdqyZYu6desmX19f5/LAwMBs5yjl72slt/Nq3bq1bDabcx8vvviizpw5o5iYmDzt40KbNm1ScnKyy5BCSYqKitKtt96a42t955135usY+W2fk44dO8rT09P5/J/vT3BwsCpVqqS33npL48aN044dO7INz83J3r17dfz4cfXq1UseHn//Oi9WrJjuvPNObd68WefPn3fZJqevlZSUlEu+/omJifrss8/UtGlTVatWTVLmdZiVKlXS9OnT81Tv5brYtTg5LX/22We1ZcsWLV26VA899JAGDRp00aGx+ZWSkqJvvvlGd9xxh/z9/V1+vnbo0EEpKSnO4aGNGjXSTz/9pAEDBujrr79WfHx8tv01atRI06dP12uvvabNmzdnG76dV5UrV1aJEiX09NNPa9KkSfrll1/ytX1gYGC2r4uePXvK4XDo22+/lZT5e6V48eLq3Lmzy3nXq1dPERERLr9X8mv//v367bffdN9990lSttf1xIkT2YZFF8T3JfBfIWwBV6jg4GCX597e3vL393f5YJy1PGtGMEk6efKkdu3aJS8vL5dHYGCgjDE6ffq0JOnIkSO6+eab9eeff+rdd9/Vd999py1btjivPUhOTnY5TkhISLYafXx8XNpl/f+fNV7I19c3277/6cyZM4qIiMj2YSosLExWq1VnzpzJd225iYiIyHHZP4+T0+vv4+Pj8vrnt/acnDlzJseZxiIjI53rL/TP8/fx8ZGU/T28UGxsrBwOx0XP/UL5/VrJyY8//qi2bdtKkj766CN9//332rJli5577rk87+Ofsl6Hi71WOb1/QUFB+TpGQcz4dqn3x2Kx6JtvvlG7du00ZswYXX/99SpZsqSGDBmS6/WNlzp/h8Oh2NjYfNVyMfPnz1diYqJ69Oihc+fO6dy5c4qLi1OPHj109OhRrVq1KtftL0dWrTl9z5w9ezbbz0hJKlu2rBo2bKgOHTroww8/VP/+/TVixAiX64ou15kzZ5SRkaH3338/28/XDh06SJLz5+uIESM0duxYbd68WbfddptCQkLUqlUrbd261bm/+fPnq3fv3vr444/VpEkTBQcH64EHHlB0dHS+6rLZbFq/fr3q1aunZ599VjVr1lRkZKReeumlPAW48PDwbMuyfgZkvfYnT57UuXPn5O3tne3co6Ojned9OU6ePClJevLJJ7Pte8CAAZKUbf9X6kyMQE6YjRC4yoSGhuZ64XpoaKgkafHixUpKStKiRYtcpmj/N9PyZu377NmzF20TGxvrbHcxISEh+uGHH2SMcQktMTExysjIuOT2+ZXTh5vo6OgcQ9ylFETtISEhOnHiRLblWT2HBXH+JUqUkMViuei5X6ggvlbmzZsnLy8vffXVVy6B9d9MfZ/1/lzstfrn63Q5s5XltI2vr2+Ok0r8mw+c5cqV09SpUyVJ+/bt02effaaRI0cqLS1NkyZNynGbS52/h4eHSpQocdk1XSirtqFDh+Z4v7ypU6eqXbt2BXKsLLVr15Yk/fzzz6pRo4ZzeUZGhn777Tfde++9l9xHo0aNNGnSJB04cOBfz+BXokQJeXp6qlevXho4cGCObSpUqCApc9TBE088oSeeeELnzp3T6tWr9eyzz6pdu3Y6evSo/P39FRoaqvHjx2v8+PE6cuSIlixZomeeeUYxMTFasWJFvmqrXbu25s2bJ2OMdu3apenTp+uVV16Rn5+fnnnmmVy3zQo7F8r6GZD1NRYaGqqQkJCL1vVvbsOQ9X06YsSIbFP6Z/nnhEvMPIiihJ4t4CrTqVMn/fHHHwoJCVHDhg2zPbJmS8v6ZZX1l20p8x5ZWVMsX47q1atLkv74448c1x8/flwpKSkuH5xy0qpVKyUmJmb7ID5z5kzn+oL06aefusyId/jwYW3cuDHHGecuJT+1X6z3rVWrVlqzZo0zXF24D39//8ueSvtCAQEBatSokRYtWuTSM5eQkKAvv/zSpW1+vlYudk4Wi0VWq9VlOF1ycrJmzZp12efQpEkT+fn5Zbtx7bFjx5xDMd2hfPny2rdvn8sMaGfOnNHGjRsLZP/XXXednn/+edWuXVvbt2+/aLuqVauqdOnSmjt3rsvXb1JSkj7//HPnDIX/1q+//qpNmzbpzjvv1Nq1a7M9WrVqpf/7v//LU69tfjRu3FilSpXKds+mhQsXKjEx8aIfzC+0du1aeXh4qGLFiv+6Hn9/f7Vs2VI7duxQnTp1cvz5mtMfaIoXL67u3btr4MCBOnv2bI43Iy5btqwGDRqkNm3a5PqeX4rFYlHdunX1zjvvqHjx4nnaV0JCgpYsWeKybO7cufLw8NAtt9wiKfP3ypkzZ2S323M87wvD0MV+BlysF7Vq1aqqUqWKfvrppxz33bBhQ+6phyKNni3gKjN06FB9/vnnuuWWW/T444+rTp06cjgcOnLkiFauXKlhw4apcePGatOmjby9vXXvvfdq+PDhSklJ0Ycffpht2FF+lClTRhUrVtTmzZs1ZMiQbOuzrmdo2bJlrvt54IEHNHHiRPXu3VuHDh1S7dq1tWHDBo0aNUodOnRQ69atL7vGnMTExOiOO+5Qv379FBcXp5deekm+vr4aMWJEvveVn9pr166tdevW6csvv1SpUqUUGBioqlWr6qWXXtJXX32lli1b6sUXX1RwcLDmzJmjpUuXasyYMbLZbAVy3q+++qrat2+vNm3aaNiwYbLb7XrzzTcVEBDg0juZn6+V2rVra9GiRfrwww/VoEEDeXh4qGHDhurYsaPGjRunnj17qn///jpz5ozGjh3rEuDyq3jx4nrhhRf07LPP6oEHHtC9996rM2fO6OWXX5avr69eeumly953bnr16qXJkyfr/vvvV79+/XTmzBmNGTMm30MUs+zatUuDBg3SXXfdpSpVqsjb21tr1qzRrl27cu2V8PDw0JgxY3TfffepU6dOevjhh5Wamqq33npL586d0xtvvHG5p+giq1dr+PDhOd7jLCEhQd98841mz56txx57LF/7/ucU+FmaN2+ukiVLasyYMerVq5cefvhh3Xvvvfr99981fPhwtWnTRu3bt3e279+/v4KCgtSoUSOFh4fr9OnTWrBggebPn6+nnnrKpVdr+vTpevDBBzVt2rRs1/tdyrvvvqubbrpJN998sx599FGVL19eCQkJ2r9/v7788kutWbNGktS5c2fVqlVLDRs2VMmSJXX48GGNHz9e5cqVU5UqVRQXF6eWLVuqZ8+eqlatmgIDA7VlyxatWLEiTyHyQl999ZU++OADde3aVRUrVpQxRosWLdK5c+fUpk2bS24fEhKiRx99VEeOHNF1112nZcuW6aOPPtKjjz6qsmXLSpLuuecezZkz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Xq5cOf35558FVhgAAAAAFGX57tlyOByy2+3Zlh87dkyBgYEFUhQAAAAAFHX5Dltt2rTR+PHjnc8tFosSExP10ksvqUOHDgVZGwAAAAAUWfkeRvjOO++oZcuWqlGjhlJSUtSzZ0/9/vvvCg0N1aeffuqOGgEAAACgyMl32IqMjNTOnTv16aefavv27XI4HOrbt6/uu+8+lwkzAAAAAOBalu+wJUl+fn566KGH9NBDDxV0PQAAAABwVbissPXnn3/q+++/V0xMjBwOh8u6IUOGFEhhAAAAAFCU5TtsTZs2TY888oi8vb0VEhIii8XiXGexWAhbAAAAAKDLCFsvvviiXnzxRY0YMUIeHvmezBAAAAAArgn5Tkvnz5/XPffcQ9ACAAAAgFzkOzH17dtXCxYscEctAAAAAHDVyPcwwtGjR6tTp05asWKFateuLS8vL5f148aNK7DiAAAAAKCoynfYGjVqlL7++mtVrVpVkrJNkAEAAAAAuIywNW7cOH3yySfq06ePG8oBAAAAgKtDvq/Z8vHxUbNmzdxRCwAAAABcNfIdth577DG9//777qgFAAAAAK4a+R5G+OOPP2rNmjX66quvVLNmzWwTZCxatKjAigMAAACAoirfYat48eLq1q2bO2oBAAAAgKtGvsPWtGnT3FEHAAAAAFxV8n3N1n/tzz//1P3336+QkBD5+/urXr162rZtm3O9MUYjR45UZGSk/Pz81KJFC+3Zs8dlH6mpqRo8eLBCQ0MVEBCgLl266NixY//1qQAAAAC4huSpZ+v666/XN998oxIlSqh+/fq53k9r+/btBVZcbGysmjVrppYtW2r58uUKCwvTH3/8oeLFizvbjBkzRuPGjdP06dN13XXX6bXXXlObNm20d+9eBQYGSpKGDh2qL7/8UvPmzVNISIiGDRumTp06adu2bfL09CywegEAAAAgS57C1u233y4fHx9JUteuXd1Zj4s333xTUVFRLkMXy5cv7/y/MUbjx4/Xc88957yObMaMGQoPD9fcuXP18MMPKy4uTlOnTtWsWbPUunVrSdLs2bMVFRWl1atXq127dv/Z+QAAAAC4dliMMSYvDR966CG9++67zt6i/0KNGjXUrl07HTt2TOvXr1fp0qU1YMAA9evXT5J04MABVapUSdu3b1f9+vWd291+++0qXry4ZsyYoTVr1qhVq1Y6e/as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stlscjgcqlevngYPHqwmTZooIyNDQ4YM0fbt29WmTRs999xz8vX1LeTqgaKDYYTANSJrqEj9+vUVEhKiTz/91LnO09NT9evXV5UqVbRq1SoNHjy4sMoEAPwHsoLW22+/rTlz5mjevHnavXu37rjjDn355ZcaOXKkvv32W1mtVr333nuqUKGCTpw4IR8fn0KuHChaCFvANWD06NF69913lZKSIm9vb3Xu3FkrV67UzJkznW28vLxUq1Ytbdy4UdOmTSvEagEA/4WYmBht3LhRr7zyipo1a6avvvpKEydO1P33369Tp07plVde0aZNm2S1WjV79mxNmTKF63qBfCJsAdeA+Ph4DRs2TNOnT5eXl5eGDRumsLAwvfvuu+rVq5cmTZqk22+/XUePHlWjRo3k4eEhu91e2GUDANwoLCxMw4cPV/v27bVz504NHDhQr732mj788EPdeeed2rx5swYPHqytW7fK09NTHh4ecjgcXM8L5IO1sAsAULAuvOA5y+jRoxUYGKiBAwfKbrdr4MCBeuedd7Ro0SLNnDlT+/fvV2hoqBYtWuT8ZZo1KxUAoOjL6XeDJF1//fXy8vLSjBkzVKdOHfXr10+SFBwcrBtvvFE333yzrr/+emf7nPYB4OIIW8BVJusX4f79+1W5cmXn8meffVYOh0NDhgyRxWLRgAEDNHjwYA0ePFgJCQkKDAyUJGVkZMhq5UcDAFwtjDHO3w1Tp07VsWPH5OnpqREjRsjLy0uSlJqaqmPHjunQoUOqWrWqVq5cqS5dumjw4MGyWCwXDWsAcsd3DXAVWr58ua677jp9+eWXLsuff/55PfPMM3ryySc1ffp0JSYmSpIzaBljCFoAcBW5cNbB5557To8//rg2bdqkt956S7fccov27t0rSWrYsKG8vLzUuXNn1axZU3v37tWAAQOc12gRtIDLw9TvwFXqf//7nxYuXKjZs2erU6dOzl+4P//8sxo3bqyUlBQtWrRIXbt2LexSAQBudvLkSfXv318jR45U7dq1debMGd16663y8fHRZ599psqVK2vZsmXat2+fkpKS9PTTT8tqtcputzOsHPgXCFtAEZfb0I7//e9/mjdvnubNm6dOnTpJkvbu3atZs2apUqVK6tWrFz1ZAHCVWblypVq0aCFvb29J0vjx4zV58mSVKVNGM2fOVKlSpSRJsbGxuummm+Tt7a0FCxa4DD2XRNACCgBhCyjCLgxaM2fO1J49e+Tp6akGDRrozjvvlCT17dtXc+fO1euvv67rrrtOU6ZMkbe3txYuXCiJa7QA4GoyduxYLViwQJs3b3YOH9y5c6d69OihmJgYbd68WdWqVXP+/oiNjVXz5s119uxZbdiwQeXLly/cEwCuMoQt4Crw1FNPadq0aWrbtq12796tjIwMNWzY0HkfrWeffVbTpk1TQECAwsPDtW7dOudF0QCAq0vWH9F2796tihUryt/fX7/88ovatm2rmjVrau7cuQoJCXEOLz9z5owee+wxzZgxg54soIARtoAi6MLeqLVr16pXr16aP3++mjVrpqSkJC1YsEBvvfWWbrrpJk2ePFlS5uyEnp6eKleunDw8POjRAoCrTNawP4fDoRUrVqhTp06aMWOGunfvLj8/P+3evVtt27ZVvXr1NGvWLIWEhGQbis7QQaBgMbUMUIQMGDBABw8elNVqVUZGhiTpzz//lJeXl+rUqSNJCvj/9u4+rud7/+P446tCly7mKjEhw1GNLcw4v6JcjDmMuTYc13PRuR3nmJthbIVNydpcjilTzlEujjZDLmojRpyyKBlycayE2Fyki2/f3x9O39U0Z1eJet5vt2639bny/rTbt0/Pz/v9fr1tbenfvz9jx47l2LFjnDlzBgAXFxcaN25sXkdLQUtEpPwouj5ipUqV6NmzJ6NHj2by5Mls2bKF7OxsXF1diY6O5vjx44wcOZKrV68+MOdXQUvk96WwJfKEOHPmDAcPHqR79+5cvHjRHJYaNmyIpaUlX3/9tflYe3t7XnrpJY4fP24OW0WphK+ISPlS+Hs9KiqK/fv3A7BmzRqGDh3KuHHjigWuXbt28fnnn/Pee++VZZNFKgS92hZ5Qri4uLB69WpmzZpFly5d2LdvH08//TQNGzbEysqKjz76CEdHR5o0aQKAnZ0drVq1wsbGpoxbLiIipaXoMMDk5GSGDh1Kv379sLa2xsPDg5UrVwIwbtw4APr164erqytnzpyhUaNGZdZukYpCc7ZEngBFx9AfPXqUGTNmcOHCBfbs2YOzszP79u1jwIABdOnShc6dO9OqVSsWLFjA9evXOXz4sIaFiIiUQ0UXLJ4zZw737t0jIiKC9PR0evXqxZtvvknbtm0BmDhxIuHh4QQFBTFixAiqVKkCaI6WSGlT2BJ5zBV9a3n79m3s7OxISEhg+vTppKWlsWfPHho3bsyXX35JQEAAiYmJ1KxZk7p167J9+3asrKz0MBURKWeKBq0lS5bwzjvvsH37duzt7blw4QKjRo2ic+fOzJgxAw8PDwAGDx5MZmYm+/btK8umi1QoClsij7GiQWvRokVcvXqVYcOG0bp1a+Lj45k5c2axwHXz5k3y8vK4e/cuTz/9NAaDQVUHRUTKkU2bNtG3b99iv9cHDhyIg4MDa9asMW+LjY2lV69e9OjRgzfeeIP27dsD6skSedQ0S17kMVYYtGbMmEFAQABt2rShdu3aALRt25aFCxfSpEkTunbtyoULF6hevTq1a9emUaNGGAwGVR0UESlH/P392bZtW7EiR3l5eeTk5JCTkwPcXxokLy8PLy8v5syZw/bt21m1ahUnT54EMFekFZFHQ2FL5DG3e/duNm7cyPbt2xk6dChOTk4UdkgXBq6mTZvSqlUrMjIyip2rqoMiIuXH3/72N0JCQqhUqRLx8fHk5uZiZWXFyy+/THh4OF9++SWWlpbmnis7Ozu6du3Kp59+SmhoKAAGg0HPBpFHSJ82kcdcZmYmdnZ2NG3alJJG/Xp4eODn58eYMWPMvV4iIlK+5ObmYm1tjaWlJTt37mTw4MEsW7aM3Nxcxo0bx4gRI+jVqxc7d+7k1q1b3L59m+joaEaPHs3ixYsJCgri/PnzZX0bIhWOxheJPObS09PJysriqaeeAu4PGbGyssJkMrFnzx7q1KlDu3btaNeuHaDx+CIi5VHlypUB2Lx5M6+88gqdOnVi8+bNWFlZ8frrrxMQEIC1tTW9e/fGxcWFe/fuUbVqVV5++WViY2Np0qQJ9vb2ZXwXIhWPerZEHnMDBw7EwsLCvEaKlZUVALdu3WLJkiUcOnSo2PEKWiIi5UfR+VWLFi1iwIABfPvttyxbtoymTZuyfv16Vq5cSY0aNVixYgU7d+5k+vTpzJs3j6SkJKysrNixYwe1a9fW80GkDKgaochjLicnh9WrV7N06VLc3NyYPXs23377LUuXLuXy5cscPXpURTBERMq5I0eOsH37djp16kTXrl2B+8uBTJ48mdTUVIYNG8b48ePN62cBnD17lkWLFhEZGUlsbCzu7u5l1XyRCkt/oYk85qpUqcJrr72Go6Mj8+bNw9vbmzp16tCoUSPi4+OxtLTU0EERkXJs165djBo1CoA+ffoA9+dw2dnZsWzZMqZMmcLGjRu5ffs206dPx9LSklu3bpGQkMD169cVtETKkHq2RJ4wJ06coFq1ajg5OVGpUiWtoyUiUs4lJCSwatUqQkNDCQgIYOrUqcAPc3hv377NsGHDqFevHitXrjQvdnz37l1MJhO2trZl2XyRCk1hS+QJUXSB44dtExGRJ9dP/V4/deoUgYGBREdH4+/vz4gRI4AfAld2djZVqlQxr6OlZ4PI40Gvw0XKgMlkMr95zM3NNVeZepiSHpx6mIqIlB9FQ9KWLVvIzMzk+++/Z+TIkbRo0YI333wTS0tLFixYgMFg4LXXXsPKyor8/Hysra0fuIaIlD31bImUoeXLl1OvXj369euneVciIgLcX7w4PDychg0bkpmZSV5eHkFBQQwePJhvvvmGJUuW8MUXX+Dr68uECRPKurki8hAKWyJlyMfHh3v37nHgwIFi2wuDV2EPmN5UiohUDJGRkUyZMoXdu3fTtGlTbG1tGTVqFHv27OGjjz6iZ8+eJCUl8e6772IymdiwYUNZN1lEHkJ/vYmUAaPRCMD8+fO5c+cOO3fuLLa/sIcrNjYW0HBBEZGKIiMjAxcXF5555hnzEPPQ0FBeeOEFpk2bhslkws3Njfnz5xMWFgbcH5ouIo8n/QUn8gj8+EFYGKYK31p+/vnnD5yzY8cOvL292bp16yNpo4iIlL3vv/+e//znP1StWtVc+AJg3rx5XL9+nWPHjgHg7OxsLoZROAdYRB4/Clsij0Dhg3D9+vW89dZbFBQUkJubS61atZg+fTrh4eEcOnSo2Dnu7u5MmDCBixcvlkWTRUSkDBRWGRw3bhyAufDF3bt3qV69+gNl3DXyQeTxpk+oyCOSlZXFgQMHCAkJwcPDg7lz53L69Gm8vLzo2LGjOWwVDjF0cnKibdu23LhxoyybLSIij1DdunWZPXs2cXFxDB06lLNnz3Ls2DH8/f2pX78+zZs3L+smisgvoAIZIqWkpKIWubm5APj5+ZGYmEhMTAxz585l48aN5OTkcPDgQezt7VUQQ0SkAvvuu+/YsWMHb7/9Nunp6dSpU4e6deuyb98+rKys9IwQeYIobImUgqIPwmPHjnH79m2efvppnJ2dzUMKTSYToaGhxMbGcuTIEVJTUwkMDGTatGkPXK/oulwiIlJxfPXVV9jb29OyZUsqVapEfn4+lpZaJlXkSaGwJfI7KxqMZs2aRVhYGBYWFly7do05c+YwYMAAnJ2dzcffuHGDK1euMHXqVAoKCti7d28ZtVxERB4XJfVeqUdL5MmjT6zI76wwaM2fP5/Q0FBCQkI4d+4cgwYNYsGCBaxatapY0QsHBwdatGjBunXriI+PL7EyoYiIPLmKvtcuHE7+v5QUqhS0RJ48+tSK/E4KCgrM/3327Fni4uIIDg6mS5cuREVFsWnTJnx8fAgODmbp0qWcP38euF8G3mg0UrNmTVxcXH72g1hERJ4MhS/hli9fzmeffQb8UAxJRMo3hS2R34HJZDK/cUxJSaFu3bqMHTuWnj178tVXXzFp0iT8/PyIjIxk2LBhhIaGEhgYSHp6OnA/cG3evJnExETc3NzK8lZERKSUbNmyhaCgIOCH9Rbhh+BV2ANW9OWdiDzZFLZEfqOiC0pOnTqVbt26kZeXh4+PDzY2NmzcuBEvLy/Gjx8PQLVq1WjQoAEZGRnUq1fPfB0vLy9SUlJo2rRpmdyHiIiUjsIwNX/+fO7cucPOnTuL7S8MXrGxsYCGC4qUJ/o0i/xGhQ/Fq1evkp2dTVhYGDVq1MDBwQGAzMxMAHJycgBIS0sjKCiIyMhIDAaD+Q2mk5OT1k8RESkHflx7rDBMNW3aFFtb2xLn5u7YsQNvb2+2bt36SNooIo+GwpbIr1R0mEd4eDgtWrTgxIkTD/RMPf/882zbto0hQ4bw7LPPkpycTKdOnTAYDMWGH4qISPlQONph/fr1vPXWWxQUFJCbm0utWrWYPn064eHh5oXsC7m7uzNhwoRiBZRE5Mmnv/JEfoWiIWnr1q2YTCbc3d1JTU2lcuXKwA89WdOmTcPf35/GjRvTuXNnkpKSsLS0xGg0au0sEZFyKisriwMHDhASEoKHhwdz587l9OnTeHl50bFjR3PYKhxi6OTkRNu2bblx40ZZNltEfmdaZ0vkFyq6jtY777xDZGQk69atIysriylTpmBjY8Phw4exsrIiJyeHKlWqPHANLUopIlK+lLQGVmF1WT8/PxITE4mJiWHu3Lls3LiRnJwcDh48iL29vdbPEinH9MkW+YUKg1ZycjInTpwgKCiI5557Dm9vb5YtW4bRaMTT05Pc3FyqVKlSYil3BS0RkfKjaFg6duwYX3zxBWlpaVhZWVG5cmX8/PyIioriww8/5MSJE9y5c4eTJ0+yevVq4MGCGHoPLlJ+qGdL5FdYvXo1y5Ytw2AwsGnTJvM8LaPRSExMDG+88QY2Njbs3bu3xJ4tEREpH4qOdpg1axZhYWFYWFhw7do15syZw4ABA3B2djYff+PGDa5cucLUqVMpKChg7969ZdRyEXkU1LMl8it4eXlRqVIlTp48SVxcnHm7hYUFnTt3JiAggLS0NHx9fcuwlSIiUtoKg9b8+fMJDQ0lJCSEc+fOMWjQIBYsWMCqVauKFb1wcHCgRYsWrFu3jvj4+BIrE4pI+aGwJfI/lLS4ZLNmzdi6dSuurq6sXbuWmJgY8z4LCws8PT3Ztm0by5cvf5RNFRGRR6Tos+Hs2bPExcURHBxMly5diIqKYtOmTfj4+BAcHMzSpUs5f/48cP8ZYTQaqVmzJi4uLiUONReR8kNhS+Qhio7DT0lJ4dChQ3z//ffcu3ePRo0aERERwY0bN3j33XfNi1HC/TlZHh4e5oeqiIiUH0Ur0qakpFC3bl3Gjh1Lz549+eqrr5g0aRJ+fn5ERkYybNgwQkNDCQwMJD09HbgfuDZv3kxiYiJubm5leSsiUsoUtkR+QtGH6axZs+jTpw+9e/emU6dOrFixgvT0dFxcXNi0aRNXrlxh0aJF7Nq164HrFC5mKSIiT76CggLz0MGpU6fSrVs38vLy8PHxwcbGho0bN+Ll5cX48eMBqFatGg0aNCAjI4N69eqZr+Pl5UVKSsoDazOKSPmisCXyEwofpv7+/oSEhPDBBx9w7do1mjRpwvvvv8/SpUv59ttvadasGZs2bSIhIaHEsCUiIuVH4Uu4q1evkp2dTVhYGDVq1MDBwQGAzMxM4Ie1FtPS0ggKCiIyMhKDwWAefujk5ETz5s3L4A5E5FFS/WmRh0hOTiY6OpoVK1bQo0cPdu/ezb59++jQoQPr16/HYDAwefJkXFxciI+Px9HRsaybLCIipaDosPLw8HB8fX1p1qzZAz1Tzz//PHPnzuXmzZtcunSJ3NxcOnXqhMFgKDZiQkQqBn3iRYr4cTGMhg0b4uvri7e3NwcOHGDEiBEEBASwa9cuXF1dWb9+Pf7+/mRmZtKgQQPN0RIRKYeKhqStW7diMplwd3cnNTWVypUrAz/0ZE2bNg1/f38aN25M586dSUpKwtLSEqPRaB4xISIVh9bZEinBhg0b8Pb2pm7duty6dQt7e3smTpyIwWDgww8/xNLSkokTJ7J//348PT3Na26JiEj5UnQdrXfeeYfIyEjWrVtHVlYWU6ZMwcbGhsOHD2NlZUVOTk6Jayvm5+drMXuRCko9WyI/cvnyZYYPH05KSgoA9vb2AFy/fp3bt2+Tn58PwM2bNwkMDDQHLb23EBEpfwqDVnJyMidOnCAoKIjnnnsOb29vli1bhtFoxNPTk9zcXKpUqVJiKXcFLZGKS2FLKrwfhyQbGxuaNGnC3bt3i213cXEhISGBIUOG8MILL3D8+HG6detmnvCsni0RkfJp9erVDB06lG+++YYmTZoA90OYl5cXixcv5t69e3Tp0oWcnBzzsEIREVDYEjGHpKysLABq1KiBu7s7+/fvB36Yx7Vw4UJ69+5NzZo1cXd3JykpyTxHSxOeRUTKLy8vLypVqsTJkyeJi4szb7ewsKBz584EBASQlpaGr69vGbZSRB5HmrMlwv0gFR4ejq2tLa1bt2b//v20a9eOwMBAbG1tsba2LvE8jcMXESlfilYdLOrChQu88sorODg4MHfuXDp37mzel5+fT2JiIm3atNHaiiJSjMKWCBAXF8e1a9eIiYkhPz+fbdu2cfnyZTp37sypU6do164dNjY2+Pr60r59+7JuroiIlIKiQSslJYWbN2/SqlUrKleuTNWqVTlz5gz9+/enXr16zJw5Ey8vrweuYTQaFbhExExhS6QEUVFRTJkyheDgYDIyMsjIyODEiRNEREToISoiUg4VrTo4a9YsIiMjycrKon79+vz5z39m8ODBODo68s033zBgwADq16/PX/7yF7p3717GLReRx5nGP4n8V+GD1mg0Urt2bSwsLOjUqRO1a9cudpzeWoqIlD+FQcvf35+QkBDWrl1Ljx496Nu3L++//z7Xrl1j8uTJNGvWjE2bNvHHP/6RXbt2KWyJyEMpbIn8V+GD1sLCgrZt22IwGDh06BB/+tOfih2noCUiUj4lJycTHR3NihUr6NGjB7t372bfvn106NCB9evXYzAYmDx5Mi4uLsTHx+Po6FjWTRaRx5xKqImUoKCggOzsbNLT08u6KSIiUkoKq80WatiwIb6+vnh7e3PgwAFGjBhBQEAAu3btwtXVlfXr1+Pv709mZiYNGjQwV6QVEfkpClsiJahcuTIBAQGMGTOmrJsiIiKlpLAYxoYNG7hy5Qr29vZ0794dOzs7wsLC6Nu3r/k58PTTT2NnZ4fJZCo2vFyjHUTkYRS2RH7C8OHDsbS0JD8/v6ybIiIipeTy5csMHz6clJQUAOzt7QG4fv06t2/fNj8Dbt68SWBgIMuWLcNgMKD6YiLyc2jOlsj/oHW0RETKj6JVBwFsbGxo0qQJd+/eLXaci4sLn376KUOGDCE9PZ3vvvuObt26YTAYfnItLhGRH9NvChEREakwCoNWVlYWADVq1MDd3Z39+/cDP8zjWrhwIb1796ZmzZq4u7uTlJRknqOloCUiP5de2YuIiEiFsnDhQsLDw7G1taV169acOnUKBwcHrl27hq2tLdbW1ubjisrPz9doBxH5RfQbQ0RERCqU//u//+MPf/gDMTEx5Ofnc+vWLT755BMuXbrEqVOnaNeuHTY2Nvj6+tK+fXvzeQpaIvJLGUya4SkiIiIVWFRUFFOmTCE4OJiMjAwyMjI4ceIEERERqjYoIr+JXtGIiIhIhVNYKMNoNFK7dm0sLCzo1KlTsbLuAEajUYFLRH41zfAUERGRCqewUIaFhQVt27bFYDBw6NChB45T0BKR30JhS0RERCq0goICsrOzSU9PL+umiEg5ozlbIiIiUuGFhYUxePBgFcEQkd+VwpaIiIjIf6m8u4j8nhS2RERERERESoHmbImIiIiIiJQChS0REREREZFSoLAlIiIiIiJSChS2RERERERESoHCloiIiIiISClQ2BIRERERESkFClsiIvJIHTx4EAsLC3r06FHWTflNDAaD+cve3h4PDw+2bNnys88fNWoUffv2Lbbt/PnzGAwGEhMTf9/GiohImVDYEhGRR2rt2rVMnTqVAwcOcPHixbJuzm8SEhJCeno68fHxPPvsswwYMIBDhw6VdbMAyMvLK+smiIhUeApbIiLyyNy5c4eIiAhef/11Xn75ZUJDQx84JioqCg8PD6pWrUqtWrXo16+feV9OTg5vvPEGDRs2pEqVKjRr1oyPP/7YvD85OZmePXtiZ2dH3bp1ee2117h27Zp5/6ZNm3Bzc8Pa2pqnnnoKHx8f7ty5A0BsbCzt2rXD1taW6tWr07FjRy5cuPDQ+6levTr16tWjRYsWrFy5kqpVqxIVFYXRaGTMmDE0btwYa2trmjdvTnBwsPm8efPmsW7dOrZt22buHYuNjaVx48YAtGnTBoPBgJeXl/mckJAQWrZsSdWqVWnRogXLly837yvsEYuIiMDLy4uqVasSFhZm7j0LDAzE0dGRp556ismTJyuIiYg8IgpbIiLyyGzcuJHmzZvTvHlzhg8fTkhICCaTybx/+/bt9OvXj169epGQkMDevXvx8PAw7x8xYgT//Oc/+eCDD0hJSWHlypXY2dkBkJ6ejqenJ61bt+bo0aPs3LmTK1euMHDgQPP+IUOGMHr0aFJSUoiNjaVfv36YTCby8/Pp27cvnp6efP311xw6dIjx48djMBh+9r1ZWVlhaWlJXl4eBQUFNGjQgIiICJKTk3nrrbd48803iYiIAODvf/87AwcOpEePHqSnp5Oens6LL77IkSNHANizZw/p6enmYYmrV69m1qxZzJ8/n5SUFBYsWMCcOXNYt25dsTbMmDEDX19fUlJS6N69OwAxMTGcPXuWmJgY1q1bR2hoaIkhV0RESoFJRETkEXnxxRdN77//vslkMpny8vJMtWrVMu3evdu8v0OHDqZhw4aVeG5qaqoJKHZ8UXPmzDF169at2LZLly6ZAFNqaqrp2LFjJsB0/vz5B869fv26CTDFxsb+7HsBTFu3bjWZTCbTvXv3TH5+fibA9Pnnn5d4/KRJk0z9+/c3fz9y5EhTnz59ih2TlpZmAkwJCQnFtjds2NC0YcOGYtv8/PxMHTp0KHZe4c+26L/RqFEjU35+vnnbgAEDTIMGDfrZ9ykiIr+eZdnFPBERqUhSU1M5cuSIubfG0tKSQYMGsXbtWnx8fABITExk3LhxJZ6fmJiIhYUFnp6eJe4/duwYMTEx5p6uos6ePUu3bt3w9vbGzc2N7t27061bN1599VVq1KhBzZo1GTVqFN27d6dr1674+PgwcOBAHB0dH3pPQ4YMwcLCguzsbKpVq0ZgYCAvvfQSACtXrmTNmjVcuHCB7OxscnNzad269c/9cZldvXqVS5cuMWbMmGI/m/z8fKpVq1bs2KK9gIVatWqFhYWF+XtHR0eSkpJ+cTtEROSXU9gSEZFH4uOPPyY/Px8nJyfzNpPJhJWVFTdu3KBGjRpYW1v/5PkP2wdQUFBA7969ee+99x7Y5+joiIWFBbt37+bgwYNER0fz4YcfMmvWLA4fPkzjxo0JCQnB19eXnTt3snHjRmbPns3u3bt54YUXfvLfXLJkCT4+Pjg4OFCnTh3z9oiICP7617+yePFiOnTogL29PQEBARw+fPih9/BT9wX3hxK2b9++2L6iIQrA1tb2gfOtrKyKfW8wGMzXFBGR0qU5WyIiUury8/P55JNPWLx4MYmJieav48eP06hRI8LDwwFwd3dn7969JV7Dzc2NgoICvvjiixL3P/fcc5w8eRJnZ2dcXFyKfRWGEIPBQMeOHXn77bdJSEigcuXKbN261XyNNm3aMHPmTA4ePIirqysbNmx46H3Vq1cPFxeXYkELYP/+/bz44otMmjSJNm3a4OLiwtmzZ4sdU7lyZYxG4wPbgGLb69ati5OTE+fOnXvgvgoLaoiIyONJYUtERErdZ599xo0bNxgzZgyurq7Fvl599VVzRcG5c+fyj3/8g7lz55KSkkJSUhKLFi0CwNnZmZEjRzJ69Gj+9a9/kZaWRmxsrLnoxOTJk8nKymLIkCEcOXKEc+fOER0dzejRozEajRw+fJgFCxZw9OhRLl68yJYtW7h69SotW7YkLS2NmTNncujQIS5cuEB0dDSnT5+mZcuWv+p+XVxcOHr0KLt27eL06dPMmTOH+Pj4Ysc4Ozvz9ddfk5qayrVr18jLy6NOnTpYW1ubi3t89913wP3qhQsXLiQ4OJjTp0+TlJRESEgIQUFBv/Z/iYiIPAIKWyIiUuo+/vhjfHx8HphjBNC/f38SExP597//jZeXF5GRkURFRdG6dWu6dOlSbOjdihUrePXVV5k0aRItWrRg3Lhx5tLt9evXJy4uDqPRSPfu3XF1deUvf/kL1apVo1KlSjg4OPDll1/Ss2dPnnnmGWbPns3ixYt56aWXsLGx4dSpU/Tv359nnnmG8ePHM2XKFCZMmPCr7nfixIn069ePQYMG0b59e65fv86kSZOKHTNu3DiaN2+Oh4cHtWvXJi4uDktLSz744ANWrVpF/fr16dOnDwBjx45lzZo1hIaG4ubmhqenJ6GhoerZEhF5zBlMpiI1d0VEREREROR3oZ4tERERERGRUqCwJSIiIiIiUgoUtkREREREREqBwpaIiIiIiEgpUNgSEREREREpBQpbIiIiIiIipUBhS0REREREpBQobImIiIiIiJQChS0REREREZFSoLAlIiIiIiJSChS2RERERERESoHCloiIiIiISCn4fwY3jgmg8HLrAAAAAElFTkSuQmCC", + "image/png": "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okQJ+fj45PoeDBQ5BkChGDx4sJFkqlSpYt566y2zdOlS079/fyPJ9OnTx1StWtV8+OGHZunSpeaJJ54wksy3335r2//s2bOmZs2apnjx4mb06NHmxx9/NGPHjjWBgYHmvvvuM1ar1db3hRdeMOPHjzeLFy82y5cvNx988IEpXry4eeKJJ+xqatiwoQkJCTGRkZFmwoQJZunSpaZXr15GkpkyZYqtX3p6uvH29jb9+/fP89zWr19vJJn58+df8jVITU010dHRxtfX14waNcrExsaaQYMGGTc3N9OqVSu7vpJMRESEqVOnjpk9e7ZZtGiRiYmJMW5ubmbv3r2XPM6KFSuMJFO2bFnTrl078/3335tp06aZypUrm4CAALv9u3XrZjw8PEy1atXMqFGjzI8//mjefPNNY7FYzNChQwtc+9q1a423t7dp1aqVWbt2rVm7dq3ZsWOHMcaYP//80/j7+5tKlSqZqVOnmoULF5qOHTsaSebdd9/NVX9ERITp3LmzWbhwoZk5c6YpV66ciYyMNFlZWZc8/x9//NG4urqau+++28ydO9fMmTPH3HnnnaZcuXLG8dt6fj5XduzYYRo0aGDCwsJs57R27Vrb9scff9xMnDjRLF261CxdutS89dZbxtvb2+71y8uOHTvMG2+8YSSZSZMmmbVr15o9e/YYY4wZPny4kWQ6duxoFi5caKZOnWoqVqxoAgMDze7du+0+fu7u7iYiIsKMGDHCLFu2zCxZsuSix8z5Oixfvrx59dVXzdKlS828efOMMee/Hho2bJhrn27dupny5cvbnu/fv9/28WnRooWZN2+emTdvnomKijLFihUzp0+ftvWtUqWKqVy5svnqq6/MqlWrzLfffmteeukls2LFiku+NtOnTzeSTLNmzcy8efPMrFmzzB133GE8PDzMzz//nOt8qlSpYt58802zdOlSM3r0aOPp6Znr6/1iVq9ebSSZV155xRhjzGOPPWYsFovZt29fnv0bNmxoqlevnue2nM/dOXPmXPR4EyZMMJJsXxcXql27tqlXr16u9uzsbJOZmWni4+PNuHHjjJubm5kwYUJ+Ti+XnI/fpEmTbG07duwwgYGBJioqykydOtXExsaal156ybi4uJghQ4bY+o0YMcK4urqawYMHm2XLlpnFixebMWPG2PVp3ry5KVGihPnss8/MypUrzbx588yb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6C/VF1qxYoVcXFxUsWLFf12Pj4+PGjVqpC1btig6OjrP7695/XElKChIDz30kHr37q1Tp07l+Uax5cqVU58+fdS0adNLfswvx2Kx6LbbbtMHH3ygoKCgfI2VkpKi+fPn27XNmDFDLi4uuvfeeyWd/7mSkJCg7OzsPM/7wiBzse8BF5u9rFKliiIjI/Xbb7/lOXbt2rV5zzRc95hRAoqIfv366dtvv9W9996rF154QdHR0bJarTp06JBiY2P10ksvqW7dumratKk8PDzUsWNH9e/fX2lpaRo/fnyuS3UKokyZMqpYsaLWrVunvn375tqec/1+o0aNLjlO165dNW7cOHXr1k0HDhxQVFSUfvnlFw0fPlytWrVSkyZNrrjGvMTHx+uBBx5Qjx49lJSUpMGDB8vLy0sDBgwo8FgFqT0qKkorV67U999/r1KlSsnf319VqlTR4MGDtWDBAjVq1EhvvvmmgoODNX36dC1cuFAjR45UYGBgoZz3W2+9pRYtWqhp06Z66aWXlJ2drXfffVe+vr52s4IF+VyJiorS3LlzNX78eN1xxx1ycXFR7dq11bp1a40ePVqdOnXS008/rYSEBI0aNcoufBVUUFCQBg0apNdff11du3ZVx44dlZCQoKFDh8rLy0uDBw++4rEvpUuXLvr000/12GOPqUePHkpISNDIkSMLfFlfjm3btqlPnz7q0KGDIiMj5eHhoeXLl2vbtm2XnA1wcXHRyJEj1blzZ7Vp00Y9e/ZUenq63nvvPZ0+fVrvvPPOlZ6inZzZpP79++f5HlYpKSlatmyZpk2bpueff75AYzsuk56jYcOGKlGihEaOHKkuXbqoZ8+e6tixo/766y/1799fTZs2VYsWLWz9n376aQUEBKhOnToKDQ3VyZMnNWfOHM2aNUuvvPKK3WzS5MmT9cQTT2jSpEm57m+7nLFjx+ruu+/WPffco2effVYRERFKSUnRnj179P3332v58uWSpLZt26pGjRqqXbu2SpQooYMHD2rMmDEqX768IiMjlZSUpEaNGqlTp06qWrWq/P39tXHjRi1evDhfAfBCCxYs0CeffKL7779fFStWlDFGc+fO1enTp9W0adPL7h8SEqJnn31Whw4d0i233KJFixbp888/17PPPqty5cpJkh599FFNnz5drVq10vPPP686derI3d1dR44c0YoVK9SuXTs9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nycA4Mq5OS+iAQCuF7t27dKGDRtssyRubm565JFH9OWXX6pJkyaSpK1bt6pHjx557r9161a5urqqYcOGeW7ftGmTVqxYYZthutDevXvVrFkzNW7cWFFRUWrevLmaNWumhx56SMWKFVNwcLAef/xxNW/eXE2bNlWTJk308MMPq1SpUpc8p44dO8rV1VWpqakKDAzUqFGj1LJlS0nShAkT9MUXX+jgwYNKTU1VRkaGatasmd+Xy+bEiRM6fPiwnnzySbvXJisrS4GBgXZ9L5x9y1G9enW5urranpcqVUrbt28vcB0AgIIjKAEALmvixInKyspS6dKlbW3GGLm7uysxMVHFihWTt7f3Rfe/1DZJslqtatu2rd59991c20qVKiVXV1ctXbpUa9asUWxsrD766CMNHDhQ69evV4UKFTRp0iT17dtXixcv1qxZs/TGG29o6dKluuuuuy56zA8++EBNmjRRQECASpYsaWufPXu2XnjhBb3//vuqV6+e/P399d5772n9+vWXPIeLnZd0/vK7unXr2m27MABJkq+vb6793d3d7Z5bLBbbmACAq4t7lAAAl5SVlaWpU6fq/fff19atW22P3377TeXLl9f06dMlSdHR0Vq2bFmeY0RFRclqtWrVqlV5br/99tu1Y8cORUREqHLlynaPnABhsVjUoEEDDR06VFu2bJGHh4e+++472xi1atXSgAEDtGbNGtWoUUMzZsy45HmFhYWpcuXKdiFJkn7++WfVr19fvXr1Uq1atVS5cmXt3bvXro+Hh4eys7NztUmyaw8NDVXp0qW1b9++XOeVs/gDAKBoIigBAC5pwYIFSkxM1JNPPqkaNWrYPR566CHbynWDBw/WzJkzNXjwYO3cuVPbt2/XyJEjJUkRERHq1q2bunfvrnnz5mn//v1auXKlbYGE3r1769SpU+rYsaM2bNigffv2KTY2Vt27d1d2drbWr1+v4cOH69dff9WhQ4c0d+5cnThxQtWqVdP+/fs1YMAArV27VgcPHlRsbKx2796tatWqXdH5Vq5cWb/++quWLFmi3bt3a9CgQdq4caNdn4iICG3btk27du3SyZMnlZmZqZIlS8rb29u2EEVSUpKk86vkjRgxQmPHjtXu3bu1fft2TZo0SaNHj77SDwkA4BogKAEALmnixIlq0qRJrntqJOnBBx/U1q1btXnzZsXExGjOnDmaP3++atasqfvuu8/ucrXx48froYceUq9evVS1alX16NHDtrx3eHi4Vq9erezsbDVv3lw1atTQ888/r8DAQLm4uCggIEA//fSTWrVqpVtuuUVvvPGG3n//fbVs2VI+Pj76888/9eCDD+qWW27R008/rT59+qhnz55XdL7PPPOM2rdvr0ceeUR169ZVQkKCevXqZdenR48eqlKlimrXrq0SJUpo9erVcnNz04cffqhPP/1U4eHhateunSTpqaee0hdffKHJkycrKipKDRs21OTJk5lRAoAizmLMBWu7AgAAAACYUQIAAAAARwQlAAAAAHBAUAIAAAAABwQlAAAAAHBAUAIAAAAABwQlAAAAAHBAUAIAAAAABwQlAAAAAHBAUAIAAAAABwQlAAAAAHBAUAIAAAAABwQlAAAAAHDwf6wjbd4st0WyAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] @@ -281,8 +224,8 @@ " y = group['time'].mean()\n", " ax.bar(f'{library}, {format}', group['time'].mean(), label=f'{library}, {format}', align='center')\n", " ax.text(x, y + 0.05, f'{group[\"time\"].mean():.2f}', ha='center', va='bottom', color='black', fontsize=12)\n", - " ax.text(x, y - (y/2) - 10, f'Total Requests: {group[\"total_requests\"].mean()}', ha='center', va='bottom', color='black', fontsize=8)\n", - " ax.text(x, y - (y/2.5), f'Total Req Bytes (MB): {round(group[\"total_requested_bytes\"].mean() / (1024*1024) , 2)}', ha='center', va='bottom', color='black', fontsize=8)\n", + " ax.text(x, y - (y/2), f'Total Requests: {group[\"total_requests\"].mean()}', ha='center', va='bottom', color='black', fontsize=8)\n", + " ax.text(x, y - (y/2.7), f'Total Req Bytes (MB): {round(group[\"total_requested_bytes\"].mean() / (1024*1024) , 2)}', ha='center', va='bottom', color='black', fontsize=8)\n", "\n", "# Set labels and title\n", "ax.set_xlabel('Access Pattern')\n", @@ -318,7 +261,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.1" + "version": "3.10.13" } }, "nbformat": 4, diff --git a/h5tests/xarray_arr_mean.py b/h5tests/xarray_arr_mean.py index 59d636d..6287a39 100644 --- a/h5tests/xarray_arr_mean.py +++ b/h5tests/xarray_arr_mean.py @@ -1,8 +1,7 @@ import fsspec import numpy as np import xarray as xr - -from h5test import H5Test, timer_decorator +from h5test import H5Test, fsspec_logging_decorator class XarrayArrMean(H5Test): @@ -19,6 +18,7 @@ def open_reference_ds(self, file: str, dataset: str): ) @timer_decorator + @fsspec_logging_decorator def run(self, io_params={}, dataset="/gt1l/heights", variable="h_ph"): if "kerchunk" in self.data_format: datasets_ref = [ diff --git a/notebooks/01_data-selection.ipynb b/notebooks/data-wrangling/01_data-selection.ipynb similarity index 100% rename from notebooks/01_data-selection.ipynb rename to notebooks/data-wrangling/01_data-selection.ipynb diff --git a/notebooks/arr_mean_bar_plot.png b/notebooks/data-wrangling/arr_mean_bar_plot.png similarity index 100% rename from notebooks/arr_mean_bar_plot.png rename to notebooks/data-wrangling/arr_mean_bar_plot.png diff --git a/notebooks/benchmark-h5repack.ipynb b/notebooks/data-wrangling/benchmark-h5repack.ipynb similarity index 100% rename from notebooks/benchmark-h5repack.ipynb rename to notebooks/data-wrangling/benchmark-h5repack.ipynb diff --git a/notebooks/benchmark-small-file-h5repack.ipynb b/notebooks/data-wrangling/benchmark-small-file-h5repack.ipynb similarity index 100% rename from notebooks/benchmark-small-file-h5repack.ipynb rename to notebooks/data-wrangling/benchmark-small-file-h5repack.ipynb diff --git a/notebooks/benchmarks-outline.ipynb b/notebooks/data-wrangling/benchmarks-outline.ipynb similarity index 100% rename from notebooks/benchmarks-outline.ipynb rename to notebooks/data-wrangling/benchmarks-outline.ipynb diff --git a/notebooks/cloud-optimized-hdf5.ipynb b/notebooks/data-wrangling/cloud-optimized-hdf5.ipynb similarity index 100% rename from notebooks/cloud-optimized-hdf5.ipynb rename to notebooks/data-wrangling/cloud-optimized-hdf5.ipynb diff --git a/notebooks/convert_h5dataframe2flatgeobuf.ipynb b/notebooks/data-wrangling/convert_h5dataframe2flatgeobuf.ipynb similarity index 100% rename from notebooks/convert_h5dataframe2flatgeobuf.ipynb rename to notebooks/data-wrangling/convert_h5dataframe2flatgeobuf.ipynb diff --git a/notebooks/example-list-test-files.ipynb b/notebooks/data-wrangling/example-list-test-files.ipynb similarity index 100% rename from notebooks/example-list-test-files.ipynb rename to notebooks/data-wrangling/example-list-test-files.ipynb diff --git a/notebooks/format-preprocessing-times.ipynb b/notebooks/data-wrangling/format-preprocessing-times.ipynb similarity index 100% rename from notebooks/format-preprocessing-times.ipynb rename to notebooks/data-wrangling/format-preprocessing-times.ipynb diff --git a/notebooks/fsspec-logs.ipynb b/notebooks/data-wrangling/fsspec-logs.ipynb similarity index 100% rename from notebooks/fsspec-logs.ipynb rename to notebooks/data-wrangling/fsspec-logs.ipynb diff --git a/notebooks/h5coro_benchmarks.ipynb b/notebooks/data-wrangling/h5coro_benchmarks.ipynb similarity index 100% rename from notebooks/h5coro_benchmarks.ipynb rename to notebooks/data-wrangling/h5coro_benchmarks.ipynb diff --git a/notebooks/h5py_testing_original_repacked_with_subsetting.ipynb b/notebooks/data-wrangling/h5py_testing_original_repacked_with_subsetting.ipynb similarity index 100% rename from notebooks/h5py_testing_original_repacked_with_subsetting.ipynb rename to notebooks/data-wrangling/h5py_testing_original_repacked_with_subsetting.ipynb diff --git a/notebooks/kerchunker.ipynb b/notebooks/data-wrangling/kerchunker.ipynb similarity index 100% rename from notebooks/kerchunker.ipynb rename to notebooks/data-wrangling/kerchunker.ipynb diff --git a/notebooks/read-results.ipynb b/notebooks/data-wrangling/read-results.ipynb similarity index 100% rename from notebooks/read-results.ipynb rename to notebooks/data-wrangling/read-results.ipynb diff --git a/notebooks/data-wrangling/ros3vfd-log-info.ipynb b/notebooks/data-wrangling/ros3vfd-log-info.ipynb new file mode 100644 index 0000000..faa57d1 --- /dev/null +++ b/notebooks/data-wrangling/ros3vfd-log-info.ipynb @@ -0,0 +1,344 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c1d4cad4-c84c-4104-981c-9eb0a20f75fd", + "metadata": {}, + "source": [ + "# ROS3 VFD Log Analysis Dashboard" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f53c6f1c-e624-4952-a3e8-69302152da81", + "metadata": {}, + "outputs": [], + "source": [ + "from dataclasses import dataclass\n", + "import io\n", + "import re\n", + "import numpy as np\n", + "from bokeh.models import HoverTool\n", + "import holoviews as hv\n", + "import panel as pn\n", + "hv.extension('bokeh')\n", + "pn.extension()" + ] + }, + { + "cell_type": "markdown", + "id": "bc1a4585-45e7-48c7-a806-d7096f0f82bc", + "metadata": {}, + "source": [ + "## Log Parser\n", + "\n", + "The class that represents information of one HTTP range GET request:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2cef30c0-71b2-405f-83d4-a440df748a52", + "metadata": {}, + "outputs": [], + "source": [ + "@dataclass(frozen=True)\n", + "class ByteRange:\n", + " start: int\n", + " end: int\n", + " filesize: int\n", + "\n", + " def __post_init__(self):\n", + " if self.start < 0 or self.end <= 0 or self.filesize <= 0:\n", + " raise ValueError('Start, end, and file size values must be positive integers')\n", + " elif self.end > self.filesize:\n", + " raise ValueError('End value must be smaller or equal to file size')\n", + " elif self.start > self.end:\n", + " raise ValueError('Start value must be smaller or equal to end value')\n", + "\n", + " @property\n", + " def size(self):\n", + " return self.end - self.start + 1\n", + "\n", + " def __len__(self):\n", + " return self.size" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b205fe75-e4a3-4bb3-86ac-a24b630580f8", + "metadata": {}, + "outputs": [], + "source": [ + "def parse_fsspec_log(content: bytes) -> list[ByteRange]:\n", + " head_line = re.compile('read: 0 - ')\n", + " fsize_line = re.compile('FileSize: ([0-9]+)')\n", + " range_line = re.compile('\\s*(read: \\d+ - \\d+)')\n", + "\n", + " ranges = list()\n", + " with io.TextIOWrapper(io.BytesIO(content)) as logtxt:\n", + " for line in logtxt:\n", + " if head_line.match(line):\n", + " break\n", + " else:\n", + " raise RuntimeError('HEAD line not found in the log file')\n", + "\n", + " for line in logtxt:\n", + " match = fsize_line.match(line)\n", + " if match:\n", + " fsize = int(match.group(1))\n", + " break\n", + " else:\n", + " raise RuntimeError('FILESIZE line not found in the log file')\n", + "\n", + " for line in logtxt:\n", + " match = range_line.search(line)\n", + " if match:\n", + " range = ByteRange(start=int(match.group('start')), \n", + " end=int(match.group('end')),\n", + " filesize=fsize)\n", + " if range.size != int(match.group('size')):\n", + " raise ValueError(f'Reported size different for {match.group()}')\n", + " ranges.append(range)\n", + " \n", + " return ranges" + ] + }, + { + "cell_type": "markdown", + "id": "a5954181-f1d7-40f3-8594-3afe62bcd2aa", + "metadata": {}, + "source": [ + "Log file parser:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4e4e020-c058-4a6c-b2dd-ed12962ae785", + "metadata": {}, + "outputs": [], + "source": [ + "def parse_ros3vfd_log(content: bytes) -> list[ByteRange]:\n", + " head_line = re.compile('HEAD: Bytes 0 - ')\n", + " fsize_line = re.compile('FILESIZE: ([0-9]+)')\n", + " range_line = re.compile('GET: Bytes (?P[0-9]+) - (?P[0-9]+), Request Size: (?P[0-9]+)')\n", + "\n", + " ranges = list()\n", + " with io.TextIOWrapper(io.BytesIO(content)) as logtxt:\n", + " for line in logtxt:\n", + " if head_line.match(line):\n", + " break\n", + " else:\n", + " raise RuntimeError('HEAD line not found in the log file')\n", + "\n", + " for line in logtxt:\n", + " match = fsize_line.match(line)\n", + " if match:\n", + " fsize = int(match.group(1))\n", + " break\n", + " else:\n", + " raise RuntimeError('FILESIZE line not found in the log file')\n", + "\n", + " for line in logtxt:\n", + " match = range_line.search(line)\n", + " if match:\n", + " range = ByteRange(start=int(match.group('start')), \n", + " end=int(match.group('end')),\n", + " filesize=fsize)\n", + " if range.size != int(match.group('size')):\n", + " raise ValueError(f'Reported size different for {match.group()}')\n", + " ranges.append(range)\n", + " \n", + " return ranges" + ] + }, + { + "cell_type": "markdown", + "id": "502ba537-da68-4bc2-95bc-ccf73b1f3322", + "metadata": {}, + "source": [ + "## Dashboard\n", + "\n", + "Function for generating log stats and plots:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8738d59c-3ff6-4d83-9ef2-4eeeb93ee851", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_ros3vfd_log(from_file):\n", + " if from_file is None:\n", + " return\n", + " elif len(from_file) == 0:\n", + " return [pn.pane.Alert('ros3vfd log file empty.', alert_type='danger')]\n", + " try:\n", + " ranges = parse_ros3vfd_log(from_file)\n", + " except Exception as e:\n", + " return [pn.pane.Alert(f'Error: {str(e)}', alert_type='danger')]\n", + " if len(ranges) == 0:\n", + " return [pn.pane.Alert('No range `GET` info found.', alert_type='info')]\n", + " start = np.fromiter([r.start for r in ranges], dtype=np.uint64)\n", + " end = np.fromiter([r.end for r in ranges], dtype=np.uint64)\n", + " req_no = np.arange(len(ranges)) + 1\n", + " sizes = np.fromiter([r.size for r in ranges], np.uint64)\n", + " info = pn.pane.Markdown(f\"\"\"\n", + "# ros3vfd Log Information\n", + "\n", + "Log size: {len(from_file):,} bytes\n", + "\n", + "HDF5 file size: {ranges[0].filesize:,} bytes\n", + "\n", + "Number of range _GET_ requests: {len(ranges):,}\n", + "\n", + "Overall range _GET_ requests stats:\n", + "\n", + "* Smallest: {np.min(sizes):,} bytes
\n", + "* Median: {int(np.median(sizes)):,} bytes
\n", + "* Largest: {np.max(sizes):,} bytes\n", + "\n", + "Maximum file byte read: {end.max():,}\n", + "\n", + "Total of file content read: {sizes.sum():,} bytes\n", + "\n", + "Percentage of content read to file size: {100 * (sizes.sum() / ranges[0].filesize) :.2f} %\n", + "\"\"\")\n", + " data = dict(start=start, end=end, start_event=req_no, end_event=req_no)\n", + " max_offset_range = min(16_000_000, np.max(end))\n", + " req_range = np.where(end <= max_offset_range)[0]\n", + " if req_range.size == 0:\n", + " max_req_range = req_no[-1]\n", + " else:\n", + " max_req_range = req_no[np.where(end <= max_offset_range)[0][-1]] + 1\n", + " ros3plt = hv.Segments(\n", + " data, \n", + " [\n", + " hv.Dimension('start', label='File offset', range=(0, max_offset_range)),\n", + " hv.Dimension('start_event', label='Req. No.', range=(0, max_req_range)), \n", + " 'end', \n", + " 'end_event'\n", + " ]\n", + " )\n", + " hvrtip = HoverTool(\n", + " tooltips = [\n", + " ('req no', '@start_event'),\n", + " ('start byte', '@start'),\n", + " ('end byte', '@end')\n", + " ]\n", + " )\n", + " ros3plt.opts(width=700, height=600, invert_axes=True, color='blue', \n", + " line_width=3, tools=[hvrtip])\n", + " size_hist = hv.Histogram(np.histogram(sizes, bins=512))\n", + " size_hist.opts(color='blue', line_color=None, tools=['hover'],\n", + " xlabel='Size (bytes)', ylabel='Number of requests')\n", + " \n", + " return [pn.Row(info, size_hist), ros3plt]" + ] + }, + { + "cell_type": "markdown", + "id": "d1578b9a-1a8f-43cb-9902-96e21c83cf3a", + "metadata": {}, + "source": [ + "### Dashboard Components" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "553c70f5-6f78-4f28-9d6b-7998cbbc7ec2", + "metadata": {}, + "outputs": [], + "source": [ + "log_file = pn.widgets.FileInput()\n", + "upld_form = pn.Row(\n", + " pn.pane.Markdown('Please select a ros3vfd log file (limit 10MB):'),\n", + " log_file\n", + ")\n", + "res = pn.Column()\n", + "app = pn.WidgetBox(upld_form, res)" + ] + }, + { + "cell_type": "markdown", + "id": "15126686-d315-4ae4-8666-054dd6127ba5", + "metadata": {}, + "source": [ + "Callback function for interactive log processing invocation:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "322e3372-be21-4d65-b97e-9db5a552aaf0", + "metadata": {}, + "outputs": [], + "source": [ + "def callback(value):\n", + " res.objects = plot_ros3vfd_log(value)" + ] + }, + { + "cell_type": "markdown", + "id": "dd2b2c83-1d2e-4db4-a23f-db9ad5d6f84d", + "metadata": {}, + "source": [ + "Register callback with the appropriate dashboard object:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "580279df-8b79-426f-bb22-002f117f200a", + "metadata": {}, + "outputs": [], + "source": [ + "log_file.param.watch_values(callback, ['value']);" + ] + }, + { + "cell_type": "markdown", + "id": "a3f35ce7-0698-4b02-a95e-75107138a29a", + "metadata": {}, + "source": [ + "Run the dashboard:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56c63583-922a-4b67-8cb0-8f3751ed7c28", + "metadata": {}, + "outputs": [], + "source": [ + "app.servable()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/run-tests.ipynb b/notebooks/data-wrangling/run-tests.ipynb similarity index 100% rename from notebooks/run-tests.ipynb rename to notebooks/data-wrangling/run-tests.ipynb diff --git a/notebooks/sliderule2geoparquet.ipynb b/notebooks/data-wrangling/sliderule2geoparquet.ipynb similarity index 100% rename from notebooks/sliderule2geoparquet.ipynb rename to notebooks/data-wrangling/sliderule2geoparquet.ipynb diff --git a/notebooks/xarray-h5coro-backend.ipynb b/notebooks/data-wrangling/xarray-h5coro-backend.ipynb similarity index 100% rename from notebooks/xarray-h5coro-backend.ipynb rename to notebooks/data-wrangling/xarray-h5coro-backend.ipynb diff --git a/notebooks/portable-full-comparison.ipynb b/notebooks/portable-full-comparison.ipynb new file mode 100644 index 0000000..334bddc --- /dev/null +++ b/notebooks/portable-full-comparison.ipynb @@ -0,0 +1 @@ +{"metadata":{"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.13"}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## AB testing access time for ICESat-2 ATL03 HDF5 files in the cloud.\n\nThis notebook requires that we have 2 versions of the same file:\n * Original A: The original file with no modifications on a S3 location.\n * Test Case B: A modified version of the orignal file to test for metadata consolidation, rechunking and other strategies to speed up access to the data in the file.\n","metadata":{"tags":[],"user_expressions":[]},"id":"6c9b37e2-2daa-4283-a228-ea581498de0c"},{"cell_type":"code","source":"import xarray as xr\nimport h5py\nimport fsspec\nimport logging\nimport re\nimport time\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n\nfrom h5coro import h5coro, s3driver, filedriver\ndriver = s3driver.S3Driver\n\nlogger = logging.getLogger('fsspec')\nlogger.setLevel(logging.DEBUG)","metadata":{"trusted":true,"tags":[]},"execution_count":1,"outputs":[],"id":"3b78fb94-10ae-48cb-8e30-521b2c8b7822"},{"cell_type":"code","source":"for library in (xr, h5py, fsspec, h5coro):\n print(f'{library.__name__} v{library.__version__}')","metadata":{"trusted":true,"tags":[]},"execution_count":2,"outputs":[{"name":"stdout","output_type":"stream","text":"xarray v2023.12.0\nh5py v3.9.0\nfsspec v2023.6.0\nh5coro v0.0.6\n"}],"id":"431d900d-0656-4b75-af6b-82f0f171d5f8"},{"cell_type":"markdown","source":"For listing files in CryoCloud\n\n```bash\naws s3 ls s3://nasa-cryo-persistent/h5cloud/ --recursive\n```","metadata":{"tags":[],"user_expressions":[]},"id":"7998cd99-6034-4a1b-9ae5-d651bc265bff"},{"cell_type":"code","source":"test_dict = {\n \"ATL03-1GB\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\"\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n },\n \"ATL03-7GB\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n },\n \"ATL03-7GB-kerchunk\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\",\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n }, \n \"ATL03-2GB\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\",\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n }\n}\n\ndef kerchunk_result(file: str, dataset: str, variable: str):\n fs = fsspec.filesystem(\n \"reference\",\n fo=file,\n remote_protocol=\"s3\",\n remote_options=dict(anon=False),\n skip_instance_cache=True,\n )\n ds = xr.open_dataset(\n fs.get_mapper(\"\"), engine=\"zarr\", consolidated=False, group=dataset\n )\n return ds[variable].mean()\n\n# This will use the embedded credentials in the hub to access the s3://nasa-cryo-persistent bucket\nfs = fsspec.filesystem('s3')\n","metadata":{"trusted":true,"tags":[]},"execution_count":3,"outputs":[],"id":"9850faac-f534-4bc2-9214-c8dababe0f52"},{"cell_type":"markdown","source":"## [h5coro](https://github.com/ICESat2-SlideRule/h5coro/)\n\n**h5coro** is optimized for reading HDF5 data in high-latency high-throughput environments. It accomplishes this through a few key design decisions:\n* __All reads are concurrent.__ Each dataset and/or attribute read by **h5coro** is performed in its own thread.\n* __Intelligent range gets__ are used to read as many dataset chunks as possible in each read operation. This drastically reduces the number of HTTP requests to S3 and means there is no longer a need to re-chunk the data (it actually works better on smaller chunk sizes due to the granularity of the request).\n* __Block caching__ is used to minimize the number of GET requests made to S3. S3 has a large first-byte latency (we've measured it at ~60ms on our systems), which means there is a large penalty for each read operation performed. **h5coro** performs all reads to S3 as large block reads and then maintains data in a local cache for access to smaller amounts of data within those blocks.\n* __The system is serverless__ and does not depend on any external services to read the data. This means it scales naturally as the user application scales, and it reduces overall system complexity.\n* __No metadata repository is needed.__ The structure of the file are cached as they are read so that successive reads to other datasets in the same file will not have to re-read and re-build the directory structure of the file.\n","metadata":{"tags":[],"user_expressions":[]},"id":"4d166627-6144-40bf-884d-2188e5c764ba"},{"cell_type":"code","source":"h5coro_beanchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n print (f\"Processing: {link}\")\n if \"kerchunk\" in link:\n continue\n group = dataset[\"group\"]\n variable = dataset['variable'] \n final_h5coro_array = []\n start = time.time()\n if link.startswith(\"s3://nasa-cryo-persistent/\"):\n h5obj = h5coro.H5Coro(link.replace(\"s3://\", \"\"), s3driver.S3Driver)\n else:\n h5obj = h5coro.H5Coro(link.replace(\"s3://\", \"\"), s3driver.S3Driver, credentials={\"annon\": True})\n ds = h5obj.readDatasets(datasets=[f'{group}/{variable}'], block=True)\n data = ds[f'{group}/{variable}'][:]\n data_mean = np.mean(data)\n elapsed = time.time() - start\n \n h5coro_beanchmarks.append({\"tool\": \"h5coro\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n\n\ndf = pd.DataFrame.from_dict(h5coro_beanchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.title('h5coro cloud optimized HDF5 performance')\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":33,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"},{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAKjCAYAAAAj5v8TAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABYzUlEQVR4nO3deVhUdf//8deAw7644haCSynuGlouKaZobllalmaubZr7banVnWilpdXtnX5NLVNbzDa1xcwolzQtdyu1vDO3FEITQUURmfP7o4v5OQdQkIGDw/NxXXPlfM6ZM+85zLzh1TnnMzbDMAwBAAAAAJy8rC4AAAAAAIobghIAAAAAmBCUAAAAAMCEoAQAAAAAJgQlAAAAADAhKAEAAACACUEJAAAAAEwISgAAAABgQlACAAAAABOCEoA8iYuLk81m08mTJ6+6bkxMjGw2W7bbHXfcUQSVWsNmsykuLs6S546JiVFMTEyRP+/x48cVFxenXbt2ZVuW9X5xp8LYZl7kdf9GRkaqW7duOS7btm2bbDabFi1a5BxbtGiRy+fDz89PlSpVUrt27TRt2jQlJSVl207WPsjpNnv2bJdaclrnsccey/frLwoffPCB6tWrJ39/f9lsthzfUwBQ1EpZXQAAz1SjRg299957LmOlS5e2phgUiuPHj2vy5MmKjIxU48aNXZY99NBDbg/GhbHN4mDhwoWqU6eOMjIylJSUpI0bN+qll17Syy+/rA8++EAdOnTI9pivvvpKoaGhLmPVq1d3ud+qVSu9/PLLLmMVK1Z0/wsooBMnTujBBx/UHXfcoTlz5sjX11c33XST1WUBAEEJQOHw9/fXrbfeamkNmZmZunTpknx9fS2toyS64YYbdMMNNxT7bRYH9evXV3R0tPN+r169NGbMGLVu3Vo9e/bU//73v2wB5+abb1b58uWvuN3SpUtb/hm8kvPnz8vPz0/79+9XRkaG+vXrp7Zt27pl22lpaQoICHDLtgCUXJx6ByBf/vrrL/Xp00ehoaGqWLGiBg8erJSUlGve3rFjx/TII48oPDxcPj4+qlKliu655x799ddfznWOHDmifv36KSwsTL6+voqKitIrr7wih8PhXOfQoUOy2WyaPn26nn/+eVWvXl2+vr5au3atJOmzzz5TixYtFBAQoODgYMXGxmrz5s15qvH06dP617/+pRo1asjX11dhYWHq0qWLfv311ys+7pdfflGPHj1UpkwZ+fn5qXHjxlq8eLHLOlmnXx06dMhlfN26dbLZbFq3bp1zzDAMTZ8+XREREfLz81PTpk21atWqPL0GSbpw4YImTpyo6tWry8fHR1WrVtXjjz+u06dPu6yXdQrZ8uXL1bBhQ/n5+alGjRp67bXXXOpr1qyZJGnQoEHOU7uyTj/M6TS5rO1+8cUXatKkifz9/RUVFaUvvvjCuS+ioqIUGBio5s2ba9u2bS6PN2/TfOra5bfLT5UzDENz5sxR48aN5e/vrzJlyuiee+7RH3/84bL9gu5fd6pWrZpeeeUVnTlzRvPmzSvS585677377rsaO3asKlWqJH9/f7Vt21Y7d+7Mtv62bdt05513qmzZsvLz81OTJk304YcfuqyT9bP6+uuvNXjwYFWoUEEBAQHq06ePWrduLUm67777sv3s8vK5zXpf7NixQ/fcc4/KlCmjmjVrSir4e27btm26//77FRkZKX9/f0VGRqpPnz46fPhwjq9v7dq1Gjp0qMqXL69y5cqpZ8+eOn78eLZ9tmTJErVo0UJBQUEKCgpS48aNtWDBApd1vvnmG7Vv314hISEKCAhQq1at9O23317pRwfAzQhKAPKlV69euummm/TJJ59owoQJWrJkicaMGZNtvQMHDqhs2bIqVaqUatasqaefflrnz593WefYsWNq1qyZli9frrFjx2rVqlWaOXOmQkNDlZycLOmf03Jatmypr7/+Ws8995w+++wzdejQQePGjdPw4cOzPe9rr72mNWvW6OWXX9aqVatUp04dLVmyRD169FBISIjef/99LViwQMnJyYqJidHGjRuv+HrPnDmj1q1ba968eRo0aJA+//xzzZ07VzfddJMSEhJyfdxvv/2mli1bas+ePXrttde0bNky1a1bVwMHDtT06dPzsquzmTx5ssaPH6/Y2FitWLFCQ4cO1cMPP6zffvvtqo81DEN33XWXXn75ZT344INauXKlxo4dq8WLF+v2229Xenq6y/q7du3S6NGjNWbMGC1fvlwtW7bUqFGjnKdyNW3aVAsXLpQkPfPMM9q8ebM2b96shx566Ip17N69WxMnTtT48eO1bNkyhYaGqmfPnpo0aZLefPNNTZ06Ve+9955SUlLUrVu3bO+Zy3Xt2tX5vFm3V199VZJUr14953qPPvqoRo8erQ4dOmjFihWaM2eO9uzZo5YtW7oE8oLs38v386VLl7LdMjMz87yNLF26dJG3t7e+++67bMuyjpZeafvfffedgoODZbfbVbduXb3yyiv5quOpp57SH3/8oTfffFNvvvmmjh8/rpiYGJeAuXbtWrVq1UqnT5/W3Llz9emnn6px48a67777XK7HyjJ48GDZ7Xa98847+vjjj/XCCy/o//7v/yRJU6dO1ebNmzVnzhxJyvfntmfPnqpVq5Y++ugjzZ071zlekPfcoUOHVLt2bc2cOVOrV6/WSy+9pISEBDVr1izH6zUfeugh2e12LVmyRNOnT9e6devUr18/l3WeffZZPfDAA6pSpYoWLVqk5cuXa8CAAS7h691331XHjh0VEhKixYsX68MPP1TZsmXVqVMnwhJQlAwAyINJkyYZkozp06e7jA8bNszw8/MzHA6Hc+zpp5825syZY6xZs8ZYuXKlMXz4cKNUqVJGmzZtjMzMTOd6gwcPNux2u7F3795cn3fChAmGJOPHH390GR86dKhhs9mM3377zTAMwzh48KAhyahZs6Zx8eJF53qZmZlGlSpVjAYNGrg895kzZ4ywsDCjZcuWV3zdU6ZMMSQZ8fHxV1xPkjFp0iTn/fvvv9/w9fU1jhw54rJe586djYCAAOP06dOGYRjGwoULDUnGwYMHXdZbu3atIclYu3atYRiGkZycbPj5+Rl33323y3rff/+9Iclo27btFev76quvcvz5ffDBB4YkY/78+c6xiIgIw2azGbt27XJZNzY21ggJCTHOnTtnGIZhbN261ZBkLFy4MNvzZb1fLhcREWH4+/sbf/75p3Ns165dhiSjcuXKzu0ahmGsWLHCkGR89tlnV9zm5X799VejXLlyRrt27Yz09HTDMAxj8+bNhiTjlVdecVn36NGjhr+/v/Hkk08ahlHw/Zv1+iRd8Xb5vsr62W/dujXXbVasWNGIiorKtg/Mt6pVq7o8btiwYcZbb71lrF+/3lixYoXxwAMPGJKMfv36XfV1ZL33mjZt6vK5PnTokGG3242HHnrIOVanTh2jSZMmRkZGhss2unXrZlSuXNn5mct6rf3798/1+T766CPnWH4+t1n75Nlnn8227YK+58wuXbpknD171ggMDDT++9//OsezXt+wYcNc1p8+fbohyUhISDAMwzD++OMPw9vb23jggQdyfY5z584ZZcuWNbp37+4ynpmZaTRq1Mho3rx5ro8F4F4cUQKQL3feeafL/YYNG+rChQsuM3Q9//zzGjp0qNq1a6cuXbpo1qxZevHFF/Xdd9/p008/da63atUqtWvXTlFRUbk+35o1a1S3bl01b97cZXzgwIEyDENr1qzJVp/dbnfe/+2333T8+HE9+OCD8vL6/y0vKChIvXr10g8//KC0tLRcn3/VqlW66aabcryg/krWrFmj9u3bKzw8PFvdaWlpeT7tL8vmzZt14cIFPfDAAy7jLVu2VERERJ7qyXr+y917770KDAzM9n+p69Wrp0aNGrmM9e3bV6mpqdqxY0e+ar9c48aNVbVqVef9rJ99TEyMyzUlWePmU5xyk5iYqDvuuEOVK1fW8uXL5ePjI0n64osvZLPZ1K9fP5cjMJUqVVKjRo2cpzYWdP9mad26tbZu3Zrt9vbbb+d5G5czDCPH8W+++cZl+19++aXL8v/7v//ToEGD1KZNG/Xo0UPvvvuuhg8frnfffTfH0+dy0rdvX5dTHSMiItSyZUvn6ay///67fv31V+c+u3z/dunSRQkJCdmOxvXq1StPz30tn9vctl2Q99zZs2c1fvx41apVS6VKlVKpUqUUFBSkc+fOad++fdmeK6f+ePk24+PjlZmZqccffzzX175p0yadOnVKAwYMcNmnDodDd9xxh7Zu3apz587l+ngA7sNkDgDypVy5ci73syZKuNIpUpLUr18/jRs3Tj/88IPuvvtuSf+cVne1i/P//vtvRUZGZhuvUqWKc/nlKleunO3xOY1nbcPhcCg5OTnXC79PnDihatWqXbHG3OrO7Tlzqjsv25OkSpUqZVuW01hOjy9VqpQqVKjgMm6z2VSpUqVs9VzpefJb++XKli3rcj8r0OQ2fuHChatu88yZM+rSpYsyMjK0atUql9ng/vrrLxmGketsbzVq1JBU8P2bJTQ01GVihoI4d+6c/v77bzVo0CDbskaNGl11Mgezfv36afbs2frhhx/UpEmTq66f277YvXu3JDlPWxw3bpzGjRuX4zbMp6fl9JnIybV8bnPbdkHec3379tW3336rf//732rWrJlCQkJks9nUpUuXHHve1frjiRMnJOmKfS9rv95zzz25rnPq1CkFBgbmuhyAexCUABSpy//vcIUKFfTnn39ecf1y5crleC1Q1gXS5j8WzRMI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uvHGGzV16lQFBASob9++FlYNAAAAwNNZGpS2bdumdu3aOe9nXVs0YMAALVq0SE8++aTOnz+vYcOGKTk5Wbfccou+/vprBQcHW1UyAAAAgBLA0qCUdYpYbmw2m+Li4hQXF1d0RQEAAAAo8YrtNUoAAAAAYBWCEgAAAACYEJQAAAAAwKTYfo+S5eJCi/C5UormaeLitGLFCu3atSvPj4mJiVHjxo01c+ZMS+sAAAAAihJBqQQZN26cRowYka/HLFu2jC9mBAAAQIlDUCoBDMNQZmamgoKCFBQUlK/Hli1btpCqAgAAAIovrlG6TqWnp2vkyJEKCwuTn5+fWrdura1bt0qS1q1bJ5vNptWrVys6Olq+vr7asGGD4uLi1LhxY+c2Ll26pJEjR6p06dIqV66cxo8frwEDBuiuu+5yrhMTE6PRo0c770dGRmrq1KkaPHiwgoODVa1aNc2fP9+ltvHjx+umm25SQECAatSooX//+9/KyMgozN0BAAAAuBVB6Tr15JNP6pNPPtHixYu1Y8cO1apVS506ddKpU6dc1pk2bZr27dunhg0bZtvGSy+9pPfee08LFy7U999/r9TUVK1YseKqz/3KK68oOjpaO3fu1LBhwzR06FD9+uuvzuXBwcFatGiR9u7dq//+979644039J///MctrxsAAAAoCgSl69C5c+f0+uuva8aMGercubPq1q2rN954Q/7+/lqwYIFzvSlTpig2NlY1a9ZUuXLlsm1n1qxZmjhxou6++27VqVNHs2fPVunSpa/6/F26dNGwYcNUq1YtjR8/XuXLl9e6deucy5955hm1bNlSkZGR6t69u/71r3/pww8/dMdLBwAAAIoE1yhdhw4cOKCMjAy1atXKOWa329W8eXPt27dPzZo1kyRFR0fnuo2UlBT99ddfat68uXPM29tbN998sxwOxxWf//KjUzabTZUqVVJSUpJz7OOPP9bMmTP1+++/6+zZs7p06ZJCQkLy/ToBAAAAq3BE6TpkGIakf0KKefzyscDAwKtuK6dtXI15FjybzeYMVz/88IPuv/9+de7cWV988YV27typp59+WhcvXrzqdgEAAIDigqB0HapVq5Z8fHy0ceNG51hGRoa2bdumqKioPG0jNDRUFStW1JYtW5xjmZmZ2rlzZ4Fq+/777xUREaGnn35a0dHRuvHGG3X48OECbRMAAAAo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ovTaa69p0KBBCgsL086dO9W8eXOVK1dOf/zxhzp37lwYNQIAAABAkcp3UJozZ47mz5+v2bNny8fHR08++aTi4+M1cuRIpaSkFEaNAAAAAFCk8h2Ujhw5opYtW0qS/P39debMGUnSgw8+qPfff9+91QEAAACABfIdlCpVqqS///5bkhQREaEffvhBknTw4EG+hBYAAACAR8h3ULr99tv1+eefS5KGDBmiMWPGKDY2Vvfddx/frwQAAADAI+R71rv58+fL4XBIkh577DGVLVtWGzduVPfu3fXYY4+5vUAAAAAAKGr5DkpeXl7y8vr/B6J69+6t3r17u7UoAAAAALDSNX3h7IYNG9SvXz+1aNFCx44dkyS988472rhxo1uLAwAAAAAr5DsoffLJJ+rUqZP8/f21c+dOpaenS5LOnDmjqVOnur1AAAAAAChq+Q5Kzz//vObOnas33nhDdrvdOd6yZUvt2LHDrcUBAAAAgBXyHZR+++03tWnTJtt4SEiITp8+7Y6aAAAAAMBS+Q5KlStX1u+//55tfOPGjapRo4ZbigIAAAAAK+U7KD366KMaNWqUfvzxR9lsNh0/flzvvfeexo0bp2HDhhVGjQAAAABQpPI9PfiTTz6plJQUtWvXThcuXFCbNm3k6+urcePGafjw4YVRIwAAAAAUqXwHJUl64YUX9PTTT2vv3r1yOByqW7eugoKC3F0bAAAAAFjimoKSJAUEBCg6OtqdtQAAAABAsZDnoDR48OA8rffWW29dczEAAAAAUBzkOSgtWrRIERERatKkiQzDKMyaAAAAAMBSeQ5Kjz32mJYuXao//vhDgwcPVr9+/VS2bNnCrA0AAAAALJHn6cHnzJmjhIQEjR8/Xp9//rnCw8PVu3dvrV69miNMAAAAADxKvr5HydfXV3369FF8fLz27t2revXqadiwYYqIiNDZs2cLq0YAAAAAKFL5/sLZLDabTTabTYZhyOFwuLMmAAAAALBUvoJSenq63n//fcXGxqp27dr6+eefNXv2bB05coTvUQIAAADgMfI8mcOwYcO0dOlSVatWTYMGDdLSpUtVrly5wqwNAAAAACyR56A0d+5cVatWTdWrV9f69eu1fv36HNdbtmyZ24oDAAAAACvkOSj1799fNputMGsBAAAAgGIhX184CwAAAAAlwTXPegcAAAAAnoqgBAAAAAAmBCUA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NWrUkCStXr1aY8eO1Z49e6wsE0AhoxcAoA/AHTiiBI9x6NAh1axZ03k/NjbWOQ2oJNWuXVsHDx60ojQARYheAIA+AHfgGiV4jEuXLiklJcV5f9myZS7Lk5OT5eXF/xsAPB29AAB9AO7AOwQeo3bt2tq0aVOuyzds2KCbbrqpCCsCYAV6AQD6ANyBoASPcf/99+vZZ5/VTz/9lG3Z7t27NXnyZPXp08eCygAUJXoBAPoA3IHJHOAxMjIy1KFDB23atEmxsbGqXbu2bDabfv31V8XHx6tFixb69ttvZbfbrS4VQCGiFwCgD8AdCErwKBcvXtSrr76qpUuXav/+/ZKkG2+8UX369NGYMWPk6+trcYUAigK9AAB9AAVFUAIAAAAAE65RAgAAAAATghJKjN27d8vb29vqMgAUgZUrV+qhhx7Sk08+qX379rksS05O1u23325RZQCKQnBwsIYMGXLFme+AqyEooUThTFPA8y1ZskQ9evRQYmKiNm/erKZNm+q9995zLr948aLWr19vYYUACtu5c+f0448/qnXr1oqKitIrr7yipKQkq8vCdYZrlOAxevbsecXlKSkpWrdunTIzM4uoIgBWaNq0qQYNGqQRI0ZIkj7++GMNGjRIM2fO1JAhQ/TXX3+pSpUq9ALAg3l5eSkxMVEJCQl68803tWTJEp09e1bdunXTQw89pDvuuEM2m83qMlHMcUQJHuPzzz/XhQsXFBoamuMtKCjI6hIBFIH9+/erW7duzvv33HOPPv/8c40ZM0Zz5861sDIARa1Ro0aaNWuWEhIStGjRIqWkpKhbt26qVq2ann32WavLQzFXyuoCAHeJiopSr169NGTIkByX79q1S1988UURVwWgqIWEhOivv/5S9erVnWMxMTH6/PPP1a1bN/35558WVgegKJiPFvn4+KhPnz7q06ePDh06pAULFmjRokWaMmWKRRXiesARJXiMm2++WTt27Mh1ua+vr6pVq1aEFQGwQvPmzbVq1aps423bttXnn3+umTNnFn1RAIrUla4siYyM1HPPPafDhw8XYUW4HnFECR5j7ty5V7zmICoqSgcPHizCigBYYcyYMbnOdBUTE6MvvvhCixcvLuKqABSlSZMmXfWUe65RwtUwmQMAAAAAmHDqHTxa165dlZCQYHUZACxGLwBAH0B+EZTg0b777judP3/e6jIAWIxe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\n","text/plain":"
"},"metadata":{}}],"id":"efe41d4a-1947-438b-a3c3-7ab954d75e13"},{"cell_type":"markdown","source":"### Xarray + kerchunk, out of the box performance.","metadata":{"tags":[],"user_expressions":[]},"id":"8f0ba64d-d89c-4879-b965-f00d70956360"},{"cell_type":"code","source":"# this is going to keep our numbers without modifying the i/o paramters\nregular_xarray_benchmarks = []\nkerchunk_benchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n print (f\"Processing: {link}\")\n try:\n log_filename = f\"logs/fsspec-xarray-{key}-{k}-default.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n \n start = time.time()\n if \"kerchunk\" in link:\n data_mean = kerchunk_result(link, dataset[\"group\"], dataset[\"variable\"])\n elapsed = time.time() - start\n kerchunk_benchmarks.append(\n {\"tool\": \"kerchunk\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean}) \n else:\n ds = xr.open_dataset(fs.open(link, mode='rb'), group=dataset[\"group\"], engine=\"h5netcdf\", decode_cf=False)\n data_mean = ds[dataset[\"variable\"]].mean() \n elapsed = time.time() - start\n regular_xarray_benchmarks.append(\n {\"tool\": \"xarray\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean}) \n \n logging.getLogger().removeHandler(file_handler)\n file_handler.close()\n\n except Exception as e:\n print(e)","metadata":{"trusted":true,"tags":[]},"execution_count":22,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"}],"id":"ff56958f-8c1d-4fd7-b885-6efb81af8da7"},{"cell_type":"markdown","source":"### Plotting Results","metadata":{"tags":[],"user_expressions":[]},"id":"92a8e67d-026e-4c6b-aa7d-b19dc10f4afd"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(kerchunk_benchmarks + regular_xarray_benchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\n\nplt.title(\"Out of the box I/O parameters\", fontsize=10)\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\n\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":24,"outputs":[{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAMfCAYAAADomSepAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACS8ElEQVR4nOzde3zP9f//8ft7s713HnPYgdkcQ8gpcsiGRpSoPikqRKWUYyKpTEKpUOn8yaED+lR0UlhyPoRKKeeztJnzMGa25+8Pv72/3u8NG+/ttc3ternswvv1er1fr8f78Hjvfd/r9Xq+bMYYIwAAAACAg4fVBQAAAABAYUNQAgAAAAAXBCUAAAAAcEFQAgAAAAAXBCUAAAAAcEFQAgAAAAAXBCUAAAAAcEFQAgAAAAAXBCUAAAAAcEFQAi4iPj5eNptNixcvtroUh9jYWNlsNqvLyJPo6GhFR0fn2/oL0+tUFF+fa8m8efN00003KTg4WDabTT179rS6pGvWyZMnFR4err59+zpNL2o9lB+fb4sXL5bNZlN8fLxb11tYTZ06VZ6entqwYYPVpQDZEJRwTfn111/Vu3dvVatWTf7+/vL19VWVKlX04IMPKiEhweryiqSePXvKZrNp9+7dVpdSpGR9GXrssccuusysWbNy/MKU9WUy68fLy0ulS5dWvXr11Lt3b82bN0+ZmZk5rjM6Otrpvq4/FwbOrBCa04+Pj487noYCs2vXLnXu3Fl79+7Vww8/rJEjR6pz585Wl3XNGj9+vI4cOaLhw4dbXco16VIBr6CD2oMPPqhKlSppyJAhBbI9IC9KWF0AUBAyMzM1ZMgQTZw4USVKlFDr1q11xx13yMvLSzt37tTcuXP16aef6sUXX9Tzzz9vdbnFysKFC/N1/U8++aTuu+8+VaxYMV+3Uxg99dRTCggIUGZmpo4dO6ZNmzbps88+05QpU9SsWTPNnDkzx+fF09NTzz33XI7rzOnLU48ePbJNL1GiaP36WLhwodLS0jRhwgTdd999VpdzTTt27JgmTJigrl27KjIy0upyrkp+f75dC0qUKKGBAweqX79+Wr58uVq0aGF1SYBD0fpNB1yh5557ThMnTlS9evX05ZdfqkqVKk7zT58+rcmTJ+vw4cMWVVh8uT7X7lamTBmVKVMmX7dRWA0ZMkRhYWFO0w4ePKj+/ftr1qxZateundatWyd/f3+nZUqUKJGnvxb37NlTsbGxbqjYOv/++68kZXu+UPA++eQTnTp1Sg8++KDVpVy1/P58u1bcd999GjRokN577z2CEgoVDr1Dsbd9+3aNHz9epUuX1rx583L8xebr66unn35ao0aNytU6v//+e7Vq1UrBwcHy9fVVvXr1NGnSJGVkZDgtd6lDGHbv3n3R8ySWL1+umJgY+fv7q3Tp0rr33nu1b9++XNWWk5UrV+q2225TSEiIfHx8VKNGDcXHxys1NTXbsjabTbGxsdq3b5/uvfdelS5dWv7+/oqNjdXKlSudlo2Ojtb06dMlSZUqVXIclnXhl+qcDvG48LyiqVOnqk6dOvL19VWlSpX05ptvSpKMMXrjjTdUo0YN+fj4qHr16vrkk0+y1ZvTOUquh6a5/ri+HsnJyRo0aJCqVq0qu92uMmXK6O6779Zff/2V4/Pp7tfHncqWLavPPvtMbdq00ebNm/X2229bXZKmTZsmm82madOmac6cObrxxhvl5+ensLAwPf744zp69GiO99u1a5cefvhhVaxYUXa7XeHh4erZs6f27NmTbdms993+/fvVs2dPhYWFycPDw7HtkSNHSpJatWrleB9ceLjolfSI67YWL17s1PMrV65Uq1atFBgYqLJly6pv3746ffq0pPPnSzVv3lz+/v4KDQ3VsGHDsn1+HD9+XK+88opiYmIUEREhb29vRUREqHv37tqxY0e2ui7shf/9739q0KCBfH19FR4erv79+zu27WrZsmW68847FRoaKrvdrsjISN11111avny503LGGE2ZMkXNmzdXUFCQ/Pz81KhRI02ZMiXH9V7MtGnTVLp0abVq1SpP9/vmm2/Upk0blSpVSj4+Pqpdu7Zee+21bM9bZmam/vvf/6px48YKCQmRn5+foqOj1blzZy1dutRp2a+++koxMTEqV66cfHx8FBkZqVtvvVVff/11rmrK6fPtzJkzev3113XDDTcoODhYAQEBqlKlirp27Zrn83CWLl2qmJgYBQQEKCQkRN26ddM///yT47K5+RzL+r2zZ88e7dmzJ9vnYnx8vON1GTVqlNP8C/vl7NmzmjBhgho0aCB/f38FBgbq5ptv1rfffputrqzDs3fu3KmJEyfq+uuvl91ud/rdV6ZMGbVq1UpffvmlTp48mafnCMhP7FFCsTdt2jRlZGSoT58+Cg0NveSydrv9sut74403NHDgQMcvLX9/f3333XcaNGiQli1bpi+//PKqTkZeuHCh2rdvLw8PD917772KiIjQwoUL1bx5c5UqVSrP6/vqq6903333ydvbW/fee6/KlSunn376SaNGjdKCBQu0aNGibI/76NGjat68ucLDw/Xoo49q//79+vzzz9WqVSvNnz/fEYQGDhyoadOm6Y8//tCAAQNUsmRJSTkfvpWTSZMmafHixerUqZNat26tr776SgMGDJCfn5/++OMPffHFF7r99tvVunVrzZo1S927d1elSpUu+xfHi+0B+eKLL7Rx40b5+fk5pu3YscPxpbdt27bq3LmzkpOT9dVXX2n+/PlauHChmjRp4lje3a9PfvDw8NCIESO0cOFCff755xo6dOhVrW/ZsmVas2aNPD09VaNGDd1yyy256hVXX375pRISEnTPPffolltu0ZIlS/Tee+9p1apVWrVqlXx9fR3L/vLLL2rXrp1OnTqljh07qmrVqtq9e7c+++wz/fjjj1q1apUqV67stP7Dhw+radOmCgkJ0b333quzZ8+qbt26GjlypBYvXqwlS5Y4HUaY9X69kh7JaVtBQUFKSUlx1P/KK6+oXbt26tOnjxYtWqR3331XKSkp6tSpk3r06KE77rhDTZo00dy5czV+/HgFBQVpxIgRjm1s2rRJL7zwglq1aqU777xT/v7+2rx5s2bMmKG5c+fqt99+U1RUVLbn+e2339aPP/6oTp06KTY2VvPmzdNbb72lw4cP67PPPsu2bL9+/eTr66s777xTFStW1P79+7V8+XJ9+eWXjl4zxuiBBx7QjBkzVL16dXXr1k3e3t5KSEhQ7969tXHjRr322muXfQ8cPXpUv//+u2699VZ5eOT+b7XPPvusxo0bpwoVKujuu+9WUFCQli5dqqefflq//PKLvvjiC8eyw4cP1/jx41WlShV169ZNgYGB2r9/v5YtW6aff/5ZLVu2lCS9++676tu3r8LDw3XnnXeqdOnSSkxM1Jo1a/T1119f8TlsPXr00P/+9z/VrVtXDz30kOx2u/bu3atFixapXbt2qlOnTq7Ws3r1ao0bN0633Xab+vfvr99++00zZ87U8uXLtXbtWqffZ7n9HCtZsqRGjhypSZMmSTr/GZ4l6zNz9+7dmj59umJiYpw+R7P6JS0tTbfeeqsWL16s+vXrq3fv3kpPT9fcuXPVqVMnvfXWW3ryySezPZ5+/fpp9erVuu2223T77bdn+33ctGlTJSQkaMWKFWrXrl2uniMg3xmgmIuNjTWSzE8//ZSn+40cOdJIMosWLXJM27FjhylRooQpV66c2bt3r2N6WlqaiYmJMZLMJ5984pi+aNEiI8mMHDky2/p37dplJJkePXo4pmVkZJjKlSsbm81mli1b5piemZlpunXrZiSZvLRtSkqKKVmypLHb7eaPP/7IcX2jR492uk/WNh588EGTmZnpmL548WJjs9lM1apVTUZGhmN6jx49jCSza9euHGuIiooyUVFRTtOyntuQkBCzY8cOx/S9e/cab29vExwcbKpXr26Sk5Md83755Rcjydxxxx05ruvC1ykn3377rfHw8DCNGjUyqampjunNmjUzJUqUMAsWLHBafsuWLSYwMNDUqVPHMc2dr0/We6Nhw4Zm5MiROf7cfffdOb5/st5riYmJF13/mTNnjJeXl/Hw8DDp6emO6VFRUcbT0zPH7c2cOdNpHVnPretPeHh4tufrUqZOneq4r2sfPvTQQ0aSefHFFx3Tzp49a6Kjo01gYKBZv3690/LLli0znp6e5vbbb3eanrX+hx56yJw7dy5bDRd7n1xNj+S0razXVZL5+uuvnR5T3bp1jc1mM2XKlDFr1qxxqqFcuXKmdOnSTq/VsWPHzOHDh7M9lp9//tl4eHiYhx9+OMfHGBwcbDZv3uyYnpqaaqpXr25sNpvZv3+/Y/qff/5pPD09TURERLb+zczMdFr2gw8+MJJM7969nWpMS0szHTt2NJLMunXrstXqau7cuUaSGTFiRI7zs97bF1qwYIGRZNq3b29OnTrlVONjjz1mJJkvv/zSMT0kJMSUL1/eadms5S98Phs0aGC8vb2dPmeyHDp06LKPxZjsn2/Hjh0zNpvNNGrUKNt749y5c+bo0aOXXeeF76H//ve/TvNGjRplJJlevXo5Tc/L51hOdee0/Zx+bxljzLPPPmskmfj4eKffESkpKaZRo0bG29vb6b2T9TuiQoUKZs+ePRd93N98842RZF544YWLLgMUNIISir0aNWoYSU5fHHIjpy9WL774opFkXnnllWzLr1q1ykgybdq0cUzLa1BasmSJkWQ6duyYbfndu3cbT0/PPAWljz/+2Egyjz/+eLZ5e/fuNSVKlDBVqlRxmi7JeHp6OgXBLLfddpuR5BQSriYoxcfHZ1u+devWRpKZPn16tnmVK1e+6LouFZT++OMPExAQYMqXL+/0C/y3335zfPnLyeDBg40ks2HDBmOMe1+fC78MXe7nSoKSMcaEhoYaSebAgQOOaVFRURfdTqdOnZzuP2fOHDN9+nSze/duc/r0abNt2zYzevRo4+vra3x8fLKFmIvJCkpxcXHZ5u3fv994eXk5vQ9nz56dY0DJctdddxkPDw9z/PhxxzRJxtvb2xw8eDDH+1zsfXKlPXKxbWW9rrGxsdnmZX1+PPTQQ9nm9erV65J95KpOnTomOjraaVrWY8zpi2bWvG+//dYxrW/fvkaSmTJlymW3V7duXePv729Onz6dbd6ff/5pJJmnnnrqsut5//33jSTz5ptv5jg/p6B0xx13GEk5fiZlBZO7777bMS0kJMRUqlTJpKWlXbKWBg0aGH9//1yFl4tx/Xw7fvy4kWSaN29+xevMeg9dd911TkHEmPOht2zZssbX19fx+PL6OZZT3TltP6ffWxkZGaZUqVKmatWq2Woz5vwfpCSZt956yzEt63fEG2+8ccnHvXr16hxDIGAlDr0D8uD333+XpBwP67rpppvk6+ur9evXX/H6//jjD0nSzTffnG1eVFSUIiMjnY4T3717t6ZNm+a0XMmSJR2HU1yq3sjISFWpUkVbtmzRiRMnFBgYmG1brm6++WbNnTtX69evd8sJt/Xr1882LTw8XJJUr169HOf98ssvedrGgQMH1LFjR2VmZurbb79VRESEY97q1aslSUlJSTmeR7Z582bHv7Vr187z65Mbffr00XvvvZfjvFmzZqlr1655Wt+FjDE5Trfb7Tpz5sxl7+966FHVqlX13HPPKTQ0VI8++qheeuklp0OeLien5y0iIkJVqlTR5s2bHe/DrNdl8+bNOb4uSUlJyszM1NatW9WoUSPH9EqVKuV5YI8r7ZHLbetK3tuStH//fqdDVxcvXqxJkybpl19+0aFDh3Tu3DnHPG9v7xy33aBBg2zTKlSoIOn8iHNZ1qxZI0lq27btRR+HJKWmpmrDhg2KiIjQyy+/nG1+enq6pP/rl0vJGjAnL4eprl69Wv7+/vroo49ynO/r6+u07S5duui9995T7dq1de+99yomJkZNmzbNNqhJly5d9Mwzz6h27dq67777FBsbqxYtWjgOMbsSQUFBuvXWWzVv3jw1aNBA//nPf3TzzTerSZMmF329LqZ58+bZDuP29fVVw4YNNW/ePG3dulW1a9fO8+fY1diyZYuOHj2qiIiIHM/pPXjwoNM2L9S4ceNLrjskJESSdOjQoauqEXAnghKKvbCwMG3evFn79+/Xddddd1Xryjr/4GLnOpUrV0779++/4vUfP37csZ6chIaGZgtKrr+soqKiHEHpcvWGhYVpy5YtSklJcfoSeKntX1jn1QoKCso2LWvY6YvNu/CL4uWcOXNGnTt31r59+/TFF19k+wJ55MgRSdLcuXM1d+7ci67n1KlTkvL++lgpLS1NR44ckaenp+MLiLv06NFDffv21YoVK/J0v0s9b5s3b3a8D7NeF9fzaVxlvS4XrievrrRHLretK3lvS/8XOqTz59Tde++9CggIULt27RQdHS0/Pz/HwBg5DWohScHBwRdd/4UDHxw7dkw2m80R0i7m6NGjMsZo//79lxzwxvX1yEnWeWgXG1giJ0eOHNG5c+dyve0333xTlStX1rRp0/TSSy/ppZdeko+Pj7p06aLXX3/dEXCHDh2q0qVL67333tOECRP0+uuvq0SJEurQoYMmTZqkSpUq5brGC3355ZcaO3asZs6c6TjnLDAwUL169dLYsWOdzpG8lNx+Duf1c+xqZG3r77//1t9//52nbV2uZ7LeE7l9foCCwKh3KPaaN28uyT3Xu8j6gnPgwIEc5ycnJzt9Cco6WTmnL/c5hY2sLzjJyck5rt91u7GxsTLnD6F1/Fz4Rf1y9WZNd/3idrnt5/RFrDDq1auXVq9erdGjR+vuu+/ONj/rcb/11lvZnscLf3r06CEp76+PlVasWKFz586pXr16br/mkbe3twIDA3McEe5SLve8Zb0eWf9+9913l3xdYmJinNZzJYOoXGmPXM2ALbkVHx8vHx8f/frrr/riiy/06quvatSoUY7pV6tkyZIyxigxMfGSy2U99oYNG17y9Vi0aNFlt1m2bFlJ//eFOzeCgoJUunTpS257165djuW9vLz09NNP6++//9b+/fs1Y8YM3Xzzzfr44491//33O5az2Wx6+OGHtW7dOh08eFBz5szRXXfdpW+//Va33XZbttH0csvf319jxozRzp07tXPnTn300UeqUaOG3njjDQ0aNCjX68nt53BeP8euRta27r777ktua+rUqdnue7meyXpPZL1HgMKAoIRir2fPnvL09NQHH3zgOCzgYtLS0i45P+twmguHos6yZs0anT592umwmqzDS3Lay5R1yM+FbrjhBknnRxlztWfPnjwPQX2pevfv368dO3aocuXKTn8pv9S2suq68DF6enpK0hV/qcgvL774ombOnKn777/faSSxC2WNZrdq1apcrdPdr09+yczM1NixYyXpqg7du5ht27bp6NGjuR7dMEtOz9u///6rHTt2qEqVKo73YV5fl6txpT1SEHbs2KGaNWuqWrVqTtOznrOrlXUo1IIFCy65XGBgoGrWrKlNmzY5Hbp3JbJGfNu2bVuu79OkSRMdPnw4T/fJEhERoa5du2revHmqVq2afvrppxz3ZpUuXVqdO3fW559/rtatW2vTpk3avn17nrfnqlKlSurVq5eWLFmigICAHIfPvpgVK1ZkO3z29OnT+vXXX+Xr66vq1atLurJ+8fT0vOhn9qU+02vWrKmgoCCtW7fOae+nO2zZskWScj0qIFAQCEoo9qpWraqhQ4fq0KFDat++vdNfHrOcOXNGEyZMuOxFOLt166YSJUpowoQJjgtYSucPl3nmmWckyenaENddd53jl+OFf0E9cOCAXnrppWzrb9GihSpVqqTvv//e6Romxhg9++yzeQ4jnTp1UnBwsKZOnep0mIQxRsOHD1d6enqO13HKyMjQiBEjnH5JL1myRD/88IOqVq2qZs2aOaZnHdZ1sWt7WOGLL75QfHy8mjZtetHzGqTzXxSbNGmimTNn6vPPP882PzMzU0uWLHHcdvfrkx8OHjyoBx54QAsXLlStWrX0+OOPX9F6Tpw4oT///DPb9KNHj6p3796S8h7CEhISsu3Zfe6555Senu701+5OnTqpYsWKmjBhQrbr3kjn+831Gj9X6kp7pCBERUVp+/btTnu7zpw5o8cffzxPh6BezGOPPSZPT08999xz2Q7jc93T1L9/f6WmpuqRRx7J8bCqXbt25eqw0zp16igkJMRxflRu9O/fX9L5PcQ5XRQ8KSlJmzZtknT+j10///xztoBx6tQpnThxQl5eXo4gMH/+/GzPY3p6uuOz+sLh6nPr4MGDOT62o0ePKi0tLU/r3LJlS7ZrVL366qs6ePCgunbt6jjnKa+fY9L5z+1Dhw7leK7ipT7TS5Qooccff1x79uzRkCFDcgxLf/3110X3hl1K1vmnrnuKAStxjhKuCS+99JLOnDmjiRMn6rrrrlPr1q1Vu3ZteXl5adeuXfrpp590+PDhHMPLhapUqaJXXnlFTz31lOrWrasuXbrI399f33//vTZv3qxOnTrpgQcecCzv7e2tJ598Ui+//LIaNGigTp066cSJE/ruu+8UExOT7a/CHh4e+uCDD9ShQwfdcsstjuv0/Pzzz0pMTFTdunVz/PJ6MUFBQfrwww/VtWtXNWnSRPfee6/Kli2rhQsXat26dWrcuLGefvrpbPerW7euFi9erJtuukmtW7fWv//+q1mzZsnLy0sffvih0/VPWrdurddee019+vTRPffcI39/f1WsWFHdunXLdZ3u1qNHDxljdMMNN2jcuHHZ5sfGxjpO3p85c6ZatWql++67T5MmTVLDhg3l4+OjvXv3atWqVTp48KDjy4S7X5+r9dprrykgIECZmZlKSUnRxo0btXTpUqWlpal58+aaNWvWFR/vf/jwYd1www1q1KiR6tSp4zj/7scff9Thw4cVFxeXp8OIJOm2225Thw4ddM899ygyMlJLlizRqlWrdMMNN2jIkCGO5ex2u7788ku1b99eMTExatOmjeMk9L1792rZsmUqXbp0rgYPuJwr7ZGC0K9fP/Xr10/169fXf/7zH507d04JCQmO93bW4CJXqk6dOpo0aZL69++v66+/Xp07d1ZUVJSSkpK0dOlS3XbbbY7r7fTp00erV6/W9OnTtWLFCt1yyy2KiIjQgQMHtHnzZv3yyy+aMWPGZfcy2mw23XHHHfr444+VmJh42fOjJOnWW2/V888/r9GjR6tq1aq69dZbFRUVpcOHD2v79u1atmyZXnrpJdWsWVOnT59WmzZtVLlyZTVp0kQVK1bUyZMn9f333yspKUnDhg1zBIx7771Xfn5+atGihaKiopSenq6EhARt3LhR9957rypWrJjn53T//v1q0qSJrr/+ejVo0EDly5fX4cOH9c033yg9PT1P1zRr27at+vbtq7lz56pGjRr67bffNH/+fEVGRjr2GGfJy+eYdP5ze926derYsaNuvvlmeXt7q0WLFmrRooVq1KihiIgIx+dHhQoVZLPZ9Pjjjys4OFijRo3Sb7/9pjfffFNz585VTEyMypYtq/3792vDhg36448/tGrVqoueY5UTY4wWLlyomjVrOvaUAYWCewbPA4qGtWvXml69epmqVasaX19fY7fbTXR0tOnatWu2609catjpb775xsTExJjAwEBjt9tNnTp1zOuvv+50fZEs586dMy+88IKJjIw03t7epnr16uaNN94wO3fuzDY8eJalS5eali1bGl9fXxMSEmLuueces2fPnhyHzs2NpUuXmvbt25uSJUs6anj++efNyZMnsy0rycTExJg9e/aYe+65x5QqVcr4+vqali1bmuXLl+e4/vHjx5tq1aoZLy8vx/2zXGp48Jye20sNN57T489pXcrjcNtHjhwxzz33nKldu7bx9fU1AQEBplq1aqZbt25m9uzZ2epwx+uTNQRvnz59LrrMzJkzLzk8eNZPiRIlTKlSpcwNN9xgevXqZebNm+d0rasLRUVFGbvdftn6jh8/bp544gnTsGFDU6ZMGVOiRAkTHBxsWrRoYd57770cr1V0MVnDg0+dOtXMnj3bNGzY0Pj4+Jhy5cqZPn365HitIGOM+eeff8yAAQNMtWrVjN1uN0FBQaZmzZrm4YcfNgsXLnRa1vV95+pyw8hfSY/k5FJDK1/4POSmvszMTPPee++Z66+/3vj4+JiwsDDTu3dvc+DAgVz3Qm62vWjRInP77bebkJAQ4+3tbSpUqGDuvvtus2LFimzLfv755+aWW24xpUqVMl5eXqZ8+fImNjbWvP766xcdmt1V1qUUXn/99WzzLtVDCQkJpmPHjqZs2bLGy8vLhIWFmaZNm5rRo0c7hg4/e/aseeWVV0zbtm1NhQoVjLe3twkNDTUxMTFm1qxZTut75513zB133GGioqKMj4+PKV26tGnSpIl5//33c/wsz4nr59vRo0dNfHy8admypQkPDzfe3t4mIiLC3HrrrWb+/Pm5WueF76ElS5aYm2++2fj5+ZmSJUua++67L8dh0o3J2+fYiRMnzCOPPGLCw8ONh4dHtvfs6tWrHb/jsj5nLvxMPnfunHn//fdN8+bNTVBQkLHb7aZixYrm1ltvNe+++65T31zuEhLGnL9OnyQzadKkXD1HQEGxGXOR8WMBXJNsNptiYmJyPGcDuBLTpk3TQw89pKlTp1p2GBsKl2bNmun48eP666+/CmRgDBRu3bt31/fff6+dO3de1fDsgLtxjhIAAChQr732mjZu3Jin63CheNq+fbtmzJih559/npCEQoegBAAAClSzZs303nvvuX3kNBQ9//zzj0aOHKknnnjC6lKAbBjMAQAAFLg+ffpYXQIKgQsH1wEKG85RAgAAAAAXHHoHAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgBwDTDG6NFHH1VISIhsNpvWr1+f6/tGR0dr0qRJbq1n8eLFstlsOnbsmFvXCwCAuxCUAMDN9u3bp969eysiIkLe3t6KiorSgAEDdPjw4TytZ/fu3XkONRczb948TZs2Td9//70SExNVu3btbMtMmzZNJUuWvOptFWbx8fGqV69ejtPvu+8+x+2VK1eqQ4cOKlWqlHx8fFSnTh29/vrrysjIKMBqC4/8CMsAUNgRlADAjXbu3KlGjRpp69atmjlzprZv36733ntPCxcuVNOmTXXkyBFL6tqxY4fCw8PVrFkzhYWFqUSJEpbUUVh9++236tSpkyRpzpw5iomJUYUKFbRo0SJt3rxZAwYM0JgxY3TffffJGFOgtRljdO7cuQLdZn45e/as1SUAQO4ZAIDb3HrrraZChQomNTXVaXpiYqLx8/Mzjz32mGOaJDNnzhyn5YKDg83UqVMd8y/8iYmJueh2Fy9ebG688Ubj7e1twsLCzLBhw0x6eroxxpgePXo4rScqKirb/RctWpRteyNHjjTGGBMVFWXGjBljHnroIRMQEGAiIyPN+++/73T/f/75x3Tp0sWULFnShISEmDvuuMPs2rXrovVmbe/77783devWNXa73TRu3Nj8+eefTst9+eWXplatWsbb29tERUWZ1157zTFv1KhRJjw83Bw6dMgxrWPHjubmm282GRkZOW535MiR5oYbbnCatnfvXuPl5WWOHj1qTp48aUqXLm3uuuuubPf99ttvjSQza9asiz6umJgY88QTT5gnnnjCBAcHm5CQEDNixAiTmZnpWOaTTz4xDRs2NAEBASY0NNR07drVHDhwINtzM2/ePNOwYUPj5eVlfv75Z7N9+3Zzxx13mHLlyhl/f3/TqFEjk5CQ4LT9qKgoM3r0aPPggw8af39/U7FiRfP111+b5ORkc8cddxh/f39Tu3Zts3btWqf7rVixwtx8883Gx8fHVKhQwfTr18+cPHnS8Zhc3xu5ud+F9fTo0cMEBQWZ7t27m7S0NPPEE0+YsLAwY7fbTVRUlBk7duxFn1MAsApBCQDc5PDhw8Zms130S98jjzxiSpUq5fjSfLmgtGbNGiPJ/PTTTyYxMdEcPnw4x/X+888/xs/Pz/Tt29ds2rTJzJkzx5QpU8YRdI4dO2ZefPFFU6FCBZOYmGiSk5OzrSMtLc1MmjTJBAUFmcTERJOYmGhOnDhhjDn/ZTckJMS8/fbbZtu2bWbcuHHGw8PDbNq0yRhjzKlTp0y1atVMr169zJ9//mk2btxounXrZq677jqTlpaWY81ZYaBmzZpmwYIF5s8//zS33367iY6ONmfPnjXGGLNu3Trj4eFhXnzxRbNlyxYzdepU4+vr63h+zp07Z5o2bWo6d+5sjDHm3XffNcHBwWb37t05btOYnIPS5MmTTZs2bYwxxsyePdtIMitXrszx/tWrVzedOnW66PpjYmJMQECAGTBggNm8ebP59NNPjZ+fn/nggw8cy3z00Ufmhx9+MDt27DCrVq0yN910k2nfvn2256Zu3bpmwYIFZvv27ebQoUNm/fr15r333jN//vmn2bp1qxkxYoTx8fExe/bscdw367V67733zNatW83jjz9uAgMDza233mr+97//mS1btpjOnTubmjVrOt6Hf/75pwkICDATJ040W7duNStWrDD169c3PXv2NMacf19XqFDBvPjii473Rm7ul1VPUFCQefXVV822bdvMtm3bzKuvvmoiIyPN0qVLze7du82yZcvMjBkzLvqcAoBVCEoA4CarV6/OMfxkmTBhgpHk2HtwuaC0a9cuI8n8/vvvl9zus88+a6677jqnvRZvv/22CQgIcOxZmThxYo57ki40depUExwcnG16VFSUeeCBBxy3MzMzTbly5cy7775rjDn/xd91+2lpacbX19fMnz8/x21lhYEL984cPnzY+Pr6ms8//9wYY0y3bt1MXFyc0/2efvppU6tWLcftHTt2mMDAQDNs2DDj5+dnPv3000s+xpyCUlxcnHnzzTeNMca8/PLLRpI5evRojve/4447TM2aNS+6/piYGKcQYowxw4YNu+R9sgJxVjDNem6+/vrrSz4WY4ypVauWeeuttxy3XV+rxMREI8k8//zzjmmrVq0ykhyB58EHHzSPPvqo03qXLVtmPDw8zOnTpx3rnThxotMyub1fVpDN0q9fP9O6dWun5wgACiPOUQKAAmL+/7ktNpvNrevdtGmTmjZt6rTe5s2b6+TJk/rnn3/cso26des6/m+z2RQWFqbk5GRJ0q+//qrt27crMDBQAQEBCggIUEhIiM6cOaMdO3Zccr1NmzZ1/D8kJETXXXedNm3a5HhczZs3d1q+efPm2rZtm2NQhcqVK+u1117TK6+8oo4dO+r+++/P0+NKSUnRkiVLdMcddzhNNxc5D8kYc9nX76abbnJapmnTpk41//777+rUqZOioqIUGBio2NhYSdLevXud1tOoUSOn26dOndLQoUNVq1YtlSxZUgEBAdq8eXO2+134WoWGhkqS6tSpk23aha/ftGnTHK9dQECA2rVrp8zMTO3ateuijzO393N9HD179tT69et13XXXqX///lqwYMFFtwEAVuJsXgBwk6pVq8pms2njxo3q3LlztvmbN29WqVKlVKZMGUnnA4frF/L09PQ8bzenL+/uDmVeXl5Ot202mzIzMyVJmZmZatiwoT777LNs9ytbtmyet5VV86Ue14WWLl0qT09P7d69W+fOncvTQBU//vijatasqaioKElS9erVJZ0Pac2aNcu2/ObNm1WrVq1cr9/VqVOn1LZtW7Vt21affvqpypYtq71796pdu3bZBjrw9/d3uv30009r/vz5eu2111S1alX5+vrqP//5T7b7XfhaZT1/OU278PXr06eP+vfvn63eihUrXvSx5PZ+ro+jQYMG2rVrl3788Uf99NNP6tKli2655RZ9+eWXF90WAFiBoAQAblK6dGnFxcXpnXfe0aBBg+Tr6+uYl5SUpM8++0zdu3d3fFEtW7asEhMTHcts27ZNqampjtve3t6SdNkhqWvVqqWvvvrKKVisXLlSgYGBKl++fK7r9/b2vqLhrxs0aKDPP/9c5cqVU1BQUJ7uu3r1aseX6qNHj2rr1q2qUaOGpPOPa/ny5U7Lr1y5UtWrV5enp6ck6fPPP9fs2bO1ePFi3XvvvRo9erRGjRqV6+1/8803TnuT2rZtq5CQEL3++uvZgtK3336rbdu2afTo0Zd9TK63q1WrJk9PT23evFmHDh3Syy+/rMjISEnSunXrclXrsmXL1LNnT915552SpJMnT2r37t25uu+lNGjQQH///beqVq160WVyem/k5n4XExQUpHvvvVf33nuv/vOf/+jWW2/VkSNHFBISkud1AUB+4dA7AHCjyZMnKy0tTe3atdPSpUu1b98+zZs3T3FxcSpfvrzGjBnjWLZ169aaPHmyfvvtN61bt06PPfaY01/+y5UrJ19fX82bN08HDhzQ8ePHc9xm3759tW/fPvXr10+bN2/WN998o5EjR2rw4MHy8Mj9x3x0dLROnjyphQsX6tChQ06h7VLuv/9+lSlTRp06ddKyZcu0a9cuLVmyRAMGDLjsoX8vvviiFi5cqL/++ks9e/ZUmTJlHHvjnnrqKS1cuFCjR4/W1q1bNX36dE2ePFlDhgyRJP3zzz96/PHH9corr6hFixaaNm2axo0bly2oXMy5c+f0448/OoYFl87v/Xj//ff1zTff6NFHH9Wff/6p3bt366OPPlLPnj31n//8R126dLnkevft26fBgwdry5Ytmjlzpt566y0NGDBA0vk9Ld7e3nrrrbe0c+dOffvtt5cNXlmqVq2q2bNna/369frjjz/UrVs3x16hqzFs2DCtWrVKTzzxhNavX69t27bp22+/Vb9+/RzLREdHa+nSpdq/f78OHTqU6/vlZOLEiZo1a5Y2b96srVu36osvvlBYWFixv4YXgCLIsrOjAKCY2r17t+nZs6cJCwszXl5eJjIy0vTr189pGGtjjNm/f79p27at8ff3N9WqVTM//PCD02AOxhjz4YcfmsjISOPh4XHFw4Mbk7vBHIwx5rHHHjOlS5fONjy464n8N9xwg2O+MecHDejevbspU6aMsdvtpnLlyuaRRx4xx48fz3E7WQMWfPfdd+b666833t7e5sYbbzTr1693Wi5reHAvLy9TsWJF8+qrrxpjzg8o0aZNG9OuXTunQQEGDRpkqlSp4hgYwdWFgzn89NNPpkKFCjkut3TpUnPrrbea4OBg4+3tbWrVqmVee+01c+7cuYs9dcaY84M59O3b1zz22GMmKCjIlCpVyjzzzDNONc6YMcNER0cbu91umjZt6hh2PGvQjqznxnVAiV27dplWrVoZX19fExkZaSZPnmxiYmLMgAEDHMvk9FrJZdCQnAYJWbNmjYmLizMBAQHG39/f1K1b14wZM8Yxf9WqVY5h3C/86nC5++VUzwcffGDq1atn/P39TVBQkGnTpo357bff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48aN6tChgwICAhQaGqoHH3xQhw4dcsw/deqUunfvroCAAIWHh+v11193/xMKAAAAXICgVEQNHTpUX331laZPn67ffvtNVatWVbt27XTkyBHHMk8//bRee+01rV27VuXKldMdd9yh9PR0NWvWTJMmTVJQUJASExOVmJioIUOGXHRbo0ePVvfu3bV+/XrVqFFD3bp1U58+fTR8+HCtW7dOkvTkk09e9P779+/X5s2btX//fm3fvl1Vq1ZVy5YtJUmJiYmKiYlRvXr1tG7dOs2bN08HDhxQly5dnB7HokWLNGfOHC1YsECLFy/Wr7/+erVPIQAAAHBRHHpXBJ06dUrvvvuupk2bpvbt20uSPvzwQyUkJOijjz7SjTfeKEkaOXKk4uLiJEnTp09XhQoVNGfOHHXp0kXBwcGy2WwKCwu77PYeeughR3AZNmyYmjZtqueff17t2rWTJA0YMEAPPfTQRe8fFhYmPz8/BQYG6p577lFwcLDef/99SdK7776rBg0aaOzYsY7lp0yZosjISG3dulURERH66KOP9PHHH2d7LAAAAEB+ISgVQTt27FB6erqaN2/umObl5aXGjRtr06ZNjqDUtGlTx/yQkBBdd9112rRpU563V7duXcf/Q0NDJUl16tRxmnbmzBmlpKQoKCjoousZMWKEVq1apbVr18rX11eS9Ouvv2rRokU5ntO0Y8cOnT59WmfPns3xsQAAAAD5haBUBBljJJ0/f8h1uus0V5ebnxMvL69s989pWmZm5kXX8fnnn2vSpElavHix096gzMxMdezYUa+88kq2+4SHh2vbtm15rhcAAAC4WpyjVARVrVpV3t7eWr58uWNaenq61q1bp5o1azqmrV692vH/o0ePauvWrapRo4YkydvbWxkZGQVS76pVqzRgwAC9++67uummm5zmNWjQQH///beio6NVtWpVpx9/f39VrVpVXl5eOT4WAAAAIL8QlIogf39/Pf7443r66ac1b948bdy4UY888ohSU1PVu3dvx3IvvviiFi5cqL/++ks9e/ZUmTJl1LlzZ0nnR7c7efKkFi5cqEOHDik1NTVfak1KStLdd9+tu+66S+3atVNSUpKSkpJ08OBBSdITTzyhI0eOqGvXrlqzZo127typBQsWqFevXsrIyFBAQIB69+6tp59+2umxeHjw1gUAAED+4dtmEfXyyy/r7rvv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jz/+qOuvvz7bF9/Zs2fnaj2//vqrkpOT1bBhQ8e0jIwMLV26VJMnT9aWLVsknd+zFB4e7lgmOTk5216mC9ntdtnt9mzTvby8+JJuMV4DQPLKPFN0fznSv3CDIt0DEn1QCKRlXPkf6gsL+sA6efkumuegVLJkSd155515vVs2bdq00YYNG5ymPfTQQ6pRo4aGDRumypUrKywsTAkJCapfv74k6ezZs1qyZIleeeWVq94+AAAAAFxMnoPS1KlT3bLhwMBA1a5d22mav7+/Spcu7Zg+cOBAjR07VtWqVVO1atU0duxY+fn5qVu3bm6pAQAAAABykuegVJCGDh2q06dPq2/fvjp69KiaNGmiBQsWcA0lAAAAAPnqioLSl19+qf/973/au3evzp496zTvt99+u+JiFi9e7HTbZrMpPj5e8fHxV7xOAAAAAMirPF9w9s0339RDDz2kcuXK6ffff1fjxo1VunRp7dy5U+3bt8+PGgEAAACgQOU5KL3zzjv64IMPNHnyZHl7e2vo0KFKSEhQ//79dfz48fyoEQAAAAAKVJ6D0t69e9WsWTNJkq+vr06cOCFJevDBBzVz5kz3VgcAAAAAFshzUAoLC9Phw4clSVFRUVq9erUkadeuXTLGuLc6AAAAALBAnoNS69at9d1330mSevfurUGDBikuLk733nuvW66vBAAAAABWy/Oodx988IEyMzMlSY899phCQkK0fPlydezYUY899pjbCwQAAACAgpbnoOTh4SEPj//bEdWlSxd16dLFrUUBAAAAgJXyfOidJC1btkwPPPCAmjZtqv3790uSPvnkEy1fvtytxQEAAACAFfIclL766iu1a9dOvr6++v3335WWliZJOnHihMaOHev2AgEAAACgoOU5KL300kt677339OGHH8rLy8sxvVmzZvrtt9/cWhwAAAAAWCHPQWnLli1q2bJltulBQUE6duyYO2oCAAAAAEvlOSiFh4dr+/bt2aYvX75clStXdktRAAAAAGClPAelPn36aMCAAfrll19ks9n077//6rPPPtOQIUPUt2/f/KgRAAAAAApUnocHHzp0qI4fP65WrVrpzJkzatmypex2u4YMGaInn3wyP2oEAAAAgAKV56AkSWPGjNGIESO0ceNGZWZmqlatWgoICHB3bQAAAABgiSsKSpLk5+enRo0aubMWAAAAACgUch2U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\n","text/plain":"
"},"metadata":{}}],"id":"149d5972-c5b9-4f29-979a-cf46c9654a06"},{"cell_type":"markdown","source":"## h5py out of the box performance.","metadata":{"tags":[],"user_expressions":[]},"id":"fa6ac2b9-989c-4246-bb89-b54b711dd695"},{"cell_type":"code","source":"regular_h5py_benchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n try:\n if \"kerchunk\" in link:\n continue \n print (f\"Processing: {link}\")\n log_filename = f\"logs/fsspec-h5py-{key}-{k}_default.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n # this is mostly IO so no perf_counter is needed\n start = time.time()\n with h5py.File(fs.open(link, mode=\"rb\")) as f:\n path = f\"{dataset['group']}/{dataset['variable']}\"\n data = f[path][:]\n data_mean = data.mean()\n elapsed = time.time() - start\n regular_h5py_benchmarks.append(\n {\"tool\": \"h5py\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n\n logging.getLogger().removeHandler(file_handler) \n file_handler.close()\n \n except Exception as e:\n print(e)","metadata":{"trusted":true,"tags":[]},"execution_count":25,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"}],"id":"98c29558-de50-44af-87e9-074092fcd0ac"},{"cell_type":"markdown","source":"### Plotting Results","metadata":{"tags":[],"user_expressions":[]},"id":"f4232e98-1159-45eb-ba11-0f0dbb905d83"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(regular_h5py_benchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\nplt.title(\"Out of the box I/O parameters\", fontsize=10)\n\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=45)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":26,"outputs":[{"output_type":"display_data","data":{"image/png":"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76/mzZtr+fLlqlatmp544gnVr19ftWvXvu37dTv16tVLdBq3t7e3qlevruXLl+vgwYOqWLFiivvY/Thw4IAuX76sQoUKJXlN799//51gn7eqVavWHbcdEBAgSbpw4cJ91QikJoISsrygoCDt379fp0+fVpkyZe5rW/HXH9zuWqf8+fPr9OnT97z9iIgI53aSUqBAgURByfrLKiQkxBmU7lZvUFCQDhw4oMjIyARfAu+0/1vrvF/+/v6JpsUPO327ebd+Ubyb69evq127djp16pTmz5+f6AvkpUuXJEnLli3TsmXLbruda9euSUr5++NK0dHRunTpktzd3Z1fQFJL9+7d1a9fP23cuDFF693pddu/f7/zcxj/vlivp7GKf19u3U5K3evPyN32dS+fben/Qod085q6Tp06yc/PT82aNVOxYsXk4+PjHBgjqUEtJClXrly33f6tAx/8888/stlszpB2O5cvX5YxRqdPn77jgDfW9yMp8deh3W5giaRcunRJsbGxyd73hx9+qBIlSmj27Nl688039eabbypHjhzq2LGj3n//fWfAHTZsmAIDAzVt2jRNnDhR77//vjw8PNSyZUtNnjxZxYsXT3aNt1qwYIHefvttzZ0713nNWc6cOdWrVy+9/fbbCa6RvJPk9uGU9rH7Eb+vP/74Q3/88UeK9nW3n5n4z0RyXx8gPTDqHbK8evXqSUqd+13Ef8E5d+5ckvPPnz+f4EtQ/MXKSX25TypsxH/BOX/+fJLbt+63YcOGMjdPoXX+u/WL+t3qjZ9u/eJ2t/0n9UUsI+rVq5c2b96ssWPH6vHHH080P/55f/TRR4lex1v/de/eXVLK3x9X2rhxo2JjY1W1atVUv+eRp6encubMmeSIcHdyt9ct/v2I/+933313x/elQYMGCbZzL4Oo3OvPyP0M2JJcYWFhypEjh3bs2KH58+frvffe05gxY5zT71fu3LlljNGZM2fuuFz8c69evfod34/Vq1ffdZ/58uWT9H9fuJPD399fgYGBd9z3sWPHnMvb7XYNHTpUf/zxh06fPq05c+aofv36+vzzz/XUU085l7PZbHr22We1fft2/f3331q8eLEee+wxLV26VK1atUo0ml5y+fr66q233tLRo0d19OhRffLJJypbtqw++OADvfTSS8neTnL7cEr72P2I39fjjz9+x33NmjUr0bp3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GUnOwNO1a1fz/PPPJ9ju+vXrjZubm/n333+d2500aVKCZZK7XnyQjde/f3/z8MMPJ3iNACAj4holAEgn5v9f22Kz2VJ1u/v27VOdOnUSbLdevXq6evWq/vzzz1TZR+XKlZ3/b7PZFBQUpPPnz0uSduzYocOHDytnzpzy8/OTn5+fAgICdP36dR05cuSO261Tp47z/wMCAlSmTBnt27fP+bzq1auXYPl69erp0KFDzkEVSpQooQkTJujdd99V69at9dRTT6XoeUVGRmrt2rVq06ZNgunmNtchGWPu+v795z//SbBMnTp1EtS8a9cutW3bViEhIcqZM6caNmwoSTp58mSC7dSoUSPB42vXrmnYsGEqX768cufOLT8/P+3fvz/Rere+VwUKFJAkVapUKdG0W9+/2bNnO987Pz8/NWvWTA6HQ8eOHbvt80zuetbn0aNHD+3evVtlypTRgAEDtHLlytvuAwBciat5ASCVhIaGymazae/evWrXrl2i+fv371eePHmUN29eSTcDh/ULeUxMTIr3m9SX99QOZXa7PcFjm80mh8MhSXI4HKpevbq++uqrROvly5cvxfuKr/lOz+tW69atk7u7u44fP67Y2NgUDVTx448/qly5cgoJCZEklS5dWtLNkFa3bt1Ey+/fv1/ly5dP9vatrl27pqZNm6pp06b68ssvlS9fPp08eVLNmjVLNNCBr69vgsdDhw7VihUrNGHCBIWGhsrb21tPPPFEovVufa/iX7+kpt36/vXu3VsDBgxIVG/RokVv+1ySu571eVSrVk3Hjh3Tjz/+qJ9++kkdO3bUI488ogULFtx2XwDgCgQlAEglgYGBatKkiT7++GO99NJL8vb2ds47e/asvvrqK3Xr1s35RTVfvnw6c+aMc5lDhw4pKirK+djT01OS7jokdfny5bVw4cIEweKXX35Rzpw5Vbhw4WTX7+npeU/DX1erVk1ff/218ufPL39//xStu3nzZueX6suXL+vgwYMqW7aspJvPa8OGDQmW/+WXX1S6dGm5u7tLkr7++mstWrRIa9asUadOnTR27FiNGTMm2fv/9ttvExxNatq0qQICAvT+++8nCkpLly7VoUOHNHbs2Ls+J+vjUqVKyd3dXfv379eFCxf0zjvvKDg4WJK0ffv2ZNW6fv169ejRQ+3bt5ckXb16VcePH0/WundSrVo1/fHHHwoNDb3tMkl9NpKz3u34+/urU6dO6tSpk5544gk1b95cly5dUkBAQIq3BQBphVPvACAVTZkyRdHR0WrWrJnWrVunU6dOafny5WrSpIkKFy6st956y7nsww8/rClTpmjnzp3avn27+vTpk+Av//nz55e3t7eWL1+uc+fOKSIiIsl99uvXT6dOnVL//v21f/9+ffvttxo9erQGDx4sN7fkt/lixYrp6tWrWrVqlS5cuJAgtN3JU089pbx586pt27Zav369jh07prVr12rgwIF3PfXvjTfe0KpVq/T777+rR48eyps3r/No3Msvv6xVq1Zp7NixOnjwoD777DNNmTJFQ4YMkST9+eef6tu3r9599109+OCDmj17tsaNG5coqNxObGysfvzxR+ew4NLNox/Tp0/Xt99+q+eff1579uzR8ePH9cknn6hHjx564okn1LFjxztu99SpUxo8eLAOHDiguXPn6qOPPtLAgQMl3TzS4unpqY8++khHjx7V0qVL7xq84oWGhmrRokXavXu3fv31V3Xp0sV5VOh+DB8+XJs2bdILL7yg3bt369ChQ1q6dKn69+/vXKZYsWJat26dTp8+rQsXLiR7vaRMmjRJ8+bN0/79+3Xw4EHNnz9fQUFBWf4eXgAyIZddHQUAWdTx48dNjx49TFBQkLHb7SY4ONj0798/wTDWxhhz+vRp07RpU+Pr62tKlSplfvjhhwSDORhjzMyZM01wcLBxc3O75+HBjUneYA7GGNOnTx8TGBiYaHhw64X8VapUcc435uagAd26dTN58+Y1Xl5epkSJEua5554zERERSe4nfsCC7777zlSoUMF4enqamjVrmt27dydYLn54cLvdbooWLWree+89Y8zNASUaN25smjVrlmBQgJdeesmULFnSOTCC1a2DOfz000+mSJEiSS63bt0607x5c5MrVy7j6elpypcvbyZMmGBiY2Nv99IZY24O5tCvXz/Tp08f4+/vb/LkyWNeeeWVBDXOmTPHFCtWzHh5eZk6deo4hx2PH7Qj/rWxDihx7Ngx06hRI+Pt7W2Cg4PNlClTTIMGDczAgQOdyyT1XskyaEhSg4Rs3brVNGnSxPj5+RlfX19TuXJl89Zbbznnb9q0yTmM+61fHe62XlL1zJgxw1StWtX4+voaf39/07hxY7Nz5847vq4A4Ao2Y9L5znkAAGQAAwYMUGxsrD7++ONU22bDhg1VtWpVTZ48OdW2CQBwDa5RAgBkSxUrVkww6h4AALciKAEAsqXnn3/e1SUAADIwTr0DAAAAAAtGvQMAAAAAC4ISAAAAAFhk+WuUHA6H/vrrL+XMmTPV7lAPAAAAIPMxxujKlSsqVKjQXe81mOWD0l9//eW8+zkAAAAAnDp1SkWKFLnjMlk+KOXMmVPSzRfD39/fxdXAFWJiYrRy5Uo1bdpUdrvd1eUAcBF6AQD6ACIjIxUcHOzMCHeS5YNS/Ol2/v7+BKVsKiYmRj4+PvL396cpAtkYvQAAfQDxknNJDoM5AAAAAIAFQQkAAAAALAhKAAAAAGCR5a9RAgAAAO4kLi5OMTExri4DqcBut8vd3T1VtkVQAgAAQLZkjNHZs2f1zz//uLoUpKLcuXMrKCjovu+hSlACAABAthQfkvLnzy8fH5/7/mIN1zLGKCoqSufPn5ckFSxY8L62R1ACAABAthMXF+cMSYGBga4uB6nE29tbknT+/Hnlz5//vk7DYzAHAAAAZDvx1yT5+Pi4uBKktvj39H6vOyMoAQAAINvidLusJ7XeU4ISAAAAAFgQlAAAAADAgqAEAAAAABYEJQAAACAD6NGjh2w2W6J/hw8fdnVpCRw/flw2m027d+92dSlpiuHBAQAAgAyiefPmmjVrVoJp+fLlS/F2bty4IU9Pz9QqK1viiBIAAACQQXh5eSkoKCjBP3d3d61du1a1atWSl5eXChYsqFdeeUWxsbHO9Ro2bKgXX3xRgwcPVt68edWkSROtWbNGNptNK1as0AMPPCBvb289/PDDOn/+vH788UeVK1dO/v7+evLJJxUVFeXc1vLly/Xggw8qd+7cCgwM1KOPPqojR4445xcvXlyS9MADD8hms6lhw4bp9vqkJ4ISAAAAkIGdPn1aLVu2VM2aNfXrr79q6tSp+uSTT/Tmm28mWO6zzz6Th4eHNm7cqOnTpzunh4WFacqUKfrll1906tQpdezYUZMnT9acOXO0bNkyhYeH66OPPnIuf+3aNQ0ePFjbtm3TqlWr5Obmpvbt28vhcEiStm7dKkn66aefdObMGS1atCgdXoX0x6l3AAAAQAbx/fffy8/Pz/m4RYsWKl26tIKDgzVlyhTZbDaVLVtWf/31l4YPH67XX39dbm43j32EhoZq/PjxznXPnj0rSXrzzTdVr149SdIzzzyjESNG6MiRIypRooQk6YknntDq1as1fPhwSdLjjz+eoKZPPvlE+fPn1969e1WxYkXnqYCBgYEKCgpKo1fC9TiiBAAAAGQQjRo10u7du53/PvzwQ+3bt0916tRJcCPVevXq6erVq/rzzz+d02rUqJHkNitXruz8/wIFCsjHx8cZkuKnnT9/3vn4yJEj6tKli0qUKCF/f3/nqXYnT55MteeZGXBECQAAAMggfH19FRoammCaMSZBSIqfJinBdF9f3yS3abfbnf9vs9kSPI6fFn9anSS1bt1awcHBmjlzpgoVKiSHw6GKFSvqxo0b9/akMimCEgAAQDZR7JVlri7BpbzcjcbXcnUVKVe+fHktXLgwQWD65ZdflDNnThUuXDhV93Xx4kXt27dP06dPV/369SVJGzZsSLBM/Gh6cXFxqbrvjIZT7wAAAIAMrF+/fjp16pT69++v/fv369tvv9Xo0aM1ePBg5/VJqSVPnjwKDAzUjBkzdPjwYf38888aPHhwgmXy588vb29vLV++XOfOnVNERESq1pBREJQAAACADKxw4cL64YcftHXrVlWpUkV9+vTRM888o1GjRqX6vtzc3DRv3jzt2LFDFStW1EsvvaT33nsvwTIeHh768MMPNX36dBUqVEht27ZN9ToyApuJP8Exi4qMjFSuXLkUEREhf39/V5cDF4iJidEPP/ygli1bJjonF0D2QS8AOPXu5ql3cWrZsqXi4uJ07NgxFS9eXDly5HB1aUhF169fv+17m5JswBElAAAAALAgKAEAAACABUEJAAAAACwISgAAAABgQVACAAAAAAuCEgAAAABYEJQAAAAAwIKgBAAAAAAWBCUAAAAAKlasmCZPnnxf2wgLC1PVqlVTpZ7badiwoQYNGpSm+5AkjzTfAwAAAJCJFHtlWbru7/g7rdJ1f7Nnz9agQYP0zz//JJi+bds2+fr63te2hwwZov79+9/XNjIKghIAAAAA5cuX77634efnJz8/v1SoxvU49Q4AAADIRKKjozVgwADlz59fOXLk0IMPPqht27ZJktasWSObzaZly5apSpUqypEjh2rXrq3ffvvNOb9nz56KiIiQzWaTzWZTWFiYpMSn3tlsNk2fPl2PPvqofHx8VK5cOW3atEmHDx9Ww4YN5evrqzp16ujIkSPOdayn3sXv49Z/xYoVc87fu3evWrZsKT8/PxUoUEBdu3bVhQsXnPOvXbumbt26yc/PTwULFtT777+f+i/obRCUAAAAgExk2LBhWrhwoT777DPt3LlToaGhatasmS5duuRcZujQoZowYYK2bdum/Pnzq02bNoqJiVHdunU1efJk+fv768yZMzpz5oyGDBly232NHTtW3bp10+7du1W2bFl16dJFvXv31ogRI7R9+3ZJ0osvvnjb9eP3cebMGR0+fFihoaF66KGHnPMaNGigqlWravv27Vq+fLnOnTunjh07Jngeq1ev1uLFi7Vy5UqtWbNGO3bsuN+XMFk49Q4AAADIJK5du6apU6dq9uzZatGihSRp5syZCg8P1yeffKKaNWtKkkaPHq0mTZpIkj777DMVKVJEixcvVseOHZUrVy7ZbDYFBQXddX89e/Z0Bpfhw4erTp06eu2119SsWTNJ0sCBA9WzZ8/brh+/D2OMHn/8ceXKlUvTp0+XJE2dOlXVqlXT22+/7Vz+008/VXBwsA4ePKhChQrpk08+0eeff57ouaQHlx5RWrdunVq3bq1ChQrJZrNpyZIlt122d+/estls9z0SBwAAAJBZHTlyRDExMapXr55zmt1uV61atbRv3z7ntDp16jj/PyAgQGXKlEkwP7kqV67s/P8CBQpIkipVqpRg2vXr1xUZGXnH7bz66qvatGmTlixZIm9vb0nSjh07tHr1aud1TX5+fipbtqzzeR45ckQ3btxI8rmkB5ceUbp27ZqqVKminj176vHHH7/tckuWLNGWLVtUqFChdKwOAAAAyFiMMZJuXvtjnW6dZnW3+Umx2+2J1k9qmsPhuO02vvzyS02aNElr1qxJcDTI4XCodevWevfddxOtU7BgQR06dCjF9aYmlx5RatGihd5880099thjt13m9OnTevHFF/XVV18leFMAAACA7CY0NFSenp7asGGDc1pMTIy2b9+ucuXKOadt3rzZ+f+XL1/WwYMHnUdrPD09FRcXly71btq0Sc8++6ymT5+u//znPwnmVatWTX/88YeKFSum0NDQBP98fX0VGhoqu92e5HNJDxn6GiWHw6GuXbtq6NChqlChQrLWiY6OVnR0tPNx/GHAmJgYxcTEpEmdyNji33fefyB7oxcAkpe7cXUJLuXldvP5x8TEKC4uTsYYORyOOx4NSQ8p2b+3t7f69OmjoUOHKnfu3CpatKjee+89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d+/eznWsd9TmyxGQud1LH5BujoZXqlQp55cp+gCQed1rH4g/2mT9f2ROBCXg/5s7d6569+6t2bNnq169ejp8+LC6dOmitWvXqlixYpKko0ePqkSJEq4tFECauZc+YP0yZP3jCYDMhe8DiMefuwDdvGv22LFjNWnSJD322GOSbp5rXLhwYX333Xc6d+6cunXrptDQUBdXCiCt3GsfsP7FmJAEZF58H8CtOKIE/H+ffPKJ6tatq3LlykmSWrVqpR07dqh69eo6e/asjh8/rh9//FG1atXicDqQRdEHANAHEI+ghGwvqSY3ffp0ffbZZ/r8888VEhIiu92uunXrKjAwUN99952LKgWQVugDAOgDsOLUO2Rbp0+flpubmzw9PRUYGJhgXvPmzdWhQwcFBAQ475VQunRphvkFshj6AAD6AG6HE6mRLc2ePVuNGzdW/fr1VapUKb399tv6/fffnfNDQkIUEBAg6eb1B9euXdPp06dVunRpV5UMIJXRBwDQB3AnnHqHbOfHH3/UE088oQ8//FClSpXSjh079N///lcPPPCA+vXrp0aNGjmXjY2N1eXLl9WzZ0+dPXtWmzdvZshfIAugDwCgD+BuCErINuLPPR42bJgOHz6sRYsWOef98MMPeuedd5Q3b1698sorqlWrlmJjY7V06VJNnjxZN27c0Pr162W32xUXF8chdyCTog8AoA8guTj1DtlG/AWacXFxioiIkMPhUFxcnCSpZcuWevXVV3Xs2DHNmzdPcXFxiomJUUhIiJ544glt2LBBdrtdsbGxNEUgE6MPAKAPILk4ooRsZ9asWerdu7e2bt2qqlWr6saNG/L09JQkff7553r22We1e/dulS9fPsF6/OUIyDroAwDoA7gbjigh2+nZs6datWqlRx99VH/99Zc8PT1148YNSVLnzp1VuHBh7dmzJ9F6NEUg66APAKAP4G4ISsjyHA5Homljx45VyZIl9Z///EeHDx92/gXp8uXL8vT0VM6cOdO7TABpiD4AgD6AlOLUO2RZW7duVaFChVSkSBE5HA65uSX8u8CuXbs0YsQIrVu3ToMHD5a/v79+/vlnnTt3Ttu3b+cvRkAWQB8AQB/AvSIoIUv6888/1apVK5UtW1aTJk1SoUKFkmyO0dHRGj9+vFasWCHp5v0SZs+ezWg2QBZAHwBAH8D9ICghy1m2bJlatWql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\n","text/plain":"
"},"metadata":{}}],"id":"d8fa6dca-f408-4298-beca-f2839d4c3b67"},{"cell_type":"markdown","source":"## Aggregated plot by tool and different file sizes","metadata":{"tags":[],"user_expressions":[]},"id":"b20b2032-9ab4-46e1-b1f8-2e62b656a265"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(regular_h5py_benchmarks + kerchunk_benchmarks + regular_xarray_benchmarks + h5coro_beanchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\nplt.title(\"Out of the box I/O parameters\", fontsize=10)\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":27,"outputs":[{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAMfCAYAAADomSepAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACqD0lEQVR4nOzdeViU9f7/8deAMOwqLiyK4J7lrmmKCVloZmWrFadSs9Isl6w0swUzrayUyo4tp9RTmZ1Kq5Mnlcx9KS1tc9+NQHJFRRHh8/vDH/N1BlDuEZkRn4/r4tK573s+93teszBv7s1mjDECAAAAADj4eLoAAAAAAPA2NEoAAAAA4IJGCQAAAABc0CgBAAAAgAsaJQAAAABwQaMEAAAAAC5olAAAAADABY0SAAAAALigUQIAAAAAFzRKQAlSUlJks9m0cOFCT5fikJiYKJvN5ukyLImLi1NcXNx5G9+bnqcL8fm5mMyZM0dXXHGFKleuLJvNpj59+ni6pIvWkSNHFBUVpYEDBzpNv9DeQ+fj823hwoWy2WxKSUkp03G91ZQpU+Tr66vffvvN06UARdAo4aLy008/qV+/fmrYsKGCg4MVGBio+vXr65577lFaWpqny7sg9enTRzabTTt27PB0KReUwi9DAwYMKHGZGTNmFPuFqfDLZOGPn5+fqlWrppYtW6pfv36aM2eOCgoKih0zLi7O6b6uP6c3nIVNaHE/AQEBZRFDudm+fbtuuukm7dq1S/fff7+ee+453XTTTZ4u66I1fvx47d+/XyNHjvR0KRelMzV45d2o3XPPPapbt64ef/zxclkfYEUlTxcAlIeCggI9/vjjmjhxoipVqqQuXbroxhtvlJ+fn7Zt26bZs2fro48+0vPPP69nnnnG0+VWKPPnzz+v4z/yyCO68847VadOnfO6Hm/02GOPKSQkRAUFBTp48KDWr1+vjz/+WB988IE6duyoTz75pNhcfH199fTTTxc7ZnFfnnr37l1keqVKF9avj/nz5ys3N1cTJkzQnXfe6elyLmoHDx7UhAkTdNdddykmJsbT5ZyT8/35djGoVKmShg4dqkGDBmnp0qXq1KmTp0sCHC6s33SAm55++mlNnDhRLVu21Oeff6769es7zT927JgmTZqkffv2eajCiss167JWvXp1Va9e/byuw1s9/vjjioyMdJr2999/a/DgwZoxY4a6deum1atXKzg42GmZSpUqWfprcZ8+fZSYmFgGFXvOX3/9JUlF8kL5+/DDD3X06FHdc889ni7lnJ3vz7eLxZ133qlHH31Ub7/9No0SvAq73qHC27Jli8aPH69q1appzpw5xf5iCwwM1BNPPKHRo0eXasxvvvlGV111lSpXrqzAwEC1bNlSqampys/Pd1ruTLsw7Nixo8TjJJYuXaqEhAQFBwerWrVquuOOO7R79+5S1Vac5cuXq0ePHgoPD1dAQIAuueQSpaSkKCcnp8iyNptNiYmJ2r17t+644w5Vq1ZNwcHBSkxM1PLly52WjYuL07Rp0yRJdevWdeyWdfqX6uJ28Tj9uKIpU6aoWbNmCgwMVN26dfXGG29Ikowxev3113XJJZcoICBAjRo10ocfflik3uKOUXLdNc31x/X5yMrK0qOPPqoGDRrIbrerevXquvXWW/X7778Xm2dZPz9lqUaNGvr444919dVXa8OGDXrrrbc8XZKmTp0qm82mqVOnatasWbr88ssVFBSkyMhIPfTQQzpw4ECx99u+fbvuv/9+1alTR3a7XVFRUerTp4927txZZNnC1116err69OmjyMhI+fj4ONb93HPPSZKuuuoqx+vg9N1F3XmPuK5r4cKFTu/55cuX66qrrlJoaKhq1KihgQMH6tixY5JOHS8VHx+v4OBgRUREaMSIEUU+Pw4dOqSXX35ZCQkJio6Olr+/v6Kjo3Xvvfdq69atReo6/b3wn//8R61bt1ZgYKCioqI0ePBgx7pdLVmyRDfffLMiIiJkt9sVExOjW265RUuXLnVazhijDz74QPHx8QoLC1NQUJDatm2rDz74oNhxSzJ16lRVq1ZNV111laX7ffXVV7r66qtVtWpVBQQEqGnTpnr11VeL5FZQUKB//etfateuncLDwxUUFKS4uDjddNNNWrx4sdOyX3zxhRISElSzZk0FBAQoJiZG1157rb788stS1VTc59vx48f12muvqUWLFqpcubJCQkJUv3593XXXXZaPw1m8eLESEhIUEhKi8PBwJScn688//yx22dJ8jhX+3tm5c6d27txZ5HMxJSXF8byMHj3aaf7p75cTJ05owoQJat26tYKDgxUaGqorr7xSX3/9dZG6CnfP3rZtmyZOnKjLLrtMdrvd6Xdf9erVddVVV+nzzz/XkSNHLGUEnE9sUUKFN3XqVOXn56t///6KiIg447J2u/2s473++usaOnSo45dWcHCw/vvf/+rRRx/VkiVL9Pnnn5/Twcjz589X9+7d5ePjozvuuEPR0dGaP3++4uPjVbVqVcvjffHFF7rzzjvl7++vO+64QzVr1tR3332n0aNHa968eVqwYEGRx33gwAHFx8crKipKDz74oNLT0/Xpp5/qqquu0ty5cx2N0NChQzV16lT98ssvGjJkiKpUqSKp+N23ipOamqqFCxeqZ8+e6tKli7744gsNGTJEQUFB+uWXX/TZZ5/p+uuvV5cuXTRjxgzde++9qlu37ln/4ljSFpDPPvtM69atU1BQkGPa1q1bHV96u3btqptuuklZWVn64osvNHfuXM2fP1/t27d3LF/Wz8/54OPjo1GjRmn+/Pn69NNPNXz48HMab8mSJfrxxx/l6+urSy65RNdcc02p3iuuPv/8c6Wlpen222/XNddco0WLFuntt9/WihUrtGLFCgUGBjqW/eGHH9StWzcdPXpUN9xwgxo0aKAdO3bo448/1rfffqsVK1aoXr16TuPv27dPHTp0UHh4uO644w6dOHFCzZs313PPPaeFCxdq0aJFTrsRFr5e3XmPFLeusLAwZWdnO+p/+eWX1a1bN/Xv318LFizQ5MmTlZ2drZ49e6p379668cYb1b59e82ePVvjx49XWFiYRo0a5VjH+vXr9eyzz+qqq67SzTffrODgYG3YsEHTp0/X7Nmz9fPPPys2NrZIzm+99Za+/fZb9ezZU4mJiZozZ47efPNN7du3Tx9//HGRZQcNGqTAwEDdfPPNqlOnjtLT07V06VJ9/vnnjveaMUZ33323pk+frkaNGik5OVn+/v5KS0tTv379tG7dOr366qtnfQ0cOHBAa9as0bXXXisfn9L/rfapp57Siy++qNq1a+vWW29VWFiYFi9erCeeeEI//PCDPvvsM8eyI0eO1Pjx41W/fn0lJycrNDRU6enpWrJkib7//nt17txZkjR58mQNHDhQUVFRuvnmm1WtWjVlZGToxx9/1Jdffun2MWy9e/fWf/7zHzVv3lx9+/aV3W7Xrl27tGDBAnXr1k3NmjUr1TgrV67Uiy++qB49emjw4MH6+eef9cknn2jp0qVatWqV0++z0n6OValSRc8995xSU1MlnfoML1T4mbljxw5NmzZNCQkJTp+jhe+X3NxcXXvttVq4cKFatWqlfv36KS8vT7Nnz1bPnj315ptv6pFHHinyeAYNGqSVK1eqR48euv7664v8Pu7QoYPS0tK0bNkydevWrVQZAeedASq4xMREI8l89913lu733HPPGUlmwYIFjmlbt241lSpVMjVr1jS7du1yTM/NzTUJCQlGkvnwww8d0xcsWGAkmeeee67I+Nu3bzeSTO/evR3T8vPzTb169YzNZjNLlixxTC8oKDDJyclGkrHyts3OzjZVqlQxdrvd/PLLL8WON2bMGKf7FK7jnnvuMQUFBY7pCxcuNDabzTRo0MDk5+c7pvfu3dtIMtu3by+2htjYWBMbG+s0rTDb8PBws3XrVsf0Xbt2GX9/f1O5cmXTqFEjk5WV5Zj3ww8/GEnmxhtvLHas05+n4nz99dfGx8fHtG3b1uTk5Dimd+zY0VSqVMnMmzfPafmNGzea0NBQ06xZM8e0snx+Cl8bbdq0Mc8991yxP7feemuxr5/C11pGRkaJ4x8/ftz4+fkZHx8fk5eX55geGxtrfH19i13fJ5984jRGYbauP1FRUUXyOpMpU6Y47uv6Puzbt6+RZJ5//nnHtBMnTpi4uDgTGhpq1q5d67T8kiVLjK+vr7n++uudpheO37dvX3Py5MkiNZT0OjmX90hx6yp8XiWZL7/80ukxNW/e3NhsNlO9enXz448/OtVQs2ZNU61aNafn6uDBg2bfvn1FHsv3339vfHx8zP3331/sY6xcubLZsGGDY3pOTo5p1KiRsdlsJj093TH9119/Nb6+viY6OrrI+7egoMBp2XfffddIMv369XOqMTc319xwww1Gklm9enWRWl3Nnj3bSDKjRo0qdn7ha/t08+bNM5JM9+7dzdGjR51qHDBggJFkPv/8c8f08PBwU6tWLadlC5c/Pc/WrVsbf39/p8+ZQnv37j3rYzGm6OfbwYMHjc1mM23bti3y2jh58qQ5cODAWcc8/TX0r3/9y2ne6NGjjSRz3333OU238jlWXN3Frb+431vGGPPUU08ZSSYlJcXpd0R2drZp27at8ff3d3rtFP6OqF27ttm5c2eJj/urr74yksyzzz5b4jJAeaNRQoV3ySWXGElOXxxKo7gvVs8//7yRZF5++eUiy69YscJIMldffbVjmtVGadGiRUaSueGGG4osv2PHDuPr62upUfr3v/9tJJmHHnqoyLxdu3aZSpUqmfr16ztNl2R8fX2dGsFCPXr0MJKcmoRzaZRSUlKKLN+lSxcjyUybNq3IvHr16pU41pkapV9++cWEhISYWrVqOf0C//nnnx1f/oozbNgwI8n89ttvxpiyfX5O/zJ0th93GiVjjImIiDCSzJ49exzTYmNjS1xPz549ne4/a9YsM23aNLNjxw5z7Ngxs3nzZjNmzBgTGBhoAgICijQxJSlslJKSkorMS09PN35+fk6vw5kzZxbboBS65ZZbjI+Pjzl06JBjmiTj7+9v/v7772LvU9LrxN33SEnrKnxeExMTi8wr/Pzo27dvkXn33XffGd9Hrpo1a2bi4uKcphU+xuK+aBbO+/rrrx3TBg4caCSZDz744Kzra968uQkODjbHjh0rMu/XX381ksxjjz121nHeeecdI8m88cYbxc4vrlG68cYbjaRiP5MKG5Nbb73VMS08PNzUrVvX5ObmnrGW1q1bm+Dg4FI1LyVx/Xw7dOiQkWTi4+PdHrPwNdS4cWOnRsSYU01vjRo1TGBgoOPxWf0cK67u4tZf3O+t/Px8U7VqVdOgQYMitRlz6g9Sksybb77pmFb4O+L1118/4+NeuXJlsU0g4EnsegdYsGbNGkkqdreuK664QoGBgVq7dq3b4//yyy+SpCuvvLLIvNjYWMXExDjtJ75jxw5NnTrVabkqVao4dqc4U70xMTGqX7++Nm7cqMOHDys0NLTIulxdeeWVmj17ttauXVsmB9y2atWqyLSoqChJUsuWLYud98MPP1hax549e3TDDTeooKBAX3/9taKjox3zVq5cKUnKzMws9jiyDRs2OP5t2rSp5eenNPr376+333672HkzZszQXXfdZWm80xljip1ut9t1/Pjxs97fddejBg0a6Omnn1ZERIQefPBBvfDCC067PJ1NcblFR0erfv362rBhg+N1WPi8bNiwodjnJTMzUwUFBdq0aZPatm3rmF63bl3LJ/Zw9z1ytnW589qWpPT0dKddVxcuXKjU1FT98MMP2rt3r06ePOmY5+/vX+y6W7duXWRa7dq1JZ0641yhH3/8UZLUtWvXEh+HJOXk5Oi3335TdHS0XnrppSLz8/LyJP3f++VMCk+YY2U31ZUrVyo4OFjvv/9+sfMDAwOd1t2rVy+9/fbbatq0qe644w4lJCSoQ4cORU5q0qtXLz355JNq2rSp7rzzTiUmJqpTp06OXczcERYWpmuvvVZz5sxR69atddttt+nKK69U+/btS3y+ShIfH19kN+7AwEC1adNGc+bM0aZNm9S0aVPLn2PnYuPGjTpw4ICio6OLPab377//dlrn6dq1a3fGscPDwyVJe/fuPacagbJEo4QKLzIyUhs2bFB6eroaN258TmMVHn9Q0rFONWvWVHp6utvjHzp0yDFOcSIiIoo0Sq6/rGJjYx2N0tnqjYyM1MaNG5Wdne30JfBM6z+9znMVFhZWZFrhaadLmnf6F8WzOX78uG666Sbt3r1bn332WZEvkPv375ckzZ49W7Nnzy5xnKNHj0qy/vx4Um5urvbv3y9fX1/HF5Cy0rt3bw0cOFDLli2zdL8z5bZhwwbH67DweXE9nsZV4fNy+jhWufseOdu63HltS//XdEinjqm74447FBISom7duikuLk5BQUGOE2MUd1ILSapcuXKJ459+4oODBw/KZrM5mrSSHDhwQMYYpaenn/GEN67PR3EKj0Mr6cQSxdm/f79OnjxZ6nW/8cYbqlevnqZOnaoXXnhBL7zwggICAtSrVy+99tprjgZ3+PDhqlatmt5++21NmDBBr732mipVqqTrrrtOqampqlu3bqlrPN3nn3+ucePG6ZNPPnEccxYaGqr77rtP48aNczpG8kxK+zls9XPsXBSu648//tAff/xhaV1ne88UviZKmw9QHjjrHSq8+Ph4SWVzvYvCLzh79uwpdn5WVpbTl6DCg5WL+3JfXLNR+AUnKyur2PFd15uYmChzahdax8/pX9TPVm/hdNcvbmdbf3FfxLzRfffdp5UrV2rMmDG69dZbi8wvfNxvvvlmkRxP/+ndu7ck68+PJy1btkwnT55Uy5Yty/yaR/7+/goNDS32jHBncrbcCp+Pwn//+9//nvF5SUhIcBrHnZOouPseOZcTtpRWSkqKAgIC9NNPP+mzzz7TK6+8otGjRzumn6sqVarIGKOMjIwzLlf42Nu0aXPG52PBggVnXWeNGjUk/d8X7tIICwtTtWrVzrju7du3O5b38/PTE088oT/++EPp6emaPn26rrzySv373//WP/7xD8dyNptN999/v1avXq2///5bs2bN0i233KKvv/5aPXr0KHI2vdIKDg7W2LFjtW3bNm3btk3vv/++LrnkEr3++ut69NFHSz1OaT+HrX6OnYvCdd16661nXNeUKVOK3Pds75nC10ThawTwBjRKqPD69OkjX19fvfvuu47dAkqSm5t7xvmFu9OcfirqQj/++KOOHTvmtFtN4e4lxW1lKtzl53QtWrSQdOosY6527txp+RTUZ6o3PT1dW7duVb169Zz+Un6mdRXWdfpj9PX1lSS3v1ScL88//7w++eQT/eMf/3A6k9jpCs9mt2LFilKNWdbPz/lSUFCgcePGSdI57bpXks2bN+vAgQOlPrthoeJy++uvv7R161bVr1/f8Tq0+rycC3ffI+Vh69atatKkiRo2bOg0vTCzc1W4K9S8efPOuFxoaKiaNGmi9evXO+26547CM75t3ry51Pdp37699u3bZ+k+haKjo3XXXXdpzpw5atiwob777rtit2ZVq1ZNN910kz799FN16dJF69ev15YtWyyvz1XdunV13333adGiRQoJCSn29NklWbZsWZHdZ48dO6affvpJgYGBatSokST33i++vr4lfmaf6TO9SZMmCgsL0+rVq522fpaFjRs3SlKpzwoIlAcaJVR4DRo00PDhw7V37151797d6S+PhY4fP64JEyac9SKcycnJqlSpkiZMmOC4gKV0aneZJ598UpKcrg3RuHFjxy/H0/+CumfPHr3wwgtFxu/UqZPq1q2rb775xukaJsYYPfXUU5abkZ49e6py5cqaMmWK024SxhiNHDlSeXl5xV7HKT8/X6NGjXL6Jb1o0SL973//U4MGDdSxY0fH9MLdukq6tocnfPbZZ0pJSVGHDh1KPK5BOvVFsX379vrkk0/06aefFplfUFCgRYsWOW6X9fNzPvz999+6++67NX/+fF166aV66KGH3Brn8OHD+vXXX4tMP3DggPr16yfJehOWlpZWZMvu008/rby8PKe/dvfs2VN16tTRhAkTilz3Rjr1fnO9xo+73H2PlIfY2Fht2bLFaWvX8ePH9dBDD1naBbUkAwYMkK+vr55++ukiu/G5bmkaPHiwcnJy9MADDxS7W9X27dtLtdtps2bNFB4e7jg+qjQGDx4s6dQW4uIuCp6Zman169dLOvXHru+//75Ig3H06FEdPnxYfn5+jkZg7ty5RXLMy8tzfFaffrr60vr777+LfWwHDhxQbm6upTE3btxY5BpVr7zyiv7++2/dddddjmOerH6OSac+t/fu3VvssYpn+kyvVKmSHnroIe3cuVOPP/54sc3S77//XuLWsDMpPP7UdUsx4Ekco4SLwgsvvKDjx49r4sSJaty4sbp06aKmTZvKz89P27dv13fffad9+/YV27ycrn79+nr55Zf12GOPqXnz5urVq5eCg4P1zTffaMOGDerZs6fuvvtux/L+/v565JFH9NJLL6l169bq2bOnDh8+rP/+979KSEgo8ldhHx8fvfvuu7ruuut0zTXXOK7T8/333ysjI0PNmzcv9strScLCwvTee+/prrvuUvv27XXHHXeoRo0amj9/vlavXq127drpiSeeKHK/5s2ba+HChbriiivUpUsX/fXXX5oxY4b8/Pz03nvvOV3/pEuXLnr11VfVv39/3X777QoODladOnWUnJxc6jrLWu/evWWMUYsWLfTiiy8WmZ+YmOg4eP+TTz7RVVddpTvvvFOpqalq06aNAgICtGvXLq1YsUJ///2348tEWT8/5+rVV19VSEiICgoKlJ2drXXr1mnx4sXKzc1VfHy8ZsyY4fb+/vv27VOLFi3Utm1bNWvWzHH83bfffqt9+/YpKSnJ0m5EktSjRw9dd911uv322xUTE6NFixZpxYoVatGihR5//HHHcna7XZ9//rm6d++uhIQEXX311Y6D0Hft2qUlS5aoWrVqpTp5wNm4+x4pD4MGDdKgQYPUqlUr3XbbbTp58qTS0tIcr+3Ck4u4q1mzZkpNTdXgwYN12WWX6aabblJsbKwyMzO1ePFi9ejRw3G9nf79+2vlypWaNm2ali1bpmuuuUbR0dHas2ePNmzYoB9++EHTp08/61ZGm82mG2+8Uf/+97+VkZFx1uOjJOnaa6/VM888ozFjxqhBgwa69tprFRsbq3379mnLli1asmSJXnjhBTVp0kTHjh3T1VdfrXr16ql9+/aqU6eOjhw5om+++UaZmZkaMWKEo8G44447FBQUpE6dOik2NlZ5eXlKS0vTunXrdMcdd6hOnTqWM01PT1f79u112WWXqXXr1qpVq5b27dunr776Snl5eZauada1a1cNHDhQs2fP1iWXXKKff/5Zc+fOVUxMjGOLcSErn2PSqc/t1atX64YbbtCVV14pf39/derUSZ06ddIll1yi6Ohox+dH7dq1ZbPZ9NBDD6ly5coaPXq0fv75Z73xxhuaPXu2EhISVKNGDaWnp+u3337TL7/8ohUrVpR4jFVxjDGaP3++mjRp4thS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7rnHBAcHmzp16pgvv/zSZGVlmRtvvNEEBwebpk2bmlWrVjndb9myZebKK680AQEBpnbt2mbQoEHmyJEjjsfk+toozf1Or6d3794mLCzM3HvvvSY3N9c8/PDDJjIy0tjtdhMbG2vGjRtXYqYA4Ck0SgBQRvbt22dsNluJX/oeeOABU7VqVceX5rM1Sj/++KORZL777juTkZFh9u3bV+y4f/75pwkKCjIDBw4069evN7NmzTLVq1d3NDoHDx40zz//vKldu7bJyMgwWVlZRcbIzc01qampJiwszGRkZJiMjAxz+PBhY8ypL7vh4eHmrbfeMps3bzYvvvii8fHxMevXrzfGGHP06FHTsGFDc99995lff/3VrFu3ziQnJ5vGjRub3NzcYmsubAaaNGli5s2bZ3799Vdz/fXXm7i4OHPixAljjDGrV682Pj4+5vnnnzcbN240U6ZMMYGBgY58Tp48aTp06GBuuukmY4wxkydPNpUrVzY7duwodp3GFN8oTZo0yVx99dXGGGNmzpxpJJnly5cXe/9GjRqZnj17ljh+QkKCCQkJMUOGDDEbNmwwH330kQkKCjLvvvuuY5n333/f/O9//zNbt241K1asMFdccYXp3r17kWyaN29u5s2bZ7Zs2WL27t1r1q5da95++23z66+/mk2bNplRo0aZgIAAs3PnTsd9C5+rt99+22zatMk89NBDJjQ01Fx77bXmP//5j9m4caO56aabTJMmTRyvw19//dWEhISYiRMnmk2bNplly5aZVq1amT59+hhjTr2ua9eubZ5//nnHa6M09yusJywszLzyyitm8+bNZvPmzeaVV14xMTExZvHixWbHjh1myZIlZvr06SVmCgCeQqMEAGVk5cqVxTY/hSZMmGAkObYenK1R2r59u5Fk1qxZc8b1PvXUU6Zx48ZOWy3eeustExIS4tiyMnHixGK3JJ1uypQppnLlykWmx8bGmrvvvttxu6CgwNSsWdNMnjzZGHPqi7/r+nNzc01gYKCZO3dusesqbAZO3zqzb98+ExgYaD799FNjjDHJyckmKSnJ6X5PPPGEufTSSx23t27dakJDQ82IESNMUFCQ+eijj874GItrlJKSkswbb7xhjDHmpZdeMpLMgQMHir3/jTfeaJo0aVLi+AkJCU5NiDHGjBgx4oz3KWyICxvTwmy+/PLLMz4WY4y59NJLzZtvvum47fpcZWRkGEnmmWeecUxbsWKFkeRoeO655x7z4IMPOo27ZMkS4+PjY44dO+YYd+LEiU7LlPZ+hY1soUGDBpkuXbo4ZQQA3ohjlACgnJj/f2yLzWYr03HXr1+vDh06OI0bHx+vI0eO6M8//yyTdTRv3tzxf5vNpsjISGVlZUmSfvrpJ23ZskWhoaEKCQlRSEiIwsPDdfz4cW3duvWM43bo0MHx//DwcDVu3Fjr1693PK74+Hin5ePj47V582bHSRXq1aunV199VS+//LJuuOEG/eMf/7D0uLKzs7Vo0SLdeOONTtNNCcchGWPO+vxdccUVTst06NDBqeY1a9aoZ8+eio2NVWhoqBITEyVJu3btchqnbdu2TrePHj2q4cOH69JLL1WVKlUUEhKiDRs2FLnf6c9VRESEJKlZs2ZFpp3+/E2dOtXx3IWEhKhbt24qKCjQ9u3bS3ycpb2f6+Po06eP1q5dq8aNG2vw4MGaN29eiesAAE/iaF4AKCMNGjSQzWbTunXrdNNNNxWZv2HDBlWtWlXVq1eXdKrhcP1CnpeXZ3m9xX15L+umzM/Pz+m2zWZTQUGBJKmgoEBt2rTRxx9/XOR+NWrUsLyuwprP9LhOt3jxYvn6+mrHjh06efKkpRNVfPvtt2rSpIliY2MlSY0aNZJ0qknr2LFjkeU3bNigSy+9tNTjuzp69Ki6du2qrl276qOPPlKNGjW0a9cudevWrciJDoKDg51uP/HEE5o7d65effVVNWjQQIGBgbrtttuK3O/056owv+Kmnf789e/fX4MHDy5Sb506dUp8LKW9n+vjaN26tbZv365vv/1W3333nXr16qVrrrlGn3/+eYnrAgBPoFECgDJSrVo1JSUl6Z///KceffRRBQYGOuZlZmbq448/1r333uv4olqjRg1lZGQ4ltm8ebNycnIct/39/SXprKekvvTSS/XFF184NRbLly9XaGioatWqVer6/f393Tr9devWrfXpp5+qZs2aCgsLs3TflStXOr5UHzhwQJs2bdIll1wi6dTjWrp0qdPyy5cvV6NGjeTr6ytJ+vTTTzVz5kwtXLhQd9xxh8aMGaPRo0eXev1fffWV09akrl27Kjw8XK+99lqRRunrr7/W5s2bNWbMmLM+JtfbDRs2lK+vrzZs2KC9e/fqpZdeUkxMjCRp9erVpap1yZIl6tOnj26++WZJ0pEjR7Rjx45S3fdMWrdurT/++EMNGjQocZniXhuluV9JwsLCdMcdd+iOO+7QbbfdpmuvvVb79+9XeHi45bEA4Hxh1zsAKEOTJk1Sbm6uunXrpsWLF2v37t2aM2eOkpKSVKtWLY0dO9axbJcuXTRp0iT9/PPPWr16tQYMGOD0l/+aNWsqMDBQc+bM0Z49e3To0KFi1zlw4EDt3r1bgwYN0oYNG/TVV1/pueee07Bhw+TjU/qP+bi4OB05ckTz58/X3r17nZq2M/nHP/6h6tWrq2fPnlqyZIm2b9+uRYsWaciQIWfd9e/555/X/Pnz9fvvv6tPnz6qXr26Y2vcY489pvnz52vMmDHatGmTpk2bpkmTJunxxx+XJP3555966KGH9PLLL6tTp06aOnWqXnzxxSKNSklOnjypb7/91nFacOnU1o933nlHX331lR588EH9+uuv2rFjh95//3316dNHt912m3r16nXGcXfv3q1hw4Zp48aN+uSTT/Tmm29qyJAhkk5tafH399ebb76pbdu26euvvz5r41WoQYMGmjlzptauXatffvlFycnJjq1C52LEiBFasWKFHn74Ya1du1abN2/W119/rUGDBjmWiYuL0+LFi5Wenq69e/eW+n7FmThxombMmKENGzZo06ZN+uyzzxQZGVnhr+EF4ALksaOjAKCC2rFjh+nTp4+JjIw0fn5+JiYmxgwaNMjpNNbGGJOenm66du1qgoODTcOGDc3//vc/p5M5GGPMe++9Z2JiYoyPj4/bpwc3pnQnczDGmAEDBphq1aoVOT2464H8LVq0cMw35tRJA+69915TvXp1Y7fbTb169cwDDzxgDh06VOx6Ck9Y8N///tdcdtllxt/f31x++eVm7dq1TssVnh7cz8/P1KlTx7zyyivGmFMnlLj66qtNt27dnE4K8Oijj5r69es7Tozg6vSTOXz33Xemdu3axS63ePFic+2115rKlSsbf39/c+mll5pXX33VnDx5sqTojDGnTuYwcOBAM2DAABMWFmaqVq1qnnzySacap0+fbuLi4ozdbjcdOnRwnHa88KQdhdm4nlBi+/bt5qqrrjKBgYEmJibGTJo0ySQkJJghQ4Y4linuuZLLSUOKO0nIjz/+aJKSkkxISIgJDg42zZs3N2PHjnXMX7FiheM07qd/dTjb/Yqr59133zUtW7Y0wcHBJiwszFx99dXm559/PmOuAOAJNmPK+cp5AAB4gcGDB+vkyZP65z//WWZjJiYmqmXLlkpNTS2zMQEAnsExSgCAi1LTpk2dzroHAMDpaJQAABelBx980NMlAAC8GLveAQAAAIALznoHAAAAAC5olAAAAADARYU/RqmgoEB//fWXQkNDy+wK9QAAAAAuPMYYHT58WNHR0We91mCFb5T++usvx9XPAQAAAGD37t2qXbv2GZep8I1SaGiopFNhhIWFebgaZ3l5eZo3b566du0qPz8/T5dzQSAz95CbdWTmHnKzjszcQ27WkZl7yM06b84sOztbMTExjh7hTCp8o1S4u11YWJhXNkpBQUEKCwvzuheRtyIz95CbdWTmHnKzjszcQ27WkZl7yM26CyGz0hySw8kcAAAAAMAFjRIAAAAAuKBRAgAAAAAXFf4YpdLKz89XXl5eua4zLy9PlSpV0vHjx5Wfn1+u675QlSYzPz8/+fr6lnNlAAAAqEgu+kbJGKPMzEwdPHjQI+uOjIzU7t27ucZTKZU2sypVqigyMpJcAQAA4BaPNkonT55USkqKPv74Y2VmZioqKkp9+vTR008/7bgAlDFGo0eP1rvvvqsDBw6offv2euutt3TZZZeVSQ2FTVLNmjUVFBRUrl+sCwoKdOTIEYWEhJz1glc45WyZGWOUk5OjrKwsSVJUVFR5lwgAAIAKwKON0ssvv6y3335b06ZN02WXXabVq1erb9++qly5soYMGSJJGj9+vCZMmKCpU6eqUaNGeuGFF5SUlKSNGzeW6vznZ5Kfn+9okqpVq1YWD8mSgoICnThxQgEBATRKpVSazAIDAyVJWVlZqlmzJrvhAQAAwDKPfjtfsWKFevbsqR49eiguLk633XabunbtqtWrV0s6tXUgNTVVo0aN0i233KKmTZtq2rRpysnJ0fTp0895/YXHJAUFBZ3zWPAuhc9peR93BgAAgIrBo1uUOnXqpLffflubNm1So0aN9Msvv2jp0qVKTU2VJG3fvl2ZmZnq2rWr4z52u10JCQlavny5+vfvX2TM3Nxc5ebmOm5nZ2dLOvWF2fVLc15enowxMsaooKDgPDzCMzPGOP71xPovRKXNrPB5zcvLY4uS/q9hpHEsPTJzD7lZR2buITfryMw95GadN2dmpSabKfzm6QHGGD311FN6+eWX5evrq/z8fI0dO1YjR46UJC1fvlzx8fFKT09XdHS0434PPvigdu7cqblz5xYZMyUlRaNHjy4yffr06UW2HFWqVEmRkZGKiYmRv79/GT86eNKJEye0e/duZWZm6uTJk54uBwAAAF4gJydHycnJOnTokMLCws64rEe3KH366af66KOPNH36dF122WVau3athg4dqujoaPXu3duxnOsJFowxJZ50YeTIkRo2bJjjdnZ2tmJiYtS1a9ciYRw/fly7d+9WSEiIAgICyvCRlY4xRocPH1ZoaChnZyul0mZ2/PhxBQYGqnPnzh55br1NXl6e0tLSlJSUJD8/P0+Xc0EgM/eQm3Vk5h5ys47M3ENu1nlzZoV7m5WGRxulJ554Qk8++aTuvPNOSVKzZs20c+dOvfjii+rdu7ciIyMlyXFGvEJZWVmKiIgodky73S673V5kup+fX5EnKj8/XzabTT4+Ph45mULhrmOFNUhSnz59NG3atCLLbt68WQ0aNCjX+s5kx44dqlu3rtasWaOWLVuW23qLy6w4Pj4+stlsxT7vFzPysI7M3ENu1pGZe8jNOjJzD7lZ542ZWanHoydzyMnJKfJl19fX1/FluG7duoqMjFRaWppj/okTJ7Ro0SJ17NixXGstT9dee60yMjKcfurWrWt5nBMnTpyH6gAAAICKz6ON0g033KCxY8dq9uzZ2rFjh2bNmqUJEybo5ptvlnRqq8HQoUM1btw4zZo1S7///rv69OmjoKAgJScne7L088putysyMtLpx9fXV4sWLVK7du1kt9sVFRWlJ5980un4m8TERD3yyCMaNmyYqlevrqSkJC1cuFA2m01z585Vq1atFBgYqC5duigrK0vffvutmjRporCwMN11113KyclxjDVnzhx16tRJVapUUbVq1XT99ddr69atjvmFjVurVq1ks9mUmJhYbvkAAAAA55tHd71788039cwzz2jgwIHKyspSdHS0+vfvr2effdaxzPDhw3Xs2DENHDjQccHZefPmnfM1lC406enpuu6669SnTx/9+9//1oYNG/TAAw8oICBAKSkpjuWmTZumhx56SMuWLZMxRpmZmZJOneRi0qRJCgoKUq9evdSrVy/Z7XZNnz5dR44c0c0336w333xTI0aMkCQdPXpUw4YNU7NmzXT06FE9++yzuvnmm7V27Vr5+Pjoxx9/VLt27fTdd9/psssu42QYAAAAqFA82iiFhoYqNTXVcTrw4thsNqWkpDg1AxXdN998o5CQEMft7t27q1GjRoqJidGkSZNks9l0ySWX6K+//tKIESP07LPPOnZhbNCggcaPH++4b2Gj9MILLyg+Pl6S1K9fP40cOVJbt25VvXr1JEm33XabFixY4GiUbr31Vqea3n//fdWsWVPr1q1T06ZNVaNGDUlStWrVHMeSAQAAABWFR3e9Q/GuuuoqrV271vHzxhtvaP369erQoYPTmd7i4+N15MgR/fnnn45pbdu2LXbM5s2bO/4fERGhoKAgR5NUOC0rK8txe+vWrUpOTla9evUUFhbm2NVu165dZfY4AQAAAG/l0S1KKF5wcHCRM9wVd0r0wktgnT49ODi42DFPP8NH4dngTmez2Zwu4HrDDTcoJiZG7733nqKjo1VQUKCmTZtygggAAABcFNiidIG49NJLtXz5cp1+feDly5crNDRUtWrVKtN17du3T+vXr9fTTz+tq6++Wk2aNNGBAweclik8Jik/P79M1w0AAAB4A7YoXSAGDhyo1NRUDRo0SI888og2btyo5557TsOGDSvza0BVrVpV1apV07vvvquoqCjt2rVLTz75pNMyNWvWVGBgoObMmaPatWsrICBAlStXLtM6AAAAUH7inpxdJuPYfY3GtyuToTyKLUoXiFq1aul///uffvzxR7Vo0UIDBgxQv3799PTTT5f5unx8fDRjxgz99NNPatq0qR599FG98sorTstUqlRJb7zxht555x1FR0erZ8+eZV4HAAAA4ClsUfIyU6dOLXFeQkKCfvzxxxLnL1y4sMi0xMREp931JKlPnz7q06eP0zTXMwtec801WrdundMyruPcf//9uv/++0usBwAAALhQsUUJAAAAAFzQKAEAAACACxolAAAAAHBBowQAAAAALmiUAAAAAMAFjRIAAAAAuKBRAgAAAAAXNEoAAAAA4IJGCQAAAABc0CjBSVxcnFJTU89pjJSUFLVs2bJM6ilJly5dNHTo0PO6DgAAAFy8Knm6AG8V9+TsclvXtnHdy21dhaZOnaqhQ4fq4MGDTtNXrVql4ODgcxr78ccf16BBg85pDAAAAMCTaJTgpEaNGuc8RkhIiEJCQsqgGgAAAMAz2PXuApWbm6vBgwerZs2aCggIUKdOnbRq1SpJ0sKFC2Wz2TR79my1aNFCAQEBat++vX777TfH/L59++rQoUOy2Wyy2WxKSUmRVHTXO5vNpnfeeUfXX3+9goKC1KRJE61YsUJbtmxRYmKigoOD1aFDB23dutVxH9dd7wrXcfpPXFycY/66det03XXXKSQkRBEREbrnnnu0d+9ex/yjR4/q3nvvVUhIiGrVqqVJkyaVfaAAAADAaWiULlDDhw/XF198oWnTpunnn39WgwYN1K1bN+3fv9+xzBNPPKFXX31Vq1atUs2aNXXjjTcqLy9PHTt2VGpqqsLCwpSRkaGMjAw9/vjjJa5rzJgxuvfee7V27VpdcsklSk5OVv/+/TVy5EitXr1akvTII4+UeP/CdWRkZGjLli1q0KCBOnfu7JiXkJCgli1bavXq1ZozZ4727NmjXr16OT2OBQsWaNasWZozZ46WLl2qn3766VwjBAAAAErErncXoKNHj2ry5MmaOnWqunc/dXzTe++9p7S0NL3//vu6/PLLJUnPPfeckpKSJEnTpk1T7dq1NWvWLPXq1UuVK1eWzWZTZGTkWdfXt29fR+MyYsQIdejQQc8884y6desmSRoyZIj69u1b4v0L12GM0a233qrKlSvrnXfekSRNnjxZrVu31rhx4xzLf/DBB4qJidGmTZsUHR2t999/X//+97+VlJSkgoICTZ48WZdddpnV2AAAAIBSo1G6AG3dulV5eXmKj493TPPz81O7du20fv16R6PUoUMHx/zw8HA1btxY69evt7y+5s2bO/4fEREhSWrWrJnTtOPHjys7O1thYWEljvPUU09pxYoVWrVqlQIDAyVJP/30kxYsWFDsMU1bt27VsWPHdOLECafHUrVqVTVu3Njy4wAAAABKi0bpAmSMkXTq2B/X6a7TXJ1tfnH8/PyK3L+4aQUFBSWO8dFHH2nixIlauHChateu7ZheUFCgG264QS+//HKR+0RFRWnz5s2W6wUAAADOFccoXYAaNGggf39/LV261DEtLy9Pq1evVpMmTRzTVq5c6fj/gQMHtGnTJl1yySWSJH9/f+Xn55dLvStWrND999+vd955R1dccYXTvNatW+uPP/5QXFycGjRo4PQTHBysBg0ayM/Pz+mxHDx4UJs2bSqX2gEAAHBxolG6AAUHB+uhhx7SE088oTlz5mjdunV64IEHlJOTo379+jmWe/755zV//nz9/vvv6tOnj6pXr66bbrpJ0qmz2x05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2X1N2Yzjc2ocb3ytWfnMsBljLCUSHR2thQsXqlGjRpYLczVjxgyNHTtWq1atUkBAgBITE9WyZUulpqZq+fLlio+PV3p6uqKjox33efDBB7Vz507NnTu32DFTUlI0evToItOnT5+uoKCgc64ZAAAAwIUpJydHycnJOnTokMLCws64rOUtSo899phef/11TZo0STabze0id+/erSFDhmjevHkKCCi523RdhzHmjOsdOXKkhg0b5ridnZ2tmJgYde3a9axhlLe8vDylpaUpKSlJfn5+ni7ngkBm7iE368jMPeRmHZm5h9ysc2T222D5FRwvm0FH/lk243ixMs/NizNrmlL8hgir7D5GY9oWeOVrrXBvs9Kw3CgtXbpUCxYs0LfffqvLLrusyIfTzJkzSzXOTz/9pKysLLVp08YxLT8/X4sXL9akSZO0ceNGSVJmZqaioqIcy2RlZSkiIqLEce12u+x2e5Hpfn5+XvtB6s21eSsycw+5WUdm7iE368jMPeRmnV/B8bL78noRZV9muXlxZrn57m8EKY43vtasfF5YbpSqVKmim2++2erdirj66qv122+/OU3r27evLrnkEo0YMUL16tVTZGSk0tLS1KpVK0nSiRMntGjRIr388svnvH4AAAAAKInlRmnKlCllsuLQ0FA1bdrUaVpwcLCqVavmmD506FCNGzdODRs2VMOGDTVu3DgFBQUpOTm5TGoAAAAAgOJYbpTK0/Dhw3Xs2DENHDhQBw4cUPv27TVv3jyuoQQAAADgvHKrUfr888/1n//8R7t27dKJEyec5v38889uF7Nw4UKn2zabTSkpKUpJSXF7TAAAAACwyvIFZ9944w317dtXNWvW1Jo1a9SuXTtVq1ZN27ZtU/fu3c9HjQAAAABQriw3Sv/85z/17rvvatKkSfL399fw4cOVlpamwYMH69ChQ+ejRgAAAAAoV5YbpV27dqljx46SpMDAQB0+fFiSdM899+iTTz4p2+oAAAAAwAMsN0qRkZHat2+fJCk2NlYrV66UJG3fvl3GmLKtDgAAAAA8wHKj1KVLF/33v/+VJPXr10+PPvqokpKSdMcdd5TJ9ZUAAAAAwNMsn/Xu3XffVUFBgSRpwIABCg8P19KlS3XDDTdowIABZV4gAAAAAJQ3y42Sj4+PfHz+b0NUr1691KtXrzItCgAAAAA8yfKud5K0ZMkS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48bpu+++kyQ1bNhQY8aMUf/+/R1O5l505h96s6ddu3aqWLGi/vjHPyomJkaWZZU6ftdddzmUzN3ozT46s6d///7auXOnpk6dWmo7dUn64osvNGjQIN19992aNWuWQwmDw8WLF3Xp0qVSawyX10dv9nmpMwYlh+Tm5iosLEzVqlVzOkrQoDP/0NuNqVq1qrZt26amTZs6HSWo0Jt9dGZPZGSkVqxYccWQ9H82b96szp076/Tp04ENFgTOnz+vP/zhD5o/f/5P7kjG1cufRm/2ebUztgd3SK1atfjF1SY68w+93ZiEhARe9OkHerOPzuwre9XtRo+Vd//6r/+qNWvW6L333lPlypU1bdo0jR07VnXq1NHs2bOdjuda9GafZzszuOm++uorU1xcXPJ548aNpkePHiYhIcF07NjRfPTRRw6mcyc68w+92ZOfn1/ytXr1anPfffeZtWvXmpMnT5Y6lp+f73RUV6E3++jMf/369TMtWrQwW7ZsueLYli1bzN13322efPJJB5K5X/369c3atWuNMcaEh4ebr7/+2hhjzOzZs02XLl0cTOZu9GafVztjUAoAn89njh8/bowxZu3atcbn85nu3bubcePGmUceecT4fD7z6aefOpzSXejMP/Rmj2VZxufzlXyV/fzjNfx/9GYfnfnv1KlTpnPnzsayLBMVFWVuv/1207RpUxMVFWV8Pp/p0qWLycvLczqmK1WtWtUcPHjQGGNM3bp1zRdffGGMMebbb781VatWdTKaq9GbfV7tjF3vAsD86DGw119/Xb/5zW/07rvvlqy99NJLGj9+vDp16uREPFeiM//Qmz1r1651OkJQojf76Mx/kZGRWr58ufbu3av//u//Vk5OjiSpdu3auu+++3jW6xri4uJ08OBBxcbGKiEhQfPnz9c999yjpUuXXvUFvqA3f3i2M4cHtXLBsqySv/LHxMSYzZs3lzqemZlpatSo4UQ016Iz/9AbgPImJyfHjB071ukYrvT222+bSZMmGWOMWbNmjQkLCzOVKlUyPp/PpKWlOZzOvejNPq92xhWlADl79qxCQ0MVFhamypUrlzpWqVIlXbx40aFk7kVn/qG3G5ednW3r5Z5Hjx5V3bp1b2Ki4EBv9tHZzZOTk6OxY8fqlVdecTqK67z44osl33fo0EF79+7V1q1b1bhxY7ahvwZ6s8+rnbHrXYA0adJEUVFROnDggLZt21bqWGZmJv9B/Al05h96u3Ft2rTRc889p4yMjKuek5+fr6lTp6pZs2ZauHBhANO5F73ZR2dwgwYNGqhXr1666667dOHCBafjBA16s88rnXFFKQDK3pseExNT6vPBgwf13HPPBTKS69GZf+jNnqysLI0fP16dO3dWSEiIEhMTVadOHYWGhurUqVPas2ePMjMzlZiYqAkTJqhLly5OR3YFerOPzuCEpKQkzZkzR/Xq1Su1npGRoX79+mnfvn0OJXM3erPPq53xwlkA5V5BQYGWLVumjRs36uDBg7p48aJq1qypli1bqlOnTmrWrJnTEV2J3uyjs1/erl271KpVq6B9oeXNlJKSos8//1zvvfee+vTpo+LiYr366qv685//rKFDh2rixIlOR3QlerPPq50xKDmgsLBQJ06cUHFxcal1O/evlzd05h96AxDshg8ffs3jubm5mjt3LoPSVfz1r3/V73//e6WkpOjgwYPKzs7Wf/7nfyo5OdnpaK5Gb/Z5sTMGpQDat2+fnnnmGW3atKnUujFGlmXxj/xPoDP/0BsAr0hKSpJlWdc9jy3Yr+6ll17Sv/3bv6lixYpat26d7r//fqcjBQV6s89rnfGMUgA99dRTqlixoj7++GPFxMTc0D/85R2d+YfeAHjFunXrnI4QtE6dOqVnn31Wq1ev1vvvv6/169frV7/6ld58802lpqY6Hc+16M0+r3bGFaUAqlq1qrZt28bL8WygM//QGwCviIuL05YtW1SjRg2nowSdunXrqlGjRkpPT1ejRo0kSR9++KFSU1N177336pNPPnE4oTvRm31e7YztwQMoISFBJ0+edDpGUKEz/9AbAK84ePAgtwv76Te/+Y02bNhQ8ourJD322GPatWuXCgsLHUzmbvRmn1c744rSTXbmzJmS77du3apRo0Zp/Pjxat68uUJCQkqdW7169UDHcyU68w+9AfAin8+nnJwcRUdHOx0FQDnDoHST+Xy+Us+H/N/D9D/GA/al0Zl/6A2AF/l8Pq1Zs0a33HLLNc9r0aJFgBK5W3Z2tq2dTY8ePcqLyEVv/igPnbGZw03GLjz20Zl/6A2AV3Xs2FE/9Xddy7L4A1AZbdq0UUpKip577jndc889P3lOfn6+5s+fr0mTJun555/X0KFDA5zSfejNvvLQGVeUAACAa/l8PmVkZKhW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\n","text/plain":"
"},"metadata":{}}],"id":"64bcc5de-aae3-46aa-9474-1c90b9ff20a9"},{"cell_type":"markdown","source":"## Now leet's run the tests with \"informed\" parameters, this is a I/O that aligns to the cloud-optimized granules chunking strategy and consolidated metadata.\n","metadata":{"tags":[],"user_expressions":[]},"id":"0ea67b0b-5e7f-4d1f-bca9-1f3cae7fe309"},{"cell_type":"code","source":"optimized_h5py_benchmarks = []\noptimized_xarray_benchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n print(f\"Processing: {link}\")\n try:\n log_filename = f\"logs/fsspec-xarray-{key}-{k}.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n \n io_params = {\n \"fsspec_params\": {},\n \"h5py_params\": {}\n }\n \n if \"repacked\" in link: \n io_params ={\n \"fsspec_params\": {\n \"cache_type\": \"blockcache\",\n \"block_size\": 8*1024*1024\n },\n \"h5py_params\" : {\n \"driver_kwds\": {\n \"page_buf_size\": 64*1024*1024,\n \"rdcc_nbytes\": 8*1024*1024\n }\n\n }\n }\n\n if \"kerchunk\" in link:\n continue\n \n start = time.time()\n ds = xr.open_dataset(fs.open(link, mode='rb', **io_params[\"fsspec_params\"]), group=dataset[\"group\"], engine=\"h5netcdf\", decode_cf=False)\n data_mean = ds[dataset[\"variable\"]].mean()\n elapsed = time.time() - start\n optimized_xarray_benchmarks.append(\n {\"tool\": \"xarray\",\n \"dataset\": key,\n \"cloud-aware\": \"yes\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n \n logging.getLogger().removeHandler(file_handler)\n file_handler.close()\n\n except Exception as e:\n print(e)\n \nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n try:\n if \"kerchunk\" in link:\n continue \n print (f\"Processing: {link}\")\n log_filename = f\"logs/fsspec-h5py-{key}-{k}_default.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n # this is mostly IO so no perf_counter is needed\n start = time.time()\n io_params = {\n \"fsspec_params\": {},\n \"h5py_params\": {}\n }\n \n if \"repacked\" in link: \n io_params ={\n \"fsspec_params\": {\n \"cache_type\": \"blockcache\",\n \"block_size\": 8*1024*1024\n },\n \"h5py_params\" : {\n \"page_buf_size\": 64*1024*1024,\n \"rdcc_nbytes\": 8*1024*1024\n }\n } \n with h5py.File(fs.open(link, mode=\"rb\", **io_params[\"fsspec_params\"]), **io_params[\"h5py_params\"]) as f:\n path = f\"{dataset['group']}/{dataset['variable']}\"\n data = f[path][:]\n data_mean = data.mean()\n elapsed = time.time() - start\n optimized_h5py_benchmarks.append(\n {\"tool\": \"h5py\",\n \"dataset\": key,\n \"cloud-aware\": \"yes\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n\n logging.getLogger().removeHandler(file_handler) \n file_handler.close()\n \n\n except Exception as e:\n print(e)","metadata":{"trusted":true,"tags":[]},"execution_count":28,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"}],"id":"8151834b-0b57-4a3d-98b5-8cfaffa37dc4"},{"cell_type":"markdown","source":"## Plotting results","metadata":{"tags":[],"user_expressions":[]},"id":"04414c2e-0666-4701-8ecc-7842727ede22"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(optimized_h5py_benchmarks+h5coro_beanchmarks+optimized_xarray_benchmarks+kerchunk_benchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\n\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\nplt.title(\"Informed I/O parameters\", fontsize=10)\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":29,"outputs":[{"output_type":"display_data","data":{"image/png":"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+fLlr7isr6/vVcd77733NHjwYPsvrcDAQH3//fd65plntHz5cs2ZM+eaDkZetGiROnXqJA8PD913332KiIjQokWL1LJlS5UqVcryeF999ZXuv/9++fj46L777lO5cuX0008/aeTIkVq4cKEWL16c43GfOHFCLVu2VHh4uB5//HEdPHhQn3/+udq0aaMFCxbYG6HBgwdr2rRp2rJli55++mmVLFlSUu67b+UmISFBS5YsUbdu3dS2bVt99dVXevrppxUQEKAtW7boyy+/1B133KG2bdtq9uzZeuSRR1S5cuWr/sUxry0gX375pbZt26aAgAD7tN27d9u/9LZv317du3dXSkqKvvrqKy1YsECLFi1Ss2bN7MsX9PNzPXh4eGj48OFatGiRPv/8cw0dOvSaxlu+fLl++eUXeXp6qmbNmrr99tvz9V5xNGfOHCUmJuree+/V7bffrqVLl+rDDz/U6tWrtXr1avn7+9uXXbt2rTp06KCzZ8+qa9euiomJ0d69e/XZZ5/pxx9/1OrVq1WlSpVs4x87dkzNmzdXaGio7rvvPl28eFF169bViBEjtGTJEi1dujTbboRZr1dn3iO5rSskJESpqan2+t966y116NBB/fr10+LFizVp0iSlpqaqW7du6tWrl+688041a9ZM8+bN09ixYxUSEqLhw4fb17F9+3a9+uqratOmje666y4FBgZqx44dmjlzpubNm6eNGzcqKioqR87/+c9/9OOPP6pbt26Ki4vT/Pnz9f777+vYsWP67LPPciz71FNPyd/fX3fddZcqVaqkgwcPasWKFZozZ479vWaM0UMPPaSZM2eqevXq6tmzp3x8fJSYmKi+fftq27Zteuedd676Gjhx4oQ2bdqkjh07ysMj/3+rfemll/TGG2+oYsWKuueeexQSEqJly5bp+eef19q1a/Xll1/al33xxRc1duxYVa1aVT179lRwcLAOHjyo5cuX6+eff1br1q0lSZMmTdKAAQMUHh6uu+66S6VLl1ZSUpJ++eUXffPNN04fw9arVy998cUXqlu3rvr06SNfX1/t379fixcvVocOHVSnTp18jbNmzRq98cYb6tKliwYNGqSNGzdq1qxZWrFihdatW5ft91l+P8dKliypESNGKCEhQdI/n+FZsj4z9+7dq+nTpys2Njbb52jW+yUtLU0dO3bUkiVL1KBBA/Xt21fp6emaN2+eunXrpvfff18DBw7M8XieeuoprVmzRl26dNEdd9yR4/dx8+bNlZiYqJUrV6pDhw75ygi47gxQzMXFxRlJ5qeffrJ0vxEjRhhJZvHixfZpu3fvNl5eXqZcuXJm//799ulpaWkmNjbWSDIzZsywT1+8eLGRZEaMGJFj/D179hhJplevXvZpGRkZpkqVKsZms5nly5fbp2dmZpqePXsaScbK2zY1NdWULFnS+Pr6mi1btuQ63qhRo7LdJ2sdDz/8sMnMzLRPX7JkibHZbCYmJsZkZGTYp/fq1ctIMnv27Mm1hqioKBMVFZVtWla2oaGhZvfu3fbp+/fvNz4+PqZEiRKmevXqJiUlxT5v7dq1RpK58847cx3r8ucpN999953x8PAwjRs3NufOnbNPb9GihfHy8jILFy7MtvzOnTtNcHCwqVOnjn1aQT4/Wa+NRo0amREjRuT6c8899+T6+sl6rSUlJeU5/oULF4y3t7fx8PAw6enp9ulRUVHG09Mz1/XNmjUr2xhZ2Tr+hIeH58jrSqZOnWq/r+P7sE+fPkaSee211+zTLl68aKKjo01wcLDZvHlztuWXL19uPD09zR133JFtetb4ffr0MZcuXcpRQ16vk2t5j+S2rqznVZL55ptvsj2munXrGpvNZsqUKWN++eWXbDWUK1fOlC5dOttzdfLkSXPs2LEcj+Xnn382Hh4e5rHHHsv1MZYoUcLs2LHDPv3cuXOmevXqxmazmYMHD9qn//rrr8bT09NERETkeP9mZmZmW/bjjz82kkzfvn2z1ZiWlma6du1qJJn169fnqNXRvHnzjCQzfPjwXOdnvbYvt3DhQiPJdOrUyZw9ezZbjf379zeSzJw5c+zTQ0NDTYUKFbItm7X85Xk2bNjQ+Pj4ZPucyXL06NGrPhZjcn6+nTx50thsNtO4ceMcr41Lly6ZEydOXHXMy19D//3vf7PNGzlypJFkHn300WzTrXyO5VZ3buvP7feWMca89NJLRpKJj4/P9jsiNTXVNG7c2Pj4+GR77WT9jqhYsaLZt29fno/722+/NZLMq6++mucyQGGjUUKxV7NmTSMp2xeH/Mjti9Vrr71mJJm33norx/KrV682ksxtt91mn2a1UVq6dKmRZLp27Zpj+b179xpPT09LjdKnn35qJJknnngix7z9+/cbLy8vU7Vq1WzTJRlPT89sjWCWLl26GEnZmoRraZTi4+NzLN+2bVsjyUyfPj3HvCpVquQ51pUapS1btpigoCBToUKFbL/AN27caP/yl5tnn33WSDJbt241xhTs83P5l6Gr/TjTKBljTPny5Y0kc/jwYfu0qKioPNfTrVu3bPefO3eumT59utm7d685f/68+fPPP82oUaOMv7+/8fPzy9HE5CWrUWrXrl2OeQcPHjTe3t7ZXodff/11rg1Klrvvvtt4eHiYU6dO2adJMj4+PubIkSO53iev14mz75G81pX1vMbFxeWYl/X50adPnxzzHn300Su+jxzVqVPHREdHZ5uW9Rhz+6KZNe+7776zTxswYICRZKZMmXLV9dWtW9cEBgaa8+fP55j366+/Gknmueeeu+o4H330kZFkJkyYkOv83BqlO++800jK9TMpqzG555577NNCQ0NN5cqVTVpa2hVradiwoQkMDMxX85IXx8+3U6dOGUmmZcuWTo+Z9RqqUaNGtkbEmH+a3rJlyxp/f3/747P6OZZb3bmtP7ffWxkZGaZUqVImJiYmR23G/PMHKUnm/ffft0/L+h3x3nvvXfFxr1mzJtcmEHAldr0DLNi0aZMk5bpb1y233CJ/f39t3rzZ6fG3bNkiSbr11ltzzIuKilJkZGS2/cT37t2radOmZVuuZMmS9t0prlRvZGSkqlatqp07d+r06dMKDg7OsS5Ht956q+bNm6fNmzcXyAG3DRo0yDEtPDxcklS/fv1c561du9bSOg4fPqyuXbsqMzNT3333nSIiIuzz1qxZI0lKTk7O9TiyHTt22P+tXbu25ecnP/r166cPP/ww13mzZ8/WAw88YGm8yxljcp3u6+urCxcuXPX+jrsexcTE6OWXX1b58uX1+OOPa/To0dl2ebqa3HKLiIhQ1apVtWPHDvvrMOt52bFjR67PS3JysjIzM/XHH3+ocePG9umVK1e2fGIPZ98jV1uXM69tSTp48GC2XVeXLFmihIQErV27VkePHtWlS5fs83x8fHJdd8OGDXNMq1ixoqR/zjiX5ZdffpEktW/fPs/HIUnnzp3T1q1bFRERoTfffDPH/PT0dEn/9365kqwT5ljZTXXNmjUKDAzU5MmTc53v7++fbd09evTQhx9+qNq1a+u+++5TbGysmjdvnuOkJj169NALL7yg2rVr6/7771dcXJxatWpl38XMGSEh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/tRxSzHgShyjhBvC6NGjdeHCBb377ruqUaOG2rZtq9q1a8vb21t79uzRTz/9pGPHjuXavFyuatWqeuutt/Tcc8+pbt266tGjhwIDA/XDDz9ox44d6tatmx566CH78j4+Pho4cKDefPNNNWzYUN26ddPp06f1/fffKzY2NsdfhT08PPTxxx+rc+fOuv322+3X6fn555+VlJSkunXr5vrlNS8hISH65JNP9MADD6hZs2a67777VLZsWS1atEjr169X06ZN9fzzz+e4X926dbVkyRLdcsstatu2rQ4dOqTZs2fL29tbn3zySbbrn7Rt21bvvPOO+vXrp3vvvVeBgYGqVKmSevbsme86C1qvXr1kjFG9evX0xhtv5JgfFxdnP3h/1qxZatOmje6//34lJCSoUaNG8vPz0/79+7V69WodOXLE/mWioJ+fa/XOO+8oKChImZmZSk1N1bZt27Rs2TKlpaWpZcuWmj17ttP7+x87dkz16tVT48aNVadOHfvxdz/++KOOHTumdu3aWdqNSJK6dOmizp07695771VkZKSWLl2q1atXq169ehoyZIh9OV9fX82ZM0edOnVSbGysbrvtNvtB6Pv379fy5ctVunTpfJ084GqcfY8UhqeeekpPPfWUGjRooH/961+6dOmSEhMT7a/trJOLOKtOnTpKSEjQoEGDdPPNN6t79+6KiopScnKyli1bpi5dutivt9OvXz+tWbNG06dP18qVK3X77bcrIiJChw8f1o4dO7R27VrNnDnzqlsZbTab7rzzTn366adKSkq66vFRktSxY0e98sorGjVqlGJiYtSxY0dFRUXp2LFj2rVrl5YvX67Ro0erVq1aOn/+vG677TZVqVJFzZo1U6VKlXTmzBn98MMPSk5O1rBhw+wNxn333aeAgAC1atVKUVFRSk9PV2JiorZt26b77rtPlSpVspzpwYMH1axZM918881q2LChKlSooGPHjunbb79Venq6pWuatW/fXgMGDNC8efNUs2ZNbdy4UQsWLFBkZKR9i3EWK59j0j+f2+vXr1fXrl116623ysfHR61atVKrVq1Us2ZNRURE2D8/KlasKJvNpieeeEIlSpTQyJEjtXHjRk2YMEHz5s1TbGysypYtq4MHD2rr1q3asmWLVq9enecxVrkxxmjRokWqVauWfUsZ4BYK5uR5QNGwbt068+ijj5qY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mi1btpjMzEwjyVSoUMF8/vnnZufOnaZ79+4mOjratG3b1syfP99s27bN3HLLLaZjx472sebPn29CQkLMtGnTzO7du83ChQtNdHS0iY+PN8YYk5GRYWrXrm3i4uLMpk2bzNKlS02DBg2MJDN37tx8Z2GMMUOGDDF9+/Y1xhgzfvx4I8kcOnQox33T0tJMUFCQefrpp/McPyoqygQHB5s33njD7Ny500yYMMF4enraszXGmHfffdf8/PPP5q+//jKLFi0yNWrUME888YR9/tSpU423t7dp0aKFWblypdmxY4c5c+aMWbRokZkxY4bZtm2b2bZtm+nbt68pX768SU1Ntd/3emSdkpJiJJmpU6eapKQkk5KSkq/7ZdVTrlw5M3nyZLN7926zd+9e8+STT5r69eubdevWmT179pjExETz3Xff5ZkpABR1NEoA4KZya5RatWqVbZkmTZqYYcOG2W9369bN9OrVy3574cKFxtPT0+zfv98+7ffffzeSzC+//GKM+adR8vb2tn+RziLJvPzyy/bbq1evNpLM5MmT7dNmzZpl/Pz87LdvvfVWM2bMmGzjzJgxw4SHhxtjjFmwYIHx9PQ0Bw4csM//8ccfnWqUqlevbv+i3r9/f1OiRIk871+3bl3TqVOnPOdHRUVla0KMMea+++674n2++OILU7p0afvtqVOnGklm8+bNed7HGGMuXbpkgoODzffff2+fdj2yzhrXMdf83m/w4MHZlunatavp06fPFR8bABQnXi7YiAUAcFLdunWz3Q4PD1dKSkqey2/fvl2RkZGKjIy0T7vppptUsmRJbd++XU2aNJEkRUVFqWzZsldcX/ny5SVJderUyTbtwoULSk1NVUhIiDZs2KB169bp9ddfty+TkZGhCxcu6Ny5c9q+fbsqVaqkihUr2uc3b948vw8/2+P6+++/dfvtt+drefP/70p4JY51NG/eXAkJCfbbixcv1pgxY7Rt2zalpqbq0qVLunDhgs6ePavAwEBJko+PT47nKCUlRa+++qp+/vlnHT58WBkZGTp37pz279+fbbmCzjogICDXx5nf+zVu3Djb/Z544gndc8892rhxo9q3b6/u3burRYsWuYcJAMUAjRIAFCHe3t7ZbttstiueMCCvBsFxetYX/SutL2v53KZl1ZCZmamRI0fq7rvvzjGWn5+fjDE5pl+tgcnNd999p3bt2snf31+SVL16dZ06dUqHDh1SREREtmUvXryov/76S23btrW8nqza9u3bp86dO6t///4aNWqUQkNDtWLFCvXt2zfbiQ78/f1zPJ7evXvryJEjSkhIUFRUlHx9fdW8eXNdvHgx23IFnXVe8ns/x9dEp06dtG/fPs2bN08//fSTbrvtNj355JN655138lwXABRlNEoAUIzddNNN2r9/vw4cOGDfqrRt2zadOnVKtWrVKvD1NWzYUDt37lRMTMwV67m8oVm9erXl9Xz77bd67LHH7LfvueceDR06VOPGjdO4ceOyLfvhhx/q7NmzeuCBB6445po1a3LcrlmzpiRp/fr1unTpksaNGycPj3/Og/TFF1/kq9bly5frgw8+UOfOnSVJBw4c0NGjR/N13yu5WtbSP41WRkaG5fvlpWzZsurdu7d69+6tW2+9Vc8//zyNEoBii0YJAIqx22+/XXXr1tWDDz6ohIQEXbp0SQMGDFBsbGyOXasKwquvvqo77rhDkZGRuvfee+Xh4aFff/1VW7du1ejRo3X77berRo0aeuSRRzRu3DilpqZq+PDhltaRkpKidevWZbs+UKVKlTR27FgNGTJEfn5+evjhh+Xt7a1vv/1WL730kp577jk1a9bsiuOuXLlSY8eOVffu3ZWYmKgvv/xS8+bNkyRVrVpVly5d0vvvv6+uXbtq5cqV+vDDD/NVb0xMjGbMmKHGjRsrNTVVzz//vH1L2LW4WtbSP2e+W7RokVq2bClfX1+VKlUqX/fLa32NGjXSzTffrLS0NP3www/XpdkGAHfB6cEBoBjLuuBoqVKl1Lp1a91+++2qUqWKPv/88+uyvg4dOuiHH35QYmKimjRpoltuuUXjx49XVFSUJMnDw0Nz585VWlqamjZtqsceeyzbsTL58f3336tZs2Y5rhP1zDPPaO7cuVq+fLkaN26s2rVra+bMmZo0aVK+tno899xz2rBhgxo0aKBRo0Zp3Lhx6tChgySpfv36Gj9+vN566y3Vrl1bn332md5444181TtlyhSdOHFCDRo00MMPP6xBgwY5fY2ry10ta0kaN26cEhMTFRkZqQYNGuT7frnx8fHRiy++qLp166p169by9PTU7Nmzr/lxAIC7spncdhgHAMBN3XnnnWrVqpWGDh1aYGNGR0dr8ODBGjx4cIGNCQAo2tiiBAAoUlq1anXV440AALhWHKMEAChSCnJLEgAAeWHXOwAAAABwwK53AAAAAOCARgkAAAAAHBT7Y5QyMzN16NAhBQcHO3X1dwAAAADFgzFGp0+fVkREhP0C4nkp9o3SoUOH7FejBwAAAIADBw6oYsWKV1ym2DdKwcHBkv4JIyQkxMXVZJeenq6FCxeqffv28vb2dnU5RQKZOYfcrCMz55CbdWTmHHKzjsycQ27WuXNmqampioyMtPcIV1LsG6Ws3e1CQkLcslEKCAhQSEiI272I3BWZOYfcrCMz55CbdWTmHHKzjsycQ27WFYXM8nNIDidzAAAAAAAHNEoAAAAA4IBGCQAAAAAcFPtjlPIrIyND6enphbrO9PR0eXl56cKFC8rIyCjUdRdV+cnM29tbnp6ehVwZAAAAipMbvlEyxig5OVknT550ybrDwsJ04MABrvGUT/nNrGTJkgoLCyNXAAAAOOWGb5SymqRy5copICCgUL9YZ2Zm6syZMwoKCrrqBa/wj6tlZozRuXPnlJKSIkkKDw8v7BIBAABQDNzQjVJGRoa9SSpdunShrz8zM1MXL16Un58fjVI+5Sczf39/SVJKSorKlSvHbngAAACw7Ib+dp51TFJAQICLK0FBy3pOC/u4MwAAABQPN3SjlIXjWIofnlMAAABcCxolAAAAAHBAowQAAAAADmiU3Ezv3r1ls9ly/OzatcvVpWWzd+9e2Ww2bd682dWlAAAAAAXuhj7rnbvq2LGjpk6dmm1a2bJlLY9z8eJF+fj4FFRZAAAAwA2DLUpuyNfXV2FhYdl+PD09tXTpUjVt2lS+vr4KDw/XCy+8oEuXLtnvFxcXp4EDB+rZZ59VmTJl1K5dOy1ZskQ2m00LFixQgwYN5O/vr7Zt2yolJUU//vijatWqpZCQED3wwAM6d+6cfaz58+erVatWKlmypEqXLq077rhDu3fvts+vXLmyJKlBgway2WyKi4srtHwAAACA641GqYg4ePCgOnfurCZNmmjLli2aNGmSJk+erNGjR2dbbvr06fLy8tLKlSv10Ucf2afHx8dr4sSJWrVqlQ4cOKAePXooISFBM2fO1Lx585SYmKj333/fvvzZs2f17LPPat26dVq0aJE8PDx01113KTMzU5L0yy+/SJJ++uknJSUl6euvvy6EFAAAAIDCwa53buiHH35QUFCQ/XanTp1UvXp1RUZGauLEibLZbKpZs6YOHTqkYcOG6dVXX7VffDUmJkZjx4613zc5OVmSNHr0aLVs2VKS1LdvX7344ovavXu3qlSpIkn617/+pcWLF2vYsGGSpHvuuSdbTZMnT1a5cuW0bds21a5d274rYOnSpRUWFnadkgAAAABcgy1KbqhNmzbavHmz/WfChAnavn27mjdvnu36QC1bttSZM2f0999/26c1btw41zHr1q1r/3/58uUVEBBgb5KypqWkpNhv7969Wz179lSVKlUUEhJi39Vu//79BfY4AQAAAHfFFiU3FBgYqJiYmGzTjDE5LqJqjJGU/eKqgYGBuY7p7e1t/7/NZst2O2ta1m51ktS1a1dFRkbqk08+UUREhDIzM1W7dm1dvHjRuQcFAAAAFCFsUSoibrrpJq1atcreHEnSqlWrFBwcrAoVKhTouo4dO6bt27fr5Zdf1m233aZatWrpxIkT2ZbJOpteRkZGga4bAAAAcAdsUSoiBgwYoISEBD311FMaOHCgdu7cqREjRujZZ5+1H59UUEqVKqXSpUvr448/Vnh4uPbv368XXngh2zLlypWTv7+/5s+fr4oVK8rPz08lSpQo0DoAAABQhL1RUcq8UDBjxZ8qmHEscOkWpfj4+BwXVr38xADGGMXHxysiIkL+/v6Ki4vT77//7sKKXadChQr6f//v/+mXX35RvXr11L9/f/Xt21cvv/xyga/Lw8NDs2fP1oYNG1S7dm0988wzevvtt7Mt4+XlpQkTJuijjz5SRESEunXrVuB1AAAAAK7i8i1KN998s3766Sf7bU9PT/v/x44dq/Hjx2vatGmqXr26Ro8erXbt2mnnzp0KDg52RbnX3bRp0/KcFxsbaz8td26WLFmSY1pcXFy23fUkqXfv3urdu3e2afHx8YqPj7ffvv3227Vt27ZsyziO89hjj+mxxx7Lsx4AAACgqHL5MUpeXl7ZLqyaddppY4wSEhI0fPhw3X333apdu7amT5+uc+fOaebMmS6uGgAAAEBx5vItSn/++aciIiLk6+urZs2aacyYMapSpYr27Nmj5ORktW/f3r6sr6+vYmNjtWrVKvXr1y/X8dLS0pSWlma/nZqaKklKT09Xenp6tmXT09NljFFmZma2M74VlqwtNFk14Orym1lmZqaMMUpPT8+2lfJGlfXad3wPIG9k5hxys47MnENu1pGZc8jNOntm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AAAAACA/LF9wNuv02+fPn78e9QAAAACAy1neonTvvfdq1qxZKleunKKjo3OcOWLjxo0FVhwAAAAAuILlRql3797asGGDHnrooWs+mQMAAAAAuCPLjdK8efO0YMECtWrV6nrUAwAAAAAuZ/kYpcjIyKtexRYAAAAAijLLjdK4ceM0dOhQ7d279zqUAwAAAACuZ3nXu4ceekjnzp1T1apVFRAQkONkDsePHy+w4gAAAADAFSw3SgkJCdehDAAAAABwH5YbpV69el2POgAAAADAbeSrUUpNTbWfwCE1NfWKy3KiBwAAAABFXb4apVKlSikpKUnlypVTyZIlc712kjFGNptNGRkZBV4kAAAAABSmfDVKP//8s0JDQyVJixcvvq4FAQAAAICr5atRio2NVZUqVbRu3TrFxsZe75oAAAAAwKXyfR2lvXv3slsdAAAAgBuC5QvOAgAAAEBxZ+n04Nu2bVNycvIVl6lbt+41FQQAAAAArmapUbrttttkjMkx3WazcdY7AAAAAMWGpUZp7dq1Klu27PWqBQAAAADcgqVGqVKlSipXrtz1qgUAAAAA3AIncwAAAAAAB/lulGJjY+Xj43M9awEAAAAAt5DvXe8WL158PesAAAAAALfBrncAAAAA4IBGCQAAAAAc0CgBAAAAgAMaJQAAAABwYOk6SpKUkZGhadOmadGiRUpJSVFmZma2+T///HOBFQcAAAAArmC5UXr66ac1bdo0denSRbVr15bNZrsedQEAAACAy1hulGbPnq0vvvhCnTt3vh71AAAAAIDLWT5GycfHRzExMdejFgAAAABwC5Ybpeeee07vvfeejDHXox4AAAAAcDnLu96tWLFCixcv1o8//qibb75Z3t7e2eZ//fXXBVYcAAAAALiC5UapZMmSuuuuu65HLQAAAADgFiw3SlOnTr0edQAAAACA2+CCswAAAADgwPIWJUmaM2eOvvjiC+3fv18XL17MNm/jxo0FUhgAAAAAuIrlLUoTJkxQnz59VK5cOW3atElNmzZV6dKl9ddff6lTp07Xo0YAAAAAKFSWG6UPPvhAH3/8sSZOnCgfHx8NHTpUiYmJGjRokE6dOnU9agQAAACAQmW5Udq/f79atGghSfL399fp06clSQ8//LBmzZpVsNUBAAAAgAtYbpTCwsJ07NgxSVJUVJTWrFkjSdqzZw8XoQUAAABQ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2FDt27dXnz59FBER4eoy3Q65WVecM+P04NdZUlKSXn31VX322WcKCwtT06ZNVaFCBfn7++v48eP67bfftGHDBkVFRWnEiBG67777XF2yy5GZc8jNOjJzDrlZR2bOeffdd/X6668rOjpad955Z665LV++XHPnztUtt9yi999/X9WqVXN12S71zTffaNiwYTp16pQ6d+6cZ2arV69W7969NWrUKJUtW9bVZbscuVl3Q2RmcF2VLVvWPPfcc2br1q15LnPu3Dkzc+ZM07RpU/P2228XYnXuicycQ27WkZlzyM06MnPOv/71L/Prr79edbnz58+b//znP+aTTz4phKrcW5MmTcx3331nMjIyrrjc33//bZ5//nnzzjvvFFJl7o3crLsRMmOL0nV25MgRS92z1eWLIzJzDrlZR2bOITfryAwAih4aJQAA4PYWLVqk2267Ldd5EydO1MCBAwu5IgDFHWe9K0THjh2z///AgQN69dVX9fzzz2v58uUurMq9kZlzyM06MnMOuVlHZs655557tG7duhzTExIS9NJLL7mgIvf2559/6quvvtKePXskSfPmzVPr1q3VpEkTvf766+Lv5LkjN+uKdWYu3O3vhvHrr7+aqKgo4+HhYWrUqGE2bdpkypcvb4KCgkxISIjx9PQ0c+fOdXWZboXMnENu1pGZc8jNOjK7NlOmTDFlypQxv//+u33a22+/bUJCQsyyZctcWJn7+frrr42Xl5fx8fExvr6+Zvr06cbX19d07NjRdOnSxXh5eZk333zT1WW6HXKzrrhnRqNUCDp27GjuuOMOs3z5ctOvXz9ToUIF06dPH5ORkWEyMjLMgAEDTLNmzVxdplshM+eQm3Vk5hxys47Mrt3bb79tKlSoYPbs2WPefPNNExISYlauXOnqstxOo0aNzEsvvWQyMzPNlClTjL+/v3n33Xft8z/66CNTs2ZN1xXopsjNuuKeGY1SIShdurTZsmWLMcaY06dPG5vNZtatW2efv337dlOiRAkXVeeeyMw55GYdmTmH3Kwjs4LxwgsvmNKlS5uSJUuaNWvWuLoctxQUFGR27dpljDEmIyPDeHp6Zjvj4p49e4y/v7+rynNb5GZdcc+MC84WguPHjyssLEySFBQUpMDAQIWGhtrnlypVSqdPn3ZVeW6JzJxDbtaRmXPIzToys27ChAk5poWHhysgIECtW7fW2rVrtXbtWknSoEGDCrs8t3X27FkFBwdLkjw8POTv76+AgAD7fH9//2wX7sU/yM264p4ZjVIhsdlsV7yNnMjMOeRmHZk5h9ysIzNr3n333Vyne3p6auXKlVq5cqWkf3KkUfo/Npst22vL8TZyR27WFffMaJQKSe/eveXr6ytJunDhgvr376/AwEBJKtKd9vVEZs4hN+vIzDnkZh2ZWZN1Fi1YY4xR9erV7V9Yz5w5owYNGsjDw8M+HzmRm3XFPTOuo1QI+vTpk6/lpk6dep0rKTrIzDnkZh2ZOYfcrCMzFJbp06fna7levXpd50qKFnKzrrhnRqMEAADcXkZGhqZNm6ZFixYpJSVFmZmZ2eb//PPPLqoMQHHFrncAAMDtPf3005o2bZq6dOmi2rVrF6vjIK6306dPZ9sFysPDQ0FBQS6sqGggN+uKW2ZsUSoESUlJmjhxol5//XVJUqtWrXTu3Dn7fE9PT33zzTeqUKGCq0p0O2TmHHKzjsycQ27Wkdm1KVOmjD799FN17tzZ1aW4vc2bN2v48OGaN2+eJCk4ODjba81ms2n16tVq0qSJq0p0S+RmXXHPzMPVBdwIPvjgA508edJ+e8uWLbr11lvVrVs3devWTZ6ennme2edGRWbOITfryMw55GYdmV0bHx8fxcTEuLqMIuH9999Xq1atsk2bMWOGfv75Zy1atEg9e/bM9dTrNzpys67YZ+aCazfdcOrVq2cWLlxovx0UFGR2795tvz1//nxz0003uaI0t0VmziE368jMOeRmHZldm3feeccMGDDAZGZmuroUt1ejRg2zbNky+23H19qaNWtMpUqVXFGaWyM364p7ZhyjVAj27t2rqlWr2m+3a9fOfjpYSapRowanQHVAZs4hN+vIzDnkZh2ZXZsVK1Zo8eLF+vHHH3XzzTfL29s72/yvv/7aRZW5nwMHDqhSpUr226+99prKlCljvx0eHq7Dhw+7ojS3Rm7WFffMaJQKwaVLl3Tq1Cn7bccP8xMnTtjPN49/kJlzyM06MnMOuVlHZtemZMmSuuuuu1xdRpHg6+urv//+W1FRUZKkZ555Jtv8AwcOKCAgwBWluTVys664Z0ajVAhq1KihVatWqUGDBrnOX758uapXr17IVbk3MnMOuVlHZs4hN+vI7Npwfan8a9Cggb755hu1bNky1/lff/11nq/DGxm5WVfsM3P1vn83grFjx5rQ0FCzZcuWHPM2b95sQkNDzdixY11QmfsiM+eQm3Vk5hxys47MUFjmzJljvLy8zMSJE01GRoZ9+qVLl8yECROMt7e3+fLLL11YoXsiN+uKe2acHrwQpKen6/bbb9eqVavUrl071ahRQzabTTt27FBiYqKaN2+uRYsW5djf+kZGZs4hN+vIzDnkZh2ZXZvKlStf8dpJf/31VyFW4/6GDRumt99+W8HBwapSpYpsNpt2796tM2fO6Nlnn9Xbb7/t6hLdErlZV5wzo1EqJBcvXtT48eM1e/Zs/fHHH5KkatWq6YEHHtAzzzwjX19fF1fofsjMOeRmHZk5h9ysIzPnvffee9lup6ena9OmTZo/f76ef/55vfDCCy6qzH2tWbNGs2bN0p9//inp/15rt9xyi4src2/kZl1xzYxGCQAAFFn/+c9/tH79eo5hAlDgOL0OAAAosjp16qSvvvrK1WUUKWfPntWyZctcXQaKgQ0bNri6hOuKRskNbNmyRZ6enq4uw+3MmzdPjz32mIYOHart27dnm3fixAm1bdvWRZW5r+DgYPXt21erVq1ydSnFBu/PvPEetYb35/UxZ84chYaGurqMImXXrl1q06aNq8twO+np6Ro6dKhiYmLUtGnTHFspDx8+zO8DB02aNFHVqlU1ZswYHTx40NXlFDgaJTfBHpDZzZw5U926dVNycrJWr16thg0b6rPPPrPPv3jxopYuXerCCt3T2bNntXbtWrVq1Uq1atXSuHHjlJKS4uqyijzenznxHrWO9+e1adCggRo2bGj/adCggcLDw/XSSy/ppZdecnV5KAZef/11ffrpp+rfv7/at2+vZ555Rv369cu2DL8Pcrrttts0YcIERUdH64477tA333yjjIwMV5dVIDhGqRDcfffdV5x/6tQpLVmypNi8qApCw4YN1adPHz311FOS/vmLYZ8+fZSQkKC+ffvq8OHDioiIIDMHHh4eSk5OVlJSkv773/9q5syZOnPmjO644w499thj6tix4xXPGnUj4v3pHN6j1vH+vDYjR47MdtvDw0Nly5ZVXFycatas6aKq3NPVtrBlZGTozJkzvD8dVKtWTe+++67uuOMOSdLu3bvVqVMntWzZUlOmTFFKSgqfaw6yPtdCQ0P17bffasqUKVqwYIHKlCmjXr166dFHH1WNGjVcXabT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ceN0/fXXm44BADCIQQkAEHYsy/rZrwcffNB0RABAmKtnOgAAAE59+eWXNd8vXrxYL7zwgj799NOataioKBOxAAAewhUlAEDYadGiRc1X06ZNZVmW39qCBQvUoUMH1a9fX1dddZXmzZvn998XFxdr4MCBatSokZo0aaK7775bX331laH/GwCAGzEoAQA8ZdmyZXriiSf09NNPa+/evXr00Uc1YsQI5ebmSpJs29agQYNUVlamTZs2ae3atTp48KCGDBliODkAwE249Q4A4CmTJk3Sgw8+qMzMTElSVlaWtm3bpkmTJqlnz55at26d/vWvf+nw4cNq3bq1JGnevHnq1KmTduzYoW7dupmMDwBwCa4oAQA8pbCwUD169PBb69GjhwoLC2uOt27dumZIkqSkpCTFxMTUnAMAAIMSAMBzLMvy+2zbds3aD7//qXMAAGBQAgB4yjXXXKMtW7b4rW3dulXXXHONpH9fPSouLtbnn39ec7ygoEDl5eU15wAAwB4lAICnjB07VnfffbduuOEG9erVSytXrtTSpUu1bt06SVJaWpo6d+6s+++/X5MnT9a5c+eUmZmp2267TSkpKYbTAwDcgitKAABPGTRokKZMmaKJEyeqU6dOeuuttzR79mylpqZK+vdtee+++65iY2N16623Ki0tTe3bt9fixYvNBgcAuIpl27ZtOgQAAAAAuAlXlAAAAAAgAIMSAAAAAARgUAIAAACAAAxKAAAAABCAQQkAAAAAAjAoAQAAAEAABiUAAAAACMCgBAAAAAABGJQAAAAAIACDEgAAAAAEYFACAAAAgAD/B7vXIIJKWjZCAAAAAElFTkSuQmCC\n","text/plain":"
"},"metadata":{}}],"id":"2db2535a-8d3a-4e65-b21c-8db6b48074c8"},{"cell_type":"markdown","source":"## Pliting tool specific performance","metadata":{"tags":[],"user_expressions":[]},"id":"ea0db03e-5653-4908-ada1-16d723666e18"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(regular_xarray_benchmarks+optimized_xarray_benchmarks)\n\npivot_df = df.pivot_table(index=['dataset','cloud-aware'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.title('Xarray \"Cloud-awared\" Access Pattern Performance (less is better)')\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":32,"outputs":[{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAKLCAYAAADIGXhIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB5J0lEQVR4nO3df3yO9f////u5X+c22/y2GTO/87tIhGKSya8XlSQlP4ukSOVHKiM/XlRS6a1IeCXl9SoUCSNWQuZ3IeVHCLMShrHN9vz+4bvz4zw3bNl2zHnerpfLeeF8Hsd5HI/jOJ/nY+fjPI7jediMMUYAAAAAAAcvqwMAAAAAgMKGQgkAAAAAXFAoAQAAAIALCiUAAAAAcEGhBAAAAAAuKJQAAAAAwAWFEgAAAAC4oFACAAAAABcUSgAAAADggkIJhVqfPn1kt9v1008/ZZn273//WzabTUuWLLEgsvxTsWJFxcTESJKioqLUq1evLPOcOHFCI0aMUN26dRUUFCR/f39Vq1ZNgwcP1m+//eaYLyYmRjabrYAid7Z27VrZbDatXbvWkvUXNlFRUYqKinI8//333532j81m05w5c3K8vJ9++kk2m02+vr46fvx43gZbCEVFRclmszkeAQEBuvXWWzV16lRlZGTkalnHjh1TTEyMtm/fnmXasmXLHJ+/wibzM5X58Pb2VmhoqB566CHt2bMnz9f38ssvq0KFCvLx8VGxYsXyfPmeaOzYsapVq5ZTn7XZbIWuz+Vl/u7Vq5eCgoJuPKgrzJ8/X1OnTs3SnpycrJiYmHz7u7N69WoFBQXp6NGj+bJ8FD4USijUpk6dqrCwMPXs2VNpaWmO9p9++kmjR49Wr1691LFjRwsjLHibNm1S3bp1NWvWLHXp0kULFy7U8uXL9cILL2jr1q1q1KiR1SGiAHz44YeSpEuXLuk///mPxdEUjMqVK2vDhg3asGGDFixYoHLlyum5557TyJEjc7WcY8eOacyYMVctlMaMGZNHEeePCRMmaMOGDVqzZo2GDx+u2NhYNWvWLE+/vH355ZcaP368Hn/8ccXFxWnVqlV5tmxPdezYMU2ePFljx46Vl1fh/vrVoEEDbdiwQQ0aNLA6lGxdq1AaM2ZMvhVKrVq1UqNGjfTSSy/ly/JR+BTuTyo8XkhIiGbNmqXt27dr3LhxkqS0tDT16NFDoaGh2SbKf+rChQvZtqelpenSpUt5tp4bkZSUpE6dOsnf31/btm3T6NGjFR0draioKPXv31/ff/+9Zs6caXWYbiU5OdnqELJISUnRJ598oltvvVXlypXTRx99ZHVIBSIgIEB33nmn7rzzTv3rX//Sl19+qcqVK2vatGlOP6QURnnZj6pVq6Y777xTzZs319ChQzVlyhSdOnUqV0ckryYzzp9//lmS9Oyzz6pZs2Zq2LBhni3bU7399tsqVqyYHnjgAatDua6QkBDdeeedCgkJsTqUQuHK7wFPP/20PvnkEx05csTiqFAQKJRQ6N17770aMGCAJkyYoC1btigmJkY7duzQrFmzVLRoUad5x4wZo8aNG6tEiRIKCQlRgwYNNGvWLBljnOarWLGiOnTooIULF6p+/fry9/d3/Apls9n08ccf6/nnn1e5cuVkt9u1b98+/fnnnxo4cKBq1aqloKAglSlTRvfcc4++//57x3KNMapWrZratGmTZTvOnTunokWL6umnn/7H+2LmzJlKSEjQ5MmTVb58+Wzn6dKlyzWXkZGRocmTJ6tGjRqy2+0qU6aMHn/8cf3xxx9O81WsWDHb0/5cTyGTpF9++UX33XefAgMDVapUKQ0YMEBnz57N8XZt3rxZ3bp1U8WKFRUQEKCKFSvqkUce0aFDhxzzJCUlycfHR6+//rqj7a+//pKXl5eKFi3qVMw+++yzKl26tON9j42NVadOnVS+fHn5+/uratWq6t+/v/766y+nODJPVdy6dau6dOmi4sWLq0qVKpIuv7f/93//p9tuu00BAQEqXry4unTpogMHDjgtwxijyZMnKzIyUv7+/mrQoIG++eabHO+LnFi8eLFOnjypfv36qWfPnvr111+1bt26LPOlpKRo7Nixqlmzpvz9/VWyZEm1bNlS69evd8yTkZGhd99917FdxYoV05133qmvvvrKaVkLFixQkyZNVKRIEQUFBalNmzbatm2b0zwHDhxQt27dFB4eLrvdrtDQULVq1crpyM23336rqKgolSxZUgEBAapQoYIefPDBf/Ql2tfXV7fffruSk5P1559/at++ferdu7eqVaumwMBAlStXTh07dnQ6dXft2rW64447JEm9e/d2nMYWExOjXr166b333pMkp1Pcfv/9d0k57wNRUVGqU6eOvvvuOzVt2lSBgYHq06eP43TLN954Q1OmTFGl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ixebli1bmpCQEGO3201kZKTp0qWLWbVqlTHGmBMnTphevXqZGjVqmCJFipigoCBTr14989ZbbzlGeNuwYYO5//77TWRkpLHb7aZkyZKmRYsW5quvvrru9l9tePArnTp1yvTt29eUKVPGBAYGmrvuust8//332e77Tz/91NSoUcP4+vo69YOUlBTTr18/U7p0aWOz2bLkjpz0gavFmjni2+uvv55lmmtfzM618pOr671fxlwejaxIkSLZvv5qn4Wc5o/c7oOrbVvmUO7x8fGOtvXr15smTZqYwMBAU7p0adOvXz+zdevWLCMZXm37ssuLOfmsGJOz9/9q7r77btOuXbss7dm993/++ad59tlnTaVKlYyvr68pUaKEuf32282oUaMcI63NnTvXtGzZ0oSGhho/Pz8THh5uunbtanbu3OlYzogRI0zDhg1N8eLFHX8Xn3vuOfPXX39dM1bXUe9y8vm+msz3YefOnSYqKsoEBASYEiVKmKeeeirbUeNyso///vtv06VLF1OsWDHH5zTTqlWrTP369Y3dbjeSnP6GHDx40PTp08eUK1fO+Pr6mtKlS5umTZuacePGZdn2q33O9u3b55Rn4d5sxrjciRNAnmnYsKFsNlu21+YAADzHF198oYcffliHDh1SuXLlrA4H/9Arr7yi//znP9q/f798fDgxy93xDgN5LCkpST///LOWLl2qLVu2aNGiRVaHBACw2AMPPKA77rhDEydO1LRp06wOB//A6dOn9d577+ndd9+lSPIQvMtAHtu6datatmypkiVLavTo0Y5hewEAnstms2nmzJn66quvrjnCHgqvgwcPauTIkVnuEwj3xal3AAAAAOCCnzMAAAAAwAWFEgAAAAC4oFACAAAAABduP5hDRkaGjh07puDgYG4MBgAAAHgwY4zOnj2r8PDw6w6q4vaF0rFjxxQREWF1GAAAAAAKiSNHjqh8+fLXnMftC6Xg4GBJl3dGSEiIxdFYIy0tTStXrlR0dLR8fX2tDgcWoA+APgD6AOgDoA9cvt9lRESEo0a4FrcvlDJPtwsJCfHoQikwMFAhISEe+6HwdPQB0AdAHwB9APSB/ycnl+QwmAMAAAAAuKBQAgAAAAAXFEoAAAAA4MLtr1ECAAAArsYYo0uXLik9Pd3qUPJdWlqafHx8dPHiRbfdXm9vb/n4+OTJbYEolAAAAOCR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\n","text/plain":"
"},"metadata":{}}],"id":"47444e8a-6d59-42c2-baff-a3c85c447eb2"}]} \ No newline at end of file diff --git a/notebooks/portable-h5py-test.ipynb b/notebooks/portable-h5py-test.ipynb index 82d88f5..05c60b8 100644 --- a/notebooks/portable-h5py-test.ipynb +++ b/notebooks/portable-h5py-test.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "48daa283-8e1e-46e3-b4ce-1a0271b86d37", "metadata": { "tags": [] @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "d6ce77fd-f9cd-48b1-94cd-1fe57f52e11f", "metadata": { "tags": [] @@ -32,52 +32,29 @@ "outputs": [], "source": [ "original_granules = [\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/average/original/ATL03_20191225111315_13680501_006_01.h5\",\n", + " # \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/original/ATL03_20190219140808_08110212_006_02.h5\",\n", "]\n", "h5py_original = H5pyArrMean('atl03-bigsize-original', files=original_granules, store_results=True)" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "60eeeb1b-9531-4fec-a847-3ca5304c4685", "metadata": { "tags": [] }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "h5py params: {}\n", - "h5py params: {}\n" - ] - }, - { - "data": { - "text/plain": [ - "[{'library': 'h5py',\n", - " 'format': 'original',\n", - " 'mean': 1032.9840463639412,\n", - " 'time': 51.46329092979431,\n", - " 'total_requested_bytes': 414028873,\n", - " 'total_requests': 12295,\n", - " 'avg_req_size': 33674}]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# takes about ~30 seconds per granule out of region (6+ GB granules)\n", "io_params ={\n", " \"fsspec_params\": {},\n", " \"h5py_params\" : {}\n", "}\n", + "\n", "results = h5py_original.run(io_params)\n", + "\n", "benchmarks.append({\"library\": \"h5py\",\n", " \"format\": \"original\",\n", " \"mean\": results[0],\n", @@ -90,63 +67,31 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "64c4584f-c527-44bb-8c05-68a96820d1ff", "metadata": {}, "outputs": [], "source": [ "cloud_optimized_granules = [\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", - " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", + " \"s3://its-live-data/cloud-experiments/h5cloud/atl03/average/repacked/ATL03_20191225111315_13680501_006_01.h5\",\n", + " # \"s3://its-live-data/cloud-experiments/h5cloud/atl03/big/repacked/ATL03_20190219140808_08110212_006_02_repacked.h5\",\n", "]\n", "h5py_cloud = H5pyArrMean('atl03-bigsize-repacked', files=cloud_optimized_granules, store_results=True)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "dfd4e404-0412-4d2f-8eba-ca39a670e369", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "h5py params: {'page_buf_size': 33554432, 'rdcc_nbytes': 1048576}\n", - "h5py params: {'page_buf_size': 33554432, 'rdcc_nbytes': 1048576}\n" - ] - }, - { - "data": { - "text/plain": [ - "[{'library': 'h5py',\n", - " 'format': 'original',\n", - " 'mean': 1032.9840463639412,\n", - " 'time': 51.46329092979431,\n", - " 'total_requested_bytes': 414028873,\n", - " 'total_requests': 12295,\n", - " 'avg_req_size': 33674},\n", - " {'library': 'h5py',\n", - " 'format': 'cloud',\n", - " 'mean': 1032.9840463639412,\n", - " 'time': 42.97014808654785,\n", - " 'total_requested_bytes': 560001136,\n", - " 'total_requests': 78,\n", - " 'avg_req_size': 7179501}]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# takes about ~30 seconds per granule out of region\n", "io_params ={\n", " \"fsspec_params\": {\n", " # \"skip_instance_cache\": True\n", " \"cache_type\": \"first\",\n", - " \"block_size\": 16*1024*1024\n", + " \"block_size\": 8*1024*1024\n", " },\n", " \"h5py_params\" : {\n", " \"page_buf_size\": 32*1024*1024,\n", @@ -168,80 +113,21 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, + "id": "3059ebd8-b110-49c5-9250-2a2cd009338f", + "metadata": {}, + "outputs": [], + "source": [ + "for run in range(5):\n", + " results = h5py_cloud.run(io_params)" + ] + }, + { + "cell_type": "code", + "execution_count": null, "id": "9d30d92b-4192-4da1-8b60-41cc94ca2db1", "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
libraryformatmeantimetotal_requested_bytestotal_requestsavg_req_size
0h5pyoriginal1032.98404651.4632914140288731229533674
1h5pycloud1032.98404642.970148560001136787179501
\n", - "
" - ], - "text/plain": [ - " library format mean time total_requested_bytes \\\n", - "0 h5py original 1032.984046 51.463291 414028873 \n", - "1 h5py cloud 1032.984046 42.970148 560001136 \n", - "\n", - " total_requests avg_req_size \n", - "0 12295 33674 \n", - "1 78 7179501 " - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "df = pd.DataFrame.from_dict(benchmarks)\n", "df" @@ -249,30 +135,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "3ff4c22f-7f77-4c69-a84c-f13b0fbba1f2", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0oAAAJhCAYAAAB/xkCsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMq0lEQVR4nOzdd3RU1d7G8WcmZdJDQhJC6E2KVEUQLIAQkGZHBUQUGwIiV68FUYpyQRERFRAVqQqiwouIgIRqoQtIsSDSe03vM/v9I2ZgJoUEAwnw/ayVtZh9ztnndyYhmWf2PnssxhgjAAAAAICTtbgLAAAAAICShqAEAAAAAG4ISgAAAADghqAEAAAAAG4ISgAAAADghqAEAAAAAG4ISgAAAADghqAEAAAAAG4ISgAAAADghqAEwOnHH3+UzWbTvn37nG233nqrBgwYUHxF/UuPPPKIAgICirTPESNGaN68eUXaZ1EYOnSoLBbLBR07c+ZMjR07tmgL+scHH3yg6tWry9vbWxaLRbGxsRflPMjfPffcI4vFon79+jnb9u7dK4vFUqCvvXv3auXKlbJYLPr666/Pe74vvvhCDRs2lI+Pj6KiojRgwAAlJia67LNlyxZ17NhRFStWlK+vr0JDQ9WsWTN99tlnF3yd2dc0derUC+7jYpg6darzefy3WrZsqbp16/77os4xYcKEXJ+zw4cPa+jQodqyZUuRng+4HBCUAEiSjDEaMGCAnnjiCVWqVMnZ/sYbb2jChAn6888/i7G6kqWkBqV/42IFpS1btqh///5q1aqVli9frjVr1igwMLDIz4P8HT9+XAsWLJAkff7550pNTZUklS1bVmvWrHH5atSokapWrZqjvWzZsgU+3+eff66uXbvqhhtu0KJFizRkyBBNnTpV99xzj8t+sbGxqlChgkaMGKGFCxdq+vTpqly5snr06KHhw4cX3RNQAnTs2LHQz+OllF9QGjZsGEEJVyXP4i4AQMmwePFibdq0STNnznRpb9GihWrWrKl33nlHH3/8cTFVh8vVjh07JElPPPGEmjRpUiR9Jicny8/P76LtfyWaPn26MjIy1LFjR3333XeaO3euunXrJpvNphtvvNFl36CgIKWnp+doLyi73a4XXnhBbdu21SeffCJJatWqlQIDA9W9e3ctWrRI7du3l5Q1MtKyZUuX4zt16qQ9e/bo448/1quvvnpBNZRE4eHhCg8PL+4ySoyUlBT5+Phc8Cg4cCkwogQUkexpT1u3blWXLl0UHBys0NBQPffcc8rMzNSff/6p22+/XYGBgapcubJGjRqVo4/4+Hj997//VZUqVeTt7a1y5cppwIABSkpKctlv/PjxuvXWWxURESF/f3/Vq1dPo0aNUkZGhst+2dMzNmzYoFtuuUV+fn6qWrWq3nzzTTkcDpd9P/zwQ91www2qWbNmjrp69OihmTNnKiEh4bzPw+nTp9WnTx+VK1dO3t7eqlq1qgYNGqS0tDSX/bKnAM2YMUO1a9eWn5+fGjRo4HzXOz/Z038+++wzPffcc4qMjJSvr69atGihzZs353rMrl271KFDBwUEBKhChQp6/vnnc9RUkNotFouSkpI0bdo055Skc1/obd++XXfeeadCQkLk4+Ojhg0batq0abnWP2vWLA0aNEhRUVEKCgpSmzZtCjxy991336lhw4ay2WyqUqWKRo8enet+BflZadmypb777jvt27fPZapVtmHDhqlp06YKDQ1VUFCQrrvuOn366acyxuRbY8uWLfXQQw9Jkpo2bSqLxaJHHnnEuX3y5Mlq0KCBfHx8FBoaqrvvvlu///67Sx/ZUye3bdumtm3bKjAwUK1bt87znNn/Dzdt2qT77rtPISEhqlatmrMe9xfl2eeoXLmy83H21K3Ro0drzJgxqlKligICAtSsWTOtXbvW5djdu3frwQcfVFRUlGw2m8qUKaPWrVsX6N33+fPnq1mzZvLz81NgYKCio6O1Zs2aXK9nx44d6tq1q4KDg1WmTBn16tVLcXFx5z1HtsmTJ6tMmTKaNm2afH19NXny5AIfW1hr167VkSNH9Oijj7q0d+nSRQEBAfq///u/8/YRFhYmT8+ifS/3r7/+Urdu3RQRESGbzabatWtr/PjxLvs4HA4NHz5cNWvWlK+vr0qVKqX69evrvffec+5z4sQJPfnkk6pQoYJsNpvCw8N10003aenSpfmeP7epd5s3b1anTp2cNUVFRaljx446ePBgga7pxx9/1I033ihfX1+VK1dOr732mux2u8s+6enpGj58uGrVquWs99FHH9WJEyec+1SuXFk7duzQqlWrnP//K1eurJUrV+qGG26QJD366KPObUOHDnUeu3HjRt1xxx0KDQ2Vj4+PGjVqpC+//DLXa1+yZIl69eql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X1Sfa8WKFbJarapateq/rsfPz0+tWrXS5s2bVb9+/Vx/v+b25kqpUqV03333qW/fvjp9+nSuHxRbsWJF9evXT9HR0fl+z8/HYrGoQYMGevfdd1WqVKkC9ZWQkKD58+e7tM2cOVNWq1W33nqrpKy/K6dOnZLdbs/1us8NMnn9Dshr9LJmzZqqUaOGfv3111z7bty4MZ+ZhsseI0pACTFgwADNmTNHt956q/7zn/+ofv36cjgc2r9/v5YsWaLnn39eTZs2VXR0tLy9vdW1a1e9+OKLSk1N1Ycffphjqk5hlC9fXlWrVtXatWvVv3//HNuz5++3atUq334efvhhjR8/Xj179tTevXtVr149/fTTTxoxYoQ6dOigNm3aXHCNuTl+/LjuvvtuPfHEE4qLi9OQIUPk4+OjgQMHFrqvwtRer149rVy5Ut9++63Kli2rwMBA1axZU0OGDNGCBQvUqlUrDR48WKGhofr888/13XffadSoUQoODi6S637jjTd0++23Kzo6Ws8//7zsdrveeust+fv7u4wKFuZnpV69epo7d64+/PBDXX/99bJarWrcuLE6duyoMWPGqFu3bnryySd16tQpjR492iV8FVapUqX02muv6ZVXXtHDDz+srl276tSpUxo2bJh8fHw0ZMiQC+47Pz169NBHH32khx56SE888YROnTqlUaNGFXpaX7atW7eqX79+6tKli2rUqCFvb28tX75cW7duzXc0wGq1atSoUerevbs6deqkp556SmlpaXr77bcVGxurN99880Iv0UX2aNKLL76Y62dYJSQkaNmyZfrss8/07LPPFqpv92XSs7Vo0ULh4eEaNWqUevTooaeeekpdu3bVX3/9pRdffFHR0dG6/fbbnfs/+eSTCgoKUpMmTVSmTBmdPHlSX331lWbPnq0XXnjBZTRp6tSpevTRRzVlypQc97edz3vvvaebb75Zt9xyi55++mlVrlxZCQkJ2rVrl7799lstX75cktS5c2fVrVtXjRs3Vnh4uPbt26exY8eqUqVKqlGjhuLi4tSqVSt169ZNtWrVUmBgoDZs2KDFixcXKACea8GCBZowYYLuuusuVa1aVcYYzZ07V7GxsYqOjj7v8aVLl9bTTz+t/fv365prrtHChQv1ySef6Omnn1bFihUlSQ8++KA+//xzdejQQc8++6yaNGkiLy8vHTx4UCtWrNCdd96pu+++W9LZ0a3Zs2eratWq8vHxUb169VStWjX5+vrq888/V+3atRUQEKCoqChFRUXpo48+Uvv27dWuXTs98sgjKleunE6fPq3ff/9dmzZt0ldffVWo5wQocYptGQngCpO9OtWJEydc2nv27Gn8/f1z7J/bylKJiYnm1VdfNTVr1jTe3t7O5Wz/85//mKNHjzr3+/bbb02DBg2Mj4+PKVeunHnhhRfMokWLjCSXZYnzWr3KfZUvY4x57bXXTEhIiElNTc2xf48ePUy9evUK8jSYU6dOmd69e5uyZcsaT09PU6lSJTNw4MAc/cptGdtslSpVynVFuXNlr7w1Y8YM079/fxMeHm5sNpu55ZZbzMaNG3Nca27Pf/b360Jq37Jli7npppuMn5+fkeSyUtS2bdtM586dTXBwsPH29jYNGjTIsVpUXiuH5bZaV17mz59v6tevb7y9vU3FihXNm2++mes1FfRn5fTp0+a+++4zpUqVMhaLxaWfyZMnm5o1axqbzWaqVq1qRo4caT799FOXFbzyktuqd9kmTZrkvIbg4GBz55135lhSOq/vX17y+n+Ybdq0aaZ27drGx8fH1KlTx8yePTvPVe/efvvtHMdLMkOGDDHGGHPs2DHzyCOPmFq1ahl/f38TEBBg6tevb959990CLXs8b94807RpU+Pj42P8/f1N69atzc8//1yg63FfQc1denq6iYiIyHcFt8zMTFO+fPkc/7cLsupdXl/n/kzNnDnT+f2NjIw0/fv3NwkJCS79TZ482dxyyy0mLCzMeHp6mlKlSpkWLVqYGTNm5Dj3Bx98YCSZxYsX53lNxuT9/2jPnj2mV69eply5csbLy8uEh4eb5s2bm+HDhzv3eeedd0zz5s1NWFiY8//WY489Zvbu3WuMMSY1NdX07t3b1K9f3wQFBRlfX19Ts2ZNM2TIEJOUlJRvXe7fsz/++MN07drVVKtWzfj6+prg4GDTpEkTM3Xq1Hz7Mebs92jlypWmcePGxmazmbJly5pXXnklxwp0GRkZZvTo0c7fAwEBAaZWrVrmqaeeMn/99Zdzv71795q2bduawMBA5xL72WbNmmVq1aplvLy8XP4PGGPMr7/+au6//34TERFhvLy8TGRkpLnttttclnfP7/cAUJJZjDnPJwYCuCocPnxYVapU0fTp0/XAAw842+Pj4xUVFaV3331XTzzxRDFWeNbKlSvVqlUrffXVVzlWqQNwZbr//vu1Z88ebdiwobhLAXCV4B4lAJKyVtsaMGCA/ve//7ksGfzuu++qYsWKevTRR4uxOgBXM2OMVq5cqf/973/FXQqAqwj3KAFwevXVV+Xn56dDhw45PwsoKChIU6dOlacnvy4AFA+LxXJBn9kFAP8GU+8AAAAAwA1T7wAAAADADUEJAAAAANwQlAAAAADAzRV/d7bD4dDhw4cVGBjo/JR6AAAAAFcfY4wSEhIUFRUlqzX/MaMrPigdPnzYuXoXAAAAABw4cEDly5fPd58rPigFBgZKynoygoKCirkaAAAAAMUlPj5eFSpUcGaE/FzxQSl7ul1QUBBBCQAAAECBbslhMQcAAAAAcENQAgAAAAA3BCUAAAAAcENQAgAAAAA3BCUAAIASauXKlbJYLLl+rV271rnfTz/9pMcff1zXX3+9bDabLBaL9u7de0HnTElJ0TXXXCOLxaLRo0fnus/27dvVpUsXhYeHy2azqXLlyurTp88FnQ8oqa74Ve8AAAAudyNGjFCrVq1c2urWrev897Jly7R06VI1atRIQUFBWrly5QWf67XXXlNSUlKe21esWKGOHTvqlltu0cSJExUWFqb9+/dr8+bNF3xOoCQiKAEAAJRwNWrU0I033pjn9tdee01DhgyRJI0ePfqCg9L69ev1wQcf6PPPP1eXLl1ybE9OTlb37t1122236dtvv3VZYrlHjx4XdE6gpGLqHQAAwGXOav33L+nS09PVq1cv9e3bV40bN851n6+++kpHjhzRCy+8UKDPoQEuZwQlAACAEq5v377y9PRUUFCQ2rVrp59++qnIz/H6668rKSlJb7zxRp77/PDDD5Iku92um2++Wd7e3goJCVHXrl11+PDhIq8JKE4EJQAAgBIqODhYzz77rD766COtWLFC7733ng4cOKCWLVvq+++/L7LzbNmyRaNGjdLEiRPl7++f536HDh2SJN1777266aab9P333+vNN99UTEyMWrRooeTk5CKrCShu3KMEAABQQjVq1EiNGjVyPr7lllt09913q169enrxxRfVrl27f32OzMxM9erVSw888MB5+3M4HJKkBx54QG+99ZYkqVWrVoqMjNRdd92lmTNn6vHHH//XNQElASNKAAAAl5FSpUqpU6dO2rp1q1JSUv51f2PHjtXu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AADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADADUEJAAAAANwQlAAAAADATaGD0rRp0/Tdd985H7/44osqVaqUmjdvrn379hVpcQAAAABQHAodlEaMGCFfX19J0po1azRu3DiNGjVKYWFh+s9//lPkBQIAAADApeZZ2AMOHDig6tWrS5LmzZun++67T08++aRuuukmtWzZsqjrAwAAAIBLrtAjSgEBATp16pQkacmSJWrTpo0kycfHRykpKUVbHQAAAAAUg0KPKEVHR+vxxx9Xo0aNtHPnTnXs2FGStGPHDlWuXLmo6wMAAACAS67QI0rjx49Xs2bNdOLECc2ZM0elS5eWJP3yyy/q2rVrkRcIAAAAAJdaoUeUSpUqpXHjxuVoHzZsWJEUBAAAAADFrUBBaevWrQXusH79+hdcDAAAAACUBAUKSg0bNpTFYpExRhaLJd997XZ7kRQGAAAAAMWlQPco7dmzR7t379aePXs0Z84cValSRRMmTNDmzZu1efNmTZgwQdWqVdOcOXMudr0AAAAAcNEVaESpUqVKzn936dJF77//vjp06OBsq1+/vipUqKDXXntNd911V5EXCQAAAACXUqFXvdu2bZuqVKmSo71KlSr67bffiqQoAAAAAChOhV71rnbt2ho+fLg+/fRT+fj4SJLS0tI0fPhw1a5du8gLBAAAcNdwYqIkKd0u7TzlUN2IrPd+a4ZZNfs+vxz7bzlq185TDt1/rdd5+165N1P/XZKqjU8G5Ng2dGWqJmzIUFSgRel2qXqoVZ909lGZgEK/95ynymMT5ONpkY+nlGaXGkVa9UlnX/l753+f+NQt6WpewUPXlPYoslqSM4xumpykHx7xV6DNopZTk7T6gF0HnwtQhH/WNe8+41D19xN1T21PfX2/n/bGZj3O/p6k2aXu9bz06q02SdIH69KVmG408Bbbec+flG502/QkpWZmPS4bYNHETr6qXCqr78W7MvXq8lSl2yU/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8YeqVq0qb29v5+/6/fv3a9q0aRoyZIjGjh2r/v37O/dPTk7WxIkTNW/ePK1atYrV7YAiRlACLoEZM2Y43ynMng7xn//8R7t379Y333zjXBJ8y5Yt6tevn6655hpNnjw5Rz+EJAC48k2YMEFjx47Vtm3bZLPZdPjwYX300UcaM2aMRo4cqX79+jn3TU1Nlc1mc65uR1gCig53+AEX2cyZMzVkyBANHjzYZc64h4eHkpOTnTftOhwONWzYUH369NHMmTN16NChHH0RkgDgymO3210e33DDDcrMzNRtt92mtLQ0RUVF6cknn9Rzzz2nQYMGacKECc59fXx8CEnARUJQAi6yzp07q3v37lq1apVeffVVZWRkSJKaNWumZcuWae7cubJYLM77lkqVKqW6devKZrMVZ9kAgEsk+02wbdu2ScoKSnPnztWJEyd06623Ki0tTeXKlXOGpX79+mnOnDkufRCSgKLH1DvgIsqeKpeYmKiRI0dq6dKlatGihYYPHy5vb289//zzmjBhgj788EPdeOONKlWqlB555BEZY7R48WL+8AHAFezcFVDXrFmjm266STNnztSDDz4oSdq8ebMeeOABhYSE6IcffpDNZtP+/fsVExOjnj17smADcJERlICLxP3zK5KSkjRy5EjFxMSoRYsWGjFihDw9PfXaa69p7NixCgoKUmBgoAICArRmzRp5eXnxGRgAcIU6d6rc+++/L7vdrueff17BwcF6//331aNHD0lZYalr164KDQ3VihUrXGYbsAQ4cHERlICL4NyAM2nSJAUFBalLly5KTk7WiBEjtHTpUrVq1UpvvPGGvLy8tHHjRsXFxSkjI0PR0dHy8PDgDyAAXAUGDx6siRMnaty4cTp9+rTWrFmjWbNmadKkSXr44YclSVu2bFHLli3VpUsXffLJJ8VcMXD14FUYcBFkh6QXX3xRM2bM0EsvvaQTJ04oIiJCAwcOlMViUUxMjAYNGqT//e9/aty4scvxdrudkAQAV5gjR46obNmyzsenTp3S/Pnz9frrr+v++++XJD322GOKiIjQ448/Lk9PT3Xr1k0NGzbU+vXrVa1ateIqHbgqMacHuEimTp2q6dOna9GiRXr22WcVEREhh8OhgIAAvfzyy4qOjtZPP/2k/v3751jxiNXtAODK0qZNG40ePdqlLS0tTQcPHlRgYKCkrNkInp6e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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", From 2e47c3044e1f4353354d2a1dbb5716ae85632d7a Mon Sep 17 00:00:00 2001 From: betolink Date: Sun, 18 Feb 2024 23:26:48 -0600 Subject: [PATCH 06/11] update environment --- environment.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/environment.yml b/environment.yml index 0c9d76a..555ab7f 100644 --- a/environment.yml +++ b/environment.yml @@ -10,14 +10,14 @@ dependencies: - numpy - s3fs - xarray - - fsspec - dask - distributed - geopandas - - h5py>3.9 + - h5py>=3.10 - zarr - kerchunk - h5netcdf - pip - pip: - - h5coro + - git+https://github.com/betolink/filesystem_spec.git + - git+https://github.com/ICESat2-SlideRule/h5coro.git From d7e8aae1040cca3f2c2f3705fe7272b8b9dc675d Mon Sep 17 00:00:00 2001 From: Andy Barrett Date: Wed, 28 Feb 2024 17:51:53 +0000 Subject: [PATCH 07/11] Add plot --- notebooks/access_time.summary.png | Bin 0 -> 49179 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 notebooks/access_time.summary.png diff --git a/notebooks/access_time.summary.png b/notebooks/access_time.summary.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c3e4e00e52afc123b6eba137434eada48d9a7a GIT binary patch literal 49179 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%0AgLSHck0!=G=_b87e*X>{pkMXXsnRqu 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 Date: Wed, 28 Feb 2024 17:52:44 +0000 Subject: [PATCH 08/11] Add benchmarks summary csv Saves results of experiments to results --- notebooks/benchmarks.csv | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 notebooks/benchmarks.csv diff --git a/notebooks/benchmarks.csv b/notebooks/benchmarks.csv new file mode 100644 index 0000000..bda4468 --- /dev/null +++ b/notebooks/benchmarks.csv @@ -0,0 +1,47 @@ +,tool,dataset,cloud-aware,format,file,time,mean,size,product +0,h5py,ATL03-1GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5,2.843794107437134,386.06738,1GB,ATL03 +1,h5py,ATL03-1GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5,4.157144546508789,386.06738,1GB,ATL03 +2,h5py,ATL03-7GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5,6.9494102001190186,1035.1631,7GB,ATL03 +3,h5py,ATL03-7GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5,13.6586012840271,1035.1631,7GB,ATL03 +4,h5py,ATL03-2GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5,1.4053022861480713,2049.7554,2GB,ATL03 +5,h5py,ATL03-2GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5,1.0851728916168213,2049.7554,2GB,ATL03 +6,kerchunk,ATL03-7GB-kerchunk,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json,10.746918678283691," +array(1035.1631, dtype=float32)",7GB,ATL03 +7,kerchunk,ATL03-7GB-kerchunk,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json,8.8134024143219," +array(1035.1631, dtype=float32)",7GB,ATL03 +8,xarray,ATL03-1GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5,46.50308704376221," +array(386.06738, dtype=float32)",1GB,ATL03 +9,xarray,ATL03-1GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5,10.25867509841919," +array(386.06738, dtype=float32)",1GB,ATL03 +10,xarray,ATL03-7GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5,62.89623713493347," +array(1035.1631, dtype=float32)",7GB,ATL03 +11,xarray,ATL03-7GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5,81.67518210411072," +array(1035.1631, dtype=float32)",7GB,ATL03 +12,xarray,ATL03-2GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5,47.506706953048706," +array(2049.7554, dtype=float32)",2GB,ATL03 +13,xarray,ATL03-2GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5,18.109654188156128," +array(2049.7554, dtype=float32)",2GB,ATL03 +14,h5coro,ATL03-1GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5,4.562052011489868,386.06738,1GB,ATL03 +15,h5coro,ATL03-1GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5,4.286046743392944,386.06738,1GB,ATL03 +16,h5coro,ATL03-7GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5,14.072925567626953,1035.1631,7GB,ATL03 +17,h5coro,ATL03-7GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5,11.79448390007019,1035.1631,7GB,ATL03 +18,h5coro,ATL03-2GB,no,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5,3.1101267337799072,2049.7554,2GB,ATL03 +19,h5coro,ATL03-2GB,no,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5,1.8120653629302979,2049.7554,2GB,ATL03 +20,h5py,ATL03-1GB,yes,original,s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5,1.8618409633636475,386.06738,1GB,ATL03 +21,h5py,ATL03-1GB,yes,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5,1.9302234649658203,386.06738,1GB,ATL03 +22,h5py,ATL03-7GB,yes,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5,6.602761507034302,1035.1631,7GB,ATL03 +23,h5py,ATL03-7GB,yes,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5,5.758350849151611,1035.1631,7GB,ATL03 +24,h5py,ATL03-2GB,yes,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5,1.2604756355285645,2049.7554,2GB,ATL03 +25,h5py,ATL03-2GB,yes,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5,0.8633284568786621,2049.7554,2GB,ATL03 +26,xarray,ATL03-1GB,yes,original,s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5,42.18248891830444," +array(386.06738, dtype=float32)",1GB,ATL03 +27,xarray,ATL03-1GB,yes,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5,2.5429904460906982," +array(386.06738, dtype=float32)",1GB,ATL03 +28,xarray,ATL03-7GB,yes,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5,48.71459078788757," +array(1035.1631, dtype=float32)",7GB,ATL03 +29,xarray,ATL03-7GB,yes,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5,6.6719231605529785," +array(1035.1631, dtype=float32)",7GB,ATL03 +30,xarray,ATL03-2GB,yes,original,s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5,40.31614112854004," +array(2049.7554, dtype=float32)",2GB,ATL03 +31,xarray,ATL03-2GB,yes,optimized,s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5,2.156572103500366," +array(2049.7554, dtype=float32)",2GB,ATL03 From d7b57b16ee8a06effe1cfc061a6a251ad51fff98 Mon Sep 17 00:00:00 2001 From: Andy Barrett Date: Wed, 28 Feb 2024 19:54:28 +0000 Subject: [PATCH 09/11] Create dedicated notebook to plot results Copied plotting from portable-full-comparison --- notebooks/plot_benchmark_results.ipynb | 449 +++++++++++++++++++++++++ 1 file changed, 449 insertions(+) create mode 100644 notebooks/plot_benchmark_results.ipynb diff --git a/notebooks/plot_benchmark_results.ipynb b/notebooks/plot_benchmark_results.ipynb new file mode 100644 index 0000000..a2195b3 --- /dev/null +++ b/notebooks/plot_benchmark_results.ipynb @@ -0,0 +1,449 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e2d85d97-bd23-4af1-b302-1ab55921a30b", + "metadata": { + "user_expressions": [] + }, + "source": [ + "# Plot Benchmarking Results\n", + "\n", + "Plots the results in `benchmarks.csv`" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "a7c05ac8-7256-42f7-a351-4b498da62ffc", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import re\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "id": "7804d7bc-a01e-46bb-807b-fb5081616d8f", + "metadata": { + "user_expressions": [] + }, + "source": [ + "## Read `benchmarks.csv`\n", + "\n", + "This file is generated using [portable-full-comparison.ipynb](https://hub.cryointhecloud.com/hub/user-redirect/lab/tree/h5cloud/notebooks/portable-full-comparison.ipynb)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1fa7d33b-ef5f-419d-a0a6-8213e075ede5", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
tooldatasetcloud-awareformatfiletimemeansizeproduct
0h5pyATL03-1GBnooriginals3://nasa-cryo-persistent/h5cloud/atl03/averag...2.843794386.067381GBATL03
1h5pyATL03-1GBnooptimizeds3://nasa-cryo-persistent/h5cloud/atl03/averag...4.157145386.067381GBATL03
2h5pyATL03-7GBnooriginals3://nasa-cryo-persistent/h5cloud/atl03/big/or...6.9494101035.16317GBATL03
3h5pyATL03-7GBnooptimizeds3://nasa-cryo-persistent/h5cloud/atl03/big/re...13.6586011035.16317GBATL03
4h5pyATL03-2GBnooriginals3://nasa-cryo-persistent/h5cloud/atl03/big/or...1.4053022049.75542GBATL03
\n", + "
" + ], + "text/plain": [ + " tool dataset cloud-aware format \\\n", + "0 h5py ATL03-1GB no original \n", + "1 h5py ATL03-1GB no optimized \n", + "2 h5py ATL03-7GB no original \n", + "3 h5py ATL03-7GB no optimized \n", + "4 h5py ATL03-2GB no original \n", + "\n", + " file time mean \\\n", + "0 s3://nasa-cryo-persistent/h5cloud/atl03/averag... 2.843794 386.06738 \n", + "1 s3://nasa-cryo-persistent/h5cloud/atl03/averag... 4.157145 386.06738 \n", + "2 s3://nasa-cryo-persistent/h5cloud/atl03/big/or... 6.949410 1035.1631 \n", + "3 s3://nasa-cryo-persistent/h5cloud/atl03/big/re... 13.658601 1035.1631 \n", + "4 s3://nasa-cryo-persistent/h5cloud/atl03/big/or... 1.405302 2049.7554 \n", + "\n", + " size product \n", + "0 1GB ATL03 \n", + "1 1GB ATL03 \n", + "2 7GB ATL03 \n", + "3 7GB ATL03 \n", + "4 2GB ATL03 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv(\"benchmarks.csv\", index_col=0)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "8e4e2660-437b-48f7-896f-795e93ae1644", + "metadata": { + "user_expressions": [] + }, + "source": [ + "## Reformat data for plotting" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "5c69cca4-430f-4552-b9e7-88bd07deea33", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
formatoptimizedoriginal
cloud-awarenoyesnoyes
toolsize
h5coro1GB4.286047NaN4.562052NaN
2GB1.812065NaN3.110127NaN
7GB11.794484NaN14.072926NaN
h5py1GB4.1571451.9302232.8437941.861841
2GB1.0851730.8633281.4053021.260476
7GB13.6586015.7583516.9494106.602762
kerchunk7GB8.813402NaN10.746919NaN
xarray1GB10.2586752.54299046.50308742.182489
2GB18.1096542.15657247.50670740.316141
7GB81.6751826.67192362.89623748.714591
\n", + "
" + ], + "text/plain": [ + "format optimized original \n", + "cloud-aware no yes no yes\n", + "tool size \n", + "h5coro 1GB 4.286047 NaN 4.562052 NaN\n", + " 2GB 1.812065 NaN 3.110127 NaN\n", + " 7GB 11.794484 NaN 14.072926 NaN\n", + "h5py 1GB 4.157145 1.930223 2.843794 1.861841\n", + " 2GB 1.085173 0.863328 1.405302 1.260476\n", + " 7GB 13.658601 5.758351 6.949410 6.602762\n", + "kerchunk 7GB 8.813402 NaN 10.746919 NaN\n", + "xarray 1GB 10.258675 2.542990 46.503087 42.182489\n", + " 2GB 18.109654 2.156572 47.506707 40.316141\n", + " 7GB 81.675182 6.671923 62.896237 48.714591" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pivot_df = df.pivot_table(index=[\"tool\", \"size\"], columns=[\"format\", \"cloud-aware\"], values=\"time\", aggfunc=\"mean\")\n", + "pivot_df" + ] + }, + { + "cell_type": "markdown", + "id": "97f6a3dc-e5eb-46e7-ac46-611a08143d07", + "metadata": { + "user_expressions": [] + }, + "source": [ + "## Plot results" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "33602bbd-41c0-4133-bab5-76f45e9fe1a5", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "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u7cGDBhgt+78+fOSsm6qm/1Gt44kJiYqICDA1g+59VflypULXCMAIEupDedXr16tF154QWazWc2bN1f79u114cIF7dq1Szt27NCYMWP04osv2u0zffp0zZ07V56enurUqZNSU1MVFhambdu2acaMGerevXsxPRoAAAAAAJAfDRo00MGDBxUVFaUHHnggz22joqIkSXXq1LnpzWOt8nNFfkk1f/58/fbbb2rRooUmTJiQY31mZqYkqUaNGmrWrFmex3J3d7f7/car5gEAhVcqw/mMjAxNmTJFZrNZH330kXr37m1bFx4erscff1xffvml/v73v6tWrVqSpO3bt2vu3Lny8/PT4sWLVadOHdv2w4cP18SJE9W+fXv5+voWx0MCAAAAAAD50L59e61YsUKbNm3S2LFj8wzd169fb9vnRrGxsapXr16O5RcuXJAkVapUyUUVF40tW7YoNDRUVapU0dtvv50jXJf+ukq/bt26N73RrFXFihUl/XXV/Y2s/QUAKDhjcRfgjJiYGMXFxalevXp2wbwktW7dWvfee68sFosOHjxoWx4aGipJGjt2rC2Yt24/aNAgXb16VcuWLSuS+gEAAAAAgHM6dOigmjVr6tKlS1q0aFGu2+3bt0+bNm2Su7u7+vbtm2P9b7/9lmPZiRMndOzYMXl5edkF99ag23rleUkTHR2tqVOnqkyZMnr33XcdzicvSY0bN5a3t7fCw8N1/fr1fB27RYsWkqTNmzfn+FZBRkaGNm3aVKjaAeBOVirD+fzeLd16MkpNTdX27dslyeFc9NZlGzZscE2BAAAAAADgljAajXrllVdkMpkUGhqqRYsW5QjNd+7cqUmTJsliseipp56y3Xw1u+XLl+vo0aO235OTkzVz5kxZLBb16tXLLnuwXj1+6tSpW/SonBcfH69XX31VqampevXVV9WwYcNct/Xw8NDAgQN17do1vfHGGw6vho+Ojrb74KJ169aqWbOmTp48qcWLF9ttu2DBAsXGxrruwQDAHaZUTmtTs2ZN1axZUzExMfr5559zTGuzdetW1ahRQ23btpWUdaV9Wlqa/P39VaVKlRzHa9q0qaS/5qIDAAAAAKC0aejtWdwl5MrVtTVr1kxTp07VlClT9MUXX2jp0qVq2rSpPDw8FBMToxMnTshoNGrUqFF67LHHHB6je/fuGjt2rFq3bi0fHx/t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ogoVKmj//v1auXKl3bply5bp8OHDCggIuOnUIrdSQECAevbsqdOnT2vatGkO51Y/ePCgduzYYfs9JCRE5cuX1++//64NGzbYlmdmZurTTz+1zWdeWP369ZOUNe1T9ivKk5KSNGPGDFksFj300EMOv22Sl/nz59sFyPHx8fr8888lSY888ohtufVGw1u2bLHrl6tXr+r999+33Ri2oGrUqKFr167l+JBg6dKlCg8Pd+qYBTVixAgZjUZNnz7dduPi7C5duqTly5fbLbvZ63T48OEym8164403HIbmZ86c0c8//1ygOn/44QeHYf/OnTslueb+Bs5gWhsAAAAAAFCqNGvWTFOnTtWUKVP0xRdfaOnSpWratKk8PDwUExOjEydOyGg0atSoUXrsscdyPU737t01duxYtW7dWj4+Ptq3b5/i4uJUp04djRw50m7bjh07av78+frf//6n3bt3y9fXV5L09NNP234uLj/++KNiY2Pl7++vrVu3avPmzTm2adGihR588EFJ0rBhw3TixAmtX79ew4cPV6NGjVS5cmUlJCTo3LlzOnfunDp16qQuXbpI+usDkRdeeEGfffaZ1q9fr1q1aun48eM6efKk+vTpo1WrVhW47latWungwYNKS0vLMae8dd55qWBT2lStWlX169dXVFSUnnnmGdWpU0dGo1GdOnVSp06dClxjSVG2bFlNmjRJr776qv7zn/9o5cqVtg9Mjh49Kk9PT73++utFNr98bv75z3/q3LlzWr9+vbZv364GDRqoYsWKiouL05kzZ3Tp0iU9+uij6tChg6SsecD/7//+T5MnT9bkyZO1bNkyBQYG6o8//lBCQoK6deuW67cFCiIkJEQPPfSQVq5cqZEjR6p169by9PRURESE4uPj1bRp0xyv+ZsJDAxUvXr1NHLkSLVp00Ymk0l79+7VtWvX1Lp1a9sHAlLWN1batm2r3bt3a9iwYXZTN/n6+qpTp07atm1bgR/X0KFDbe+FK1asUEBAgKKjo3Xy5Ek99thjWrp0aYGPWVCtWrXSc889p1mzZumf//yn6tevr+rVqystLU2xsbE6ceKEypYta9cfN3s/feCBB3T8+HF98803evLJJ9WwYUNVrVpV169fV2xsrE6ePKn69eurd+/e+a7zxx9/1EcffaQ6deqoVq1acnNz06lTp3Ts2DGVKVPGdgV9USOc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V16RyWRSaGioFi1apMzMTLttdu7cqUmTJsliseipp55S1apVC93uQw89JCkrX7h8+bJt+YULFzR//vxCH/9matSoIemv3MNq48aNWrt27S1vHwDgeqXyyvncJCUl6bfffpMkPfzww7blqamp2r59uySpZ8+eOfbr2bOnFixYoA0bNmjUqFFFUywAAAAAAC5kquxV3CXkytW1NWvWTFOnTtWUKVP0xRdfaOnSpWratKk8PDwUExOjEydOyGg0atSoUXrsscdc0uYDDzygTZs2KSwsTCNGjFCbNm1kNpu1d+9etW7dWmaz2S60d7XBgwdr165d+uKLL7Rx40bVrFlTp0+fVlRUlAYOHKjFixffsrYBALfGbRXO//LLL0pKSlLTpk3VsGFD2/KYmBilpaXJ399fVapUybFf06ZNJf11oxgAAAAAAEoLs9ksc6ZZFQc1Lu5S8mTONMtsNrvseHfffbe+/vprfffdd9q+fbvCw8OVkZGhihUrqk+fPurfv7/q16/vsvYMBoMmT56sb775RmvWrNGOHTtUsWJFDRgwQMOGDdODDz6o8uXLu6y9GwUHB+vjjz/WnDlzdPToUZ0+fVr16tXTlClT1LBhQ8J5ACiFbqtwfuXKlZKkRx55xG659cYojoJ5SfLy8lL58uWVkJCga9euycfH59YWCgAAAACAi5jNZl28dNFuateSyGx2bTgvSX5+fnryySf15JNP5nufm4XYVatWzXUOd3d3d40YMSLHPPeRkZFKT09XgwYN8nWsXr16qVevXrnWMGPGDIfLmzVrpg8//NDhOmfaAQAUr9smnL948aK2b98uNzc39enTx25dUlKSJMnT0zPX/cuWLavExEQlJSU5Fc4bDIYC73M7s/YH/YKCYNzAGYwbx7L3h8FgoH9uwLiBsxg7pYOrn5/Cvo8ybhzjXJW3go6bWxF8I6eYmBjVqlVLJtNfccq5c+f00UcfSZK6detWXKUBcLEbz1OA1c3+binIeLltwvmffvpJmZmZuu+++xQQEGC3zmKxSMq7Y6zbOCMwMFDe3t5O7387CwwMLO4SUAoxbuAMxo2969ev237mPJU7xg2cxdi5s1SqVMklx2Hc2ONclT+VKlVSQkKC3N3d5e7uXtzl3PE+//xzHT58WA0aNFCFChV04cIFHT58WGlpabrnnnvUu3fvEhHiMVbgDMaNvew3mjaZTHJzcyvGakq2O2nsuLm5KSAgIM+LwLP/jXMzt004b71b+Y1T2kiy/ZGXnJyc6/4pKSmSsqa4KajY2Fin9rudGQwGBQYGKjY2tlAffODOwriBMxg3jlm/NSZxnnKEcQNnMXZKB5PJ5LJAXZIuXbqkjIwMp/dn3DjGuSpv1nFz6dIlZWZmKj09vbhLgrJuCpuZmamYmBjt379fJpNJ9erVU9euXdWvX79CvVe4iru7O+MFBca4ySn7t5EyMjL4dlIu7qSxk56erszMTF28eDHPDySy/41zM7dFOB8dHa3IyEh5eXk5/ApZtWrVJEnnz593uH9SUpISExNVvnx5p+eb549sxywWC32DAmPcwBmMG3vZ+4K+yR19A2cxdko2Vz83rnq+GTf2OFflD/1SsnTt2lVdu3Yt7jIAFIEbz1OA1c3+binIeCnZd4vJpx9++EFS1ifYZcuWzbG+bt268vDwUFxcnMOAPjIyUpIUFBR0awsFAAAAAAAAAEC3QThvsVj0008/SXI8pY2UdSPYDh06SJLWrFmTY711WUhIyK0pEgAAAAAAAACAbEp9OL97926dOXNGlStXtgXwjowcOVKS9Omnn+rPP/+0LQ8PD9fixYvl4+OjAQMG3OpyAQAAAAAAAAAo/XPOW28E+9BDD8lozP2zho4dO2rEiBGaP3+++vbtq44dOyo9PV1hYWEym8364IMP5OfnV0RVAwAAAAAAAADuZKU6nE9LS9PatWslSQ8//PBNt3/ttdfUpEkTLVy4UGFhYTKZTOrQoYPGjh2rtm3b3upyAQAAAAAAAACQVMrDeQ8PD+3atatA+/Tv31/9+/e/RRUBAAAAAAAAAHBzpX7OeQAAAAAAAAAAShvCeQAAAAAAAAAAihjhPAAAAAAAAAAARYxwHgAAAACAUs5oNMpkMpXo/4xG10cQ8fHxmjNnjp588kn16dNHPXr00JAhQ/TBBx8oJibG6eOeO3dOISEhGj9+fKFrdOWxnLF69WqFhIQoNDS0SNsdOHCgQkJCCrxfSEiIBg4c6JIaXN33mZmZ+uqrrzRkyBB169ZNISEhmj59ukuOXRo5M7Zc+fwCt4NSfUNYAAAAAADudEajUQEVK8poKtn/xDdnZOji5csym80uOd7u3bv11ltv6dq1a/Lz81OrVq3k7u6umJgY/fTTT/r55581evRoDR061CXtofDOnTunwYMHKzg4WDNmzCjucgps2bJlmj9/vipVqqT77rtPHh4eatGiRXGXBbhUaGio5s2bp5dfflm9evUq7nJueyX7zA0AAAAAAPJkNBplNJl05sWXlFaIq8VvJY969VT9g/dlNBpdEs4fPnxYEydOVEZGhsaMGaOBAwfKlO3DiR07dmjq1KmaPXu2PD099eijjxbo+AEBAZo3b548PT0LXasrj1WafPjhh8rIyCjWGlzd91u3bpUkzZw5U9WqVXPJMe808+bNs3utAnc6Xg0AAAAAANwG0mJilBIZWdxl3HIWi0XTp09Xenq6Ro0a5fDK+A4dOuidd97R888/r88//1ydOnVSlSpV8t2GyWRS7dq1XVKvK49VmlSvXr24S3B531+8eFGSCOYL4U58LQB5IZwHAAAAAAClxs6dO3XixAlVqlRJQ4YMyXW74OBghYSEaMOGDVqxYoWeeeYZ27qBAwcqNjZWGzZs0PLly7Vq1SqdPn1aNWrU0Jw5c/KcfiUjI0PffPONVq9erYsXL6pSpUp64IEHNHz4cA0dOlSxsbHauHGjbfvcjrV69Wq99957evzxx9W7d2998cUX2r17t5KTk1WnTh098cQT6tixo13bFotFv/32m7Zu3aqjR4/q0qVLMhgMql27tnr27KmHH364kL2b1TdXrlzRypUrVaZMGdvy//73v1qxYoWqVKmib7/91m6fV155RTt27FBoaKjq1q1r18fWvrBOlSFJ+/bts5uPvkePHpo4caLdMTMzM7VkyRKtWrVKsbGx8vPzU7du3TRy5Eh5eHjk67G4qu+nT5+utWvX2n7PXvs333yjqlWrSpIuXLigBQsWaNeuXYqLi5O3t7datGihoUOHqnHjxrnWNm3aNM2bN0+bN2/WxYsX1bdvX/3jH/+w68Ply5frhx9+0NmzZ+Xv769HHnlEgwYNksFg0JEjR/TVV1/p0KFDysjIUJs2bfSPf/zD4QdSFotFa9eu1c8//6zo6Gilp6erRo0a6tWrl/r16+fwqvbo6GjNnj1bBw4ckCQ1btxYo0aNytdzcKOQkBAFBgZq8eLFOdbt2LFDS5cuVVRUlFJTU1WlShXde++9GjJkiMqVK5fvNrK/vpctW6aVK1fq7Nmz8vX1VefOnTVy5Mgcx7t8+bJ++eUX7dixQ2fOnFF8fLzKlSunmjVrqlu3bmrevHme7Th6H8nP6/XGe3Fkn1KmXr16mjNnjg4dOiSj0ai77rpLzz77rCpXrqzk5GTNnTtXGzduVFxcnKpXr64nnngi1/s8xMTEaNGiRYqIiFBCQoLKly+vdu3a6fHHH7eN3+yPSZLee+89vffee7Z1H330kVq3bm37ff/+/VqyZIkOHjyo69evy9/fX506ddKIESPk5+dn1771NfTRRx8pPT1dixYt0tGjR3X9+nWtXLlS5cqV04ULF7Ro0SLt2bNHFy5ckIeHhypWrKgWLVroscceU61atfL1/Jc2hPMAAAAAAKDU2LFjh6SskO9m02N07dpVGzZs0M6dO+3CeasPP/xQq1evVnBwsGrVqnXTaVgsFovefPNNbdu2TV5eXrr77rtlsVi0ZMkSHTt2zKnHc/78eT3zzDO2+cuvXLmiQ4cOadKkSXrvvffUrl0727ZpaWl6++23Va5cOdWuXVsNGzZUQkKCIiMj9d///ld//PGH3njjDafqsGrVqpXWrl2ryMhIuyAuIiLCVu+5c+dsgV5mZqYOHDggX19f1alTJ9fjNmjQQJ07d9bmzZtVoUIFtW/f3rbO0bzt77zzjrZv364mTZqoZs2a2r9/v7755htdvHhRkyZNKtRjtMpv31vr27Rpk1JSUtSjRw/bMcqWLSspK/ycMGGCEhISVKtWLd133326cOGCtmzZorCwML3++usOg9O0tDSNHz9esbGxCg4OVqNGjXIEx7NmzdKPP/6opk2bqmrVqtq3b58+//xzpaSkqG3btnrppZdUpUoVtW7dWtHR0dq2bZuOHz+u0NBQuw9YzGazpkyZoo0bN8rb21tBQUEqW7as/vjjD33yySfas2ePpk2bZhcYR0ZG6oUXXlBKSooaNGigWrVq6fjx4xo/frx69uzpkudBkr7++mvNnj1bbm5uCg4Olq+vrw4ePKhvvvlGW7du1YwZM+Tv71+gY86YMUM//fSTWrVqpXr16ikiIkLff/+99u3bp48//lheXl62bbdu3arPP/9c1atXV926deXt7a3Tp09r//79OnTokAIDA3X33Xc7bCe395H8vF5v/FDK6o8//tCHH36o6tWr66677lJ0dLQ2btyo6Ohoffrpp3rxxRd19uxZNWvWzDYmJk+eLC8vL7vXlpQ1bt955x2lp6erUaNGatasmc6ePas1a9YoLCxMM2bMsH2odv/992vPnj2Kjo5W8+bN7b4Bk73/ly1bplmzZslgMKhp06aqWLGijh8/ru+//17bt2/XrFmzVLFixRyPa/369Vq1apWCgoJ099136+zZszIYDLpw4YLGjBmjhIQE1a9fXx07dlRaWprOnz+vn376SU2bNiWcBwAAAAAAKG7WELxRo0Y33da6zYkTJ5SRkZEjzN+8ebNmz55tC6ZuZt26ddq2bZuqV6+umTNn2sKnCxcu6B//+IftitOCWLt2rfr3769nn33WVt93332nWbNmacGCBXbhvJubm6ZMmaJ77rlH7u7utuXx8fF6+eWXtXbtWj388MNq1qxZgeuwsobzERERtnA+Pj5eJ06cUJ06dfTnn38qIiLCFs5br37t3LmzDAZDrse977771KBBA23evFm1atXKNZSUpNjYWHl6eio0NNTWzrlz5/TUU0/p119/1ciRI10ybU5++/7BBx/Ugw8+qIiICKWkpOSo3WKx6J133lFCQoKGDh2qJ5980tYXGzdu1JQpU/Tvf/9bLVu2zBEw//HHH2rWrJkWLVqU69XhGzdu1Oeff24bpydOnNCTTz6pxYsXa+3atRo9erQee+wxSVJ6erpefvll7d27V7/99pvdDT0XL16sjRs3qm3btpo0aZLt6ubk5GS988472rZtm3744Qf169dPUlaY/+677yolJUVjxoyxm0Jqzpw5WrBggVP9fqPDhw9rzpw58vLy0n/+8x81adJEUla4PW3aNG3cuFEzZ87UW2+9VaDjrlu3Tp988omCgoIkSUlJSZo0aZL27t2r0NBQjRs3zrZtixYtNGfOHNWvX9+2LDMzU0uXLtXs2bM1Y8YMff311w7HeG7vI/l5vfbu3VvBwcE5jvnjjz9q3Lhxtuc1IyNDL7/8svbs2aPnnntOfn5++vrrr21jZtWqVXr//ff19ddf24Xz586d0/Tp0+Xh4aEPPvjArq21a9dq+vTpeu+99/TZZ59Jkp599lmFhoYqOjpaffr0cXhD2EOHDumTTz5R5cqVNW3aNDVu3Fjp6emyWCxasGCBvvrqK82cOVOTJ0/Ose9PP/2kN954Q126dLFbvnTpUiUkJOjZZ5/V3//+d7t158+fV2ZmZo5j3S6MN98EAAAAAACgZEhMTJQkVahQ4abbWsNHs9ls2y+7wYMH5zuYl7ICM0kaNWqU3VWhlStX1hNPPJHv42RXrVo1u3BYkvr27aty5copMjJS6enptuUmk0mdO3e2C/qkrMc5ZswYSdKWLVucqsPKGt5Zr5SXsqahsVgsGjp0qNzd3XOsk7JCfVf65z//aTfdRtWqVdW9e3dJWdNpuEJB+j4vERERiomJUdWqVTVq1Ci7ADckJET33nuvkpKStHr1aof7/+Mf/8hz2pbRo0fbjdPatWvrnnvuUUpKigIDA20BriS5u7vbboCc/XnKyMjQt99+Ky8vL7tgXsq6+v+VV16Ru7u7Vq5cafe4Tp48qZo1a+aYQurxxx9XYGBg3h2TT8uXL5fZbNaAAQNswbwkeXh4aPz48SpTpoxtyp+C6Nevny2YlyQvLy+NHz9eBoNBP//8s9LS0mzr6tWrZxfMWzVp0kStWrXS2bNndfz4cYft5PY+kp/X67Zt2xweMzg42O55NZlMtuf15MmTevHFF+3GTM+ePeXr62ub2sjqu+++U0pKip555pkcHwL06NFD9957rw4fPqwjR444rMORRYsWyWw268UXX7TrM4PBoOHDh6thw4basmWL4uPjc+zboUOHHMG8JNu22b+tY1WlSpUScQ+LW4Ur5wEAAAAAQKlhsVjs/p+fbSU5vOK1U6dO+W43IyNDUVFRMhqN6ty5c471999/v938zPnVqlWrHFf0m0wmVa1aVUeOHFFiYmKO6SGOHj2q3bt3KzY2VikpKbJYLEpOTpYknTp1qsA1ZFetWjUFBgYqMjJSqampKlOmjCIiImQwGNS+fXsFBQXZhb7Wn10ZzptMJofHq1GjhiQpLi7OJe040/eOWD8s+Nvf/iY3N7cc67t3767Nmzfb5mzPrmLFijnmo7/RXXfdlWOZ9YMLR+usN6zN3k/Hjh1TQkKC7r777hzzgUtZU5bUqFFDx48ftz3v1nrvv//+HK8fk8mk+++/X0uWLMmz9vyw9l+3bt1yrKtQoYLatm2rbdu26dChQ7nOqe6IoxC4du3aql+/vo4dO6aYmBi7vk9LS9OuXbt0+PBhxcfHKy0tTfHx8Tp37pwk6fTp06pXr16OY97sfSSv1+vp06cd7pPXc16lShXba8HKzc1NVapUUVRUlBISEmzjds+ePXnW2KJFC23dulWHDx/O17eRzGaz9u7dKy8vL7Vp0ybHeoPBoObNm+vo0aM6cuRIjil2cqvD2vaMGTM0evRotWjR4qbTlt0u7oxHCQAAAAAAbgu+vr46deqUw6syb5SQkCApKzBydGVy5cqV891uQkKC0tPTVbFixRxXwkpZV+WWK1dOV69ezfcxJSkgIMDhcutc5tmv7k1PT9e7776r9evX53q8pKSkArXvSHBwsH755RfbvPMRERGqV6+efH191apVKy1cuFDnzp1TYGCgbb75gnwD4WYqVqzoMOR21CeFUZC+z8ulS5ckyeENWLMvt26XXX7GoKM6PT09b7oue/3nz5+XlHVD5ZsF3ImJiQoICLDVm9sV8gV5/eTFeqPU3NrJq//yktfxjh07Zne8mJgYvfrqq7Z+ciS311Zu/VCY12tBn/Ps6x097/3798+1Bumv98qbSUxMtH2w0LVr1wIfM7e+6tmzp3bv3q0NGzZowoQJ8vT0VFBQkNq3b6/evXvn65tSpRXhPAAAAAAAKDUaNGiggwcPKioqSg888ECe20ZFRUmS6tSp4/AqzOw3y8yvvOZVz8/V/IWxZMkSrV+/XnXr1tUzzzxju3moyWTSqVOnNHz4cJe0Yw3nraH8n3/+aQv3rOF8RESE6tevr2vXrt10vvk7xc36wNF6Dw+PQh83P6xzdteoUcPhPQmMRqPMZrMk5fjwqaQ8t66q48bXqcVi0VtvvaXz58/r4Ycf1sMPP6xq1arJw8NDhw4d0sqVK/Xrr7/m+vrO7X0kP6/XW/2ekZmZKYPBcNP3yrxu5nzj8aSsDyPvu+8+SfZjJztHH47kNt7d3Nz05ptvasiQIdq6dasiIiIUGRmpffv2adGiRfr3v/9dqHtplGSE8wAAAAAAoNRo3769VqxYoU2bNmns2LF5Tn1gvWL1xqkVnOHr6yuTyaS4uDilp6fnCDCTkpJ07dq1QreTl61bt0qSXn/99RzTa5w9e9Zl7VinlLEG8BaLxbasefPmtnnnrd8ScHRDyztJpUqVJMk2/cmNrDcKzs8UObeK9WrrunXrOrwZr7u7e4459q315nY1+YULF1xSW6VKlXTu3DnFxsaqVq1aOdY723+xsbEOp6Gx1m193k6ePKmTJ08qKChIL7zwgm07axB9+fLlArVrVVSv17wEBATo7Nmz+uc//ylvb+9CH8/X11fu7u4ymUy2ceRo7DirYcOGatiwoSTp+vXrmjdvnpYsWaJZs2bp008/dUkbJQ03hAUAAAAAAKVGhw4dVLNmTV26dEmLFi3Kdbt9+/Zp06ZNcnd3V9++fQvdrslkUuPGjWU2mx3edHXTpk2FbuNmrGG4o6khNm7c6LJ2qlevroCAAEVGRmrXrl0yGAy2AN463URERESB55u3fqBhDT1vFy1btpQkbdiwweFjW7dunaSs+b2LS+PGjeXt7a3w8HBdv349X/tY6928eXOOK7wzMjJcNuat/ffrr7/mWBcfH6/du3fLaDQW+Mrp3377LceyEydO6NixY/Ly8rIF5tbXlaPpYpKSkmzfwCmoonq95sU6d731g4L8yOt1ar0fRGJiou1m0LeKt7e3nnzySRkMBsXExNzStooT4TwAAAAAACg1jEajXnnlFZlMJoWGhmrRokU5QqSdO3dq0qRJslgseuqpp2w3Uiyshx56SJIUGhpqdzXthQsXNH/+fJe0kRfrTSB//PFHu+UbN27U2rVrXdpWcHCw0tPT9csvv6hevXoqX768bV2rVq0UGxur3bt3q3z58g6vTnbE+u2Ds2fP3lYBfatWrVSvXj2dO3dOoaGhdkH2li1btGXLFpUtW1Y9e/Ystho9PDw0cOBAXbt2TW+88YbDq+Gjo6PtAu3WrVurZs2aOnnypBYvXmy37YIFC2xXtBdW3759ZTQatWzZMh0+fNi2PD09XTNmzFBKSoruu+++XOdaz83y5ct19OhR2+/JycmaOXOmLBaLevXqZZtipXr16jIajQoPD7e7QWtaWpqWLFni9H0civL1mpuBAweqTJky+uSTTxQWFpZjfWJiolasWKHU1FTbMus3FHK7ufSwYcNkNBo1ffp02818s7t06ZKWL19eoDp/+eUXhwH8rl27ZLFYXHZ/g5KIaW0AAAAAALgNeOQzIC0Orq6tWbNmmjp1qqZMmaIvvvhCS5cuVdOmTeXh4aGYmBidOHFCRqNRo0aN0mOPPeaydh944AFt2rRJYWFhGjFihNq0aSOz2ay9e/eqdevWMpvNTk+BkR+DBw/Wrl279MUXX2jjxo2qWbOmTp8+raioKA0cODBHgFoYrVq10q+//qq0tLQcV8Zb551PS0tT+/bt8z0XuLu7u9q3b6+wsDCNHj1ajRo1kslkUosWLdSrVy+X1V7UDAaDJk2apOeff14LFy7Uli1b1KBBA8XGxurgwYNyc3PTyy+/XKzT2khZoeqJEye0fv16DR8+XI0aNVLlypWVkJCg8+fP6+zZs+rUqZO6dOki6a8Pwl544QV99tlnWr9+vWrVqqXjx4/r5MmT6tOnj1atWlXoupo0aaJRo0bpyy+/1Lhx49SqVSv5+vrq4MGDunDhgmrUqKHx48cX+Ljdu3fX2LFj1bp1a/n4+Gjfvn2Ki4tTnTp1NHLkSNt2FSpUUO/evfXTTz9p9OjRat26tcqUKaP9+/fbxviuXbsK3H5Rvl5zU6NGDb322muaOnWqXn31VdWsWVO1a9eWxWJRbGysTpw4ofT0dHXt2tU2d367du3k4eGhpUuX6vjx47bpfwYNGqRatWopODhYzz33nGbNmqV//vOfatCggapVq6a0tDTbMcuWLat+/frlu85NmzZp2rRpqlatmurVq6cyZcro/PnzioyMlNFo1JgxY25J/5QEhPMAAAAAAJRiZrNZ5owMVf/g/eIuJU/mjAyHNw101t13362vv/5a3333nbZv367w8HBlZGSoYsWK6tOnj/r376/69eu7rD0pK4SdPHmyvvnmG61Zs0Y7duxQxYoVNWDAAA0bNkwPPvig3RXmrhYcHKyPP/5Yc+bM0dGjR3X69GnVq1dPU6ZMUcOGDV0ezjv6Wfpr3vn09PR8T2lj9dJLL+nTTz/V7t279euvv8psNiszM7NUh/OSVK9ePc2ePVsLFizQrl27tGnTJnl7e+vee+/V0KFD1aRJk+IuUUajUa+//ro6d+6sVatWKSoqSlFRUfL19VWVKlX0wAMP2IJ5q2bNmmnWrFn68ssvdeDAAZ05c0aNGzfWhAkTdPr0aZeE81LWBwf169fX0qVLdfjwYaWlpaly5coaPHiwhgwZonLlyhX4mOPHj1fVqlW1atUqRUREqHz58urbt69Gjx4tHx8fu20nTJigWrVq6eeff9bevXvl7e2tNm3a6N5779XOnTudekxF+XrNS+fOnVWvXj0tXrxYe/bs0c6dO+Xh4aFKlSqpW7du6ty5s11/VKpUSVOnTtW8efN04MABJScnS8r6sMN6T4D+/furWbNmWrp0qQ4cOKCwsDB5eXkpICBADz/8sEJCQgpU49///ncFBATo4MGD2r9/v1JSUlSpUiV17dpVAwcOtM1DfzsyWG71bYFvU9evX7cN3OjoaJUtW7aYKypZDAaDqlSpovPnz9/yO0/j9sG4gTMYN44lJSWpQYMGkmSbUxF/YdzAWYyd0sFkMikgIEDdf4/SgWvJTh+nhU9ZrWsXpIsXLyojI8Pp4zBuHONclTfruDl16pSuXLkiPz+/HDcgzc5oNMpoLNkz15rNZpeG8yVNZGSknn32WbVv317//ve/i60OV96cEXeO22ncDBw4ULGxsYWe1z0zM1MHDx6UlPWBlJubmwuqu/3cTmPnZtLT0xUfH3/Tc3L2v3GuXbuW5814uXIeAAAAAIBS7nYPvkuSmJgY1apVSybTX5HKuXPn9NFHH0mSunXrVlylAQBKGcJ5AAAAAACAfPr0008VFRWlBg0ayM/PTxcvXlRUVJTS0tLUoUMHde/evbhLBACUEoTzAAAAAAAA+dSzZ09ZLBbFxMTo6tWrMplMqlevnrp27ap+/frl++aoAAAQzgMAAAAAAORT165d1bVr1+IuA0AuiupGq4ArlOy7xQAAAAAAAAAAcBsinAcAAAAAAAAAoIgRzgMAAAAAAAAAUMQI5wEAAAAAAAAAyAdX3vibcB4AAAAAgBLKaMz6Z3tmZmYxVwIAwJ3NbDZLIpwHAAAAAOCO4ObmJnd3dyUnJ9tCAQAAULQsFotSUlJkMpnk5ubmsuOaXHYkAAAAAADgct7e3kpISNCVK1fk6ekpd3d3l161h9tPenp6cZeAUohxY89sNttC2IyMDD4gzcPtPnbMZrNSUlKUlpamcuXKufTYhPMAAAAAAJRg7u7uqlChgq5fv67k5GQlJSUVd0kowdzc3JgGCQXGuMnJbDbbQuf4+HjbNGOwd6eMHZPJpHLlysnT09O1x3Xp0QAAAAAAgMu5ubmpfPnyslgsMpvNslgsslgsxV0WShiDwaCAgABdvHiR8YF8Y9w4lpKSomeffVaS9Msvv7g8lL0d3Aljx2AwyGAwuHQqm+wI5wEAAAAAKCVuZUCA0s9gMNimPrpdgzK4HuPGsfT0dJ04cULSX/f/gD3GTuERzgMAAABAETCZTIX+h6vZbGbOWwAAgNsE4TwAAAAA3EJGo1EWs0WVKlUq9LHMmWZdvHSRgB4AAOA2QDgPAAAAALeQ0WiUwWjQ5W8PK+OC8zfyNFX2UsVBjWU0GgnnAQAAbgOE8wAAAABQBDIuJCn97PXiLgMAAAAlhLG4CwAAAAAAAAAA4E5DOA8AAAAAAAAAQBEjnAcAAAAAAAAAoIgRzgMAAAAAAAAAUMQI5wEAAAAAAAAAKGKE8wAAAAAAAAAAFDHCeQAAAAAAAAAAihjhPAAAAAAAAAAARcxU3AUU1sWLFzV79mxt2rRJ586dk6enp2rUqKEOHTroX//6V47tV6xYoYULFyo6Olru7u4KDg7W2LFj1aZNm2KoHgAAAAAAAABwJyrVV86Hh4erd+/emjdvnkwmk7p06aLg4GDFx8dr7ty5ObafPn26Xn75ZR09elT33HOPWrRoobCwMA0bNkzr1q0r+gcAAAAAAAAAALgjldor52NjY/XUU08pLS1Ns2bNUvfu3e3W79+/3+737du3a+7cufLz89PixYtVp04dSVkB//DhwzVx4kS1b99evr6+RfUQAAAAAAAAAAB3qFJ75fx//vMfJSYm6qWXXsoRzEtSy5Yt7X4PDQ2VJI0dO9YWzEtS69atNWjQIF29elXLli27pTUDAAAAAAAAACCV0nA+ISFBq1evVrly5fTYY4/ddPvU1FRt375dktSzZ88c663LNmzY4NpCAQAAAAAAAABwoFROa7N3716lpaWpY8eOMplMWrNmjfbs2aOMjAzVq1dPvXr1UqVKlWzbx8TEKC0tTf7+/qpSpUqO4zVt2lSSFBUVVWSPAQAAAAAAAABw5yqV4fzRo0clSRUrVtTQoUMVHh5ut/7DDz/UtGnT1KtXL0nS2bNnJclhMC9JXl5eKl++vBISEnTt2jX5+PgUuCaDwVDgfW5n1v6gX1AQjBs4g3HjWPb+MBgM9M8NGDdwFmOndHD181PY99GSVk9Jwbkqb7zfwBmMGziDceMY56mbY+w4VpD+KJXhfGJioiTphx9+kIeHh6ZOnaouXbooKSlJCxcuVGhoqF566SXVrVtXjRs3VlJSkiTJ09Mz12OWLVtWiYmJSkpKKnA4HxgYKG9vb+cf0G0sMDCwuEtAKcS4gTMYN/auX79u+5nzVO4YN3AWY+fOkv1buSVBSavHWZyr8of3GziDcQNnMG7scZ7KP8aOvexj52ZKZTifmZkpScrIyNAbb7yhAQMGSJL8/f31yiuv6OzZs1q7dq2+/PJLffDBB7JYLJLy/tTCuo0zYmNj5eXl5fT+tyODwaDAwEDFxsYWqm9xZ2HcwBmMG8esH0xLnKccYdzAWYyd0sFkMrk0wL506ZIyMjKc3t/d3V0VK1YsMfWUFJyr8sb7DZzBuIEzGDeOcZ66OcaOY9nHzs2UynDe+kmV0WhUv379cqx/9NFHtXbtWu3atctu++Tk5FyPmZKSIklOv9AYgI5ZLBb6BgXGuIEzGDf2svcFfZM7+gbOYuyUbK5+bgr7fJe0ekoKzlX5Q9/AGYwbOINxY4/zVP7RP/YK0hfGW1jHLVOjRg1JWV/n9PDwyHV9XFycJKlatWqSpPPnzzs8XlJSkhITE1W+fHmn5psHAAAAAAAAAKAgSmU436RJE0lZc887+iTiypUrkv66Cr5u3bry8PBQXFycw4A+MjJSkhQUFHSrSgYAAAAAAAAAwKZUhvNBQUGqUaOGUlJStG/fvhzrrdPZNG3aVFLWjWA7dOggSVqzZk2O7a3LQkJCblHFAAAAAAAAAAD8pVSG85I0ZswYSdI777xjm75Gkg4ePKjQ0FBJ0qBBg2zLR44cKUn69NNP9eeff9qWh4eHa/HixfLx8bHdWBYAAAAAAAAAgFupVN4QVpL+/ve/a/v27VqzZo169eql1q1b6/r16woPD1d6err+/ve/q2fPnrbtO3bsqBEjRmj+/Pnq27evOnbsqPT0dIWFhclsNuuDDz6Qn59f8T0gAAAAAAAAAMAdo9SG80ajUR999JHat2+v7777Tjt27JDBYFDz5s01aNAg9e3bN8c+r732mpo0aaKFCxcqLCxMJpNJHTp00NixY9W2bduifxAAAAAAAAAAgDtSqQ3npayAfujQoRo6dGi+9+nfv7/69+9/C6sCAAAAAAAAACBvpXbOeQAAAAAAAAAASivCeQAAAAAAAAAAihjhPAAAAAAAAAAARYxwHgAAAAAAAACAIkY4DwAAAAAAAABAESOcBwAAAAAAAACgiBHOAwAAAAAAAABQxAjnAQAAAAAAAAAoYoTzAAAAAAAAAAAUMcJ5AAAAAAAAAACKGOE8AAAAAAAAAABFjHAeAAAAAAAAAIAiRjgPAAAAAAAAAEARI5wHAAAAAAAAAKCIEc4DAAAAAAAAAFDECOcBAAAAAAAAAChihPMAAAAAAAAAABQxwnkAAAAAAAAAAIoY4TwAAAAAAAAAAEWMcB4AAAAAAAAAgCJGOA8AAAAAAAAAQBEjnAcAAAAAAAAAoIgRzgMAAAAAAAAAUMQI5wEAAAAAAAAAKGKE8wAAAAAAAAAAFDHCeQAAAAAAAAAAihjhPAAAAAAAAAAARYxwHgAAAAAAAACAIkY4DwAAAAAAAABAESOcBwAAAAAAAACgiBHOAwAAAAAAAABQxAjnAQAAAAAAAAAoYoTzAAAAAAAAAAAUMcJ5AAAAAAAAAACKGOE8AAAAAAAAAABFjHAeAAAAAAAAAIAiRjgPAAAAAAAAAEARI5wHAAAAAAAAAKCIEc4DAAAAAAAAAFDECOcBAAAAAAAAAChihPMAAAAAAAAAABQxwnkAAAAAAAAAAIoY4TwAAAAAAAAAAEWMcB4AAAAAAAAAgCJmcsVBLly4oPDwcJ0/f15xcXGKj4+Xp6en/P395e/vr0aNGqlZs2YymVzSHAAAAAAAAAAApZpTabnFYlFYWJh+/vln7dq1S6dPn77pPp6enmrZsqVCQkLUp08fVa5c2ZmmbYYPH65du3blun727Nnq3LlzjuUrVqzQwoULFR0dLXd3dwUHB2vs2LFq06ZNoeoBAAAAAAAAACC/ChTOJyUl6dtvv9XXX3+ts2fPSsoK6vMjOTlZO3fu1K5du/Sf//xHXbp00ciRI9W6deuCV51Njx495OXllWN5YGBgjmXTp0/X3Llz5enpqU6dOik1NVVhYWHatm2bZsyYoe7duxeqFgAAAAAAAAAA8iNf4XxGRoYWLlyozz//XPHx8bZAvkaNGgoODlaLFi3UvHlz+fv7y8/PT+XLl1dKSooSEhKUmJio48eP68CBA7b/UlNT9csvv2jdunW699579dJLL6lRo0ZOPYB//etfqlGjxk232759u+bOnSs/Pz8tXrxYderUkSSFh4dr+PDhmjhxotq3by9fX1+n6gAAAAAAAAAAIL/yFc4/+OCDOnHihCwWiwIDA9W7d2899NBDatq0aa77+Pj4yMfHR9WrV1eTJk3Uu3dvSdL169e1bt06rVy5Ujt27NCWLVsUFhamadOm6ZFHHnHNo3IgNDRUkjR27FhbMC9JrVu31qBBg7RgwQItW7ZMo0aNumU1AAAAAAAAAAAgScb8bPTnn3+qfv36+uCDD7Rhwwa9/PLLeQbzefH29lbfvn01Z84crVu3Tn//+99lNBp16tQpp46XH6mpqdq+fbskqWfPnjnWW5dt2LDhltUAAAAAAAAAAIBVvq6c/+ijj9SzZ08ZDAaXNl6tWjVNmTJF48aNs81hX1Dfffed4uPjZTQaVadOHXXr1k3VqlWz2yYmJkZpaWny9/dXlSpVchzD+kFDVFSUUzUAAAAAAAAAAFAQ+Qrne/XqdUuLCAwMdHgD1/z49NNP7X7/97//rbFjx2rcuHG2Zdbg31EwL0leXl4qX768EhISdO3aNfn4+BS4Dld/cFHaWfuDfkFBMG7gDMaNY9n7w2Aw0D83YNzAWYyd0sHVz09h30dLWj0lBeeqvPF+A2cwbuAMxo1jnKdujrHjWEH6I1/hfEnUtm1bDRgwQG3atFFAQIDOnTuntWvX6tNPP9XMmTPl4+Ojxx9/XJKUlJQkSfL09Mz1eGXLllViYqKSkpIKHM4HBgbK29vb+QdzG3P2Qxfc2Rg3cAbjxt7169dtP3Oeyh3jBs5i7NxZKlWqVNwl2Clp9TiLc1X+8H4DZzBu4AzGjT3OU/nH2LGXfezcTKkN58ePH2/3e926dfXMM8+oefPmGj16tD7++GMNHDhQnp6eslgskvL+1MK6jTNiY2Pl5eXl9P63I4PBoMDAQMXGxhaqb3FnYdzAGYwbx6wfTEucpxxh3MBZjJ3SwWQyuTTAvnTpkjIyMpze393dXRUrViwx9ZQUnKvyxvsNnMG4gTMYN45xnro5xo5j2cfOzRQ6nE9OTpaUdeW5IwsWLNDq1at15coV1ahRQ0OGDNHf/va3wjabq3vvvVfNmzfXwYMHFRERoQ4dOtg+2bLW6khKSookOf1CYwA6ZrFY6BsUGOMGzmDc2MveF/RN7ugbOIuxU7K5+rkp7PNd0uopKThX5Q99A2cwbuAMxo09zlP5R//YK0hfGAvT0G+//aY2bdrovvvu07Vr13KsnzhxoqZNm6bw8HAdP35cW7du1bPPPqvZs2cXptmbqlOnjiTp4sWLkmS7Qez58+cdbp+UlKTExESVL1/eqfnmAQAAAAAAAAAoiEKF81u3bpXFYlG3bt1yhNq7d+/W8uXLJWXN9d60aVOVKVNGFotFM2bM0NGjRwvTdJ4SEhIk/XUVfN26deXh4aG4uDiHAX1kZKQkKSgo6JbVBAAAAAAAAACAVaHC+YiICBkMBt1999051i1ZskSSVLlyZa1evVrff/+9Vq9erapVqyozM1OLFy8uTNO5iouL0549eyRJzZo1k5T14UCHDh0kSWvWrMmxj3VZSEjILakJAAAAAAAAAIDsChXOx8XFSZJq166dY92WLVtkMBg0bNgwValSRZJUtWpVDRs2TBaLRbt27XK63YiICO3YsSPH/D2nT5/WuHHjlJSUpC5dutjalaSRI0dKkj799FP9+eeftuXh4eFavHixfHx8NGDAAKdrAgAAAAAAAAAgvwp1Q1hrOH/jTVSPHTumK1euyGAwqEuXLnbrmjdvLkk6c+aM0+3GxMRo4sSJCggIUN26dVWpUiWdP39ehw4dUmpqqho2bKh33nnHbp+OHTtqxIgRmj9/vvr27auOHTsqPT1dYWFhMpvN+uCDD+Tn5+d0TQAAAABQFEymQv0zTmazWWaz2UXVAAAAwFmF+qvOzc1N6enptjnerXbv3i1J8vf3V/369e3W+fr6SpJSU1Odbjc4OFiDBw/W/v37dezYMe3du1dly5ZVkyZN1LNnTw0ePFienp459nvttdfUpEkTLVy4UGFhYTKZTOrQoYPGjh2rtm3bOl0PAAAAANxqRh93WTIzVaFChUIdx5yRoYuXLxPQAwAAFLNChfOVK1fWyZMn9ccff9jNO79x40YZDAbdddddOfa5evWqJBXqD8r69evrrbfecmrf/v37q3///k63DQAAAADFwVjWJIObm868+JLSYmKcOoZHvXqq/sH7MhqNhPMAAADFrFDhfNu2bXXixAl9/fXXevjhh+Xv76/9+/dr69atkqT77rsvxz7R0dGSpICAgMI0DQAAAAB3pLSYGKVERhZ3GQAAACikQoXzQ4YM0fLly3X69Gl169ZNderUUXR0tDIyMuTr66tevXrl2GfHjh0yGAxq3LhxYZoGAAAAAAAAAKDUMhZm52bNmulf//qXDAaDkpKSFBkZqdTUVJlMJr3zzjvy8fGx2/7q1avatGmTJKlTp06FaRoAAAAAAAAAgFKrUFfOS9ITTzyhe+65R2vXrtWlS5cUEBCgPn36qF69ejm23blzp5o3by5JuueeewrbNAAAAAAAAAAApVKhw3lJCgoKUlBQ0E2369atm7p16+aKJgEAAAAAAAAAKLVcEs4DAAAAdxKTySSLxeL0/mazWWaz2YUVAQAAAChtCOcBAACAfDIajbKYLapUqVKhjmPONOvipYsE9AAAAMAdLF/h/P79+9WyZctbVkRycrLOnDmjBg0a3LI2AAAAgMIyGo0yGA26/O1hZVxIcuoYpspeqjiosYxGI+E8AAAAcAcz5mejgQMH6qmnntL+/ftd2nhSUpK++OILdenSRWvWrHHpsQEAAIBbJeNCktLPXnfqP2dDfQAAAAC3l3xdOV++fHlt3rxZW7ZsUevWrfXII4+oZ8+e8vX1darR3bt3a+XKlVqzZo0SExNlsVhUoUIFp44FAAAAAAAAAEBpk69w/pdfftHHH3+sxYsXa+/evQoPD9c777yj9u3bq1WrVmrRooWaNGmiihUrymSyP+S1a9d0/PhxHThwQAcOHNCOHTt0/vx5SZLFYlHDhg310ksvqXPnzq5/dAAAAAAAAAAAlED5Cud9fX01adIkjR49Wl988YVWrFih5ORkbdu2TWFhYXbbenp6ytfXVykpKbp69WqOeTQtFoskqWnTpnryySfVq1cvGQwGFz0cAACA/DOZTLa/TZxlNpuZNxwAAAAAUGD5CuetqlatqjfffFMvvPCCVq1apdWrVysiIkKpqam2bZKTk5WcnOxw/2rVqikkJESPPPKIgoODC1c5AACAk4xGoyxmiypVqlToY5kzzbp46SIBPQAAAACgQAoUzluVK1dOgwYN0qBBg5SWlqYDBw4oPDxc58+f15UrVxQfH68yZcrI399f/v7+atSokdq2basqVaq4un4AAIACMxqNMhgNuvzt4ULdnNNU2UsVBzWW0WgknAcAAAAAFIhT4Xx2Hh4euuuuu3TXXXe5oh4AAIAik3EhSelnrxd3GQAAAACAO5CxuAsAAAAAAAAAAOBOQzgPAAAAAAAAAEARI5wHAAAAAAAAAKCIEc4DAAAAAAAAAFDECOcBAAAAAAAAAChihPMAAAAAAAAAABQxwnkAAAAAAAAAAIoY4TwAAAAAAAAAAEWMcB4AAAAAAAAAgCJGOA8AAAAAAAAAQBEjnAcAAAAAAAAAoIiZXHmwU6dOKTw8XJcuXVJycrIGDx4sf39/VzYBAAAAAAAAAECp55JwPjIyUtOmTdOePXvslvfo0cMunP/66681a9YslStXTqtWrZK7u7srmgcAAAAAAAAAoFQp9LQ2Gzdu1KBBg7Rnzx5ZLBbbf4707dtXKSkpOnXqlDZu3FjYpgEAAAAAAAAAKJUKFc5fvHhRL7zwgtLS0tSgQQPNnj1be/fuzXV7b29vdevWTZK0efPmwjQNAAAAAAAAAECpVahwfu7cuUpKSlK1atX09ddf67777pOXl1ee+7Rv314Wi0WHDh0qTNMAAAAAAAAAAJRahQrnt27dKoPBoFGjRql8+fL52qdu3bqSpDNnzhSmaQAAAAAAAAAASq1ChfOnT5+WJLVs2TLf+/j4+EiSrl+/XpimAQAAAAAAAAAotQoVzmdkZEiSTCZTvvdJTEyUpJtOfwMAAAAAAAAAwO2qUOF8pUqVJP11BX1+RERESJICAwML0zQAAAAAAAAAAKVWocL5Nm3aSJLWrVuXr+2Tk5P17bffymAwqF27doVpGgAAAAAAAACAUqtQ4Xy/fv1ksVi0atUqbd26Nc9tr1+/rueff15nz56VJA0YMKAwTQMAAAAAAAAAUGrlf7J4Bzp27Khu3brp119/1dixYzVs2DD16tXLtj4+Pl779u3T1q1b9e233+rSpUsyGAzq27evmjZtWujiAQAAAAAAAAAojQoVzkvS+++/r6efflq7du3S3LlzNXfuXBkMBknS8OHDbdtZLBZJ0j333KPJkycXtlkAAIASw2Qq9J9UMpvNMpvNLqgGAAAAAFAaFPpfkmXLlrWF8qGhobp48aLD7Xx9fTV69Gg9+eSTMhoLNZsOAABAiWD0cZclM1MVKlQo9LHMGRm6ePkyAT0AAAAA3CEKf5mXJKPRqFGjRmnEiBHav3+/Dh48qMv//x+Xfn5+atq0qe666y55eHi4ojkAAIASwVjWJIObm868+JLSYmKcPo5HvXqq/sH7MhqNhPMAAAAAcIdwSThvO5jJpDZt2qhNmzauPCwAAECJlhYTo5TIyOIuAwAAAABQijC/DAAAAAAAAAAARYxwHgAAAAAAAACAIuayaW2uXLmiiIgInTp1StevX1dmZuZN93nuuedc1TwAAAAAAAAAAKVGocP5ixcv6t1339XatWvzFchn58pwPj4+Xr169VJcXJzq1q2rNWvW5LrtihUrtHDhQkVHR8vd3V3BwcEaO3Ysc+UDAAAAAAAAAIpEocL5uLg4DRo0SGfPnpXFYnFVTU559913deXKlZtuN336dM2dO1eenp7q1KmTUlNTFRYWpm3btmnGjBnq3r17EVQLAAAAAAAAALiTFSqcnzlzps6cOSNJ6tmzpwYPHqzGjRurfPnyMhgMLikwP7Zv367ly5dr4MCBWrx4cZ7bzZ07V35+flq8eLHq1KkjSQoPD9fw4cM1ceJEtW/fXr6+vkVUOQAAAAAAAADgTlSoG8Ju3LhRBoNBffv21X//+1/dfffd8vX1LdJgPiUlRW+++aYaNGigUaNG5bltaGioJGns2LG2YF6SWrdurUGDBunq1atatmzZrSwXAAAAAAAAAIDChfNxcXGSpEcffdQlxThj1qxZOnnypN566y2ZTLl/ESA1NVXbt2+XlHWV/42syzZs2HBrCgUAAAAAAAAA4P8r1LQ2lStX1pkzZ1S2bFlX1VMghw8fVmhoqPr376927drp9OnTuW4bExOjtLQ0+fv7q0qVKjnWN23aVJIUFRV1y+oFAAAArPK6sCS/zGazzGazC6oBAAAAUNQK9S+Cdu3a6cyZMzpy5IiaN2/uqpryxWw26/XXX1e5cuX00ksv3XT7s2fPSpLDYF6SvLy8VL58eSUkJOjatWvy8fFxab0AAACAJBl93GXJzFSFChUKfSxzRoYuXr5MQA8AAACUQoUK50eNGqVVq1YpNDRUffr0UZkyZVxV100tWLBA+/fv1/Tp0/P1D5ukpCRJkqenZ67blC1bVomJiUpKSipwOF+U8+yXBtb+oF9QEIwbOINx41j2/jAYDPTPDUpqf/BclXyueH6MZU0yuLnpzIsvKS0mxunjeNSrp+ofvC83NzdZLJZC13U7cfXrqLCvzZL4ui4J7zecq/LG3zhwBuMGzmDcOMZ56uYYO44VpD8KFc43bNhQ06ZN0yuvvKLRo0fr7bffVt26dQtzyHw5d+6c/vvf/6p9+/bq379/vvax/oMlr85x9h81gYGB8vb2dmrf211gYGBxl4BSiHEDZzBu7F2/ft32M+ep0qNSpUrFXQKKUFpMjFIiIwt9HMbNrXc79nFJeEycq/KHv3HgDMYNnMG4scd5Kv8YO/ayj52bKfRElw8++KBq166tp59+Wn369FFQUJDq1KmT5xXqUlZIPm3aNKfanDx5stLT0/XWW2/lex/rCyg5OTnXbVJSUiRlTXFTELGxsQXe53ZnMBgUGBio2NhYruRCvjFu4AzGjWPWb4xJnKcccXd3V8WKFYu7jBwuXbqkjIyM4i4DeSiJY4dxk5PJZHJp+FzYPmbcOMa5Km/8jQNnMG7gDMaNY5ynbo6x41j2sXMzhQ7njx8/rnfffVdXrlyRlHWT1sOHD+e5j8ViKVQ4v2HDBpUvXz5HOJ+amiop68r64cOHS5I+++wzeXt7q1q1apKk8+fPOzxmUlKSEhMTVb58eafmm2cAOmaxWOgbFBjjBs5g3NjL3hf0TU4ltT94rkq+kvj8MG5ycnV/FLaPS+LzUxLGDeeq/KFv4AzGDZzBuLHHeSr/6B97BemLQoXzZ8+e1bBhwxQXF2dr1MfHR+XKlbvlcw0lJiZq165dDtelpKTY1mVmZkqS6tatKw8PD8XFxen8+fM5bgwb+f+/UhwUFHQLqwYAAAAAAAAAoJDh/CeffKLLly/LaDRq1KhRGjJkiKpXr+6q2nIVFRXlcPnp06fVtWtX1a1bV2vWrLFb5+npqQ4dOmjz5s1as2aNnnjiCbv11u1DQkJuRckAAAAAAAAAANgYC7Pz9u3bZTAYNGLECL300ktFEswXxsiRIyVJn376qf7880/b8vDwcC1evFg+Pj4aMGBAMVUHAAAAAAAAALhTFOrK+cuXL0uSHnjgAZcUc6t17NhRI0aM0Pz589W3b1917NhR6enpCgsLk9ls1gcffCA/P7/iLhMAAAAAAAAAcJsrVDgfEBCgM2fOyN3d3VX13HKvvfaamjRpooULFyosLEwmk0kdOnTQ2LFj1bZt2+IuDwAAAAAAAABwByhUON+xY0ctXbpUBw4cUIsWLVxVk9Nq1KiR63z02fXv31/9+/cvgooAAAAAAAAAAMipUHPOjx49WmXLltWXX36p+Ph4F5UEAAAAAAAAAMDtrVDhfO3atfXJJ5/o+vXrGjx4sLZt2+aqugAAAAAAAAAAuG0ValqbESNGSJL8/Px0/PhxPfnkkypfvrxq164tT0/PPPc1GAyaN29eYZoHAAAAAAAAAKBUKlQ4v2vXLhkMBtvvFotFCQkJ2r9/f677GAwGWSwWu/0AAAAAAAAAALiTFCqcb9eunavqAAAAAAAAAADgjlGocH7BggWuqgMAAAAAAAAAgDtGoW4ICwAAAAAAAAAACo5wHgAAAAAAAACAIkY4DwAAAAAAAABAEcvXnPNnz561/VytWjWHy52R/VgAAAAAAAAAANwp8hXOd+3aVZJkMBgUGRmZY7kzbjwWAAAAAAAAAAB3inyF8xaLpUDLAQAAAAAAAABA7vIVzk+fPl1S1tXujpYDAAAAAAAAAID8y1c4369fPzVu3FhGo1HNmzdXgwYNbMsBAAAAAAAAAEDBGAuyMdPYAAAAAAAAAABQeAUK5wEAAAAAAAAAQOERzgMAAAAAAAAAUMQI5wEAAAAAAAAAKGKE8wAAAAAAAAAAFLECh/MGg+FW1AEAAAAAAAAAwB3DVNAdRo0aJZOpwLvlYDAY9Ouvvxb6OAAAAAAAAAAAlDYFTtljY2Nd0jBX4AMAAAAAAAAA7lQFDucrV67skivnAQAAAAAAAAC4UxU4Zf/qq6/UoEGDW1ELAAAAAAAAAAB3hALfEBYAAAAAAAAAABQO4TwAAAAAAAAAAEWMcB4AAAAAAAAAgCJGOA8AAAAAAAAAQBEjnAcAAAAAAAAAoIgRzgMAAAAAAAAAUMRM+d1w/fr1kqTAwMBbVgwAAAAAAAAAAHeCfIfz1atXv5V1AAAAAAAAAABwx2BaGwAAAAAAAAAAihjhPAAAAAAAAAAARYxwHgAAAAAAAACAIkY4DwAAAAAAAABAESOcBwAAAAAAAACgiBHOAwAAAAAAAABQxAjnAQAAAAAAAAAoYoTzAAAAAAAAAAAUMcJ5AAAAAAAAAACKGOE8AAAAAAAAAABFjHAeAAAAAAAAAIAiRjgPAAAAAAAAAEARI5wHAAAAAAAAAKCIEc4DAAAAAAAAAFDETMVdgLNCQ0O1Z88eHTlyRJcvX1ZqaqoCAgLUvn17Pfnkk2rYsKHD/VasWKGFCxcqOjpa7u7uCg4O1tixY9WmTZsifgQAAAAAAAAAgDtVqb1y/rPPPtPmzZvl6+ure+65RyEhIfLw8NCKFSvUr18/bdq0Kcc+06dP18svv6yjR4/qnnvuUYsWLRQWFqZhw4Zp3bp1xfAoAAAAAAAAAAB3olJ75fz//vc/NW/eXGXKlLFbvmjRIk2ePFmTJk3Sxo0b5ebmJknavn275s6dKz8/Py1e/P/au/Pwpsr0/+OfnCbpSim0pYgKOAotq4KMoKCAC6COih1UXEBRREFRQRGrIzoODo6KfhUEZFQQcBRBllERZBRxoJXNsgsimwhCCxVKWuiW8/uDXzOtTbc0TdLm/bourquc5TlPTu/mzrnPyfPMVcuWLSVJ6enpGjRokFJSUnTJJZeoYcOGvn4pAAAAAAAAAIAgU2efnL/44ovLFOYl6Y477lCLFi2UkZGhvXv3upbPmDFDkjR8+HBXYV6SOnXqpIEDB+rkyZP65JNPar3fAAAAAAAAAADU2eJ8RQzjzMuy2WySpLy8PKWlpUmS+vXrV2b74mUrVqzwUQ8BAAAAAAAAAMGs3hXnFy1apL1796ply5Y699xzJUl79uxRfn6+GjdurKZNm5bZp23btpKknTt3+rSvAAAAAAAAAIDgVGfHnC/2zjvv6KefflJubq727NmjXbt2qUmTJpo4caLrCfpDhw5JktvCvCRFREQoOjpaJ06ckMPhUFRUVLX7YbFYPH8R9VDx+eC8oDqIG3iCuHGv5PmwWCycn98J1PPB7yrwBeLvh7gpy9vno6bnOBB/P4EQN+SqivEZB54gbuAJ4sY98lTliB33qnM+6nxxftWqVa4hayTprLPO0ssvv6z27du7luXm5kqSwsLCym0nPDxc2dnZys3NrXZxPiEhQZGRkdXseXBISEjwdxdQBxE38ARxU1pOTo7rZ/JU3REXF+fvLqAOIm5qX308x4HwmshVVcNnHHiCuIEniJvSyFNVR+yUVjJ2KlPni/MzZ86UJGVnZ+vHH3/UW2+9pUGDBumxxx7T8OHDJUmmaUqq+K5F8TaeOHLkiCIiIjzevz6yWCxKSEjQkSNHanRuEVyIG3iCuHGv+Ma0RJ5yx2azKTY21t/dKOPo0aMqLCz0dzdQgUCMHeKmLKvV6tXic03PMXHjHrmqYnzGgSeIG3iCuHGPPFU5Yse9krFTmTpfnC8WHR2tLl26aPr06brtttv0xhtvqHv37urYsaPrztapU6fK3f/06dOS5PEfGgHonmmanBtUG3EDTxA3pZU8F5ybsgL1fPC7CnyB+Pshbsry9vmo6TkOxN9PIMQNuapqODfwBHEDTxA3pZGnqo7zU1p1zkW9mxDWZrPpuuuuk2maWrFihSSpWbNmkqTDhw+73Sc3N1fZ2dmKjo72aLx5AAAAAAAAAACqo94V5yWpUaNGkqSsrCxJ0nnnnSe73a6srCy3Bfrt27dLkhITE33XSQAAAAAAAABA0KqXxfl169ZJkpo3by7pzESw3bp1kyQtXbq0zPbFy3r16uWbDgIAAAAAAAAAglqdLM6vX79eS5YsKTOBUUFBgWbPnq3FixcrLCxM1113nWvdkCFDJElTp07Vvn37XMvT09M1d+5cRUVFacCAAT7pPwAAAAAAAAAguNXJCWF//vlnpaSkqFGjRmrXrp1iYmJ0/Phx7dy5U5mZmQoNDdWECRN01llnufa57LLLNHjwYM2aNUv9+/fXZZddpoKCAqWmpsrpdOrVV19VTEyM/14UAAAAAAAAACBo1Mni/B//+Ec9+OCDWrt2rXbu3Knjx4/LZrPp7LPPVr9+/TRo0CC1aNGizH7PPPOM2rRpozlz5ig1NVVWq1XdunXT8OHD1aVLFz+8EgAAAAAAAABAMKqTxflzzz1Xo0aN8mjf5ORkJScne7lHAAAAAAAAAABUXZ0ccx4AAAAAAAAAgLqM4jwAAAAAAAAAAD5GcR4AAAAAAAAAAB+jOA8AAAAAAAAAgI9RnAcAAAAAAAAAwMcozgMAAAAAAAAA4GMU5wEAAAAAAAAA8DGK8wAAAAAAAAAA+BjFeQAAAAAAAAAAfIziPAAAAAAAAAAAPkZxHgAAAAAAAAAAH6M4DwAAAAAAAACAj1GcBwAAAAAAAADAxyjOAwAAAAAAAADgYxTnAQAAAAAAAADwMYrzAAAAAAAAAAD4GMV5AAAAAAAAAAB8jOI8AAAAAAAAAAA+RnEeAAAAAAAAAAAfozgPAAAAAAAAAICPUZwHAAAAAAAAAMDHKM4DAAAAAAAAAOBjFOcBAAAAAAAAAPAxivMAAAAAAAAAAPgYxXkAAAAAAAAAAHyM4jwAAAAAAAAAAD5GcR4AAAAAAAAAAB+jOA8AAAAAAAAAgI9RnAcAAAAAAAAAwMcozgMAAAAAAAAA4GMU5wEAAAAAAAAA8DGK8wAAAAAAAAAA+BjFeQAAAAAAAAAAfIziPAAAAAAAAAAAPkZxHgAAAAAAAAAAH6M4DwAAAAAAAACAj1GcBwAAAAAAAADAxyjOAwAAAAAAAADgYxTnAQAAAAAAAADwMYrzAAAAAAAAAAD4GMV5AAAAAAAAAAB8jOI8AAAAAAAAAAA+RnEeAAAAAAAAAAAfozgPAAAAAAAAAICPUZwHAAAAAAAAAMDHrP7ugCdOnTql1atX6+uvv9aWLVt08OBBOZ1ONW/eXH369NGQIUMUGRnpdt9FixZpzpw52r17t2w2my688EINHz5cnTt39vGrAAAAAAAAAAAEqzr55Pxnn32mhx56SJ988olM09Tll1+uiy++WL/88osmTZqkAQMG6NixY2X2mzBhgsaOHatdu3bp0ksvVYcOHZSamqq77rpLy5cv98MrAQAAAAAAAAAEozr55LzNZtPtt9+ue+65Ry1btnQtz8jI0AMPPKDt27fr73//uyZOnOhal5aWppkzZyomJkZz58517Zeenq5BgwYpJSVFl1xyiRo2bOjjVwMAAAAAAAAACDZ18sn5/v376/nnny9VmJekJk2aaNy4cZKkL7/8Uvn5+a51M2bMkCQNHz681H6dOnXSwIEDdfLkSX3yySe13ncAAAAAAAAAAOpkcb4iSUlJkqT8/HwdP35ckpSXl6e0tDRJUr9+/crsU7xsxYoVvukkAAAAAAAAACCo1bvi/IEDBySdGfomJiZGkrRnzx7l5+ercePGatq0aZl92rZtK0nauXOnz/oJAAAAAAAAAAhe9a44P2vWLElSjx49ZLfbJUmHDh2SJLeFeUmKiIhQdHS0Tpw4IYfD4ZuOAgAAAAAAAACCVp2cELY8K1eu1Pz582Wz2fTYY4+5lufm5kqSwsLCyt03PDxc2dnZys3NVVRUVLWPbbFYqr1PfVZ8PjgvqA7iBp4gbtwreT4sFgvn53cC9Xzwuwp8gfj7IW7K8vb5qOk5DsTfTyDEDbmqYnzGgSeIG3iCuHGPPFU5Yse96pyPelOc3717t8aMGSPTNDVmzBjX2POSZJqmpIpPTPE2nkhISFBkZKTH+9dnCQkJ/u4C6iDiBp4gbkrLyclx/Uyeqjvi4uL83QXUQcRN7auP5zgQXhO5qmr4jANPEDfwBHFTGnmq6oid0krGTmXqRXH+8OHDGjp0qE6cOKEhQ4bo7rvvLrW++I/n1KlT5bZx+vRpSWeGuKmuI0eOeLRffWaxWJSQkKAjR47U6MYHggtxA08QN+4Vf2tMIk+5Y7PZFBsb6+9ulHH06FEVFhb6uxuoQCDGDnFTltVq9WrxuabnmLhxj1xVMT7jwBPEDTxB3LhHnqocseNeydipTJ0vzmdlZWnIkCE6dOiQkpOTNXbs2DLbNGvWTNKZIr47ubm5ys7OVnR0tEdD2kg1e/K+PjNNk3ODaiNu4AniprSS54JzU1agng9+V4EvEH8/xE1Z3j4fNT3Hgfj7CYS4IVdVDecGniBu4AnipjTyVNVxfkqrzrmo0xPCOhwO3X///dqzZ4/69Omj8ePHux265rzzzpPdbldWVpbbAv327dslSYmJibXeZwAAAAAAAAAA6mxxPj8/XyNGjNDWrVvVo0cPTZw4USEhIW63DQsLU7du3SRJS5cuLbO+eFmvXr1qrb8AAAAAAAAAABSrk8X5oqIijR49WmvWrFGXLl00efJk2e32CvcZMmSIJGnq1Knat2+fa3l6errmzp2rqKgoDRgwoDa7DQAAAAAAAACApDo65vycOXO0fPlySVKjRo3017/+1e12Tz75pBo3bixJuuyyyzR48GDNmjVL/fv312WXXaaCggKlpqbK6XTq1VdfVUxMjK9eAgAAAAAAAAAgiNXJ4nx2drbr5+IivTsPP/ywqzgvSc8884zatGmjOXPmKDU1VVarVd26ddPw4cPVpUuXWu0zAAAAAAAAAADF6mRxfuTIkRo5cqRH+yYnJys5OdnLPQIAAAAAAAAAoOrq5JjzAAAAAAAAAADUZXXyyXkAAAAED8MwZBg1f6bE6XTK6XR6oUcAAAAAUHMU5wEAABCwDMNQbHy8rF4ozhc6nTqWmUmBHgAAAEBAoDgPAACAgGUYhqyGoRHb92tXzmmP22kVGaYpbVvIMAyK8wAAAAACAsV5AAAABLxdOae1xXHK390AAAAAAK9hQlgAAAAAAAAAAHyM4jwAAAAAAAAAAD5GcR4AAAAAAAAAAB+jOA8AAAAAAAAAgI9RnAcAAAAAAAAAwMcozgMAAAAAAAAA4GMU5wEAAAAAAAAA8DGK8wAAAAAAAAAA+BjFeQAAAAAAAAAAfIziPAAAAAAAAAAAPkZxHgAAAAAAAAAAH6M4DwAAAAAAAACAj1GcBwAAAAAAAADAxyjOAwAAAAAAAADgYxTnAQAAAAAAAADwMYrzAAAAAAAAAAD4GMV5AAAAAAAAAAB8jOI8AAAAAAAAAAA+RnEeAAAAAAAAAAAfozgPAAAAAAAAAICPUZwHAAAAAAAAAMDHKM4DAAAAAAAAAOBjVn93AAAAAAAAAIB/Wa1WmaZZozacTqecTqeXegTUfxTnAQAAAAAAgCBlGIZMp6m4uLgat+UscirzaCYFeqCKKM4DADxiGIYMo2ajo/FUBQAAAAD4l2EYshgWHftohwozcj1ux9okQrEDk2QYBtd5QBVRnAcAVJthGIqNj5e1hsX5QqdTxzJ5qgIAAAAA/K0wI1cFh3L83Q0gqFCcBwBUm2EYshqGRmzfr105pz1qo1VkmKa0bcFTFQAAAAAAIChRnAcAeGxXzmltcZzydzcAAAAAAADqnJqNRwAAAAAAAAAAAKqN4jwAAAAAAAAAAD5GcR4AAAAAAAAAAB+jOA8AAAAAAAAAgI9RnAcAAAAAAAAAwMcozgMAAAAAAAAA4GMU5wEAAAAAAAAA8DGK8wAAAAAAAAAA+JjV3x0AAAAAAAAAgo1hGDKMmj8363Q65XQ6vdAjAL5GcR4AAAAAAADwIcMwFBsfL6sXivOFTqeOZWZSoAfqIIrzAAAAAAAAgA8ZhiGrYWjE9v3alXPa43ZaRYZpStsWMgyD4jxQB1GcBwAAAAAAAPxgV85pbXGc8nc3APgJE8ICAAAAAAAAAOBjdfbJ+a1btyo1NVWbN2/Wpk2blJGRIbvdri1btlS436JFizRnzhzt3r1bNptNF154oYYPH67OnTv7qOcAAAAAAAAAgGBXZ4vzU6ZM0VdffVWtfSZMmKCZM2cqLCxM3bt3V15enlJTU7V69Wq98cYbuuaaa2qptwAAAAAAAABQ/1itVpmm6fH+TqczaOdMqLPF+YsuukhJSUnq0KGDOnTooO7du1e4fVpammbOnKmYmBjNnTtXLVu2lCSlp6dr0KBBSklJ0SWXXKKGDRv6oPcAAAAAAAAAUHcZhiHTaSouLq5G7TiLnMo8mhmUBfo6W5wfNmxYtbafMWOGJGn48OGuwrwkderUSQMHDtTs2bP1ySef6N577/VmNwEAAAAAAACg3jEMQxbDomMf7VBhRq5HbVibRCh2YJIMw6A4X1/l5eUpLS1NktSvX78y6/v166fZs2drxYoVFOcBAKhFhmHIMGo+H30wf+0RAAAAAAJJYUauCg7l+LsbdVJQFOf37Nmj/Px8NW7cWE2bNi2zvm3btpKknTt3+rprAAAEDcMwFBsfL6sXivOFTqeOZQbn1x4BAAAAAPVDUBTnDx06JEluC/OSFBERoejoaJ04cUIOh0NRUVHVPobFYqlRH+ub4vPBeUF1EDd1hzd/RxaLpUbtETfulTwfNT3H3hISEiKrYWjE9v3alXPa43ZaRYZpStsWCgkJ8XjSoUA4H+4Eyu8qkHj7fHjrPSeQEDdlETeVC4S4CcRcFUj4jANPEDd1RyDlqkDqSyAhT1UukGoDgaQ6ryMoivO5uWfGPAoLCyt3m/DwcGVnZys3N7faxfmEhARFRkbWqI/1VUJCgr+7gDqIuAkuNZ04phhxU1pOzv++UhhoeWpXzmltcZyqcTveip1AUh9fU6Cpj+e4Pr6mQFMfz3EgvKZAzlWBhM848ARxE3wC4X29WCD1pSbIU75VX+JGKh07lQmK4nzxU3UV3bXw9Mk7STpy5IgiIiI83r8+slgsSkhI0JEjR2p0bhFciJu6w2q1ei1xHj16VIWFhR7vT9y4V3xjWgqcPOXNuJFqFjs2m02xsbFe64u31PTvoT4KpLiRAjN2iJuyiJvKBULcBGKuCiR8xoEniJu6I5BylbfzVCDkGG8gT1XOm7FTX+JGKh07lQmK4nzxna1Tp8p/Su/06TNfr/f0D42k555pmpwbVBtxE/i8+fvx1u+buCmt5LkIlHPj7T7U5HUFwvlwJ1B+V4EkkOKmeP9AQ9yURdxULhDiJhBzVSDi3MATxE3gC6RcFUh9CSTkqcoFYm0gEFTnddR8RrY6oFmzZpKkw4cPu12fm5ur7OxsRUdHezTePAAAAAAAAAAA1REUxfnzzjtPdrtdWVlZbgv027dvlyQlJib6umsAAAAAAAAAgCAUFMX5sLAwdevWTZK0dOnSMuuLl/Xq1cuX3QIAAAAAAAAABKmgKM5L0pAhQyRJU6dO1b59+1zL09PTNXfuXEVFRWnAgAF+6h0AAAAAAAAAVMwwDFmt1hr/M4ygKQsHtDo7Iew333yjKVOmlFpWUFCgW2+91fX/ESNGuJ6Gv+yyyzR48GDNmjVL/fv312WXXaaCggKlpqbK6XTq1VdfVUxMjA9fAQAAAAAAAABUjWEYio2Pl9ULhfVCp1PHMjPldDq90DN4qs4W57OysrRp06ZSy0zTLLUsKyur1PpnnnlGbdq00Zw5c5Samiqr1apu3bpp+PDh6tKli0/6DQAAAAAAAADVZRiGrIahEdv3a1fOaY/baRUZpiltW8gwDIrzflZni/PJyclKTk722X4AAAAAAAAA4G+7ck5ri+OUv7sBL2BwIQAAAAAAAAAAfIziPAAAAAAAAAAAPkZxHgAAAAAAAAAAH6M4DwAAAAAAAACAj1GcBwAAAAAAAADAxyjOAwAAAAAAAADgYxTnAQAAAAAAAADwMYrzAAAAAAAAAAD4mNXfHQAAwBusVqtM06xRG06nU06n00s9AgAAAAAAKB/FeQBAnWYYhkynqbi4uBq35SxyKvNoJgV6AAAAAABQ6yjOAwDqNMMwZDEsOvbRDhVm5HrcjrVJhGIHJslut6uwsLBGfeIJfACoX6zWml02hYSEeKknAAAAqE8ozgMA6oXCjFwVHMrxeH8jyiazqEiNGjWqcV+chYXKPHaMAj0A1HHxdquKnKZXcgMAAADwexTnAQCQZIRbZQkJ0cEnxih/zx6P27H/4Q86+9VXZBgGxXkAqOMaWkMUYlj06Efp+inD4XE7vRLjNaZvkhd7BgAAgPqA4jwAACXk79mj09u3+7sbAIAA8lOGQ9sOZXu8//nxkV7sDQAAAOoLw98dAAAAAAAAAAAg2PDkPADAr5hkDwAAAAAABCOK8wAAv2CSPQAAAAAAEMwozgMA/IJJ9gAAAAAAQDCjOA8A8Csm2QMAAAAAAMGICWEBAAAAAAAAAPAxivMAAAAAAAAAAPgYxXkAAAAAAAAAAHyM4jwAAAAAAAAAAD7GhLAAAAAAAAQoq9Uq0zRr1IbT6ZTT6fRSjwAAgLdQnAcAAAAAIMAYhiHTaSouLq7GbTmLnMo8mkmBHgCAAENxvh4xDEOGUfORiniqAgAAAEAwCqRrKsMwZDEsOvbRDhVm5HrcjrVJhGIHJskwDK7zAAAIMBTn6wnDMBQbHy+rFz5IFjqdOpbJUxUAAAAAgkegXlMVZuSq4FBOjdsBAACBh+J8PWEYhqyGoRHb92tXzmmP22kVGaYpbVvwVAUAAACAoMI1FQAA8DWK8/XMrpzT2uI45e9uAAAAAECdxDUVAADwlZp/Xw8AAAAAAAAAAFQLxXkAAAAAAAAAAHyM4jwAAAAAAAAAAD7GmPMAAAAAAAD1iNVqlWmaNWrD6XQyqTEA1DKK8wAAAAAAAPWAYRgynabi4uJq3JazyKnMo5kU6AGgFlGcR63ibj0AAAAAAL5hGIYshkXHPtqhwoxcj9uxNolQ7MAkGYbB9TgA1CKK86gV3K0HANQ2q9XzjzEhISFe7AkAAEBgKczIVcGhHH93AwBQCYrzqBXcrQcA1JZ4u1VFTlONGjXyd1cAAAAAAPAYxXnUKu7WAwC8raE1RCGGRY9+lK6fMhwetdErMV5j+iZ5uWcAAAAAAFQdxXkAAFAn/ZTh0LZD2R7te358pJd7g7qiJsMhSQyJBAAAAMB7KM7DLS5cAQBAfcJwSAAAAAACDcV5lBKoF641vVngdDoZsx4AgCDmjeGQJIZEAgC4ZxiGDMOoURtctwJA8KE4j1IC7cLViLLJLCqq8c0CZ2GhMo8d44MOAABBribDIUkMiQQAKMswDMXGx8taw+J8odOpY5mZXLcCQBChOA+3AuXC1Qi3yhISooNPjFH+nj0etWH/wx909quvyDAMPuQAAAAAALzKMAxZDUMjtu/XrpzTHrXRKjJMU9q24LoVAIIMxXnUCfl79uj09u3+7gZ8xGq1yjRNf3dDEl8tBQAAAFA1u3JOa4vjlL+7AQCoQyjOAwgYhmHIdJqKi4urcVtmUZEsXpiYmCGRAAAAAAAAUBuCrjifl5ent99+W59//rkOHTqkhg0b6vLLL9ejjz6qpk2b+rt7gF8EyuRFhmHIYlh07KMdKszI9bid0MRGiul7Xo2GQ5IYEgkAAAAAAAC1J6iK83l5ebr77ruVnp6u+Ph4XXXVVTp48KAWLFigb775RnPnzlXz5s393U3Ap7w5edGJ336rURE75P8/6V6YkauCQzket2OND5fEcEgAAAAAAAAIXEFVnJ82bZrS09PVqVMnvfvuu4qMPDNp6YwZM/TSSy/p6aef1pw5c/zcS8C3vDF50SUNI/XCBWcrNjbWy70DAAAAAAAA6qegKc4XFBS4Cu/jxo1zFeYlaciQIVq4cKHWrVunrVu3qn379v7qJuA3NZm86IKIUIUYFj36Ubp+ynB43IdeifEa0zfJ4/0BAAAAAACAuiJoivMbNmxQdna2mjdvrrZt25ZZ37dvX+3cuVMrVqygOA946KcMh7YdyvZ4//PjIyvfCAAAAAAAAKgHajbIdB2yY8cOSXJbmJekdu3aldoOAAAAAAAAAIDaEjRPzv/666+SpKZNm7pdX7y8eLvqMAzDNZGlvxQfv0ODcEXUYGLPCyLCJEntmkUr3O75azo/PkqSZGsWJYvd8/6E/P+JPUPbtJElPNyjNuwtW55pKyREpml63Jf6yhuxUx/jRiJ2KkLclC9Q4sYo8XsJhDwlBVauIm7qjkCKG8k7sUPc1L76GDdS/ftsHGi5yltxc35kqCTJZrPV6DUV71vTuLHGRXilP5LkdDrldDpr1EZ95I3YIW6CTyC95xA37gVanpICK25K9qcmsVPf4kYqHTuVsZj+/kTmI88++6w+/vhjPfjggxo1alSZ9fv371efPn3UsmVLLVu2rNL2cnJyFBV15kO2w+EoNYY9AAD+Rp4CAAQ6chUAIJCRp+Cp6sRO0AxrU3wPwmKxVLgeAAAAAAAAAIDaFjTF+eI7FKdOnXK7/vTp06W2AwAAAAAAAACgtgRNcf6ss86SJB0+fNjt+uLlxdsBAAAAAAAAAFBbgqY4n5SUJEnavn272/Xbtm2TJCUmJvqsTwAAAAAAAACA4BQ0xfnOnTurQYMG+vnnn90W6Isnge3Vq5ePewYAAAAAAAAACDZBU5y32+268847JUkvvPCCcnNzXetmzJihnTt36uKLL1bHjh391UUAAAAAAAAAQJCw+rsDvjRixAilpaUpPT1dffr0UZcuXXTo0CFt2rRJMTExmjBhgr+7CAAAAAAAAAAIAkHz5LwkhYaGatasWRoxYoTCw8P1n//8RwcPHtTNN9+sRYsWqUWLFv7uIgAAAAAAAAAgCATVk/OSFBYWpkcffVSPPvqov7sCAAAAAAAAAAhSQfXkPAAAAAAAAAAAgSDonpxH+bZu3arU1FRt3rxZmzZtUkZGhux2u7Zs2VLhfqZpavny5VqyZIk2bdqkY8eOSZLi4uLUpk0b9erVS9dee62ioqJK7Tdo0CCtXbu21DLDMBQdHa327dvrjjvu0FVXXeXdFwmvO3XqlFavXq2vv/5aW7Zs0cGDB+V0OtW8eXP16dNHQ4YMUWRkpNt9iZ3gtWbNGg0ePLjS7UaOHKmHH3641DLiJriRq1Bd5Cl4ilwFT5GrUF3kKniCPAVPETuBxWKapunvTtRFOTk5rkBzOBzlJsq6ZMSIEfrqq69KLavsQ2RmZqZGjhyp9PR0GYahpKQknXvuuTIMQ4cPH9bWrVtVUFCgmJgYzZ07Vy1btnTtW/yH2aNHD8XHx0uS8vLytHv3bu3cuVOS9Nhjj2n48OHef7Hwmnnz5ukvf/mLJKlVq1Y6//zz5XA4lJ6erpycHP3hD3/QnDlzFBsbW2o/Yie47d69W//85z/drisqKtK///1vSdL777+vbt26udYRN1VXH/OURK5C9ZGn4ClyVe0jV/0PcRPcyFXwBHmq9tXXPEXs1L5qxY4JjzgcDlOSKcl0OBz+7o5XvP322+Ybb7xhfv3112ZmZqbZunVrs3379uVuf/LkSbNPnz5m69atzQceeMA8cOCA223effdd85JLLjHT09NLrbvrrrvM1q1bm999912Z/T788EOzdevWZrt27cyMjIwavzbUnoULF5rPPfecuXfv3lLLjxw5Yvbv399s3bq1OXr06FLriB1U5JtvvjFbt25t9uzZ0ywqKnItJ26qpz7mKdMkV6H6yFOoDeQq7yBXnUHcgFwFbyNPeUd9zVMVIXa8ozqxw5jzcBk2bJgeeeQR9e7dW3FxcZVu/+qrr2rfvn264oorNGXKFJ1zzjlltomKitK9996rTz/9VM2aNatyXwYOHKhmzZqpoKBAmzZtqtbrgG/1799fzz//fKk7opLUpEkTjRs3TpL05ZdfKj8/37WO2EFFiu/S33DDDTKM/6Up4gYSuQrVR55CbSBXoSLkKlQXuQreRp6Cp4gd36M4D4/89ttvWrBggSwWi5555plSf7DuNGnSRE2aNKnWMRo3bixJKiws9Lif8K+kpCRJUn5+vo4fPy6J2EHFcnNz9fXXX0uSbrzxRtdy4gaeIG5QGfIUPEGugjcRN6gMuQrVRZ6Cp4gd/6A4D4+sWbNGeXl5atu2bZm7+97gcDi0b98+SdL555/v9fbhGwcOHJAk2Ww2xcTESCJ2ULEvv/xSubm5atu2rVq1auVaTtzAE8QNKkOegifIVfAm4gaVIVehushT8BSx4x9Wf3cAddOOHTskSW3btvVqu3l5edq7d68mTpwoh8OhK6+8stQbAuqWWbNmSZJ69Oghu90uidhBxT799FNJ0k033VRqOXEDTxA3qAx5Cp4gV8GbiBtUhlyF6iJPwVPEjn9QnIdHfvvtN0lSo0aN3K6fPn269uzZU2pZ165ddfPNN5fZdvDgwWWW2Ww2PfTQQ3rwwQe90Fv4w8qVKzV//nzZbDY99thjruXEDsqTmZmptLQ0hYSE6Prrry+1jriBJ4gbVIQ8BU+Qq+BtxA0qQq5CdZGn4Clix38ozsMjpmlKkiwWi9v1//3vf7V27dpSy+x2u9s/zB49eig+Pl6S5HQ6lZGRoU2bNmnGjBmKiYlx+4eLwLZ7926NGTNGpmlqzJgxrnESJWIH5fvss89UVFSkyy+/3PV7LUbcwBPEDcpDnoKnyFXwNuIG5SFXwRPkKXiK2PEfivPwSPHdsuK7Z783e/Zs188LFixQSkpKuW0NGzZMXbt2LbUsKytLQ4cO1YsvvqhGjRrphhtu8EKv4QuHDx/W0KFDdeLECQ0ZMkR33313qfXEDspTPCv8779CJxE38AxxA3fIU6gJchW8jbiBO+QqeIo8BU8RO/7DhLDwSPFd+23bttVK+40bN9YjjzwiSZoxY0atHAPel5WVpSFDhujQoUNKTk7W2LFjy2xD7MCd3bt3a/v27YqIiNDVV19dZj1xA08QN/g98hRqglyF2kDc4PfIVfAUeQqeInb8i+I8PNK1a1fZ7XZt375d+/fvr5VjnHPOOZKkvXv31kr78C6Hw6H7779fe/bsUZ8+fTR+/Hi3X3kiduDO4sWLJUl9+vRReHh4mfXEDTxB3KAk8hRqilyF2kDcoCRyFWqCPAVPETv+RXEeHmncuLFuvvlmmaap8ePHy+l0ev0YBw4ckCS3bwwILPn5+RoxYoS2bt2qHj16aOLEiQoJCXG7LbGD3zNNU5999pkk91+hk4gbeIa4QTHyFGqKXIXaQtygGLkKNUGegqeIHf+jOA+PjRkzRs2bN9e3336rESNGuP6QSnI4HNq4cWO1287KytKkSZMkST179qxpV1GLioqKNHr0aK1Zs0ZdunTR5MmTZbfbK9yH2EFJ69ev18GDB9WkSRN169at3O2IG3iCuAF5Ct5ArkJtIm5ArkJNkafgKWLH/5gQFi7ffPONpkyZUmpZQUGBbr31Vtf/R4wYoV69ekmSGjRooDlz5ujhhx/WihUrtHLlSiUlJencc8+VxWJRRkaGduzYodzcXDVq1EhXXHGF2+NOnz5dCxculHRmpubMzExt3LhRubm5at68uUaNGlU7LxheMWfOHC1fvlzSmUlC/vrXv7rd7sknn1Tjxo0lETsorXjimRtuuEGGUf49Y+IGErkK1UeegjeQq1Ad5CpUF7kKNUWegqeIHf+jOA+XrKwsbdq0qdQy0zRLLcvKyiq1PiEhQR9//LGWLl2qL774Qps3b9bu3bslSbGxserWrZt69+6t6667TlFRUW6Pu2rVqlL/j4iIUMuWLXXllVdqyJAh5e6HwJCdne36ufgDpTsPP/yw64OkROzgjPz8fC1btkySdOONN1a6PXEDchWqizyFmiJXobrIVaguchVqgjwFTxE7gcFimqbp707URTk5Oa6AcTgcioyM9HOPAAD4H/IUACDQkasAAIGMPAVPVSd2GHMeAAAAAAAAAAAfozgPAAAAAAAAAICPUZwHAAAAAAAAAMDHKM4DAAAAAAAAAOBjFOcBAAAAAAAAAPAxivMAAAAAAAAAAPgYxXkA5Ro0aJASExM1adIkf3cFAAAAAAIC10kAqqO+vWckJiYqMTFRa9as8XdXqm3BggVKTEzUlVde6e+uuFj93QEA9dOkSZM0efLkSrf78ssv1aJFCx/0CAAAAAD8i+skAEBJFOcB1CqbzaaGDRuWuz4kJMSHvQEAAAAA/+M6CQAgUZwHUMs6deqk2bNn+7sbAAAAABAwuE4CAEiMOQ8AAAAAAAAAgM9RnAdQJaZp6uOPP9Ytt9yizp07q1OnTrrtttu0ePHiWjleyQlGMjMz9cILL+jKK69Uhw4d1L17dz3++OPavXt3mf0+/PBDJSYmqmvXrsrLyyu3fafTqSuvvLJeTcoCAPXJ9OnTlZiYqPbt22vz5s1ut1m5cqWSkpKUmJioTz/91LX80KFD+uCDDzRs2DD17dtXF110kTp16qTrrrtOL774og4dOlTucUtO2FVQUKD33ntPycnJ6tKlS6mJr4pzyIIFC5STk6M33nhDN9xwgzp16qTExET98ssvkqSCggKtXr1a48ePV3Jysnr06KH27dvr0ksv1X333afPPvtMpmmW6cerr76qxMREXX/99RWeJ4fD4TrmggULKj2vAADv8vV1UrFNmzYpJSVF11xzjS666CJ17txZ1113nVJSUrRq1Sq3+5w8eVKTJ0/WzTffrM6dO6tjx47q06ePnnvuOR04cKDcY5W8Njt27JgmTJigvn376sILL1RiYmKpbfPy8jRz5kwNHDhQf/zjH9WhQwf17t1bTz75pH744QevngOgvli4cKHatWunxMREvfbaa6XWrVmzRqNHj1avXr3UoUMHXXzxxRowYID++c9/Kjc31217Tz31lBITE/XUU0/JNE3NmzdPt99+u7p27er2M+Ovv/6ql19+WTfddJMuvvhidezYUVdffbWGDx+uRYsWVVhbcTgcev3119WvXz917NhRXbt21QMPPKBNmza53X7NmjWu95SKlDfp7O/3379/v1JSUtSzZ0+1b99eV1xxhf7yl7/oyJEjFbZfnl9++UV9+/ZVYmKibr75Zh09etSjdqqDYW0AVKqoqEgPPfSQvvrqK1mtVoWFhSknJ0cbN27Uxo0btX//fj3yyCO1cuxffvlFjz/+uDIzMxUWFiar1aqjR4/qs88+0/LlyzV58mRdccUVru1vvPFGvfLKKzp+/LiWLl2qm266yW27q1at0sGDBxUSEqIBAwbUSt8BAJ67//77lZaWptTUVI0ePVqLFi1SVFSUa31GRobrgqN///664YYbXOvGjh2rtWvXuv7foEED5eTkaPfu3dq9e7cWLlyoadOmqUuXLuUePy8vT4MGDVJ6erqsVqsiIyPdbnf8+HElJydr3759stlsCg8PL7X++++/17333uv6v91ul81mU1ZWllatWqVVq1Zp+fLlev3112UY/3tu5rbbbtM777yjn376SevXry+3r59++qlyc3PVoEEDXXvtteW+HgCA9/njOqmoqEgTJkwoNSRORESEnE6nK88tX75c69evL7Xfrl27NHToUB0+fFiSFBoaKqvVqv3792v//v1asGCBXn31VfXt27fcY//8888aPXq0jh496tq/pCNHjmjo0KH68ccfJZ0ZVz8sLEyHDh3S4sWL9emnn+rpp5/WoEGDvHU6gDpv+vTpmjhxogzD0LPPPqu77rpLklRYWKjnn39e8+bNc20bERGhU6dOacuWLdqyZYs++eQTvfvuuzr77LPdtm2aph599FEtW7ZMhmGoQYMGpT5vStKiRYs0btw4VwG++O/2wIEDOnDggL7++mslJiaqTZs2ZdrPzMxUcnKy9u/fr9DQUBmGoePHj+ubb77R6tWrNXXqVF1++eXeOlVlfPfddxo+fLhyc3MVGRkp0zR15MgRzZs3TytXrtT8+fOVkJBQ5fZ27NihoUOHKjMzU5deeqkmT55c6vqjtvDkPIBK/etf/9LatWv10ksvacOGDdqwYYNWrlyp3r17S5KmTp2qffv2ud13165d+tOf/qSOHTuqU6dO6tu3r/7yl79o+/btVTr2hAkTZLPZ9N5772njxo1KT0/XvHnz1Lp1a+Xl5WnUqFGuD5iSFBkZ6SrQlExiv1e87oorrtBZZ51Vpb4AAHzHYrHo5ZdfVmxsrA4cOKDnnnvOtc40TY0dO1ZZWVlq0aKFxo0bV2rfVq1a6fHHH9eSJUu0adMmrV+/Xlu2bNG8efN0+eWX6+TJkxo1apROnz5d7vE/+OAD7dy5UxMmTNCGDRu0du1afffdd2We8pk0aZJycnI0efJkpaena926dVq5cqViY2MlSWFhYfrTn/6k6dOna/Xq1dq8ebPS09O1Zs0aPfPMM4qKitLSpUs1Z86cUu2ee+656tGjh6Sq5bObbrqpzI0BAEDt8sd10muvveYqzP/5z3/W0qVLlZ6ero0bNyo1NVVvvfVWmWKYw+HQgw8+qMOHDyshIUHTp0/Xxo0b9f3332vx4sW66KKLlJ+fryeeeEI7duwo99h///vf1aBBA82cOdO1/9KlSyWduWkwcuRI/fjjj2rQoIFeeeUVff/991q/fr3+85//qHfv3nI6nRo/frxWrlxZ1VMM1FumaWr8+PGaOHGi7Ha7XnvtNVdhXpL+8Y9/aN68eYqLi9Nzzz2nNWvWKD09XZs2bdKsWbPUtm1b7d27VyNHjpTT6XR7jC+//FJfffWVxo4dq3Xr1mnt2rVav3696zPmypUr9dRTTykvL0+dO3fWBx98oM2bN2v9+vXasGGDPvjgA916662y2Wxu23/hhRdks9n0/vvvl6rXnHfeeSooKNBzzz1Xbt+84ZFHHlG3bt20ZMkSff/990pPT9frr7+uyMhIZWRkaOLEiVVu67vvvtOdd96pzMxMXX/99Zo+fbpPCvMSxXkAVXDixAnX1x/DwsIkSU2bNtWbb76pJk2ayOl06osvvnC772+//abdu3crPDxc+fn52rdvn+bNm6fk5GS9/vrrlR779OnTeuedd9S9e3dZLBZJUseOHTVz5kzFxMTI4XDo7bffLrXP7bffLklat26d26Fvjh49qhUrVkiSbr311qqfCACAT8XHx2vChAmyWCz67LPPtHDhQknSP//5T6Wmpspms2nixIllnmofN26chg0bpvPPP9+Vt6xWqzp27Ki3335biYmJysjI0LJly8o9dm5uriZOnKjk5GRXG40aNVJMTEyp7fLy8jR9+nRdc801rguXpk2bugrlF154oSZOnKiePXsqLi7OlctiYmI0ePBgvfjii5LkdlLAgQMHSpKWLl2q7OzsMuu3bdumbdu2SSKfAYA/+Po6ae/evXrvvfckSUOHDtXf//53nXfeea71sbGxuvrqq8vs/69//Uu//PKLbDab3nnnHfXs2dP19GxSUpLrydv8/PwKr9EMw9DMmTN16aWXuvYvPv6yZctcw1i8/vrruvHGG2W32yWdueE8efJkXXjhhZLODN0GBLP8/HyNHj1as2fPVoMGDfTOO++U+gbkjz/+qNmzZys8PFzvvfee7rjjDtdnUJvNpq5du2r27Nlq2rSptm3bpq+//trtcXJzc/XUU0/p3nvvdRWaIyMj1aRJExUWFuqFF16QaZq6+OKL9f7776tLly6uv+2oqCh16dJFf/vb33TBBRe4bT8kJESzZs1St27dZBiGLBaLOnbsqDfeeEOSdPDgQaWnp3vrtJWRlJSkt956S+eff76kM99Qve666zRq1ChJZ96XCgsLK21nyZIlGjp0qBwOh+6++27XDRNfoTgPoFKdO3dWt27dyiy32+2uO647d+4sta5FixYaM2aMli5dqs2bN7vu8r777rtq166dTNPUtGnTXB8uy9OvXz/XG21JsbGxrqLFkiVLSq1LSkpSp06dJLl/2nDBggUqKChQ06ZN1bNnzwqPDwDwr549e+qee+6RdObpnMWLF+vNN9+UJI0aNUodOnSoVnshISGuJwo3bNhQ7natWrXSlVdeWWl7l19+udq2bVutPpTUq1cvSWeGCsjIyCi1rnfv3jrrrLN0+vRpt2MXz507V5JcY84DAHzL19dJixYtktPpVExMTLWGyym+QdC3b1+1bt26zPqoqCgNHTpUkvTtt9/q5MmTbtu56aab1LRpU7friq/JOnXq5HYYC6vVqoceekjSmcLj788LECwcDoeGDh2qJUuWKD4+XnPmzFHXrl1LbTN//nyZpqmePXuW+xkvKipKV199tSTpv//9r9ttGjZsqNtuu83tujVr1rjmSEpJSfGoGH3rrbe6vi1aUmJios455xxJZd8DvenBBx8sM0yPJF111VWSzjzsuX///grbmDVrlkaPHq3CwkI9/vjjevrpp10P0/gKY84DqFTxEw7uNGnSRNKZp0ZKuvHGG8tsW/wh9Y9//KPuvPNObdmyRZMmTdItt9yiBg0auG3f3YfdkuumTZum48eP68CBAzr33HNd6wYOHKj09HQtWrRIo0ePdiUa0zQ1f/58SdKAAQMUEhJSbvsAgMAwevRorV27Vtu2bdOTTz4pSerRo0epsdx/b/369Zo/f742btyoI0eOuJ0wq6KJojp37lylvlVlO4fDoY8++kjffPONdu/erZMnT6qgoMBtf4rzqiTXvCiTJk3Sxx9/XGqM3tzcXH3++eeSeGoeAPzF19dJ33//vSSpe/fuCg0NrVIf8/PzXcWxSy+9tNztunfvLklyOp3atm2b2+uwinLe1q1bKz1Gt27dFBISoqKiIm3dupUbywg6mZmZuuuuu/TDDz+oZcuWevfdd11F7JKKHyD59ttvXX+b7hR/vj106JDb9R06dCi36F78RHt8fHy1H3YpVtl74C+//FLmPdCbOnbsWO6xix0/frzc/SdOnKjp06fLarXqxRdfVP/+/b3cw6rhyXkAlSpvEjxJrkmAqvJVoWKhoaEaPXq0pDPJJC0trdxtK5q8o+QbblZWVql11157rWJiYvTbb79p+fLlruXfffed9u/fz0SwAFCH2O12vfTSS67/N2jQQC+99FK5T7W88soruvPOO7Vw4ULt3btXeXl5atiwoeLi4hQXF6eIiAhJcluwL9a4ceMq9a2y7fbu3avrr79er7zyitatW6esrCxZrVY1btzY1Z9ip06dKrP/LbfcIqvVqh9//FEbN250Lf/888/lcDgUHR3NRLAA4Ce+vk46evSoJKlZs2ZVbvPEiRMqKiqSVPG1Vckn4n9/bVXM3ROyxY4dO1bpMUJDQ9WoUaNS2wPBZO7cufrhhx8UGhqqmTNnui3MS3J9mzI3N1dHjx4t91/xZ9ny5lGq6HNqZmampOq9n/yet98Dq6u8MeFLTlZd3vEPHjyo6dOnSzrzIJC/CvMSxXkAfnLRRRe5fj5w4EC523n6daLQ0FDdfPPNkv73tX9J+vjjjyUxESwA1DXF79/SmSfRf/jhB7fbrV69Wu+8844k6Y477tCnn36qLVu2aO3atVq9erVWr16tu+++u9LjVfWbVZVtl5KSosOHD+vss8/WG2+8oTVr1mjjxo1KS0vT6tWr9e2337q2NU2zzP4JCQmu4XVK5rPiYdtuvPFGJoIFgHqkKtdJnl4jVbRfVdp0N3yEJ+1UZzugPundu7caNGigvLw8paSkuH0wQ5JrEtXHH39cO3furPSfu7mLpKp9ng3Wv8X4+HjXN32mTp3qmjPDHyjOAwhohw8fLnddybF53d0RHjhwoCwWi9auXav9+/crKyvL9RR9eeOuAQACz4oVK1wXHYmJiTJNU0899ZTrCcKSiod66dGjh5577jm1bt26zIWJu/1qw6+//ur6yvBrr72mfv36lZlQtip9KZ5j5YsvvpDD4dDOnTtdFxAMaQMAwSM+Pl7SmSc+q6phw4auPPjrr7+Wu13JdVX99lhJxU/VV3SMvLw81xATnhwDqOvatWunGTNmqGHDhkpLS9OwYcPcfpOz+JuVP/74Y631pfj9pHjceV8p+bk8Ly/P7TblzXvhTXa7XdOmTVOPHj108uRJ3XvvvbU6eW1FKM4D8IuSdyXL+yqXdGaSkvJ89913kqSYmJhS480Xa9mypbp16ybTNPXxxx9r8eLFrolgr7jiihr0HgDgKxkZGUpJSZEkJScn64MPPtDZZ5+tY8eOaezYsWWeNi++qVveJK2mabryR20rWaAorz+pqamVtnPZZZepRYsWOnXqlP7973+7nppnIlgAqH8quk7q1KmTpDPfEiuvqPV7drvdlSsqyn/F+cgwDLVr165afZak9u3bV3qMNWvWuIaY8HSMa6Cu69Chg2bOnKmYmBitXbtW999/v3JyckptUzy/w8qVK8us85biYxw9elRbtmyplWO407BhQ9fP5d3M89VT7GFhYZoyZYquuOIKORwO3Xfffa7x/n2J4jwAr3P3tfyS8vPz9frrr0uSIiIiKpw0aOnSpdqzZ0+Z5VlZWa6v91c01m7x04YLFy50bc9EsABQNzidTj355JP67bff1LJlSz377LNq0KCBJk6cKKvVqlWrVmnGjBml9ikee3LHjh1u2/zwww8rHE7Nm0pO4ueuPw6HQ1OnTq20HYvF4vrG14cffqh///vfknhqHgDqmppeJyUnJyskJETHjx/Xm2++WeXjXnfddZKkZcuWuX0SNycnxzUkXM+ePUvlr+oeIz09XatWrSqzvrCwUFOmTJEktW7dWq1bt672MYD6om3btnr//ffVqFEjrV+/XkOHDpXD4XCtv/XWW2WxWJSdna2XX365wrYKCgo8KuB37drV9ZDjhAkTlJ+fX+02PNGyZUuFhYVJkr788ssy651Op95++22f9EU6MyTyW2+9pd69eysnJ0dDhw7VunXrfHZ8ieI8gFqwbt063XPPPVq8eHGpYWkKCgqUlpamO+64w3UndMSIEYqOji63rdDQUA0dOlSpqamuD7ObN2/WkCFD9NtvvykyMlLDhg0rd/+rr75a8fHxOnbsmPbu3ctEsABQh7zzzjtKS0uTzWbTxIkTXRO5durUSQ899JCkM8PFbNu2zbXP5ZdfLkn69ttv9dZbb7m+Kpydna1p06Zp/PjxZYaWqS0XXHCBa5Ktp59+Wlu3bnWtS09P1+DBg3XixIkqtZWcnCy73a4ff/xRJ06cUHR0tKsQAgCoG2p6ndSiRQvdd999ks7kyGeeeUb79u1zrc/KytKSJUtcObLY7bffrnPOOUcFBQW6//77tXLlSteY1jt37tR9992nX375RTabTY899phHr61v37668MILJUmPPfaYPv30UxUUFEg6M3b+yJEjXUNGPPHEEx4dA6hPkpKSNGvWLMXGxur777/Xfffd5yrQt2nTxjVH0kcffaRHHnlEP/zwg6smUlRUpB07duitt97SNddcU+5cTBUJCQnRs88+K4vFog0bNuiee+7R+vXrXe8NDodDa9as0RNPPKGffvrJS69astls6tOnjyRp2rRpWrJkievGwJ49e/TQQw9p586dXjteVdjtdr355pu66qqrlJubq2HDhvnsm7aSZK18EwCoHtM0lZaWprS0NElnvioUHh4uh8Ph+oBmGIaGDRum+++/v8K2nnrqKf3f//2fhgwZovDwcFksFlehxW6367XXXqtwdnGr1aoBAwa4nkxkIlgAqBs2b97seipw1KhRrq/LF3vwwQeVlpamtWvXavTo0Vq4cKEiIiLUv39/LVq0SOvXr9ebb76pSZMmKTo6WidPnpTT6VSvXr3Upk2bKj2xXlMWi0Xjxo3Tww8/rF27dunPf/6za/LWU6dOKTw8XFOnTtU999xTaVuNGjVSv379XE/N33jjja6njgAAdYM3rpMee+wx5eTk6IMPPtD8+fM1f/58RUREyDRN1+SSv3/yPSoqSlOnTtXQoUN1+PBhDRs2TKGhobLZbK5ioN1u1yuvvKKkpCSPXltISIgmTZqk++67T7t27dITTzyhlJQUhYeHKzs72/XaUlJS1LNnT4+OAdQ3rVu31qxZs3T33Xdr48aNGjJkiN59911FR0frySeflGmaev/997Vs2TItW7ZMoaGhrveM4iGiJM8nde3Zs6deeuklPfvss9qwYYPuvPNO2e12hYWFuf5uJbluCnrL448/ru+++04ZGRkaNWqUbDabQkND5XA4FBkZqWnTpmnQoEFePWZl7Ha73njjDY0ePVpffvmlHnjgAU2bNq3CkR68hSfnAXhd69atNXbsWPXt29f1laWTJ08qNDRUSUlJuuuuu7Ro0SKNGjWq0rbOPfdcLVy4UHfeeacaN26sgoICxcbG6k9/+pMWLVqkXr16VdpGv379XD8zESwABD6Hw6HRo0eroKBA3bt317333ltmG8Mw9MorrygmJkb79u3T3/72N0lnnsZ577339PDDD6tly5ayWq0yTVMdO3bU888/r6lTp/p0aLPevXtrzpw56tWrl6Kjo1VYWKhGjRopOTlZCxYsqNYH/pL5jCFtAKDu8cZ1UkhIiMaNG6d//etfuuGGG9SsWTMVFhbKZrOpVatWGjBggCZNmuT22J9//rlGjhypNm3aKCQkRPn5+WrevLkGDhyozz//vFSe8URCQoI++eQTpaSk6KKLLlJYWJhOnTqls846SzfddJMWLFigwYMH1+gYQH1zwQUXaNasWYqPj9fmzZt1zz336MSJEwoJCdHTTz+thQsX6rbbbtN5552nkJAQORwORUdHq3Pnzho5cqQWL16siy++2OPj9+/fX1988YXuvvtuXXDBBbJarSooKFDz5s119dVX6+WXX9b555/vxVcsNW3aVPPmzdMtt9yihIQESXI9ZLNw4UJdcsklXj1eVdlsNr3++uu69tprdfr0aT3wwANuh+nyNotZ2aBncCsnJ8c1pmnxnR0A3lM8adGsWbPUtWvXGrX13nvv6R//+IeaNm2qr7/+mvHmERTIU0D987e//U1z5sxRp06d9NFHH/m7O0CNkasAAIGMPAVPVSd2GNbGQxEREerevbvrZwCBqaioSB9++KGkM08ZUphHsCBPAfWLw+HQokWLJP1vsnOgriNXAQACGXkKnqpO7FCc95DFYtF///tf188AAo/T6dSbb76pn3/+WREREbr99tv93SXAZ8hTQP2Rn5+vF198UQ6HQ2eddRYTwaLeIFcBAAIZeQqeqk7sUJyvAf4wgcC0dOlSvfzyyzp+/LhycnIkSSNHjlTjxo393DPAt8hTQN02c+ZMzZo1S8eOHdPp06clnZko3W63+7lngPeQqwAAgYw8BU9VNXYozgOod3Jzc3Xw4EHZbDb94Q9/0F133aU777zT390CAKBaTp48qYMHDyo0NFRt2rTRsGHDajxZHwAAAIDAwYSwAAAAAAAAAAD4mOHvDgAAAAAAAAAAEGwozgMAAAAAAAAA4GMU5wEAAAAAAAAA8DGK8wAAAAAAAAAA+BjFeQAAAAAAAAAAfIziPAAAAAAAAAAAPkZxHgAAAAAAAAAAH6M4DwAAAAAAAACAj/0/DlcVRbYR9JIAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Set seaborn plot style\n", + "sns.set_style(\"darkgrid\", rc={'axes.facecolor': '0.9'})\n", + "\n", + "tool_order = [\"h5py\", \"xarray\", \"h5coro\", \"kerchunk\"]\n", + "# Create figure and axis to \"contain\" plot - allows customization via ax object\n", + "fig, ax = plt.subplots(figsize=(15,6), layout=\"constrained\")\n", + "\n", + "# Plot results\n", + "pivot_df.loc[tool_order,:].plot(kind=\"bar\", ax=ax, \n", + " color=[\"tab:cyan\", \"tab:blue\", \"tab:pink\", \"tab:red\"],\n", + " xlabel=\"\", fontsize=15);\n", + "ax.legend(labels = [\"Optimized\", \"Optimized with informed io parameters\", \"Original\", \"Original with informed io parameters\"], fontsize=15)\n", + "ax.set_ylabel(\"Time (s)\", fontsize=20)\n", + "\n", + "## Make two level axis\n", + "\n", + "# helper to create axis labels\n", + "def parse_text(s):\n", + " return re.sub(r\"[()]\", \"\", s).split(\", \")\n", + "\n", + "# Retrieve and parse axis labels and position\n", + "tool, size, x, y = map(np.array, zip(*[(*parse_text(l.get_text()), *l.get_position()) for l in ax.get_xticklabels()]))\n", + "# Make labels and x-positions for seconary axis\n", + "sec_x, sec_label = zip(*[(x[tool == tool_name].mean(), \"\\n\"+tool_name) for tool_name in np.unique(tool)])\n", + "# Assign ticks and labels\n", + "ax.set_xticks(x, size, rotation=0);\n", + "sec = ax.secondary_xaxis(location=0);\n", + "sec.set_xticks(sec_x, sec_label, fontsize=18);\n", + "sec.tick_params(length=0)\n", + "\n", + "sepa_x = np.array([x[tool == tool_name].min()-0.5 for tool_name in np.unique(tool)] + [x.max()+0.5])\n", + "[ax.axvline(xs, c='k', ymin=-.1, clip_on=False, zorder=3) for xs in sepa_x];\n", + "\n", + "# Uncomment to save figure\n", + "# fig.savefig(\"access_time.summary.png\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "815347b5-f23c-4d25-9104-42523e9de093", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 8d8996af477958ebe7b609768a3c9166b249f6e1 Mon Sep 17 00:00:00 2001 From: Andy Barrett Date: Wed, 28 Feb 2024 19:57:42 +0000 Subject: [PATCH 10/11] Remove outputs and add plotting Add plotting for end to end running --- notebooks/portable-full-comparison.ipynb | 800 ++++++++++++++++++++++- 1 file changed, 799 insertions(+), 1 deletion(-) diff --git a/notebooks/portable-full-comparison.ipynb b/notebooks/portable-full-comparison.ipynb index 334bddc..8b1dfb8 100644 --- a/notebooks/portable-full-comparison.ipynb +++ b/notebooks/portable-full-comparison.ipynb @@ -1 +1,799 @@ -{"metadata":{"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.13"}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## AB testing access time for ICESat-2 ATL03 HDF5 files in the cloud.\n\nThis notebook requires that we have 2 versions of the same file:\n * Original A: The original file with no modifications on a S3 location.\n * Test Case B: A modified version of the orignal file to test for metadata consolidation, rechunking and other strategies to speed up access to the data in the file.\n","metadata":{"tags":[],"user_expressions":[]},"id":"6c9b37e2-2daa-4283-a228-ea581498de0c"},{"cell_type":"code","source":"import xarray as xr\nimport h5py\nimport fsspec\nimport logging\nimport re\nimport time\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n\nfrom h5coro import h5coro, s3driver, filedriver\ndriver = s3driver.S3Driver\n\nlogger = logging.getLogger('fsspec')\nlogger.setLevel(logging.DEBUG)","metadata":{"trusted":true,"tags":[]},"execution_count":1,"outputs":[],"id":"3b78fb94-10ae-48cb-8e30-521b2c8b7822"},{"cell_type":"code","source":"for library in (xr, h5py, fsspec, h5coro):\n print(f'{library.__name__} v{library.__version__}')","metadata":{"trusted":true,"tags":[]},"execution_count":2,"outputs":[{"name":"stdout","output_type":"stream","text":"xarray v2023.12.0\nh5py v3.9.0\nfsspec v2023.6.0\nh5coro v0.0.6\n"}],"id":"431d900d-0656-4b75-af6b-82f0f171d5f8"},{"cell_type":"markdown","source":"For listing files in CryoCloud\n\n```bash\naws s3 ls s3://nasa-cryo-persistent/h5cloud/ --recursive\n```","metadata":{"tags":[],"user_expressions":[]},"id":"7998cd99-6034-4a1b-9ae5-d651bc265bff"},{"cell_type":"code","source":"test_dict = {\n \"ATL03-1GB\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\"\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n },\n \"ATL03-7GB\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n },\n \"ATL03-7GB-kerchunk\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\",\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n }, \n \"ATL03-2GB\": {\n \"links\": {\n \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\",\n \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\",\n },\n \"group\": \"/gt1l/heights\",\n \"variable\": \"h_ph\",\n \"processing\": [\n \"h5repack -S PAGE -G 8000000\"\n ]\n }\n}\n\ndef kerchunk_result(file: str, dataset: str, variable: str):\n fs = fsspec.filesystem(\n \"reference\",\n fo=file,\n remote_protocol=\"s3\",\n remote_options=dict(anon=False),\n skip_instance_cache=True,\n )\n ds = xr.open_dataset(\n fs.get_mapper(\"\"), engine=\"zarr\", consolidated=False, group=dataset\n )\n return ds[variable].mean()\n\n# This will use the embedded credentials in the hub to access the s3://nasa-cryo-persistent bucket\nfs = fsspec.filesystem('s3')\n","metadata":{"trusted":true,"tags":[]},"execution_count":3,"outputs":[],"id":"9850faac-f534-4bc2-9214-c8dababe0f52"},{"cell_type":"markdown","source":"## [h5coro](https://github.com/ICESat2-SlideRule/h5coro/)\n\n**h5coro** is optimized for reading HDF5 data in high-latency high-throughput environments. It accomplishes this through a few key design decisions:\n* __All reads are concurrent.__ Each dataset and/or attribute read by **h5coro** is performed in its own thread.\n* __Intelligent range gets__ are used to read as many dataset chunks as possible in each read operation. This drastically reduces the number of HTTP requests to S3 and means there is no longer a need to re-chunk the data (it actually works better on smaller chunk sizes due to the granularity of the request).\n* __Block caching__ is used to minimize the number of GET requests made to S3. S3 has a large first-byte latency (we've measured it at ~60ms on our systems), which means there is a large penalty for each read operation performed. **h5coro** performs all reads to S3 as large block reads and then maintains data in a local cache for access to smaller amounts of data within those blocks.\n* __The system is serverless__ and does not depend on any external services to read the data. This means it scales naturally as the user application scales, and it reduces overall system complexity.\n* __No metadata repository is needed.__ The structure of the file are cached as they are read so that successive reads to other datasets in the same file will not have to re-read and re-build the directory structure of the file.\n","metadata":{"tags":[],"user_expressions":[]},"id":"4d166627-6144-40bf-884d-2188e5c764ba"},{"cell_type":"code","source":"h5coro_beanchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n print (f\"Processing: {link}\")\n if \"kerchunk\" in link:\n continue\n group = dataset[\"group\"]\n variable = dataset['variable'] \n final_h5coro_array = []\n start = time.time()\n if link.startswith(\"s3://nasa-cryo-persistent/\"):\n h5obj = h5coro.H5Coro(link.replace(\"s3://\", \"\"), s3driver.S3Driver)\n else:\n h5obj = h5coro.H5Coro(link.replace(\"s3://\", \"\"), s3driver.S3Driver, credentials={\"annon\": True})\n ds = h5obj.readDatasets(datasets=[f'{group}/{variable}'], block=True)\n data = ds[f'{group}/{variable}'][:]\n data_mean = np.mean(data)\n elapsed = time.time() - start\n \n h5coro_beanchmarks.append({\"tool\": \"h5coro\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n\n\ndf = pd.DataFrame.from_dict(h5coro_beanchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.title('h5coro cloud optimized HDF5 performance')\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":33,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"},{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAKjCAYAAAAj5v8TAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABYzUlEQVR4nO3deVhUdf//8deAw7644haCSynuGlouKaZobllalmaubZr7banVnWilpdXtnX5NLVNbzDa1xcwolzQtdyu1vDO3FEITQUURmfP7o4v5OQdQkIGDw/NxXXPlfM6ZM+85zLzh1TnnMzbDMAwBAAAAAJy8rC4AAAAAAIobghIAAAAAmBCUAAAAAMCEoAQAAAAAJgQlAAAAADAhKAEAAACACUEJAAAAAEwISgAAAABgQlACAAAAABOCEoA8iYuLk81m08mTJ6+6bkxMjGw2W7bbHXfcUQSVWsNmsykuLs6S546JiVFMTEyRP+/x48cVFxenXbt2ZVuW9X5xp8LYZl7kdf9GRkaqW7duOS7btm2bbDabFi1a5BxbtGiRy+fDz89PlSpVUrt27TRt2jQlJSVl207WPsjpNnv2bJdaclrnsccey/frLwoffPCB6tWrJ39/f9lsthzfUwBQ1EpZXQAAz1SjRg299957LmOlS5e2phgUiuPHj2vy5MmKjIxU48aNXZY99NBDbg/GhbHN4mDhwoWqU6eOMjIylJSUpI0bN+qll17Syy+/rA8++EAdOnTI9pivvvpKoaGhLmPVq1d3ud+qVSu9/PLLLmMVK1Z0/wsooBMnTujBBx/UHXfcoTlz5sjX11c33XST1WUBAEEJQOHw9/fXrbfeamkNmZmZunTpknx9fS2toyS64YYbdMMNNxT7bRYH9evXV3R0tPN+r169NGbMGLVu3Vo9e/bU//73v2wB5+abb1b58uWvuN3SpUtb/hm8kvPnz8vPz0/79+9XRkaG+vXrp7Zt27pl22lpaQoICHDLtgCUXJx6ByBf/vrrL/Xp00ehoaGqWLGiBg8erJSUlGve3rFjx/TII48oPDxcPj4+qlKliu655x799ddfznWOHDmifv36KSwsTL6+voqKitIrr7wih8PhXOfQoUOy2WyaPn26nn/+eVWvXl2+vr5au3atJOmzzz5TixYtFBAQoODgYMXGxmrz5s15qvH06dP617/+pRo1asjX11dhYWHq0qWLfv311ys+7pdfflGPHj1UpkwZ+fn5qXHjxlq8eLHLOlmnXx06dMhlfN26dbLZbFq3bp1zzDAMTZ8+XREREfLz81PTpk21atWqPL0GSbpw4YImTpyo6tWry8fHR1WrVtXjjz+u06dPu6yXdQrZ8uXL1bBhQ/n5+alGjRp67bXXXOpr1qyZJGnQoEHOU7uyTj/M6TS5rO1+8cUXatKkifz9/RUVFaUvvvjCuS+ioqIUGBio5s2ba9u2bS6PN2/TfOra5bfLT5UzDENz5sxR48aN5e/vrzJlyuiee+7RH3/84bL9gu5fd6pWrZpeeeUVnTlzRvPmzSvS585677377rsaO3asKlWqJH9/f7Vt21Y7d+7Mtv62bdt05513qmzZsvLz81OTJk304YcfuqyT9bP6+uuvNXjwYFWoUEEBAQHq06ePWrduLUm67777sv3s8vK5zXpf7NixQ/fcc4/KlCmjmjVrSir4e27btm26//77FRkZKX9/f0VGRqpPnz46fPhwjq9v7dq1Gjp0qMqXL69y5cqpZ8+eOn78eLZ9tmTJErVo0UJBQUEKCgpS48aNtWDBApd1vvnmG7Vv314hISEKCAhQq1at9O23317pRwfAzQhKAPKlV69euummm/TJJ59owoQJWrJkicaMGZNtvQMHDqhs2bIqVaqUatasqaefflrnz593WefYsWNq1qyZli9frrFjx2rVqlWaOXOmQkNDlZycLOmf03Jatmypr7/+Ws8995w+++wzdejQQePGjdPw4cOzPe9rr72mNWvW6OWXX9aqVatUp04dLVmyRD169FBISIjef/99LViwQMnJyYqJidHGjRuv+HrPnDmj1q1ba968eRo0aJA+//xzzZ07VzfddJMSEhJyfdxvv/2mli1bas+ePXrttde0bNky1a1bVwMHDtT06dPzsquzmTx5ssaPH6/Y2FitWLFCQ4cO1cMPP6zffvvtqo81DEN33XWXXn75ZT344INauXKlxo4dq8WLF+v2229Xenq6y/q7du3S6NGjNWbMGC1fvlwtW7bUqFGjnKdyNW3aVAsXLpQkPfPMM9q8ebM2b96shx566Ip17N69WxMnTtT48eO1bNkyhYaGqmfPnpo0aZLefPNNTZ06Ve+9955SUlLUrVu3bO+Zy3Xt2tX5vFm3V199VZJUr14953qPPvqoRo8erQ4dOmjFihWaM2eO9uzZo5YtW7oE8oLs38v386VLl7LdMjMz87yNLF26dJG3t7e+++67bMuyjpZeafvfffedgoODZbfbVbduXb3yyiv5quOpp57SH3/8oTfffFNvvvmmjh8/rpiYGJeAuXbtWrVq1UqnT5/W3Llz9emnn6px48a67777XK7HyjJ48GDZ7Xa98847+vjjj/XCCy/o//7v/yRJU6dO1ebNmzVnzhxJyvfntmfPnqpVq5Y++ugjzZ071zlekPfcoUOHVLt2bc2cOVOrV6/WSy+9pISEBDVr1izH6zUfeugh2e12LVmyRNOnT9e6devUr18/l3WeffZZPfDAA6pSpYoWLVqk5cuXa8CAAS7h691331XHjh0VEhKixYsX68MPP1TZsmXVqVMnwhJQlAwAyINJkyYZkozp06e7jA8bNszw8/MzHA6Hc+zpp5825syZY6xZs8ZYuXKlMXz4cKNUqVJGmzZtjMzMTOd6gwcPNux2u7F3795cn3fChAmGJOPHH390GR86dKhhs9mM3377zTAMwzh48KAhyahZs6Zx8eJF53qZmZlGlSpVjAYNGrg895kzZ4ywsDCjZcuWV3zdU6ZMMSQZ8fHxV1xPkjFp0iTn/fvvv9/w9fU1jhw54rJe586djYCAAOP06dOGYRjGwoULDUnGwYMHXdZbu3atIclYu3atYRiGkZycbPj5+Rl33323y3rff/+9Iclo27btFev76quvcvz5ffDBB4YkY/78+c6xiIgIw2azGbt27XJZNzY21ggJCTHOnTtnGIZhbN261ZBkLFy4MNvzZb1fLhcREWH4+/sbf/75p3Ns165dhiSjcuXKzu0ahmGsWLHCkGR89tlnV9zm5X799VejXLlyRrt27Yz09HTDMAxj8+bNhiTjlVdecVn36NGjhr+/v/Hkk08ahlHw/Zv1+iRd8Xb5vsr62W/dujXXbVasWNGIiorKtg/Mt6pVq7o8btiwYcZbb71lrF+/3lixYoXxwAMPGJKMfv36XfV1ZL33mjZt6vK5PnTokGG3242HHnrIOVanTh2jSZMmRkZGhss2unXrZlSuXNn5mct6rf3798/1+T766CPnWH4+t1n75Nlnn8227YK+58wuXbpknD171ggMDDT++9//OsezXt+wYcNc1p8+fbohyUhISDAMwzD++OMPw9vb23jggQdyfY5z584ZZcuWNbp37+4ynpmZaTRq1Mho3rx5ro8F4F4cUQKQL3feeafL/YYNG+rChQsuM3Q9//zzGjp0qNq1a6cuXbpo1qxZevHFF/Xdd9/p008/da63atUqtWvXTlFRUbk+35o1a1S3bl01b97cZXzgwIEyDENr1qzJVp/dbnfe/+2333T8+HE9+OCD8vL6/y0vKChIvXr10g8//KC0tLRcn3/VqlW66aabcryg/krWrFmj9u3bKzw8PFvdaWlpeT7tL8vmzZt14cIFPfDAAy7jLVu2VERERJ7qyXr+y917770KDAzM9n+p69Wrp0aNGrmM9e3bV6mpqdqxY0e+ar9c48aNVbVqVef9rJ99TEyMyzUlWePmU5xyk5iYqDvuuEOVK1fW8uXL5ePjI0n64osvZLPZ1K9fP5cjMJUqVVKjRo2cpzYWdP9mad26tbZu3Zrt9vbbb+d5G5czDCPH8W+++cZl+19++aXL8v/7v//ToEGD1KZNG/Xo0UPvvvuuhg8frnfffTfH0+dy0rdvX5dTHSMiItSyZUvn6ay///67fv31V+c+u3z/dunSRQkJCdmOxvXq1StPz30tn9vctl2Q99zZs2c1fvx41apVS6VKlVKpUqUUFBSkc+fOad++fdmeK6f+ePk24+PjlZmZqccffzzX175p0yadOnVKAwYMcNmnDodDd9xxh7Zu3apz587l+ngA7sNkDgDypVy5ci73syZKuNIpUpLUr18/jRs3Tj/88IPuvvtuSf+cVne1i/P//vtvRUZGZhuvUqWKc/nlKleunO3xOY1nbcPhcCg5OTnXC79PnDihatWqXbHG3OrO7Tlzqjsv25OkSpUqZVuW01hOjy9VqpQqVKjgMm6z2VSpUqVs9VzpefJb++XKli3rcj8r0OQ2fuHChatu88yZM+rSpYsyMjK0atUql9ng/vrrLxmGketsbzVq1JBU8P2bJTQ01GVihoI4d+6c/v77bzVo0CDbskaNGl11Mgezfv36afbs2frhhx/UpEmTq66f277YvXu3JDlPWxw3bpzGjRuX4zbMp6fl9JnIybV8bnPbdkHec3379tW3336rf//732rWrJlCQkJks9nUpUuXHHve1frjiRMnJOmKfS9rv95zzz25rnPq1CkFBgbmuhyAexCUABSpy//vcIUKFfTnn39ecf1y5crleC1Q1gXS5j8WzRMIZP3hkts2vLy8VKZMmVyfPy81FqRuPz8/Scp2jZD5D8ys15GYmJhtm4mJiTmGSfPjL126pBMnTriEJcMwlJiY6JyY4fJt5vQ8l9dSHGRkZKhXr146cOCANmzYkO0P0PLly8tms2nDhg05zn6YNVbQ/VsYVq5cqczMTLd9R1bW0anLP4NXktu+yNpXWe/hiRMnqmfPnjluo3bt2i738/o9WNfyuXX3d2ylpKToiy++0KRJkzRhwgTneHp6uk6dOnVN28z67P3555/ZjjZnydqvs2bNynXWwuI4zTvgiTj1DkCRyJrt7fJf/J07d9batWuveLF8+/bttXfv3myne7399tuy2Wxq167dFZ+3du3aqlq1qpYsWeJyGtO5c+f0ySefOGfUyk3nzp21f//+bKf4XU379u21Zs2abDNevf322woICHDuh6w/wH/66SeX9T777DOX+7feeqv8/PyyfTfVpk2b8nR6Wvv27SX9c5H45T755BOdO3fOuTzLnj17nEcOsixZskTBwcFq2rSppLwfTSxMQ4YM0bp167Rs2TLnaU6X69atmwzD0LFjxxQdHZ3tlnW0pqD7192OHDmicePGKTQ0VI8++qhbtpl1+l9epwx///33XT4zhw8f1qZNm5zBrXbt2rrxxhu1e/fuHPdtdHS0goODr6nWgn5u3cFms8kwjGwB+80337ymyTkkqWPHjvL29tbrr7+e6zqtWrVS6dKltXfv3lz3a9bRLwCFiyNKANxqw4YNeuGFF3T33XerRo0aunDhglatWqX58+fr9ttvV/fu3Z3rTpkyRatWrVKbNm301FNPqUGDBjp9+rS++uorjR07VnXq1NGYMWP09ttvq2vXrpoyZYoiIiK0cuVKzZkzR0OHDr3qF1N6eXlp+vTpeuCBB9StWzc9+uijSk9P14wZM3T69Gm9+OKLV3z86NGj9cEHH6hHjx6aMGGCmjdvrvPnz2v9+vXq1q1brkFt0qRJ+uKLL9SuXTs9++yzKlu2rN577z2tXLlS06dPd54e1qxZM9WuXVvjxo3TpUuXVKZMGS1fvjzbrF5lypTRuHHj9Pzzz+uhhx7Svffeq6NHjyouLi5Pp4bFxsaqU6dOGj9+vFJTU9WqVSv99NNPmjRpkpo0aaIHH3zQZf0qVarozjvvVFxcnCpXrqx3331X8fHxeumll5x/oNasWVP+/v567733FBUVpaCgIFWpUsV5emFhmzFjht555x2NGDFCgYGB+uGHH5zLQkJCVLduXbVq1UqPPPKIBg0apG3btqlNmzYKDAxUQkKCNm7cqAYNGmjo0KEF3r8F8csvvzivQ0lKStKGDRu0cOFCeXt7a/ny5dlOl7yaJUuWaNmyZeratasiIiJ0+vRpffTRR1q6dKkGDhyY7dqz3CQlJenuu+/Www8/rJSUFE2aNEl+fn6aOHGic5158+apc+fO6tSpkwYOHKiqVavq1KlT2rdvn3bs2KGPPvooX7VnKejn1h1CQkLUpk0bzZgxQ+XLl1dkZKTWr1+vBQsWXPOXZ0dGRuqpp57Sc889p/Pnzzu/amHv3r06efKkJk+erKCgIM2aNUsDBgzQqVOndM899ygsLEwnTpzQ7t27deLEiSsGLQBuZNUsEgCuL1kzS504ccJl3Dxr2//+9z+jS5cuRtWqVQ1fX1/Dz8/PaNCggfHCCy8YFy5cyLbdo0ePGoMHDzYqVapk2O12o0qVKkbv3r2Nv/76y7nO4cOHjb59+xrlypUz7Ha7Ubt2bWPGjBkus2FlzXo3Y8aMHOtfsWKFccsttxh+fn5GYGCg0b59e+P777/P02tPTk42Ro0aZVSrVs2w2+1GWFiY0bVrV+PXX391riPTrHeGYRg///yz0b17dyM0NNTw8fExGjVqlOMMcfv37zc6duxohISEGBUqVDBGjBhhrFy50mXWO8MwDIfDYUybNs0IDw83fHx8jIYNGxqff/650bZt2zzNynb+/Hlj/PjxRkREhGG3243KlSsbQ4cONZKTk13Wi4iIMLp27Wp8/PHHRr169QwfHx8jMjLSePXVV7Nt8/333zfq1Klj2O12l32Q26x3Xbt2zbYNScbjjz/uMpbTz9O8zQEDBuQ6u5x5f7z11lvGLbfcYgQGBhr+/v5GzZo1jf79+xvbtm1zrlPQ/Zvb6zOMnGcIzPrsZN18fHyMsLAwo23btsbUqVONpKSkbNvJ7XN4uc2bNxvt27d3fqYCAgKMZs2aGXPmzHH5zOQmaxa6d955xxg5cqRRoUIFw9fX17jttttc9leW3bt3G7179zbCwsIMu91uVKpUybj99tuNuXPnZnutOc3wl9Osd1ny8rm90j4p6Hvuzz//NHr16mWUKVPGCA4ONu644w7jl19+MSIiIowBAwZc9fWZZ6/M8vbbbxvNmjUz/Pz8jKCgIKNJkybZesP69euNrl27GmXLljXsdrtRtWpVo2vXrjnuJwCFw2YYuUypAwAokSIjI1W/fn3nl3KiZFm3bp3atWunjz766IoTCgCAp+MaJQAAAAAwISgBAAAAgAmn3gEAAACACUeUAAAAAMCEoAQAAAAAJgQlAAAAADDx+C+cdTgcOn78uIKDg2Wz2awuBwAAAIBFDMPQmTNnVKVKFXl5XfmYkccHpePHjys8PNzqMgAAAAAUE0ePHtUNN9xwxXU8PigFBwdL+mdnhISEWFwNrJCRkaGvv/5aHTt2lN1ut7ocABahFwCgDyA1NVXh4eHOjHAlHh+Usk63CwkJISiVUBkZGQoICFBISAhNESjB6AUA6APIkpdLcpjMAQAAAABMCEoAAAAAYEJQAgAAAAATj79GKS8Mw9ClS5eUmZlpdSlwA29vb5UqVYrp4AEAAHDNSnxQunjxohISEpSWlmZ1KXCjgIAAVa5cWT4+PlaXAgAAgOtQiQ5KDodDBw8elLe3t6pUqSIfHx+OQlznDMPQxYsXdeLECR08eFA33nij1SUBAADgOlSig9LFixflcDgUHh6ugIAAq8uBm/j7+8tut+vw4cO6ePGivL29rS4JAAAA1xkmc5Dk5cVu8DT8TAEAAFAQ/DUJAAAAACYEJQAAAAAwISgBAAAAgAlBqZgZOHCgbDZbttvvv/9udWkuDh06JJvNpl27dlldCgAAAOB2JXrWu+Lqjjvu0MKFC13GKlSokO/tXLx4ke8RAgAAAK4BR5SKIV9fX1WqVMnl5u3trfXr16t58+by9fVV5cqVNWHCBF26dMn5uJiYGA0fPlxjx45V+fLlFRsbq3Xr1slms2n16tVq0qSJ/P39dfvttyspKUmrVq1SVFSUQkJC1KdPH5cv3f3qq6/UunVrlS5dWuXKlVO3bt104MAB5/Lq1atLkpo0aSKbzaaYmJgi2z8AAABAYSMoXSeOHTumLl26qFmzZtq9e7def/11LViwQM8//7zLeosXL1apUqX0/fffa968ec7xuLg4zZ49W5s2bdLRo0fVu3dvzZw5U0uWLNHKlSsVHx+vWbNmOdc/d+6cxo4dq61bt+rbb7+Vl5eX7r77bjkcDknSli1bJEnffPONEhIStGzZsiLYCwAAAEDR4NS7YuiLL75QUFCQ837nzp110003KTw8XLNnz5bNZlOdOnV0/PhxjR8/Xs8++6zze4Nq1aql6dOnOx+bmJgoSXr++efVqlUrSdKQIUM0ceJEHThwQDVq1JAk3XPPPVq7dq3Gjx8vSerVq5dLTQsWLFBYWJj27t2r+vXrO08FLFeunCpVqlRIewIAAACwBkeUiqF27dpp165dzttrr72mffv2qUWLFrLZbM71WrVqpbNnz+rPP/90jkVHR+e4zYYNGzr/XbFiRQUEBDhDUtZYUlKS8/6BAwfUt29f1ahRQyEhIc5T7Y4cOeK21wkAAAAUVxxRKoYCAwNVq1YtlzHDMFxCUtaYJJfxwMDAHLdpt9ud/7bZbC73s8ayTquTpO7duys8PFxvvPGGqlSpIofDofr16+vixYvX9qIAAACA6whHlK4TdevW1aZNm5zhSJI2bdqk4OBgVa1a1a3P9ffff2vfvn165pln1L59e0VFRSk5OdllnazZ9DIzM9363AAAAEBxwBGl68SwYcM0c+ZMjRgxQsOHD9dvv/2mSZMmaezYsc7rk9ylTJkyKleunObPn6/KlSvryJEjmjBhgss6YWFh8vf311dffaUbbrhBfn5+Cg0NdWsdAAAAhWLaDZLjgtVVWCMuxeoKrhscUbpOVK1aVV9++aW2bNmiRo0a6bHHHtOQIUP0zDPPuP25vLy8tHTpUm3fvl3169fXmDFjNGPGDJd1SpUqpddee03z5s1TlSpV1KNHD7fXAQAAAFjFZlx+LpcHSk1NVWhoqFJSUhQSEuKy7MKFCzp48KCqV68uPz8/iypEYbj8Z+vt7a0vv/xSXbp0yXZtFoCSIyMjg14AlHDOPrD7Edk5olQiXSkbmHFECQAAAABMCEoAAAAAYEJQAgAAAAATghIAAAAAmBCUAAAAAMCEoAQAAAAAJgQlAAAAADAhKAEAAACACUEJAAAAAExKWV1AcRU5YWWRPdehF7sW2XNdTWRkpEaPHq3Ro0df8zbi4uK0YsUK7dq1y211mcXExKhx48aaOXNmoT0HAAAASi6OKJVQixYtUunSpbONb926VY888kiBtj1u3Dh9++23BdoGAAAAYCWOKMFFhQoVCryNoKAgBQUFuaEaAAAAwBocUbpOpaena+TIkQoLC5Ofn59at26trVu3SpLWrVsnm82mlStXqlGjRvLz89Mtt9yin3/+2bl80KBBSklJkc1mk81mU1xcnKR/Tr27/HQ2m82mefPmqVu3bgoICFBUVJQ2b96s33//XTExMQoMDFSLFi104MAB52Pi4uLUuHFjl22Yb5GRkc7le/fuVZcuXRQUFKSKFSvqwQcf1MmTJ53Lz507p/79+ysoKEiVK1fWK6+84v4dCgAAAFyGoHSdevLJJ/XJJ59o8eLF2rFjh2rVqqVOnTrp1KlTznWeeOIJvfzyy9q6davCwsJ05513KiMjQy1bttTMmTMVEhKihIQEJSQkaNy4cbk+13PPPaf+/ftr165dqlOnjvr27atHH31UEydO1LZt2yRJw4cPz/XxWc+RkJCg33//XbVq1VKbNm2cy9q2bavGjRtr27Zt+uqrr/TXX3+pd+/eLq9j7dq1Wr58ub7++mutW7dO27dvL+guBAAAAHLFqXfXoXPnzun111/XokWL1LlzZ0nSG2+8ofj4eC1YsEDNmjWTJE2aNEmxsbGSpMWLF+uGG27Q8uXL1bt3b4WGhspms6lSpUpXfb5BgwY5g8v48ePVokUL/fvf/1anTp0kSaNGjdKgQYNyfXzWcxiGoV69eik0NFTz5s2TJL3++utq2rSppk6d6lz/rbfeUnh4uPbv368qVapowYIFevvtt7O9FgAAAKCwEJSuQwcOHFBGRoZatWrlHLPb7WrevLn27dvnDEotWrRwLi9btqxq166tffv25fv5GjZs6Px3xYoVJUkNGjRwGbtw4YJSU1MVEhKS63aeeuopbd68WVu3bpW/v78kafv27Vq7dm2O1zQdOHBA58+f18WLF3N8LQAAAEBhsfTUu++++07du3dXlSpVZLPZtGLFCpflhmEoLi5OVapUkb+/v2JiYrRnzx5rii1GDMOQ9M+1P+Zx85jZ1ZbnxG63Z3t8TmMOhyPXbbz77rv6z3/+o+XLl7scDXI4HOrevbt27drlcvvf//6nNm3aOF8rAAAAUJQsDUrnzp1To0aNNHv27ByXT58+Xa+++qpmz56trVu3qlKlSoqNjdWZM2eKuNLipVatWvLx8dHGjRudYxkZGdq2bZuioqKcYz/88IPz38nJydq/f7/q1KkjSfLx8VFmZmaR1Lt582Y99NBDmjdvnm699VaXZU2bNtWePXsUGRmpWrVqudwCAwNVq1Yt2e32HF8LAAAAUFgsDUqdO3fW888/r549e2ZbZhiGZs6cqaefflo9e/ZU/fr1tXjxYqWlpWnJkiUWVFt8BAYGaujQoXriiSf01Vdfae/evXr44YeVlpamIUOGONebMmWKvv32W/3yyy8aOHCgypcvr7vuukvSP7PbnT17Vt9++61OnjyptLS0Qqk1MTFRd999t+6//3516tRJiYmJSkxM1IkTJyRJjz/+uE6dOqU+ffpoy5Yt+uOPP/T1119r8ODByszMVFBQkIYMGaInnnjC5bV4eTEPCQAAAApPsb1G6eDBg0pMTFTHjh2dY76+vmrbtq02bdqkRx99NMfHpaenKz093Xk/NTVV0j9HXDIyMlzWzcjIkGEYcjgc2U4b+2NqZ3e9lKu60ilruZk6daoyMzP14IMP6syZM4qOjtaqVasUGhrq3N7UqVM1atQo/e9//1OjRo20YsUKlSpVSg6HQ7feeqseffRR3Xffffr777/17LPPatKkSZLk3CeX15d1//L/5jaWdbqcw+HQ3r179ddff2nx4sVavHixc5sRERH6448/VKlSJW3YsEETJkxQp06dlJ6eroiICOdEEQ6HQy+99JLOnDmjO++8U8HBwRo7dqxSUlKy1Wnep4ZhKCMjw7mO+ecPoGTJ6gH0AqDkcvYBLz+LK7FQCe+B+fkdYDOKyUUgNptNy5cvdx7x2LRpk1q1aqVjx46pSpUqzvUeeeQRHT58WKtXr85xO3FxcZo8eXK28SVLliggIMBlrFSpUqpUqZLCw8Pl4+PjvhdjsY0bN6p79+46dOiQQkNDrS7HEhcvXtTRo0eVmJioS5cuWV0OAAAAioG0tDT17dtXKSkpV5yETCrGR5Sy5HfCgokTJ2rs2LHO+6mpqQoPD1fHjh2z7YwLFy7o6NGjCgoKkp+f5/yfhaxAGBwcfNU3gKe6cOGC/P391aZNG3l7eys+Pl6xsbEuk1AAKFkyMjLoBUAJ5+wDP4+U3XHB6nKsMfFPqyuwVNbZZnlRbINS1nfvJCYmqnLlys7xpKQk5xTVOfH19ZWvr2+2cbvdnu0XY2Zmpmw2m7y8vDzqmpes1+Jprys/vLy8ZLPZZLfb5e3tLSnn9wCAkodeAMDuuFByg1IJ73/56f/F9q/o6tWrq1KlSoqPj3eOXbx4UevXr1fLli0trKz4i4mJkWEYKl26tNWlAAAAANclS48onT17Vr///rvz/sGDB7Vr1y6VLVtW1apV0+jRozV16lTdeOONuvHGGzV16lQFBASob9++FlYNAAAAwNNZGpS2bdumdu3aOe9nXVs0YMAALVq0SE8++aTOnz+vYcOGKTk5Wbfccou+/vprBQcHW1UyAAAAgBLA0qCUdYpYbmw2m+Li4hQXF1d0RQEAAAAo8YrtNUoAAAAAYBWCEgAAAACYEJQAAAAAwKTYfo+S5eJCi/C5UormaeLitGLFCu3atSvPj4mJiVHjxo01c+ZMS+sAAAAAihJBqQQZN26cRowYka/HLFu2jC9mBAAAQIlDUCoBDMNQZmamgoKCFBQUlK/Hli1btpCqAgAAAIovrlG6TqWnp2vkyJEKCwuTn5+fWrdura1bt0qS1q1bJ5vNptWrVys6Olq+vr7asGGD4uLi1LhxY+c2Ll26pJEjR6p06dIqV66cxo8frwEDBuiuu+5yrhMTE6PRo0c770dGRmrq1KkaPHiwgoODVa1aNc2fP9+ltvHjx+umm25SQECAatSooX//+9/KyMgozN0BAAAAuBVB6Tr15JNP6pNPPtHixYu1Y8cO1apVS506ddKpU6dc1pk2bZr27dunhg0bZtvGSy+9pPfee08LFy7U999/r9TUVK1YseKqz/3KK68oOjpaO3fu1LBhwzR06FD9+uuvzuXBwcFatGiR9u7dq//+979644039J///MctrxsAAAAoCgSl69C5c+f0+uuva8aMGercubPq1q2rN954Q/7+/lqwYIFzvSlTpig2NlY1a9ZUuXLlsm1n1qxZmjhxou6++27VqVNHs2fPVunSpa/6/F26dNGwYcNUq1YtjR8/XuXLl9e6deucy5955hm1bNlSkZGR6t69u/71r3/pww8/dMdLBwAAAIoE1yhdhw4cOKCMjAy1atXKOWa329W8eXPt27dPzZo1kyRFR0fnuo2UlBT99ddfat68uXPM29tbN998sxwOxxWf//KjUzabTZUqVVJSUpJz7OOPP9bMmTP1+++/6+zZs7p06ZJCQkLy/ToBAAAAq3BE6TpkGIakf0KKefzyscDAwKtuK6dtXI15FjybzeYMVz/88IPuv/9+de7cWV988YV27typp59+WhcvXrzqdgEAAIDigqB0HapVq5Z8fHy0ceNG51hGRoa2bdumqKioPG0jNDRUFStW1JYtW5xjmZmZ2rlzZ4Fq+/777xUREaGnn35a0dHRuvHGG3X48OECbRMAAAAo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ovTaa69p0KBBCgsL086dO9W8eXOVK1dOf/zxhzp37lwYNQIAAABAkcp3UJozZ47mz5+v2bNny8fHR08++aTi4+M1cuRIpaSkFEaNAAAAAFCk8h2Ujhw5opYtW0qS/P39debMGUnSgw8+qPfff9+91QEAAACABfIdlCpVqqS///5bkhQREaEffvhBknTw4EG+hBYAAACAR8h3ULr99tv1+eefS5KGDBmiMWPGKDY2Vvfddx/frwQAAADAI+R71rv58+fL4XBIkh577DGVLVtWGzduVPfu3fXYY4+5vUAAAAAAKGr5DkpeXl7y8vr/B6J69+6t3r17u7UoAAAAALDSNX3h7IYNG9SvXz+1aNFCx44dkyS988472rhxo1uLAwAAAAAr5DsoffLJJ+rUqZP8/f21c+dOpaenS5LOnDmjqVOnur1AAAAAAChq+Q5Kzz//vObOnas33nhDdrvdOd6yZUvt2LHDrcUBAAAAgBXyHZR+++03tWnTJtt4SEiITp8+7Y6aAAAAAMBS+Q5KlStX1u+//55tfOPGjapRo4ZbigIAAAAAK+U7KD366KMaNWqUfvzxR9lsNh0/flzvvfeexo0bp2HDhhVGjQAAAABQpPI9PfiTTz6plJQUtWvXThcuXFCbNm3k6+urcePGafjw4YVRIwAAAAAUqXwHJUl64YUX9PTTT2vv3r1yOByqW7eugoKC3F0bAAAAAFjimoKSJAUEBCg6OtqdtQAAAABAsZDnoDR48OA8rffWW29dczEAAAAAUBzkOSgtWrRIERERatKkiQzDKMyaAAAAAMBSeQ5Kjz32mJYuXao//vhDgwcPVr9+/VS2bNnCrA0AAAAALJHn6cHnzJmjhIQEjR8/Xp9//rnCw8PVu3dvrV69miNMAAAAADxKvr5HydfXV3369FF8fLz27t2revXqadiwYYqIiNDZs2cLq0YAAAAAKFL5/sLZLDabTTabTYZhyOFwuLMmAAAAALBUvoJSenq63n//fcXGxqp27dr6+eefNXv2bB05coTvUQIAAADgMfI8mcOwYcO0dOlSVatWTYMGDdLSpUtVrly5wqwNAAAAACyR56A0d+5cVatWTdWrV9f69eu1fv36HNdbtmyZ24oDAAAAACvkOSj1799fNputMGsBAAAAgGIhX184CwAAAAAlwTXPegcAAAAAnoqgBAAAAAAmBCUA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NWrUkCStXr1aY8eO1Z49e6wsE0AhoxcAoA/AHTiiBI9x6NAh1axZ03k/NjbWOQ2oJNWuXVsHDx60ojQARYheAIA+AHfgGiV4jEuXLiklJcV5f9myZS7Lk5OT5eXF/xsAPB29AAB9AO7AOwQeo3bt2tq0aVOuyzds2KCbbrqpCCsCYAV6AQD6ANyBoASPcf/99+vZZ5/VTz/9lG3Z7t27NXnyZPXp08eCygAUJXoBAPoA3IHJHOAxMjIy1KFDB23atEmxsbGqXbu2bDabfv31V8XHx6tFixb69ttvZbfbrS4VQCGiFwCgD8AdCErwKBcvXtSrr76qpUuXav/+/ZKkG2+8UX369NGYMWPk6+trcYUAigK9AAB9AAVFUAIAAAAAE65RAgAAAAATghJKjN27d8vb29vqMgAUgZUrV+qhhx7Sk08+qX379rksS05O1u23325RZQCKQnBwsIYMGXLFme+AqyEooUThTFPA8y1ZskQ9evRQYmKiNm/erKZNm+q9995zLr948aLWr19vYYUACtu5c+f0448/qnXr1oqKitIrr7yipKQkq8vCdYZrlOAxevbsecXlKSkpWrdunTIzM4uoIgBWaNq0qQYNGqQRI0ZIkj7++GMNGjRIM2fO1JAhQ/TXX3+pSpUq9ALAg3l5eSkxMVEJCQl68803tWTJEp09e1bdunXTQw89pDvuuEM2m83qMlHMcUQJHuPzzz/XhQsXFBoamuMtKCjI6hIBFIH9+/erW7duzvv33HOPPv/8c40ZM0Zz5861sDIARa1Ro0aaNWuWEhIStGjRIqWkpKhbt26qVq2ann32WavLQzFXyuoCAHeJiopSr169NGTIkByX79q1S1988UURVwWgqIWEhOivv/5S9erVnWMxMTH6/PPP1a1bN/35558WVgegKJiPFvn4+KhPnz7q06ePDh06pAULFmjRokWaMmWKRRXiesARJXiMm2++WTt27Mh1ua+vr6pVq1aEFQGwQvPmzbVq1aps423bttXnn3+umTNnFn1RAIrUla4siYyM1HPPPafDhw8XYUW4HnFECR5j7ty5V7zmICoqSgcPHizCigBYYcyYMbnOdBUTE6MvvvhCixcvLuKqABSlSZMmXfWUe65RwtUwmQMAAAAAmHDqHTxa165dlZCQYHUZACxGLwBAH0B+EZTg0b777judP3/e6jIAWIxe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\n","text/plain":"
"},"metadata":{}}],"id":"efe41d4a-1947-438b-a3c3-7ab954d75e13"},{"cell_type":"markdown","source":"### Xarray + kerchunk, out of the box performance.","metadata":{"tags":[],"user_expressions":[]},"id":"8f0ba64d-d89c-4879-b965-f00d70956360"},{"cell_type":"code","source":"# this is going to keep our numbers without modifying the i/o paramters\nregular_xarray_benchmarks = []\nkerchunk_benchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n print (f\"Processing: {link}\")\n try:\n log_filename = f\"logs/fsspec-xarray-{key}-{k}-default.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n \n start = time.time()\n if \"kerchunk\" in link:\n data_mean = kerchunk_result(link, dataset[\"group\"], dataset[\"variable\"])\n elapsed = time.time() - start\n kerchunk_benchmarks.append(\n {\"tool\": \"kerchunk\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean}) \n else:\n ds = xr.open_dataset(fs.open(link, mode='rb'), group=dataset[\"group\"], engine=\"h5netcdf\", decode_cf=False)\n data_mean = ds[dataset[\"variable\"]].mean() \n elapsed = time.time() - start\n regular_xarray_benchmarks.append(\n {\"tool\": \"xarray\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean}) \n \n logging.getLogger().removeHandler(file_handler)\n file_handler.close()\n\n except Exception as e:\n print(e)","metadata":{"trusted":true,"tags":[]},"execution_count":22,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"}],"id":"ff56958f-8c1d-4fd7-b885-6efb81af8da7"},{"cell_type":"markdown","source":"### Plotting Results","metadata":{"tags":[],"user_expressions":[]},"id":"92a8e67d-026e-4c6b-aa7d-b19dc10f4afd"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(kerchunk_benchmarks + regular_xarray_benchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\n\nplt.title(\"Out of the box I/O parameters\", fontsize=10)\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\n\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":24,"outputs":[{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAMfCAYAAADomSepAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACS8ElEQVR4nOzde3zP9f//8ft7s713HnPYgdkcQ8gpcsiGRpSoPikqRKWUYyKpTEKpUOn8yaED+lR0UlhyPoRKKeeztJnzMGa25+8Pv72/3u8NG+/ttc3ternswvv1er1fr8f78Hjvfd/r9Xq+bMYYIwAAAACAg4fVBQAAAABAYUNQAgAAAAAXBCUAAAAAcEFQAgAAAAAXBCUAAAAAcEFQAgAAAAAXBCUAAAAAcEFQAgAAAAAXBCUAAAAAcEFQAi4iPj5eNptNixcvtroUh9jYWNlsNqvLyJPo6GhFR0fn2/oL0+tUFF+fa8m8efN00003KTg4WDabTT179rS6pGvWyZMnFR4err59+zpNL2o9lB+fb4sXL5bNZlN8fLxb11tYTZ06VZ6entqwYYPVpQDZEJRwTfn111/Vu3dvVatWTf7+/vL19VWVKlX04IMPKiEhweryiqSePXvKZrNp9+7dVpdSpGR9GXrssccuusysWbNy/MKU9WUy68fLy0ulS5dWvXr11Lt3b82bN0+ZmZk5rjM6Otrpvq4/FwbOrBCa04+Pj487noYCs2vXLnXu3Fl79+7Vww8/rJEjR6pz585Wl3XNGj9+vI4cOaLhw4dbXco16VIBr6CD2oMPPqhKlSppyJAhBbI9IC9KWF0AUBAyMzM1ZMgQTZw4USVKlFDr1q11xx13yMvLSzt37tTcuXP16aef6sUXX9Tzzz9vdbnFysKFC/N1/U8++aTuu+8+VaxYMV+3Uxg99dRTCggIUGZmpo4dO6ZNmzbps88+05QpU9SsWTPNnDkzx+fF09NTzz33XI7rzOnLU48ePbJNL1GiaP36WLhwodLS0jRhwgTdd999VpdzTTt27JgmTJigrl27KjIy0upyrkp+f75dC0qUKKGBAweqX79+Wr58uVq0aGF1SYBD0fpNB1yh5557ThMnTlS9evX05ZdfqkqVKk7zT58+rcmTJ+vw4cMWVVh8uT7X7lamTBmVKVMmX7dRWA0ZMkRhYWFO0w4ePKj+/ftr1qxZateundatWyd/f3+nZUqUKJGnvxb37NlTsbGxbqjYOv/++68kZXu+UPA++eQTnTp1Sg8++KDVpVy1/P58u1bcd999GjRokN577z2CEgoVDr1Dsbd9+3aNHz9epUuX1rx583L8xebr66unn35ao0aNytU6v//+e7Vq1UrBwcHy9fVVvXr1NGnSJGVkZDgtd6lDGHbv3n3R8ySWL1+umJgY+fv7q3Tp0rr33nu1b9++XNWWk5UrV+q2225TSEiIfHx8VKNGDcXHxys1NTXbsjabTbGxsdq3b5/uvfdelS5dWv7+/oqNjdXKlSudlo2Ojtb06dMlSZUqVXIclnXhl+qcDvG48LyiqVOnqk6dOvL19VWlSpX05ptvSpKMMXrjjTdUo0YN+fj4qHr16vrkk0+y1ZvTOUquh6a5/ri+HsnJyRo0aJCqVq0qu92uMmXK6O6779Zff/2V4/Pp7tfHncqWLavPPvtMbdq00ebNm/X2229bXZKmTZsmm82madOmac6cObrxxhvl5+ensLAwPf744zp69GiO99u1a5cefvhhVaxYUXa7XeHh4erZs6f27NmTbdms993+/fvVs2dPhYWFycPDw7HtkSNHSpJatWrleB9ceLjolfSI67YWL17s1PMrV65Uq1atFBgYqLJly6pv3746ffq0pPPnSzVv3lz+/v4KDQ3VsGHDsn1+HD9+XK+88opiYmIUEREhb29vRUREqHv37tqxY0e2ui7shf/9739q0KCBfH19FR4erv79+zu27WrZsmW68847FRoaKrvdrsjISN11111avny503LGGE2ZMkXNmzdXUFCQ/Pz81KhRI02ZMiXH9V7MtGnTVLp0abVq1SpP9/vmm2/Upk0blSpVSj4+Pqpdu7Zee+21bM9bZmam/vvf/6px48YKCQmRn5+foqOj1blzZy1dutRp2a+++koxMTEqV66cfHx8FBkZqVtvvVVff/11rmrK6fPtzJkzev3113XDDTcoODhYAQEBqlKlirp27Zrn83CWLl2qmJgYBQQEKCQkRN26ddM///yT47K5+RzL+r2zZ88e7dmzJ9vnYnx8vON1GTVqlNP8C/vl7NmzmjBhgho0aCB/f38FBgbq5ptv1rfffputrqzDs3fu3KmJEyfq+uuvl91ud/rdV6ZMGbVq1UpffvmlTp48mafnCMhP7FFCsTdt2jRlZGSoT58+Cg0NveSydrv9sut74403NHDgQMcvLX9/f3333XcaNGiQli1bpi+//PKqTkZeuHCh2rdvLw8PD917772KiIjQwoUL1bx5c5UqVSrP6/vqq6903333ydvbW/fee6/KlSunn376SaNGjdKCBQu0aNGibI/76NGjat68ucLDw/Xoo49q//79+vzzz9WqVSvNnz/fEYQGDhyoadOm6Y8//tCAAQNUsmRJSTkfvpWTSZMmafHixerUqZNat26tr776SgMGDJCfn5/++OMPffHFF7r99tvVunVrzZo1S927d1elSpUu+xfHi+0B+eKLL7Rx40b5+fk5pu3YscPxpbdt27bq3LmzkpOT9dVXX2n+/PlauHChmjRp4lje3a9PfvDw8NCIESO0cOFCff755xo6dOhVrW/ZsmVas2aNPD09VaNGDd1yyy256hVXX375pRISEnTPPffolltu0ZIlS/Tee+9p1apVWrVqlXx9fR3L/vLLL2rXrp1OnTqljh07qmrVqtq9e7c+++wz/fjjj1q1apUqV67stP7Dhw+radOmCgkJ0b333quzZ8+qbt26GjlypBYvXqwlS5Y4HUaY9X69kh7JaVtBQUFKSUlx1P/KK6+oXbt26tOnjxYtWqR3331XKSkp6tSpk3r06KE77rhDTZo00dy5czV+/HgFBQVpxIgRjm1s2rRJL7zwglq1aqU777xT/v7+2rx5s2bMmKG5c+fqt99+U1RUVLbn+e2339aPP/6oTp06KTY2VvPmzdNbb72lw4cP67PPPsu2bL9+/eTr66s777xTFStW1P79+7V8+XJ9+eWXjl4zxuiBBx7QjBkzVL16dXXr1k3e3t5KSEhQ7969tXHjRr322muXfQ8cPXpUv//+u2699VZ5eOT+b7XPPvusxo0bpwoVKujuu+9WUFCQli5dqqefflq//PKLvvjiC8eyw4cP1/jx41WlShV169ZNgYGB2r9/v5YtW6aff/5ZLVu2lCS9++676tu3r8LDw3XnnXeqdOnSSkxM1Jo1a/T1119f8TlsPXr00P/+9z/VrVtXDz30kOx2u/bu3atFixapXbt2qlOnTq7Ws3r1ao0bN0633Xab+vfvr99++00zZ87U8uXLtXbtWqffZ7n9HCtZsqRGjhypSZMmSTr/GZ4l6zNz9+7dmj59umJiYpw+R7P6JS0tTbfeeqsWL16s+vXr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MbsSQUFBuvXWWzVv3jw1aNBA//nPf3TzzTerSZMmF329LqZ58+bZDuP29fVVw4YNNW/ePG3dulW1a9fO8+fY1diyZYuOHj2qiIiIHM/pPXjwoNM2L9S4ceNLrjskJESSdOjQoauqEXAnghKKvbCwMG3evFn79+/Xddddd1Xryjr/4GLnOpUrV0779++/4vUfP37csZ6chIaGZgtKrr+soqKiHEHpcvWGhYVpy5YtSklJcfoSeKntX1jn1QoKCso2LWvY6YvNu/CL4uWcOXNGnTt31r59+/TFF19k+wJ55MgRSdLcuXM1d+7ci67n1KlTkvL++lgpLS1NR44ckaenp+MLiLv06NFDffv21YoVK/J0v0s9b5s3b3a8D7NeF9fzaVxlvS4XrievrrRHLretK3lvS/8XOqTz59Tde++9CggIULt27RQdHS0/Pz/HwBg5DWohScHBwRdd/4UDHxw7dkw2m80R0i7m6NGjMsZo//79lxzwxvX1yEnWeWgXG1giJ0eOHNG5c+dyve0333xTlStX1rRp0/TSSy/ppZdeko+Pj7p06aLXX3/dEXCHDh2q0qVL67333tOECRP0+uuvq0SJEurQoYMmTZqkSpUq5brGC3355ZcaO3asZs6c6TjnLDAwUL169dLYsWOdzpG8lNx+Duf1c+xqZG3r77//1t9//52nbV2uZ7LeE7l9foCCwKh3KPaaN28uyT3Xu8j6gnPgwIEc5ycnJzt9Cco6WTmnL/c5hY2sLzjJyck5rt91u7GxsTLnD6F1/Fz4Rf1y9WZNd/3idrnt5/RFrDDq1auXVq9erdGjR+vuu+/ONj/rcb/11lvZnscLf3r06CEp76+PlVasWKFz586pXr16br/mkbe3twIDA3McEe5SLve8Zb0eWf9+9913l3xdYmJinNZzJYOoXGmPXM2ALbkVHx8vHx8f/frrr/riiy/06quvatSoUY7pV6tkyZIyxigxMfGSy2U99oYNG17y9Vi0aNFlt1m2bFlJ//eFOzeCgoJUunTpS257165djuW9vLz09NNP6++//9b+/fs1Y8YM3Xzzzfr44491//33O5az2Wx6+OGHtW7dOh08eFBz5szRXXfdpW+//Va33XZbttH0csvf319jxozRzp07tXPnTn300UeqUaOG3njjDQ0aNCjX68nt53BeP8euRta27r777ktua+rUqdnue7meyXpPZL1HgMKAoIRir2fPnvL09NQHH3zgOCzgYtLS0i45P+twmguHos6yZs0anT592umwmqzDS3Lay5R1yM+FbrjhBknnRxlztWfPnjwPQX2pevfv368dO3aocuXKTn8pv9S2suq68DF6enpK0hV/qcgvL774ombOnKn777/faSSxC2WNZrdq1apcrdPdr09+yczM1NixYyXpqg7du5ht27bp6NGjuR7dMEtOz9u///6rHTt2qEqVKo73YV5fl6txpT1SEHbs2KGaNWuqWrVqTtOznrOrlXUo1IIFCy65XGBgoGrWrKlNmzY5Hbp3JbJGfNu2bVuu79OkSRMdPnw4T/fJEhERoa5du2revHmqVq2afvrppxz3ZpUuXVqdO3fW559/rtatW2vTpk3avn17nrfnqlKlSurVq5eWLFmigICAHIfPvpgVK1ZkO3z29OnT+vXXX+Xr66vq1atLurJ+8fT0vOhn9qU+02vWrKmgoCCtW7fOae+nO2zZskWScj0qIFAQCEoo9qpWraqhQ4fq0KFDat++vdNfHrOcOXNGEyZMuOxFOLt166YSJUpowoQJjgtYSucPl3nmmWckyenaENddd53jl+OFf0E9cOCAXnrppWzrb9GihSpVqqTvv//e6Romxhg9++yzeQ4jnTp1UnBwsKZOnep0mIQxRsOHD1d6enqO13HKyMjQiBEjnH5JL1myRD/88IOqVq2qZs2aOaZnHdZ1sWt7WOGLL75QfHy8mjZtetHzGqTzXxSbNGmimTNn6vPPP882PzMzU0uWLHHcdvfrkx8OHjyoBx54QAsXLlStWrX0+OOPX9F6Tpw4oT///DPb9KNHj6p3796S8h7CEhISsu3Zfe6555Senu701+5OnTqpYsWKmjBhQrbr3kjn+831Gj9X6kp7pCBERUVp+/btTnu7zpw5o8cffzxPh6BezGOPPSZPT08999xz2Q7jc93T1L9/f6WmpuqRRx7J8bCqXbt25eqw0zp16igkJMRxflRu9O/fX9L5PcQ5XRQ8KSlJmzZtknT+j10///xztoBx6tQpnThxQl5eXo4gMH/+/GzPY3p6uuOz+sLh6nPr4MGDOT62o0ePKi0tLU/r3LJlS7ZrVL366qs6ePCgunbt6jjnKa+fY9L5z+1Dhw7leK7ipT7TS5Qooccff1x79uzRkCFDcgxLf/3110X3hl1K1vmnrnuKAStxjhKuCS+99JLOnDmjiRMn6rrrrlPr1q1Vu3ZteXl5adeuXfrpp590+PDhHMPLhapUqaJXXnlFTz31lOrWrasuXbrI399f33//vTZv3qxOnTrpgQcecCzv7e2tJ598Ui+//LIaNGigTp066cSJE/ruu+8UExOT7a/CHh4e+uCDD9ShQwfdcsstjuv0/Pzzz0pMTFTdunVz/PJ6MUFBQfrwww/VtWtXNWnSRPfee6/Kli2rhQsXat26dWrcuLGefvrpbPerW7euFi9erJtuukmtW7fWv//+q1mzZsnLy0sffvih0/VPWrdurddee019+vTRPffcI39/f1WsWFHdunXLdZ3u1qNHDxljdMMNN2jcuHHZ5sfGxjpO3p85c6ZatWql++67T5MmTVLDhg3l4+OjvXv3atWqVTp48KDjy4S7X5+r9dprrykgIECZmZlKSUnRxo0btXTpUqWlpal58+aaNWvWFR/vf/jwYd1www1q1KiR6tSp4zj/7scff9Thw4cVFxeXp8OIJOm2225Thw4ddM899ygyMlJLlizRqlWrdMMNN2jIkCGO5ex2u7788ku1b99eMTExatOmjeMk9L1792rZsmUqXbp0rgYPuJwr7ZGC0K9fP/Xr10/169fXf/7zH507d04JCQmO93bW4CJXqk6dOpo0aZL69++v66+/Xp07d1ZUVJSSkpK0dOlS3XbbbY7r7fTp00erV6/W9OnTtWLFCt1yyy2KiIjQgQMHtHnzZv3yyy+aMWPGZfcy2mw23XHHHfr444+VmJh42fOjJOnWW2/V888/r9GjR6tq1aq69dZbFRUVpcOHD2v79u1atmyZXnrpJdWsWVOnT59WmzZtVLlyZTVp0kQVK1bUyZMn9f333yspKUnDhg1zBIx7771Xfn5+atGihaKiopSenq6EhARt3LhR9957rypWrJjn53T//v1q0qSJrr/+ejVo0EDly5fX4cOH9c033yg9PT1P1zRr27at+vbtq7lz56pGjRr67bffNH/+fEVGRjr2GGfJy+eYdP5ze926derYsaNuvvlmeXt7q0WLFmrRooVq1KihiIgIx+dHhQoVZLPZ9Pjjjys4OFijRo3Sb7/9pjfffFNz585VTEyMypYtq/3792vDhg36448/tGrVqoueY5UTY4wWLlyomjVrOvaUAYWCewbPA4qGtWvXml69epmqVasaX19fY7fbTXR0tOnatWu2609catjpb775xsTExJjAwEBjt9tNnTp1zOuvv+50fZEs586dMy+88IKJjIw03t7epnr16uaNN94wO3fuzDY8eJalS5eali1bGl9fXxMSEmLuueces2fPnhyHzs2NpUuXmvbt25uSJUs6anj++efNyZMnsy0rycTExJg9e/aYe+65x5QqVcr4+vqali1bmuXLl+e4/vHjx5tq1aoZLy8vx/2zXGp48Jye20sNN57T489pXcrjcNtHjhwxzz33nKldu7bx9fU1AQEBplq1aqZbt25m9uzZ2epwx+uTNQRvnz59LrrMzJkzLzk8eNZPiRIlTKlSpcwNN9xgevXqZebNm+d0rasLRUVFGbvdftn6jh8/bp544gnTsGFDU6ZMGVOiRAkTHBxsWrRoYd57770cr1V0MVnDg0+dOtXMnj3bNGzY0Pj4+Jhy5cqZPn365HitIGOM+eeff8yAAQNMtWrVjN1uN0FBQaZmzZrm4YcfNgsXLnRa1vV95+pyw8hfSY/k5FJDK1/4POSmvszMTPPee++Z66+/3vj4+JiwsDDTu3dvc+DAgVz3Qm62vWjRInP77bebkJAQ4+3tbSpUqGDuvvtus2LFimzLfv755+aWW24xpUqVMl5eXqZ8+fImNjbWvP766xcdmt1V1qUUXn/99WzzLtVDCQkJpmPHjqZs2bLGy8vLhIWFmaZNm5rRo0c7hg4/e/aseeWVV0zbtm1NhQoVjLe3twkNDTUxMTFm1qxZTut75513zB133GGioqKMj4+PKV26tGnSpIl5//33c/wsz4nr59vRo0dNfHy8admypQkPDzfe3t4mIiLC3HrrrWb+/Pm5WueF76ElS5aYm2++2fj5+ZmSJUua++67L8dh0o3J2+fYiRMnzCOPPGLCw8ONh4dHtvfs6tWrHb/jsj5nLvxMPnfunHn//fdN8+bNTVBQkLHb7aZixYrm1ltvNe+++65T31zuEhLGnL9OnyQzadKkXD1HQEGxGXOR8WMBXJNsNptiYmJyPGcDuBLTpk3TQw89pKlTp1p2GBsKl2bNmun48eP666+/CmRgDBRu3bt31/fff6+dO3de1fDsgLtxjhIAAChQr732mjZu3Jin63CheNq+fbtmzJih559/npCEQoegBAAAClSzZs303nvvuX3kNBQ9//zzj0aOHKknnnjC6lKAbBjMAQAAFLg+ffpYXQIKgQsH1wEKG85RAgAAAAAXHHoHAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgAAAADggqAEAAAAAC4ISgBwDTDG6NFHH1VISIhsNpvWr1+f6/tGR0dr0qRJbq1n8eLFstlsOnbsmFvXCwCAuxCUAMDN9u3bp969eysiIkLe3t6KiorSgAEDdPjw4TytZ/fu3XkONRczb948TZs2Td9//70SExNVu3btbMtMmzZNJUuWvOptFWbx8fGqV69ejtPvu+8+x+2VK1eqQ4cOKlWqlHx8fFSnTh29/vrrysjIKMBqC4/8CMsAUNgRlADAjXbu3KlGjRpp69atmjlzprZv36733ntPCxcuVNOmTXXkyBFL6tqxY4fCw8PVrFkzhYWFqUSJEpbUUVh9++236tSpkyRpzpw5iomJUYUKFbRo0SJt3rxZAwYM0JgxY3TffffJGFOgtRljdO7cuQLdZn45e/as1SUAQO4ZAIDb3HrrraZChQomNTXVaXpiYqLx8/Mzjz32mGOaJDNnzhyn5YKDg83UqVMd8y/8iYmJueh2Fy9ebG688Ubj7e1twsLCzLBhw0x6eroxxpgePXo4rScqKirb/RctWpRteyNHjjTGGBMVFWXGjBljHnroIRMQEGAiIyPN+++/73T/f/75x3Tp0sWULFnShISEmDvuuMPs2rXrovVmbe/77783devWNXa73TRu3Nj8+eefTst9+eWXplatWsbb29tERUWZ1157zTFv1KhRJjw83Bw6dMgxrWPHjubmm282GRkZOW535MiR5oYbbnCatnfvXuPl5WWOHj1qTp48aUqXLm3uuuuubPf99ttvjSQza9asiz6umJgY88QTT5gnnnjCBAcHm5CQEDNixAiTmZnpWOaTTz4xDRs2NAEBASY0NNR07drVHDhwINtzM2/ePNOwYUPj5eVlfv75Z7N9+3Zzxx13mHLlyhl/f3/TqFEjk5CQ4LT9qKgoM3r0aPPggw8af39/U7FiRfP111+b5ORkc8cddxh/f39Tu3Zts3btWqf7rVixwtx8883Gx8fHVKhQwfTr18+cPHnS8Zhc3xu5ud+F9fTo0cMEBQWZ7t27m7S0NPPEE0+YsLAwY7fbTVRUlBk7duxFn1MAsApBCQDc5PDhw8Zms130S98jjzxiSpUq5fjSfLmgtGbNGiPJ/PTTTyYxMdEcPnw4x/X+888/xs/Pz/Tt29ds2rTJzJkzx5QpU8YRdI4dO2ZefPFFU6FCBZOYmGiSk5OzrSMtLc1MmjTJBAUFmcTERJOYmGhOnDhhjDn/ZTckJMS8/fbbZtu2bWbcuHHGw8PDbNq0yRhjzKlTp0y1atVMr169zJ9//mk2btxounXrZq677jqTlpaWY81ZYaBmzZpmwYIF5s8//zS33367iY6ONmfPnjXGGLNu3Trj4eFhXnzxRbNlyxYzdepU4+vr63h+zp07Z5o2bWo6d+5sjDHm3XffNcHBwWb37t05btOYnIPS5MmTTZs2bYwxxsyePdtIMitXrszx/tWrVzedOnW66PpjYmJMQECAGTBggNm8ebP59NNPjZ+fn/nggw8cy3z00Ufmhx9+MDt27DCrVq0yN910k2nfvn2256Zu3bpmwYIFZvv27ebQoUNm/fr15r333jN//vmn2bp1qxkxYoTx8fExe/bscdw367V67733zNatW83jjz9uAgMDza233mr+97//mS1btpjOnTubmjVrOt6Hf/75pwkICDATJ040W7duNStWrDD169c3PXv2NMacf19XqFDBvPjii473Rm7ul1VPUFCQefXVV822bdvMtm3bzKuvvmoiIyPN0qVLze7du82yZcvMjBkzLvqcAoBVCEoA4CarV6/OMfxkmTBhgpHk2HtwuaC0a9cuI8n8/vvvl9zus88+a6677jqnvRZvv/22CQgIcOxZmThxYo57ki40depUExwcnG16VFSUeeCBBxy3MzMzTbly5cy7775rjDn/xd91+2lpacbX19fMnz8/x21lhYEL984cPnzY+Pr6ms8//9wYY0y3bt1MXFyc0/2efvppU6tWLcftHTt2mMDAQDNs2DDj5+dnPv3000s+xpyCUlxcnHnzzTeNMca8/PLLRpI5evRojve/4447TM2aNS+6/piYGKcQYowxw4YNu+R9sgJxVjDNem6+/vrrSz4WY4ypVauWeeuttxy3XV+rxMREI8k8//zzjmmrVq0ykhyB58EHHzSPPvqo03qXLVtmPDw8zOnTpx3rnThxotMyub1fVpDN0q9fP9O6dWun5wgACiPOUQKAAmL+/7ktNpvNrevdtGmTmjZt6rTe5s2b6+TJk/rnn3/cso26des6/m+z2RQWFqbk5GRJ0q+//qrt27crMDBQAQEBCggIUEhIiM6cOaMdO3Zccr1NmzZ1/D8kJETXXXedNm3a5HhczZs3d1q+efPm2rZtm2NQhcqVK+u1117TK6+8oo4dO+r+++/P0+NKSUnRkiVLdMcddzhNNxc5D8kYc9nX76abbnJapmnTpk41//777+rUqZOioqIUGBio2NhYSdLevXud1tOoUSOn26dOndLQoUNVq1YtlSxZUgEBAdq8eXO2+134WoWGhkqS6tSpk23aha/ftGnTHK9dQECA2rVrp8zMTO3ateuijzO393N9HD179tT69et13XXXqX///lqwYMFFtwEAVuJsXgBwk6pVq8pms2njxo3q3LlztvmbN29WqVKlVKZMGUnnA4frF/L09PQ8bzenL+/uDmVeXl5Ot202mzIzMyVJmZmZatiwoT777LNs9ytbtmyet5VV86Ue14WWLl0qT09P7d69W+fOncvTQBU//vijatasqaioKElS9erVJZ0Pac2aNcu2/ObNm1WrVq1cr9/VqVOn1LZtW7Vt21affvqpypYtq71796pdu3bZBjrw9/d3uv30009r/vz5eu2111S1alX5+vrqP//5T7b7XfhaZT1/OU278PXr06eP+vfvn63eihUrXvSx5PZ+ro+jQYMG2rVrl3788Uf99NNP6tKli2655RZ9+eWXF90WAFiBoAQAblK6dGnFxcXpnXfe0aBBg+Tr6+uYl5SUpM8++0zdu3d3fFEtW7asEhMTHcts27ZNqampjtve3t6SdNkhqWvVqqWvvvrKKVisXLlSgYGBKl++fK7r9/b2vqLhrxs0aKDPP/9c5cqVU1BQUJ7uu3r1aseX6qNHj2rr1q2qUaOGpPOPa/ny5U7Lr1y5UtWrV5enp6ck6fPPP9fs2bO1ePFi3XvvvRo9erRGjRqV6+1/8803TnuT2rZtq5CQEL3++uvZgtK3336rbdu2afTo0Zd9TK63q1WrJk9PT23evFmHDh3Syy+/rMjISEnSunXrclXrsmXL1LNnT915552SpJMnT2r37t25uu+lNGjQQH///beqVq160WVyem/k5n4XExQUpHvvvVf33nuv/vOf/+jWW2/VkSNHFBISkud1AUB+4dA7AHCjyZMnKy0tTe3atdPSpUu1b98+zZs3T3FxcSpfvrzGjBnjWLZ169aaPHmyfvvtN61bt06PPfaY01/+y5UrJ19fX82bN08HDhzQ8ePHc9xm3759tW/fPvXr10+bN2/WN998o5EjR2rw4MHy8Mj9x3x0dLROnjyphQsX6tChQ06h7VLuv/9+lSlTRp06ddKyZcu0a9cuLVmyRAMGDLjsoX8vvviiFi5cqL/++ks9e/ZUmTJlHHvjnnrqKS1cuFCjR4/W1q1bNX36dE2ePFlDhgyRJP3zzz96/PHH9corr6hFixaaNm2axo0bly2oXMy5c+f0448/OoYFl87v/Xj//ff1zTff6NFHH9Wff/6p3bt366OPPlLPnj31n//8R126dLnkevft26fBgwdry5Ytmjlzpt566y0NGDBA0vk9Ld7e3nrrrbe0c+dOffvtt5cNXlmqVq2q2bNna/369frjjz/UrVs3x16hqzFs2DCtWrVKTzzxhNavX69t27bp22+/Vb9+/RzLREdHa+nSpdq/f78OHTqU6/vlZOLEiZo1a5Y2b96srVu36osvvlBYWFixv4YXgCLIsrOjAKCY2r17t+nZs6cJCwszXl5eJjIy0vTr189pGGtjjNm/f79p27at8ff3N9WqVTM//PCD02AOxhjz4YcfmsjISOPh4XHFw4Mbk7vBHIwx5rHHHjOlS5fONjy464n8N9xwg2O+MecHDejevbspU6aMsdvtpnLlyuaRRx4xx48fz3E7WQMWfPfdd+b666833t7e5sYbbzTr1693Wi5reHAvLy9TsWJF8+qrrxpjzg8o0aZNG9OuXTunQQEGDRpkqlSp4hgYwdWFgzn89NNPpkKFCjkut3TpUnPrrbea4OBg4+3tbWrVqmVee+01c+7cuYs9dcaY84M59O3b1zz22GMmKCjIlCpVyjzzzDNONc6YMcNER0cbu91umjZt6hh2PGvQjqznxnVAiV27dplWrVoZX19fExkZaSZPnmxiYmLMgAEDHMvk9FrJZdCQnAYJWbNmjYmLizMBAQHG39/f1K1b14wZM8Yxf9WqVY5h3C/86nC5++VUzwcffGDq1atn/P39TVBQkGnTpo357bff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48aN6tChgwICAhQaGqoHH3xQhw4dcsw/deqUunfvroCAAIWHh+v11193/xMKAAAAXICgVEQNHTpUX331laZPn67ffvtNVatWVbt27XTkyBHHMk8//bRee+01rV27VuXKldMdd9yh9PR0NWvWTJMmTVJQUJASExOVmJioIUOGXHRbo0ePVvfu3bV+/XrVqFFD3bp1U58+fTR8+HCtW7dOkvTkk09e9P779+/X5s2btX//fm3fvl1Vq1ZVy5YtJUmJiYmKiYlRvXr1tG7dOs2bN08HDhxQly5dnB7HokWLNGfOHC1YsECLFy/Wr7/+erVPIQAAAHBRHHpXBJ06dUrvvvuupk2bpvbt20uSPvzwQyUkJOijjz7SjTfeKEkaOXKk4uLiJEnTp09XhQoVNGfOHHXp0kXBwcGy2WwKCwu77PYeeughR3AZNmyYmjZtqueff17t2rWTJA0YMEAPPfTQRe8fFhYmPz8/BQYG6p577lFwcLDef/99SdK7776rBg0aaOzYsY7lp0yZosjISG3dulURERH66KOP9PHHH2d7LAAAAEB+ISgVQTt27FB6erqaN2/umObl5aXGjRtr06ZNjqDUtGlTx/yQkBBdd9112rRpU563V7duXcf/Q0NDJUl16tRxmnbmzBmlpKQoKCjoousZMWKEVq1apbVr18rX11eS9Ouvv2rRokU5ntO0Y8cOnT59WmfPns3xsQAAAAD5haBUBBljJJ0/f8h1uus0V5ebnxMvL69s989pWmZm5kXX8fnnn2vSpElavHix096gzMxMdezYUa+88kq2+4SHh2vbtm15rhcAAAC4WpyjVARVrVpV3t7eWr58uWNaenq61q1bp5o1azqmrV692vH/o0ePauvWrapRo4YkydvbWxkZGQVS76pVqzRgwAC9++67uummm5zmNWjQQH///beio6NVtWpVpx9/f39VrVpVXl5eOT4WAAAAIL8QlIogf39/Pf7443r66ac1b948bdy4UY888ohSU1PVu3dvx3IvvviiFi5cqL/++ks9e/ZUmTJl1LlzZ0nnR7c7efKkFi5cqEOHDik1NTVfak1KStLdd9+tu+66S+3atVNSUpKSkpJ08OBBSdITTzyhI0eOqGvXrlqzZo127typBQsWqFevXsrIyFBAQIB69+6tp59+2umxeHjw1gUAAED+4dtmEfXyyy/r7rvv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jz/+qOuvvz7bF9/Zs2fnaj2//vqrkpOT1bBhQ8e0jIwMLV26VJMnT9aWLVsknd+zFB4e7lgmOTk5216mC9ntdtnt9mzTvby8+JJuMV4DQPLKPFN0fznSv3CDIt0DEn1QCKRlXPkf6gsL+sA6efkumuegVLJkSd155515vVs2bdq00YYNG5ymPfTQQ6pRo4aGDRumypUrKywsTAkJCapfv74k6ezZs1qyZIleeeWVq94+AAAAAFxMnoPS1KlT3bLhwMBA1a5d22mav7+/Spcu7Zg+cOBAjR07VtWqVVO1atU0duxY+fn5qVu3bm6pAQAAAABykuegVJCGDh2q06dPq2/fvjp69KiaNGmiBQsWcA0lAAAAAPnqioLSl19+qf/973/au3evzp496zTvt99+u+JiFi9e7HTbZrMpPj5e8fHxV7xOAAAAAMirPF9w9s0339RDDz2kcuXK6ffff1fjxo1VunRp7dy5U+3bt8+PGgEAAACgQOU5KL3zzjv64IMPNHnyZHl7e2vo0KFKSEhQ//79dfz48fyoEQAAAAAKVJ6D0t69e9WsWTNJkq+vr06cOCFJevDBBzVz5kz3VgcAAAAAFshzUAoLC9Phw4clSVFRUVq9erUkadeuXTLGuLc6AAAAALBAnoNS69at9d1330mSevfurUGDBikuLk733nuvW66vBAAAAABWy/Oodx988IEyMzMlSY899phCQkK0fPlydezYUY899pjbCwQAAACAgpbnoOTh4SEPj//bEdWlSxd16dLFrUUBAAAAgJXyfOidJC1btkwPPPCAmjZtqv3790uSPvnkEy1fvtytxQEAAACAFfIclL766iu1a9dOvr6++v3335WWliZJOnHihMaOHev2AgEAAACgoOU5KL300kt677339OGHH8rLy8sxvVmzZvrtt9/cWhwAAAAAWCHPQWnLli1q2bJltulBQUE6duyYO2oCAAAAAEvlOSiFh4dr+/bt2aYvX75clStXdktRAAAAAGClPAelPn36aMCAAfrll19ks9n077//6rPPPtOQIUPUt2/f/KgRAAAAAApUnocHHzp0qI4fP65WrVrpzJkzatmypex2u4YMGaInn3wyP2oEAAAAgAKV56AkSWPGjNGIESO0ceNGZWZmqlatWgoICHB3bQAAAABgiSsKSpLk5+enRo0aubMWAAAAACgUch2U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\n","text/plain":"
"},"metadata":{}}],"id":"149d5972-c5b9-4f29-979a-cf46c9654a06"},{"cell_type":"markdown","source":"## h5py out of the box performance.","metadata":{"tags":[],"user_expressions":[]},"id":"fa6ac2b9-989c-4246-bb89-b54b711dd695"},{"cell_type":"code","source":"regular_h5py_benchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n try:\n if \"kerchunk\" in link:\n continue \n print (f\"Processing: {link}\")\n log_filename = f\"logs/fsspec-h5py-{key}-{k}_default.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n # this is mostly IO so no perf_counter is needed\n start = time.time()\n with h5py.File(fs.open(link, mode=\"rb\")) as f:\n path = f\"{dataset['group']}/{dataset['variable']}\"\n data = f[path][:]\n data_mean = data.mean()\n elapsed = time.time() - start\n regular_h5py_benchmarks.append(\n {\"tool\": \"h5py\",\n \"dataset\": key,\n \"cloud-aware\": \"no\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n\n logging.getLogger().removeHandler(file_handler) \n file_handler.close()\n \n except Exception as e:\n print(e)","metadata":{"trusted":true,"tags":[]},"execution_count":25,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"}],"id":"98c29558-de50-44af-87e9-074092fcd0ac"},{"cell_type":"markdown","source":"### Plotting Results","metadata":{"tags":[],"user_expressions":[]},"id":"f4232e98-1159-45eb-ba11-0f0dbb905d83"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(regular_h5py_benchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\nplt.title(\"Out of the box I/O parameters\", fontsize=10)\n\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=45)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":26,"outputs":[{"output_type":"display_data","data":{"image/png":"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76/mzZtr+fLlqlatmp544gnVr19ftWvXvu37dTv16tVLdBq3t7e3qlevruXLl+vgwYOqWLFiivvY/Thw4IAuX76sQoUKJXlN799//51gn7eqVavWHbcdEBAgSbpw4cJ91QikJoISsrygoCDt379fp0+fVpkyZe5rW/HXH9zuWqf8+fPr9OnT97z9iIgI53aSUqBAgURByfrLKiQkxBmU7lZvUFCQDhw4oMjIyARfAu+0/1vrvF/+/v6JpsUPO327ebd+Ubyb69evq127djp16pTmz5+f6AvkpUuXJEnLli3TsmXLbruda9euSUr5++NK0dHRunTpktzd3Z1fQFJL9+7d1a9fP23cuDFF693pddu/f7/zcxj/vlivp7GKf19u3U5K3evPyN32dS+fben/Qod085q6Tp06yc/PT82aNVOxYsXk4+PjHBgjqUEtJClXrly33f6tAx/8888/stlszpB2O5cvX5YxRqdPn77jgDfW9yMp8deh3W5giaRcunRJsbGxyd73hx9+qBIlSmj27Nl688039eabbypHjhzq2LGj3n//fWfAHTZsmAIDAzVt2jRNnDhR77//vjw8PNSyZUtNnjxZxYsXT3aNt1qwYIHefvttzZ0713nNWc6cOdWrVy+9/fbbCa6RvJPk9uGU9rH7Eb+vP/74Q3/88UeK9nW3n5n4z0RyXx8gPTDqHbK8evXqSUqd+13Ef8E5d+5ckvPPnz+f4EtQ/MXKSX25TypsxH/BOX/+fJLbt+63YcOGMjdPoXX+u/WL+t3qjZ9u/eJ2t/0n9UUsI+rVq5c2b96ssWPH6vHHH080P/55f/TRR4lex1v/de/eXVLK3x9X2rhxo2JjY1W1atVUv+eRp6encubMmeSIcHdyt9ct/v2I/+933313x/elQYMGCbZzL4Oo3OvPyP0M2JJcYWFhypEjh3bs2KH58+frvffe05gxY5zT71fu3LlljNGZM2fuuFz8c69evfod34/Vq1ffdZ/58uWT9H9fuJPD399fgYGBd9z3sWPHnMvb7XYNHTpUf/zxh06fPq05c+aofv36+vzzz/XUU085l7PZbHr22We1fft2/f3331q8eLEee+wxLV26VK1atUo0ml5y+fr66q233tLRo0d19OhRffLJJypbtqw++OADvfTSS8neTnL7cEr72P2I39fjjz9+x33NmjUr0bp3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GUnOwNO1a1fz/PPPJ9ju+vXrjZubm/n333+d2500aVKCZZK7XnyQjde/f3/z8MMPJ3iNACAj4holAEgn5v9f22Kz2VJ1u/v27VOdOnUSbLdevXq6evWq/vzzz1TZR+XKlZ3/b7PZFBQUpPPnz0uSduzYocOHDytnzpzy8/OTn5+fAgICdP36dR05cuSO261Tp47z/wMCAlSmTBnt27fP+bzq1auXYPl69erp0KFDzkEVSpQooQkTJujdd99V69at9dRTT6XoeUVGRmrt2rVq06ZNgunmNtchGWPu+v795z//SbBMnTp1EtS8a9cutW3bViEhIcqZM6caNmwoSTp58mSC7dSoUSPB42vXrmnYsGEqX768cufOLT8/P+3fvz/Rere+VwUKFJAkVapUKdG0W9+/2bNnO987Pz8/NWvWTA6HQ8eOHbvt80zuetbn0aNHD+3evVtlypTRgAEDtHLlytvuAwBciat5ASCVhIaGymazae/evWrXrl2i+fv371eePHmUN29eSTcDh/ULeUxMTIr3m9SX99QOZXa7PcFjm80mh8MhSXI4HKpevbq++uqrROvly5cvxfuKr/lOz+tW69atk7u7u44fP67Y2NgUDVTx448/qly5cgoJCZEklS5dWtLNkFa3bt1Ey+/fv1/ly5dP9vatrl27pqZNm6pp06b68ssvlS9fPp08eVLNmjVLNNCBr69vgsdDhw7VihUrNGHCBIWGhsrb21tPPPFEovVufa/iX7+kpt36/vXu3VsDBgxIVG/RokVv+1ySu571eVSrVk3Hjh3Tjz/+qJ9++kkdO3bUI488ogULFtx2XwDgCgQlAEglgYGBatKkiT7++GO99NJL8vb2ds47e/asvvrqK3Xr1s35RTVfvnw6c+aMc5lDhw4pKirK+djT01OS7jokdfny5bVw4cIEweKXX35Rzpw5Vbhw4WTX7+npeU/DX1erVk1ff/218ufPL39//xStu3nzZueX6suXL+vgwYMqW7aspJvPa8OGDQmW/+WXX1S6dGm5u7tLkr7++mstWrRIa9asUadOnTR27FiNGTMm2fv/9ttvExxNatq0qQICAvT+++8nCkpLly7VoUOHNHbs2Ls+J+vjUqVKyd3dXfv379eFCxf0zjvvKDg4WJK0ffv2ZNW6fv169ejRQ+3bt5ckXb16VcePH0/WundSrVo1/fHHHwoNDb3tMkl9NpKz3u34+/urU6dO6tSpk5544gk1b95cly5dUkBAQIq3BQBphVPvACAVTZkyRdHR0WrWrJnWrVunU6dOafny5WrSpIkKFy6st956y7nsww8/rClTpmjnzp3avn27+vTpk+Av//nz55e3t7eWL1+uc+fOKSIiIsl99uvXT6dOnVL//v21f/9+ffvttxo9erQGDx4sN7fkt/lixYrp6tWrWrVqlS5cuJAgtN3JU089pbx586pt27Zav369jh07prVr12rgwIF3PfXvjTfe0KpVq/T777+rR48eyps3r/No3Msvv6xVq1Zp7NixOnjwoD777DNNmTJFQ4YMkST9+eef6tu3r9599109+OCDmj17tsaNG5coqNxObGysfvzxR+ew4NLNox/Tp0/Xt99+q+eff1579uzR8ePH9cknn6hHjx564okn1LFjxztu99SpUxo8eLAOHDiguXPn6qOPPtLAgQMl3TzS4unpqY8++khHjx7V0qVL7xq84oWGhmrRokXavXu3fv31V3Xp0sV5VOh+DB8+XJs2bdILL7yg3bt369ChQ1q6dKn69+/vXKZYsWJat26dTp8+rQsXLiR7vaRMmjRJ8+bN0/79+3Xw4EHNnz9fQUFBWf4eXgAyIZddHQUAWdTx48dNjx49TFBQkLHb7SY4ONj0798/wTDWxhhz+vRp07RpU+Pr62tKlSplfvjhhwSDORhjzMyZM01wcLBxc3O75+HBjUneYA7GGNOnTx8TGBiYaHhw64X8VapUcc435uagAd26dTN58+Y1Xl5epkSJEua5554zERERSe4nfsCC7777zlSoUMF4enqamjVrmt27dydYLn54cLvdbooWLWree+89Y8zNASUaN25smjVrlmBQgJdeesmULFnSOTCC1a2DOfz000+mSJEiSS63bt0607x5c5MrVy7j6elpypcvbyZMmGBiY2Nv99IZY24O5tCvXz/Tp08f4+/vb/LkyWNeeeWVBDXOmTPHFCtWzHh5eZk6deo4hx2PH7Qj/rWxDihx7Ngx06hRI+Pt7W2Cg4PNlClTTIMGDczAgQOdyyT1XskyaEhSg4Rs3brVNGnSxPj5+RlfX19TuXJl89Zbbznnb9q0yTmM+61fHe62XlL1zJgxw1StWtX4+voaf39/07hxY7Nz5847vq4A4Ao2Y9L5znkAAGQAAwYMUGxsrD7++ONU22bDhg1VtWpVTZ48OdW2CQBwDa5RAgBkSxUrVkww6h4AALciKAEAsqXnn3/e1SUAADIwTr0DAAAAAAtGvQMAAAAAC4ISAAAAAFhk+WuUHA6H/vrrL+XMmTPV7lAPAAAAIPMxxujKlSsqVKjQXe81mOWD0l9//eW8+zkAAAAAnDp1SkWKFLnjMlk+KOXMmVPSzRfD39/fxdXAFWJiYrRy5Uo1bdpUdrvd1eUAcBF6AQD6ACIjIxUcHOzMCHeS5YNS/Ol2/v7+BKVsKiYmRj4+PvL396cpAtkYvQAAfQDxknNJDoM5AAAAAIAFQQkAAAAALAhKAAAAAGCR5a9RAgAAAO4kLi5OMTExri4DqcBut8vd3T1VtkVQAgAAQLZkjNHZs2f1zz//uLoUpKLcuXMrKCjovu+hSlACAABAthQfkvLnzy8fH5/7/mIN1zLGKCoqSufPn5ckFSxY8L62R1ACAABAthMXF+cMSYGBga4uB6nE29tbknT+/Hnlz5//vk7DYzAHAAAAZDvx1yT5+Pi4uBKktvj39H6vOyMoAQAAINvidLusJ7XeU4ISAAAAAFgQlAAAAADAgqAEAAAAABYEJQAAACAD6NGjh2w2W6J/hw8fdnVpCRw/flw2m027d+92dSlpiuHBAQAAgAyiefPmmjVrVoJp+fLlS/F2bty4IU9Pz9QqK1viiBIAAACQQXh5eSkoKCjBP3d3d61du1a1atWSl5eXChYsqFdeeUWxsbHO9Ro2bKgXX3xRgwcPVt68edWkSROtWbNGNptNK1as0AMPPCBvb289/PDDOn/+vH788UeVK1dO/v7+evLJJxUVFeXc1vLly/Xggw8qd+7cCgwM1KOPPqojR4445xcvXlyS9MADD8hms6lhw4bp9vqkJ4ISAAAAkIGdPn1aLVu2VM2aNfXrr79q6tSp+uSTT/Tmm28mWO6zzz6Th4eHNm7cqOnTpzunh4WFacqUKfrll1906tQpdezYUZMnT9acOXO0bNkyhYeH66OPPnIuf+3aNQ0ePFjbtm3TqlWr5Obmpvbt28vhcEiStm7dKkn66aefdObMGS1atCgdXoX0x6l3AAAAQAbx/fffy8/Pz/m4RYsWKl26tIKDgzVlyhTZbDaVLVtWf/31l4YPH67XX39dbm43j32EhoZq/PjxznXPnj0rSXrzzTdVr149SdIzzzyjESNG6MiRIypRooQk6YknntDq1as1fPhwSdLjjz+eoKZPPvlE+fPn1969e1WxYkXnqYCBgYEKCgpKo1fC9TiiBAAAAGQQjRo10u7du53/PvzwQ+3bt0916tRJcCPVevXq6erVq/rzzz+d02rUqJHkNitXruz8/wIFCsjHx8cZkuKnnT9/3vn4yJEj6tKli0qUKCF/f3/nqXYnT55MteeZGXBECQAAAMggfH19FRoammCaMSZBSIqfJinBdF9f3yS3abfbnf9vs9kSPI6fFn9anSS1bt1awcHBmjlzpgoVKiSHw6GKFSvqxo0b9/akMimCEgAAQDZR7JVlri7BpbzcjcbXcnUVKVe+fHktXLgwQWD65ZdflDNnThUuXDhV93Xx4kXt27dP06dPV/369SVJGzZsSLBM/Gh6cXFxqbrvjIZT7wAAAIAMrF+/fjp16pT69++v/fv369tvv9Xo0aM1ePBg5/VJqSVPnjwKDAzUjBkzdPjwYf38888aPHhwgmXy588vb29vLV++XOfOnVNERESq1pBREJQAAACADKxw4cL64YcftHXrVlWpUkV9+vTRM888o1GjRqX6vtzc3DRv3jzt2LFDFStW1EsvvaT33nsvwTIeHh768MMPNX36dBUqVEht27ZN9ToyApuJP8Exi4qMjFSuXLkUEREhf39/V5cDF4iJidEPP/ygli1bJjonF0D2QS8AOPXu5ql3cWrZsqXi4uJ07NgxFS9eXDly5HB1aUhF169fv+17m5JswBElAAAAALAgKAEAAACABUEJAAAAACwISgAAAABgQVACAAAAAAuCEgAAAABYEJQAAAAAwIKgBAAAAAAWBCUAAAAAKlasmCZPnnxf2wgLC1PVqlVTpZ7badiwoQYNGpSm+5AkjzTfAwAAAJCJFHtlWbru7/g7rdJ1f7Nnz9agQYP0zz//JJi+bds2+fr63te2hwwZov79+9/XNjIKghIAAAAA5cuX77634efnJz8/v1SoxvU49Q4AAADIRKKjozVgwADlz59fOXLk0IMPPqht27ZJktasWSObzaZly5apSpUqypEjh2rXrq3ffvvNOb9nz56KiIiQzWaTzWZTWFiYpMSn3tlsNk2fPl2PPvqofHx8VK5cOW3atEmHDx9Ww4YN5evrqzp16ujIkSPOdayn3sXv49Z/xYoVc87fu3evWrZsKT8/PxUoUEBdu3bVhQsXnPOvXbumbt26yc/PTwULFtT777+f+i/obRCUAAAAgExk2LBhWrhwoT777DPt3LlToaGhatasmS5duuRcZujQoZowYYK2bdum/Pnzq02bNoqJiVHdunU1efJk+fv768yZMzpz5oyGDBly232NHTtW3bp10+7du1W2bFl16dJFvXv31ogRI7R9+3ZJ0osvvnjb9eP3cebMGR0+fFihoaF66KGHnPMaNGigqlWravv27Vq+fLnOnTunjh07Jngeq1ev1uLFi7Vy5UqtWbNGO3bsuN+XMFk49Q4AAADIJK5du6apU6dq9uzZatGihSRp5syZCg8P1yeffKKaNWtKkkaPHq0mTZpIkj777DMVKVJEixcvVseOHZUrVy7ZbDYFBQXddX89e/Z0Bpfhw4erTp06eu2119SsWTNJ0sCBA9WzZ8/brh+/D2OMHn/8ceXKlUvTp0+XJE2dOlXVqlXT22+/7Vz+008/VXBwsA4ePKhChQrpk08+0eeff57ouaQHlx5RWrdunVq3bq1ChQrJZrNpyZIlt122d+/estls9z0SBwAAAJBZHTlyRDExMapXr55zmt1uV61atbRv3z7ntDp16jj/PyAgQGXKlEkwP7kqV67s/P8CBQpIkipVqpRg2vXr1xUZGXnH7bz66qvatGmTlixZIm9vb0nSjh07tHr1aud1TX5+fipbtqzzeR45ckQ3btxI8rmkB5ceUbp27ZqqVKminj176vHHH7/tckuWLNGWLVtUqFChdKwOAAAAyFiMMZJuXvtjnW6dZnW3+Umx2+2J1k9qmsPhuO02vvzyS02aNElr1qxJcDTI4XCodevWevfddxOtU7BgQR06dCjF9aYmlx5RatGihd5880099thjt13m9OnTevHFF/XVV18leFMAAACA7CY0NFSenp7asGGDc1pMTIy2b9+ucuXKOadt3rzZ+f+XL1/WwYMHnUdrPD09FRcXly71btq0Sc8++6ymT5+u//znPwnmVatWTX/88YeKFSum0NDQBP98fX0VGhoqu92e5HNJDxn6GiWHw6GuXbtq6NChqlChQrLWiY6OVnR0tPNx/GHAmJgYxcTEpEmdyNji33fefyB7oxcAkpe7cXUJLuXldvP5x8TEKC4uTsYYORyOOx4NSQ8p2b+3t7f69OmjoUOHKnfu3CpatKjee+89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d+/eznWsd9TmyxGQud1LH5BujoZXqlQp55cp+gCQed1rH4g/2mT9f2ROBCXg/5s7d6569+6t2bNnq169ejp8+LC6dOmitWvXqlixYpKko0ePqkSJEq4tFECauZc+YP0yZP3jCYDMhe8DiMefuwDdvGv22LFjNWnSJD322GOSbp5rXLhwYX333Xc6d+6cunXrptDQUBdXCiCt3GsfsP7FmJAEZF58H8CtOKIE/H+ffPKJ6tatq3LlykmSWrVqpR07dqh69eo6e/asjh8/rh9//FG1atXicDqQRdEHANAHEI+ghGwvqSY3ffp0ffbZZ/r8888VEhIiu92uunXrKjAwUN99952LKgWQVugDAOgDsOLUO2Rbp0+flpubmzw9PRUYGJhgXvPmzdWhQwcFBAQ475VQunRphvkFshj6AAD6AG6HE6mRLc2ePVuNGzdW/fr1VapUKb399tv6/fffnfNDQkIUEBAg6eb1B9euXdPp06dVunRpV5UMIJXRBwDQB3AnnHqHbOfHH3/UE088oQ8//FClSpXSjh079N///lcPPPCA+vXrp0aNGjmXjY2N1eXLl9WzZ0+dPXtWmzdvZshfIAugDwCgD+BuCErINuLPPR42bJgOHz6sRYsWOef98MMPeuedd5Q3b1698sorqlWrlmJjY7V06VJNnjxZN27c0Pr162W32xUXF8chdyCTog8AoA8guTj1DtlG/AWacXFxioiIkMPhUFxcnCSpZcuWevXVV3Xs2DHNmzdPcXFxiomJUUhIiJ544glt2LBBdrtdsbGxNEUgE6MPAKAPILk4ooRsZ9asWerdu7e2bt2qqlWr6saNG/L09JQkff7553r22We1e/dulS9fPsF6/OUIyDroAwDoA7gbjigh2+nZs6datWqlRx99VH/99Zc8PT1148YNSVLnzp1VuHBh7dmzJ9F6NEUg66APAKAP4G4ISsjyHA5Homljx45VyZIl9Z///EeHDx92/gXp8uXL8vT0VM6cOdO7TABpiD4AgD6AlOLUO2RZW7duVaFChVSkSBE5HA65uSX8u8CuXbs0YsQIrVu3ToMHD5a/v79+/vlnnTt3Ttu3b+cvRkAWQB8AQB/AvSIoIUv6888/1apVK5UtW1aTJk1SoUKFkmyO0dHRGj9+vFasWCHp5v0SZs+ezWg2QBZAHwBAH8D9ICghy1m2bJlatWql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\n","text/plain":"
"},"metadata":{}}],"id":"d8fa6dca-f408-4298-beca-f2839d4c3b67"},{"cell_type":"markdown","source":"## Aggregated plot by tool and different file sizes","metadata":{"tags":[],"user_expressions":[]},"id":"b20b2032-9ab4-46e1-b1f8-2e62b656a265"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(regular_h5py_benchmarks + kerchunk_benchmarks + regular_xarray_benchmarks + h5coro_beanchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\nplt.title(\"Out of the box I/O parameters\", fontsize=10)\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":27,"outputs":[{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAMfCAYAAADomSepAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACqD0lEQVR4nOzdeViU9f7/8deAMOwqLiyK4J7lrmmKCVloZmWrFadSs9Isl6w0swUzrayUyo4tp9RTmZ1Kq5Mnlcx9KS1tc9+NQHJFRRHh8/vDH/N1BlDuEZkRn4/r4tK573s+93teszBv7s1mjDECAAAAADj4eLoAAAAAAPA2NEoAAAAA4IJGCQAAAABc0CgBAAAAgAsaJQAAAABwQaMEAAAAAC5olAAAAADABY0SAAAAALigUQIAAAAAFzRKQAlSUlJks9m0cOFCT5fikJiYKJvN5ukyLImLi1NcXNx5G9+bnqcL8fm5mMyZM0dXXHGFKleuLJvNpj59+ni6pIvWkSNHFBUVpYEDBzpNv9DeQ+fj823hwoWy2WxKSUkp03G91ZQpU+Tr66vffvvN06UARdAo4aLy008/qV+/fmrYsKGCg4MVGBio+vXr65577lFaWpqny7sg9enTRzabTTt27PB0KReUwi9DAwYMKHGZGTNmFPuFqfDLZOGPn5+fqlWrppYtW6pfv36aM2eOCgoKih0zLi7O6b6uP6c3nIVNaHE/AQEBZRFDudm+fbtuuukm7dq1S/fff7+ee+453XTTTZ4u66I1fvx47d+/XyNHjvR0KRelMzV45d2o3XPPPapbt64ef/zxclkfYEUlTxcAlIeCggI9/vjjmjhxoipVqqQuXbroxhtvlJ+fn7Zt26bZs2fro48+0vPPP69nnnnG0+VWKPPnzz+v4z/yyCO68847VadOnfO6Hm/02GOPKSQkRAUFBTp48KDWr1+vjz/+WB988IE6duyoTz75pNhcfH199fTTTxc7ZnFfnnr37l1keqVKF9avj/nz5ys3N1cTJkzQnXfe6elyLmoHDx7UhAkTdNdddykmJsbT5ZyT8/35djGoVKmShg4dqkGDBmnp0qXq1KmTp0sCHC6s33SAm55++mlNnDhRLVu21Oeff6769es7zT927JgmTZqkffv2eajCiss167JWvXp1Va9e/byuw1s9/vjjioyMdJr2999/a/DgwZoxY4a6deum1atXKzg42GmZSpUqWfprcZ8+fZSYmFgGFXvOX3/9JUlF8kL5+/DDD3X06FHdc889ni7lnJ3vz7eLxZ133qlHH31Ub7/9No0SvAq73qHC27Jli8aPH69q1appzpw5xf5iCwwM1BNPPKHRo0eXasxvvvlGV111lSpXrqzAwEC1bNlSqampys/Pd1ruTLsw7Nixo8TjJJYuXaqEhAQFBwerWrVquuOOO7R79+5S1Vac5cuXq0ePHgoPD1dAQIAuueQSpaSkKCcnp8iyNptNiYmJ2r17t+644w5Vq1ZNwcHBSkxM1PLly52WjYuL07Rp0yRJdevWdeyWdfqX6uJ28Tj9uKIpU6aoWbNmCgwMVN26dfXGG29Ikowxev3113XJJZcoICBAjRo10ocfflik3uKOUXLdNc31x/X5yMrK0qOPPqoGDRrIbrerevXquvXWW/X7778Xm2dZPz9lqUaNGvr444919dVXa8OGDXrrrbc8XZKmTp0qm82mqVOnatasWbr88ssVFBSkyMhIPfTQQzpw4ECx99u+fbvuv/9+1alTR3a7XVFRUerTp4927txZZNnC1116err69OmjyMhI+fj4ONb93HPPSZKuuuoqx+vg9N1F3XmPuK5r4cKFTu/55cuX66qrrlJoaKhq1KihgQMH6tixY5JOHS8VHx+v4OBgRUREaMSIEUU+Pw4dOqSXX35ZCQkJio6Olr+/v6Kjo3Xvvfdq69atReo6/b3wn//8R61bt1ZgYKCioqI0ePBgx7pdLVmyRDfffLMiIiJkt9sVExOjW265RUuXLnVazhijDz74QPHx8QoLC1NQUJDatm2rDz74oNhxSzJ16lRVq1ZNV111laX7ffXVV7r66qtVtWpVBQQEqGnTpnr11VeL5FZQUKB//etfateuncLDwxUUFKS4uDjddNNNWrx4sdOyX3zxhRISElSzZk0FBAQoJiZG1157rb788stS1VTc59vx48f12muvqUWLFqpcubJCQkJUv3593XXXXZaPw1m8eLESEhIUEhKi8PBwJScn688//yx22dJ8jhX+3tm5c6d27txZ5HMxJSXF8byMHj3aaf7p75cTJ05owoQJat26tYKDgxUaGqorr7xSX3/9dZG6CnfP3rZtmyZOnKjLLrtMdrvd6Xdf9erVddVVV+nzzz/XkSNHLGUEnE9sUUKFN3XqVOXn56t///6KiIg447J2u/2s473++usaOnSo45dWcHCw/vvf/+rRRx/VkiVL9Pnnn5/Twcjz589X9+7d5ePjozvuuEPR0dGaP3++4uPjVbVqVcvjffHFF7rzzjvl7++vO+64QzVr1tR3332n0aNHa968eVqwYEGRx33gwAHFx8crKipKDz74oNLT0/Xpp5/qqquu0ty5cx2N0NChQzV16lT98ssvGjJkiKpUqSKp+N23ipOamqqFCxeqZ8+e6tKli7744gsNGTJEQUFB+uWXX/TZZ5/p+uuvV5cuXTRjxgzde++9qlu37ln/4ljSFpDPPvtM69atU1BQkGPa1q1bHV96u3btqptuuklZWVn64osvNHfuXM2fP1/t27d3LF/Wz8/54OPjo1GjRmn+/Pn69NNPNXz48HMab8mSJfrxxx/l6+urSy65RNdcc02p3iuuPv/8c6Wlpen222/XNddco0WLFuntt9/WihUrtGLFCgUGBjqW/eGHH9StWzcdPXpUN9xwgxo0aKAdO3bo448/1rfffqsVK1aoXr16TuPv27dPHTp0UHh4uO644w6dOHFCzZs313PPPaeFCxdq0aJFTrsRFr5e3XmPFLeusLAwZWdnO+p/+eWX1a1bN/Xv318LFizQ5MmTlZ2drZ49e6p379668cYb1b59e82ePVvjx49XWFiYRo0a5VjH+vXr9eyzz+qqq67SzTffrODgYG3YsEHTp0/X7Nmz9fPPPys2NrZIzm+99Za+/fZb9ezZU4mJiZozZ47efPNN7du3Tx9//HGRZQcNGqTAwEDdfPPNqlOnjtLT07V06VJ9/vnnjveaMUZ33323pk+frkaNGik5OVn+/v5KS0tTv379tG7dOr366qtnfQ0cOHBAa9as0bXXXisfn9L/rfapp57Siy++qNq1a+vWW29VWFiYFi9erCeeeEI//PCDPvvsM8eyI0eO1Pjx41W/fn0lJycrNDRU6enpWrJkib7//nt17txZkjR58mQNHDhQUVFRuvnmm1WtWjVlZGToxx9/1Jdffun2MWy9e/fWf/7zHzVv3lx9+/aV3W7Xrl27tGDBAnXr1k3NmjUr1TgrV67Uiy++qB49emjw4MH6+eef9cknn2jp0qVatWqV0++z0n6OValSRc8995xSU1MlnfoML1T4mbljxw5NmzZNCQkJTp+jhe+X3NxcXXvttVq4cKFatWqlfv36KS8vT7Nnz1bPnj315ptv6pFHHinyeAYNGqSVK1eqR48euv7664v8Pu7QoYPS0tK0bNkydevWrVQZAeedASq4xMREI8l89913lu733HPPGUlmwYIFjmlbt241lSpVMjVr1jS7du1yTM/NzTUJCQlGkvnwww8d0xcsWGAkmeeee67I+Nu3bzeSTO/evR3T8vPzTb169YzNZjNLlixxTC8oKDDJyclGkrHyts3OzjZVqlQxdrvd/PLLL8WON2bMGKf7FK7jnnvuMQUFBY7pCxcuNDabzTRo0MDk5+c7pvfu3dtIMtu3by+2htjYWBMbG+s0rTDb8PBws3XrVsf0Xbt2GX9/f1O5cmXTqFEjk5WV5Zj3ww8/GEnmxhtvLHas05+n4nz99dfGx8fHtG3b1uTk5Dimd+zY0VSqVMnMmzfPafmNGzea0NBQ06xZM8e0snx+Cl8bbdq0Mc8991yxP7feemuxr5/C11pGRkaJ4x8/ftz4+fkZHx8fk5eX55geGxtrfH19i13fJ5984jRGYbauP1FRUUXyOpMpU6Y47uv6Puzbt6+RZJ5//nnHtBMnTpi4uDgTGhpq1q5d67T8kiVLjK+vr7n++uudpheO37dvX3Py5MkiNZT0OjmX90hx6yp8XiWZL7/80ukxNW/e3NhsNlO9enXz448/OtVQs2ZNU61aNafn6uDBg2bfvn1FHsv3339vfHx8zP3331/sY6xcubLZsGGDY3pOTo5p1KiRsdlsJj093TH9119/Nb6+viY6OrrI+7egoMBp2XfffddIMv369XOqMTc319xwww1Gklm9enWRWl3Nnj3bSDKjRo0qdn7ha/t08+bNM5JM9+7dzdGjR51qHDBggJFkPv/8c8f08PBwU6tWLadlC5c/Pc/WrVsbf39/p8+ZQnv37j3rYzGm6OfbwYMHjc1mM23bti3y2jh58qQ5cODAWcc8/TX0r3/9y2ne6NGjjSRz3333OU238jlWXN3Frb+431vGGPPUU08ZSSYlJcXpd0R2drZp27at8ff3d3rtFP6OqF27ttm5c2eJj/urr74yksyzzz5b4jJAeaNRQoV3ySWXGElOXxxKo7gvVs8//7yRZF5++eUiy69YscJIMldffbVjmtVGadGiRUaSueGGG4osv2PHDuPr62upUfr3v/9tJJmHHnqoyLxdu3aZSpUqmfr16ztNl2R8fX2dGsFCPXr0MJKcmoRzaZRSUlKKLN+lSxcjyUybNq3IvHr16pU41pkapV9++cWEhISYWrVqOf0C//nnnx1f/oozbNgwI8n89ttvxpiyfX5O/zJ0th93GiVjjImIiDCSzJ49exzTYmNjS1xPz549ne4/a9YsM23aNLNjxw5z7Ngxs3nzZjNmzBgTGBhoAgICijQxJSlslJKSkorMS09PN35+fk6vw5kzZxbboBS65ZZbjI+Pjzl06JBjmiTj7+9v/v7772LvU9LrxN33SEnrKnxeExMTi8wr/Pzo27dvkXn33XffGd9Hrpo1a2bi4uKcphU+xuK+aBbO+/rrrx3TBg4caCSZDz744Kzra968uQkODjbHjh0rMu/XX381ksxjjz121nHeeecdI8m88cYbxc4vrlG68cYbjaRiP5MKG5Nbb73VMS08PNzUrVvX5ObmnrGW1q1bm+Dg4FI1LyVx/Xw7dOiQkWTi4+PdHrPwNdS4cWOnRsSYU01vjRo1TGBgoOPxWf0cK67u4tZf3O+t/Px8U7VqVdOgQYMitRlz6g9Sksybb77pmFb4O+L1118/4+NeuXJlsU0g4EnsegdYsGbNGkkqdreuK664QoGBgVq7dq3b4//yyy+SpCuvvLLIvNjYWMXExDjtJ75jxw5NnTrVabkqVao4dqc4U70xMTGqX7++Nm7cqMOHDys0NLTIulxdeeWVmj17ttauXVsmB9y2atWqyLSoqChJUsuWLYud98MPP1hax549e3TDDTeooKBAX3/9taKjox3zVq5cKUnKzMws9jiyDRs2OP5t2rSp5eenNPr376+333672HkzZszQXXfdZWm80xljip1ut9t1/Pjxs97fddejBg0a6Omnn1ZERIQefPBBvfDCC067PJ1NcblFR0erfv362rBhg+N1WPi8bNiwodjnJTMzUwUFBdq0aZPatm3rmF63bl3LJ/Zw9z1ytnW589qWpPT0dKddVxcuXKjU1FT98MMP2rt3r06ePOmY5+/vX+y6W7duXWRa7dq1JZ0641yhH3/8UZLUtWvXEh+HJOXk5Oi3335TdHS0XnrppSLz8/LyJP3f++VMCk+YY2U31ZUrVyo4OFjvv/9+sfMDAwOd1t2rVy+9/fbbatq0qe644w4lJCSoQ4cORU5q0qtXLz355JNq2rSp7rzzTiUmJqpTp06OXczcERYWpmuvvVZz5sxR69atddttt+nKK69U+/btS3y+ShIfH19kN+7AwEC1adNGc+bM0aZNm9S0aVPLn2PnYuPGjTpw4ICio6OLPab377//dlrn6dq1a3fGscPDwyVJe/fuPacagbJEo4QKLzIyUhs2bFB6eroaN258TmMVHn9Q0rFONWvWVHp6utvjHzp0yDFOcSIiIoo0Sq6/rGJjYx2N0tnqjYyM1MaNG5Wdne30JfBM6z+9znMVFhZWZFrhaadLmnf6F8WzOX78uG666Sbt3r1bn332WZEvkPv375ckzZ49W7Nnzy5xnKNHj0qy/vx4Um5urvbv3y9fX1/HF5Cy0rt3bw0cOFDLli2zdL8z5bZhwwbH67DweXE9nsZV4fNy+jhWufseOdu63HltS//XdEinjqm74447FBISom7duikuLk5BQUGOE2MUd1ILSapcuXKJ459+4oODBw/KZrM5mrSSHDhwQMYYpaenn/GEN67PR3EKj0Mr6cQSxdm/f79OnjxZ6nW/8cYbqlevnqZOnaoXXnhBL7zwggICAtSrVy+99tprjgZ3+PDhqlatmt5++21NmDBBr732mipVqqTrrrtOqampqlu3bqlrPN3nn3+ucePG6ZNPPnEccxYaGqr77rtP48aNczpG8kxK+zls9XPsXBSu648//tAff/xhaV1ne88UviZKmw9QHjjrHSq8+Ph4SWVzvYvCLzh79uwpdn5WVpbTl6DCg5WL+3JfXLNR+AUnKyur2PFd15uYmChzahdax8/pX9TPVm/hdNcvbmdbf3FfxLzRfffdp5UrV2rMmDG69dZbi8wvfNxvvvlmkRxP/+ndu7ck68+PJy1btkwnT55Uy5Yty/yaR/7+/goNDS32jHBncrbcCp+Pwn//+9//nvF5SUhIcBrHnZOouPseOZcTtpRWSkqKAgIC9NNPP+mzzz7TK6+8otGjRzumn6sqVarIGKOMjIwzLlf42Nu0aXPG52PBggVnXWeNGjUk/d8X7tIICwtTtWrVzrju7du3O5b38/PTE088oT/++EPp6emaPn26rrzySv373//WP/7xD8dyNptN999/v1avXq2///5bs2bN0i233KKvv/5aPXr0KHI2vdIKDg7W2LFjtW3bNm3btk3vv/++LrnkEr3++ut69NFHSz1OaT+HrX6OnYvCdd16661nXNeUKVOK3Pds75nC10ThawTwBjRKqPD69OkjX19fvfvuu47dAkqSm5t7xvmFu9OcfirqQj/++KOOHTvmtFtN4e4lxW1lKtzl53QtWrSQdOosY6527txp+RTUZ6o3PT1dW7duVb169Zz+Un6mdRXWdfpj9PX1lSS3v1ScL88//7w++eQT/eMf/3A6k9jpCs9mt2LFilKNWdbPz/lSUFCgcePGSdI57bpXks2bN+vAgQOlPrthoeJy++uvv7R161bVr1/f8Tq0+rycC3ffI+Vh69atatKkiRo2bOg0vTCzc1W4K9S8efPOuFxoaKiaNGmi9evXO+26547CM75t3ry51Pdp37699u3bZ+k+haKjo3XXXXdpzpw5atiwob777rtit2ZVq1ZNN910kz799FN16dJF69ev15YtWyyvz1XdunV13333adGiRQoJCSn29NklWbZsWZHdZ48dO6affvpJgYGBatSokST33i++vr4lfmaf6TO9SZMmCgsL0+rVq522fpaFjRs3SlKpzwoIlAcaJVR4DRo00PDhw7V37151797d6S+PhY4fP64JEyac9SKcycnJqlSpkiZMmOC4gKV0aneZJ598UpKcrg3RuHFjxy/H0/+CumfPHr3wwgtFxu/UqZPq1q2rb775xukaJsYYPfXUU5abkZ49e6py5cqaMmWK024SxhiNHDlSeXl5xV7HKT8/X6NGjXL6Jb1o0SL973//U4MGDdSxY0fH9MLdukq6tocnfPbZZ0pJSVGHDh1KPK5BOvVFsX379vrkk0/06aefFplfUFCgRYsWOW6X9fNzPvz999+6++67NX/+fF166aV66KGH3Brn8OHD+vXXX4tMP3DggPr16yfJehOWlpZWZMvu008/rby8PKe/dvfs2VN16tTRhAkTilz3Rjr1fnO9xo+73H2PlIfY2Fht2bLFaWvX8ePH9dBDD1naBbUkAwYMkK+vr55++ukiu/G5bmkaPHiwcnJy9MADDxS7W9X27dtLtdtps2bNFB4e7jg+qjQGDx4s6dQW4uIuCp6Zman169dLOvXHru+//75Ig3H06FEdPnxYfn5+jkZg7ty5RXLMy8tzfFaffrr60vr777+LfWwHDhxQbm6upTE3btxY5BpVr7zyiv7++2/dddddjmOerH6OSac+t/fu3VvssYpn+kyvVKmSHnroIe3cuVOPP/54sc3S77//XuLWsDMpPP7UdUsx4Ekco4SLwgsvvKDjx49r4sSJaty4sbp06aKmTZvKz89P27dv13fffad9+/YV27ycrn79+nr55Zf12GOPqXnz5urVq5eCg4P1zTffaMOGDerZs6fuvvtux/L+/v565JFH9NJLL6l169bq2bOnDh8+rP/+979KSEgo8ldhHx8fvfvuu7ruuut0zTXXOK7T8/333ysjI0PNmzcv9strScLCwvTee+/prrvuUvv27XXHHXeoRo0amj9/vlavXq127drpiSeeKHK/5s2ba+HChbriiivUpUsX/fXXX5oxY4b8/Pz03nvvOV3/pEuXLnr11VfVv39/3X777QoODladOnWUnJxc6jrLWu/evWWMUYsWLfTiiy8WmZ+YmOg4eP+TTz7RVVddpTvvvFOpqalq06aNAgICtGvXLq1YsUJ///2348tEWT8/5+rVV19VSEiICgoKlJ2drXXr1mnx4sXKzc1VfHy8ZsyY4fb+/vv27VOLFi3Utm1bNWvWzHH83bfffqt9+/YpKSnJ0m5EktSjRw9dd911uv322xUTE6NFixZpxYoVatGihR5//HHHcna7XZ9//rm6d++uhIQEXX311Y6D0Hft2qUlS5aoWrVqpTp5wNm4+x4pD4MGDdKgQYPUqlUr3XbbbTp58qTS0tIcr+3Ck4u4q1mzZkpNTdXgwYN12WWX6aabblJsbKwyMzO1ePFi9ejRw3G9nf79+2vlypWaNm2ali1bpmuuuUbR0dHas2ePNmzYoB9++EHTp08/61ZGm82mG2+8Uf/+97+VkZFx1uOjJOnaa6/VM888ozFjxqhBgwa69tprFRsbq3379mnLli1asmSJXnjhBTVp0kTHjh3T1VdfrXr16ql9+/aqU6eOjhw5om+++UaZmZkaMWKEo8G44447FBQUpE6dOik2NlZ5eXlKS0vTunXrdMcdd6hOnTqWM01PT1f79u112WWXqXXr1qpVq5b27dunr776Snl5eZauada1a1cNHDhQs2fP1iWXXKKff/5Zc+fOVUxMjGOLcSErn2PSqc/t1atX64YbbtCVV14pf39/derUSZ06ddIll1yi6Ohox+dH7dq1ZbPZ9NBDD6ly5coaPXq0fv75Z73xxhuaPXu2EhISVKNGDaWnp+u3337TL7/8ohUrVpR4jFVxjDGaP3++mjRp4thS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7rnHBAcHmzp16pgvv/zSZGVlmRtvvNEEBwebpk2bmlWrVjndb9myZebKK680AQEBpnbt2mbQoEHmyJEjjsfk+toozf1Or6d3794mLCzM3HvvvSY3N9c8/PDDJjIy0tjtdhMbG2vGjRtXYqYA4Ck0SgBQRvbt22dsNluJX/oeeOABU7VqVceX5rM1Sj/++KORZL777juTkZFh9u3bV+y4f/75pwkKCjIDBw4069evN7NmzTLVq1d3NDoHDx40zz//vKldu7bJyMgwWVlZRcbIzc01qampJiwszGRkZJiMjAxz+PBhY8ypL7vh4eHmrbfeMps3bzYvvvii8fHxMevXrzfGGHP06FHTsGFDc99995lff/3VrFu3ziQnJ5vGjRub3NzcYmsubAaaNGli5s2bZ3799Vdz/fXXm7i4OHPixAljjDGrV682Pj4+5vnnnzcbN240U6ZMMYGBgY58Tp48aTp06GBuuukmY4wxkydPNpUrVzY7duwodp3GFN8oTZo0yVx99dXGGGNmzpxpJJnly5cXe/9GjRqZnj17ljh+QkKCCQkJMUOGDDEbNmwwH330kQkKCjLvvvuuY5n333/f/O9//zNbt241K1asMFdccYXp3r17kWyaN29u5s2bZ7Zs2WL27t1r1q5da95++23z66+/mk2bNplRo0aZgIAAs3PnTsd9C5+rt99+22zatMk89NBDJjQ01Fx77bXmP//5j9m4caO56aabTJMmTRyvw19//dWEhISYiRMnmk2bNplly5aZVq1amT59+hhjTr2ua9eubZ5//nnHa6M09yusJywszLzyyitm8+bNZvPmzeaVV14xMTExZvHixWbHjh1myZIlZvr06SVmCgCeQqMEAGVk5cqVxTY/hSZMmGAkObYenK1R2r59u5Fk1qxZc8b1PvXUU6Zx48ZOWy3eeustExIS4tiyMnHixGK3JJ1uypQppnLlykWmx8bGmrvvvttxu6CgwNSsWdNMnjzZGHPqi7/r+nNzc01gYKCZO3dusesqbAZO3zqzb98+ExgYaD799FNjjDHJyckmKSnJ6X5PPPGEufTSSx23t27dakJDQ82IESNMUFCQ+eijj874GItrlJKSkswbb7xhjDHmpZdeMpLMgQMHir3/jTfeaJo0aVLi+AkJCU5NiDHGjBgx4oz3KWyICxvTwmy+/PLLMz4WY4y59NJLzZtvvum47fpcZWRkGEnmmWeecUxbsWKFkeRoeO655x7z4IMPOo27ZMkS4+PjY44dO+YYd+LEiU7LlPZ+hY1soUGDBpkuXbo4ZQQA3ohjlACgnJj/f2yLzWYr03HXr1+vDh06OI0bHx+vI0eO6M8//yyTdTRv3tzxf5vNpsjISGVlZUmSfvrpJ23ZskWhoaEKCQlRSEiIwsPDdfz4cW3duvWM43bo0MHx//DwcDVu3Fjr1693PK74+Hin5ePj47V582bHSRXq1aunV199VS+//LJuuOEG/eMf/7D0uLKzs7Vo0SLdeOONTtNNCcchGWPO+vxdccUVTst06NDBqeY1a9aoZ8+eio2NVWhoqBITEyVJu3btchqnbdu2TrePHj2q4cOH69JLL1WVKlUUEhKiDRs2FLnf6c9VRESEJKlZs2ZFpp3+/E2dOtXx3IWEhKhbt24qKCjQ9u3bS3ycpb2f6+Po06eP1q5dq8aNG2vw4MGaN29eiesAAE/iaF4AKCMNGjSQzWbTunXrdNNNNxWZv2HDBlWtWlXVq1eXdKrhcP1CnpeXZ3m9xX15L+umzM/Pz+m2zWZTQUGBJKmgoEBt2rTRxx9/XOR+NWrUsLyuwprP9LhOt3jxYvn6+mrHjh06efKkpRNVfPvtt2rSpIliY2MlSY0aNZJ0qknr2LFjkeU3bNigSy+9tNTjuzp69Ki6du2qrl276qOPPlKNGjW0a9cudevWrciJDoKDg51uP/HEE5o7d65effVVNWjQQIGBgbrtttuK3O/056owv+Kmnf789e/fX4MHDy5Sb506dUp8LKW9n+vjaN26tbZv365vv/1W3333nXr16qVrrrlGn3/+eYnrAgBPoFECgDJSrVo1JSUl6Z///KceffRRBQYGOuZlZmbq448/1r333uv4olqjRg1lZGQ4ltm8ebNycnIct/39/SXprKekvvTSS/XFF184NRbLly9XaGioatWqVer6/f393Tr9devWrfXpp5+qZs2aCgsLs3TflStXOr5UHzhwQJs2bdIll1wi6dTjWrp0qdPyy5cvV6NGjeTr6ytJ+vTTTzVz5kwtXLhQd9xxh8aMGaPRo0eXev1fffWV09akrl27Kjw8XK+99lqRRunrr7/W5s2bNWbMmLM+JtfbDRs2lK+vrzZs2KC9e/fqpZdeUkxMjCRp9erVpap1yZIl6tOnj26++WZJ0pEjR7Rjx45S3fdMWrdurT/++EMNGjQocZniXhuluV9JwsLCdMcdd+iOO+7QbbfdpmuvvVb79+9XeHi45bEA4Hxh1zsAKEOTJk1Sbm6uunXrpsWLF2v37t2aM2eOkpKSVKtWLY0dO9axbJcuXTRp0iT9/PPPWr16tQYMGOD0l/+aNWsqMDBQc+bM0Z49e3To0KFi1zlw4EDt3r1bgwYN0oYNG/TVV1/pueee07Bhw+TjU/qP+bi4OB05ckTz58/X3r17nZq2M/nHP/6h6tWrq2fPnlqyZIm2b9+uRYsWaciQIWfd9e/555/X/Pnz9fvvv6tPnz6qXr26Y2vcY489pvnz52vMmDHatGmTpk2bpkmTJunxxx+XJP3555966KGH9PLLL6tTp06aOnWqXnzxxSKNSklOnjypb7/91nFacOnU1o933nlHX331lR588EH9+uuv2rFjh95//3316dNHt912m3r16nXGcXfv3q1hw4Zp48aN+uSTT/Tmm29qyJAhkk5tafH399ebb76pbdu26euvvz5r41WoQYMGmjlzptauXatffvlFycnJjq1C52LEiBFasWKFHn74Ya1du1abN2/W119/rUGDBjmWiYuL0+LFi5Wenq69e/eW+n7FmThxombMmKENGzZo06ZN+uyzzxQZGVnhr+EF4ALksaOjAKCC2rFjh+nTp4+JjIw0fn5+JiYmxgwaNMjpNNbGGJOenm66du1qgoODTcOGDc3//vc/p5M5GGPMe++9Z2JiYoyPj4/bpwc3pnQnczDGmAEDBphq1aoVOT2464H8LVq0cMw35tRJA+69915TvXp1Y7fbTb169cwDDzxgDh06VOx6Ck9Y8N///tdcdtllxt/f31x++eVm7dq1TssVnh7cz8/P1KlTx7zyyivGmFMnlLj66qtNt27dnE4K8Oijj5r69es7Tozg6vSTOXz33Xemdu3axS63ePFic+2115rKlSsbf39/c+mll5pXX33VnDx5sqTojDGnTuYwcOBAM2DAABMWFmaqVq1qnnzySacap0+fbuLi4ozdbjcdOnRwnHa88KQdhdm4nlBi+/bt5qqrrjKBgYEmJibGTJo0ySQkJJghQ4Y4linuuZLLSUOKO0nIjz/+aJKSkkxISIgJDg42zZs3N2PHjnXMX7FiheM07qd/dTjb/Yqr59133zUtW7Y0wcHBJiwszFx99dXm559/PmOuAOAJNmPK+cp5AAB4gcGDB+vkyZP65z//WWZjJiYmqmXLlkpNTS2zMQEAnsExSgCAi1LTpk2dzroHAMDpaJQAABelBx980NMlAAC8GLveAQAAAIALznoHAAAAAC5olAAAAADARYU/RqmgoEB//fWXQkNDy+wK9QAAAAAuPMYYHT58WNHR0We91mCFb5T++usvx9XPAQAAAGD37t2qXbv2GZep8I1SaGiopFNhhIWFebgaZ3l5eZo3b566du0qPz8/T5dzQSAz95CbdWTmHnKzjszcQ27WkZl7yM06b84sOztbMTExjh7hTCp8o1S4u11YWJhXNkpBQUEKCwvzuheRtyIz95CbdWTmHnKzjszcQ27WkZl7yM26CyGz0hySw8kcAAAAAMAFjRIAAAAAuKBRAgAAAAAXFf4YpdLKz89XXl5eua4zLy9PlSpV0vHjx5Wfn1+u675QlSYzPz8/+fr6lnNlAAAAqEgu+kbJGKPMzEwdPHjQI+uOjIzU7t27ucZTKZU2sypVqigyMpJcAQAA4BaPNkonT55USkqKPv74Y2VmZioqKkp9+vTR008/7bgAlDFGo0eP1rvvvqsDBw6offv2euutt3TZZZeVSQ2FTVLNmjUVFBRUrl+sCwoKdOTIEYWEhJz1glc45WyZGWOUk5OjrKwsSVJUVFR5lwgAAIAKwKON0ssvv6y3335b06ZN02WXXabVq1erb9++qly5soYMGSJJGj9+vCZMmKCpU6eqUaNGeuGFF5SUlKSNGzeW6vznZ5Kfn+9okqpVq1YWD8mSgoICnThxQgEBATRKpVSazAIDAyVJWVlZqlmzJrvhAQAAwDKPfjtfsWKFevbsqR49eiguLk633XabunbtqtWrV0s6tXUgNTVVo0aN0i233KKmTZtq2rRpysnJ0fTp0895/YXHJAUFBZ3zWPAuhc9peR93BgAAgIrBo1uUOnXqpLffflubNm1So0aN9Msvv2jp0qVKTU2VJG3fvl2ZmZnq2rWr4z52u10JCQlavny5+vfvX2TM3Nxc5ebmOm5nZ2dLOvWF2fVLc15enowxMsaooKDgPDzCMzPGOP71xPovRKXNrPB5zcvLY4uS/q9hpHEsPTJzD7lZR2buITfryMw95GadN2dmpSabKfzm6QHGGD311FN6+eWX5evrq/z8fI0dO1YjR46UJC1fvlzx8fFKT09XdHS0434PPvigdu7cqblz5xYZMyUlRaNHjy4yffr06UW2HFWqVEmRkZGKiYmRv79/GT86eNKJEye0e/duZWZm6uTJk54uBwAAAF4gJydHycnJOnTokMLCws64rEe3KH366af66KOPNH36dF122WVau3athg4dqujoaPXu3duxnOsJFowxJZ50YeTIkRo2bJjjdnZ2tmJiYtS1a9ciYRw/fly7d+9WSEiIAgICyvCRlY4xRocPH1ZoaChnZyul0mZ2/PhxBQYGqnPnzh55br1NXl6e0tLSlJSUJD8/P0+Xc0EgM/eQm3Vk5h5ys47M3ENu1nlzZoV7m5WGRxulJ554Qk8++aTuvPNOSVKzZs20c+dOvfjii+rdu7ciIyMlyXFGvEJZWVmKiIgodky73S673V5kup+fX5EnKj8/XzabTT4+Ph45mULhrmOFNUhSnz59NG3atCLLbt68WQ0aNCjX+s5kx44dqlu3rtasWaOWLVuW23qLy6w4Pj4+stlsxT7vFzPysI7M3ENu1pGZe8jNOjJzD7lZ542ZWanHoydzyMnJKfJl19fX1/FluG7duoqMjFRaWppj/okTJ7Ro0SJ17NixXGstT9dee60yMjKcfurWrWt5nBMnTpyH6gAAAICKz6ON0g033KCxY8dq9uzZ2rFjh2bNmqUJEybo5ptvlnRqq8HQoUM1btw4zZo1S7///rv69OmjoKAgJScne7L088putysyMtLpx9fXV4sWLVK7du1kt9sVFRWlJ5980un4m8TERD3yyCMaNmyYqlevrqSkJC1cuFA2m01z585Vq1atFBgYqC5duigrK0vffvutmjRporCwMN11113KyclxjDVnzhx16tRJVapUUbVq1XT99ddr69atjvmFjVurVq1ks9mUmJhYbvkAAAAA55tHd71788039cwzz2jgwIHKyspSdHS0+vfvr2effdaxzPDhw3Xs2DENHDjQccHZefPmnfM1lC406enpuu6669SnTx/9+9//1oYNG/TAAw8oICBAKSkpjuWmTZumhx56SMuWLZMxRpmZmZJOneRi0qRJCgoKUq9evdSrVy/Z7XZNnz5dR44c0c0336w333xTI0aMkCQdPXpUw4YNU7NmzXT06FE9++yzuvnmm7V27Vr5+Pjoxx9/VLt27fTdd9/psssu42QYAAAAqFA82iiFhoYqNTXVcTrw4thsNqWkpDg1AxXdN998o5CQEMft7t27q1GjRoqJidGkSZNks9l0ySWX6K+//tKIESP07LPPOnZhbNCggcaPH++4b2Gj9MILLyg+Pl6S1K9fP40cOVJbt25VvXr1JEm33XabFixY4GiUbr31Vqea3n//fdWsWVPr1q1T06ZNVaNGDUlStWrVHMeSAQAAABWFR3e9Q/GuuuoqrV271vHzxhtvaP369erQoYPTmd7i4+N15MgR/fnnn45pbdu2LXbM5s2bO/4fERGhoKAgR5NUOC0rK8txe+vWrUpOTla9evUUFhbm2NVu165dZfY4AQAAAG/l0S1KKF5wcHCRM9wVd0r0wktgnT49ODi42DFPP8NH4dngTmez2Zwu4HrDDTcoJiZG7733nqKjo1VQUKCmTZtygggAAABcFNiidIG49NJLtXz5cp1+feDly5crNDRUtWrVKtN17du3T+vXr9fTTz+tq6++Wk2aNNGBAweclik8Jik/P79M1w0AAAB4A7YoXSAGDhyo1NRUDRo0SI888og2btyo5557TsOGDSvza0BVrVpV1apV07vvvquoqCjt2rVLTz75pNMyNWvWVGBgoObMmaPatWsrICBAlStXLtM6AAAAUH7inpxdJuPYfY3GtyuToTyKLUoXiFq1aul///uffvzxR7Vo0UIDBgxQv3799PTTT5f5unx8fDRjxgz99NNPatq0qR599FG98sorTstUqlRJb7zxht555x1FR0erZ8+eZV4HAAAA4ClsUfIyU6dOLXFeQkKCfvzxxxLnL1y4sMi0xMREp931JKlPnz7q06eP0zTXMwtec801WrdundMyruPcf//9uv/++0usBwAAALhQsUUJAAAAAFzQKAEAAACACxolAAAAAHBBowQAAAAALmiUAAAAAMAFjRIAAAAAuKBRAgAAAAAXNEoAAAAA4IJGCQAAAABc0CjBSVxcnFJTU89pjJSUFLVs2bJM6ilJly5dNHTo0PO6DgAAAFy8Knm6AG8V9+TsclvXtnHdy21dhaZOnaqhQ4fq4MGDTtNXrVql4ODgcxr78ccf16BBg85pDAAAAMCTaJTgpEaNGuc8RkhIiEJCQsqgGgAAAMAz2PXuApWbm6vBgwerZs2aCggIUKdOnbRq1SpJ0sKFC2Wz2TR79my1aNFCAQEBat++vX777TfH/L59++rQoUOy2Wyy2WxKSUmRVHTXO5vNpnfeeUfXX3+9goKC1KRJE61YsUJbtmxRYmKigoOD1aFDB23dutVxH9dd7wrXcfpPXFycY/66det03XXXKSQkRBEREbrnnnu0d+9ex/yjR4/q3nvvVUhIiGrVqqVJkyaVfaAAAADAaWiULlDDhw/XF198oWnTpunnn39WgwYN1K1bN+3fv9+xzBNPPKFXX31Vq1atUs2aNXXjjTcqLy9PHTt2VGpqqsLCwpSRkaGMjAw9/vjjJa5rzJgxuvfee7V27VpdcsklSk5OVv/+/TVy5EitXr1akvTII4+UeP/CdWRkZGjLli1q0KCBOnfu7JiXkJCgli1bavXq1ZozZ4727NmjXr16OT2OBQsWaNasWZozZ46WLl2qn3766VwjBAAAAErErncXoKNHj2ry5MmaOnWqunc/dXzTe++9p7S0NL3//vu6/PLLJUnPPfeckpKSJEnTpk1T7dq1NWvWLPXq1UuVK1eWzWZTZGTkWdfXt29fR+MyYsQIdejQQc8884y6desmSRoyZIj69u1b4v0L12GM0a233qrKlSvrnXfekSRNnjxZrVu31rhx4xzLf/DBB4qJidGmTZsUHR2t999/X//+97+VlJSkgoICTZ48WZdddpnV2AAAAIBSo1G6AG3dulV5eXmKj493TPPz81O7du20fv16R6PUoUMHx/zw8HA1btxY69evt7y+5s2bO/4fEREhSWrWrJnTtOPHjys7O1thYWEljvPUU09pxYoVWrVqlQIDAyVJP/30kxYsWFDsMU1bt27VsWPHdOLECafHUrVqVTVu3Njy4wAAAABKi0bpAmSMkXTq2B/X6a7TXJ1tfnH8/PyK3L+4aQUFBSWO8dFHH2nixIlauHChateu7ZheUFCgG264QS+//HKR+0RFRWnz5s2W6wUAAADOFccoXYAaNGggf39/LV261DEtLy9Pq1evVpMmTRzTVq5c6fj/gQMHtGnTJl1yySWSJH9/f+Xn55dLvStWrND999+vd955R1dccYXTvNatW+uPP/5QXFycGjRo4PQTHBysBg0ayM/Pz+mxHDx4UJs2bSqX2gEAAHBxolG6AAUHB+uhhx7SE088oTlz5mjdunV64IEHlJOTo379+jmWe/755zV//nz9/vvv6tOnj6pXr66bbrpJ0qmz2x05ckTz58/X3r17lZOTc15qzczM1M0336w777xT3bp1U2ZmpjIzM/X3339Lkh5++GHt379fd911l3788Udt27ZN8+bN03333af8/HyFhISoX79+euKJJxyPZeDAgfLx4aULAACA84dvmxeol156SbfeeqvuuecetW7dWlu2bNHcuXNVtWpVp2WGDBmiNm3aKCMjQ19//bX8/f0lSR07dtSAAQN0xx13qEaNGho/fvx5qXPDhg3as2ePpk2bpqioKMdP4XFU0dHRWrZsmfLz89WtWzc1bdpUQ4YMUeXKlR3N0CuvvKLOnTvrxhtvVNeuXXXFFVeoTZs256VeAAAAQOIYpRLteKnHeV9HQUGBsrOz3bpvQECA3njjDb3xxhslLtOpUyf9/vvvJc6fPHmyJk+e7DRtx44dTrcLj4cqFBcXV2RaYmKi07SUlBTHdZlc5xWnYcOGmjlzZonzQ0JC9OGHH+rDDz90ZPb000+zVQkAAADnDd80AQAAAMAFjRIAAAAAuGDXuwqoNLu7AQAAACgZW5QAAAAAwAWNEgAAAAC4oFECAAAAABc0SgAAAADggkYJAAAAAFzQKAEAAACACxqli0hKSopatmxp6T6JiYkaOnSox+sAAAAAyhPXUSpJSuXzvgofSVUkFTx74LyvS5Ief/xxDRo0yNJ9Zs6cKT8/v/NUEQAAAOCdaJQuAsYY5efnKyQkRCEhIZbuGx4efp6qAgAAALwXu95doHJzczV48GDVrFlTAQEB6tSpk1atWiVJWrhwoWw2m+bOnau2bdvKbrdryZIlRXZ5O3nypAYPHqwqVaqoWrVqGjFihHr37q2bbrrJsYzrrndxcXEaN26c7rvvPoWGhqpOnTp69913nWobMWKEGjVqpKCgINWrV0/PPPOM8vLyzmccAAAAQJmiUbpADR8+XF988YWmTZumn3/+WQ0aNFC3bt20f/9+p2VefPFFrV+/Xs2bNy8yxssvv6yPP/5YU6ZM0bJly5Sdna0vv/zyrOt+7bXX1LZtW61Zs0YDBw7UQw89pA0bNjjmh4aGaurUqVq3bp1ef/11vffee5o4cWKZPG4AAACgPNAoXYCOHj2qyZMn65VXXlH37t116aWX6r333lNgYKDef/99x3LPP/+8kpKSVL9+fVWrVq3IOG+++aZGjhypm2++WZdccokmTZqkKlWqnHX91113nQYOHKgGDRpoxIgRql69uhYuXOiY//TTT6tjx46Ki4vTDTfcoMcee0z/+c9/yuKhAwAAAOWCY5QuQFu3blVeXp7i4+Md0/z8/NSuXTutX79el19+uSSpbdu2JY5x6NAh7dmzR+3atXNM8/X1VZs2bVRQUHDG9Z++dcpmsykyMlJZWVmOaZ9//rlSU1O1ZcsWHTlyRCdPnlRYWJjlxwkAAAB4CluULkDGGEmnmhTX6adPCw4OPutYxY1xNq5nwbPZbI7mauXKlbrzzjvVvXt3ffPNN1qzZo1GjRqlEydOnHVcAAAAwFvQKF2AGjRoIH9/fy1dutQxLS8vT6tXr1aTJk1KNUblypUVERGhH3/80TEtPz9fa9asOafali1bptjYWI0aNUpt27ZVw4YNtXPnznMaEwAAAChv7Hp3AQoODtZDDz2kJ554QuHh4apTp47Gjx+vnJwc9evXT7/88kupxhk0aJBefPFFNWjQQJdcconefPNNHThwoMhWJisaNGigXbt2acaMGbr88ss1e/ZszZo1y+3xAAAAAE/w6BaluLg42Wy2Ij8PP/ywpFO7gaWkpCg6OlqBgYFKTEzUH3/84cmSvcZLL72kW2+9Vffcc49at26tLVu2aO7cuapatWqpxxgxYoTuuusu3XvvverQoYNCQkLUrVs3BQQEuF1Xz5499eijj+qRRx5Ry5YttXz5cj3zzDNujwcAAAB4gke3KK1atUr5+fmO27///ruSkpJ0++23S5LGjx+vCRMmaOrUqWrUqJFeeOEFJSUlaePGjQoNDT2/xaUcOr/jSyooKFB2drbcOc1BQECA3njjDb3xxhtF5iUmJhZ7rFFKSopSUlIctytVqqQ333xTb775pqOeJk2aqFevXo5lTj+bnSTt2LGjyLhr1651uj1+/HiNHz/eadrp12JyrQMAAADwNh7dolSjRg1FRkY6fr755hvVr19fCQkJMsYoNTVVo0aN0i233KKmTZtq2rRpysnJ0fTp0z1ZdoWxc+dOvffee9q0aZN+++03PfTQQ9q+fbuSk5M9XRoAAADgUV5zjNKJEyf00UcfadiwYbLZbNq2bZsyMzPVtWtXxzJ2u10JCQlavny5+vfvX+w4ubm5ys3NddzOzs6WdOpkB3l5eU7L5uXlyRijgoKCs54S+3wo3OpTWIMnTJ06VY8//riMMWratKnmzZunxo0be6yesyltZgUFBTLGKC8vT76+vuVVntcqfO27vgdQMjJzD7lZR2buITfryMw9F1Nudt+zn/24VOP4nBrHGzOzUpPNlOZ80OXgP//5j5KTk7Vr1y5FR0dr+fLlio+PV3p6uqKjox3LPfjgg9q5c6fmzp1b7DgpKSkaPXp0kenTp09XUFCQ07RKlSopMjJSMTEx8vf3L9sHBI86ceKEdu/erczMTJ08edLT5QAAAMAL5OTkKDk5WYcOHTrrdT69ZovS+++/r+7duzs1RdLZrxXkauTIkRo2bJjjdnZ2tmJiYtS1a9ciYRw/fly7d+9WSEjIOZ3AwF3GGB0+fFihoaHndKa5i0lpMzt+/LgCAwPVuXNnjzy33iYvL09paWlKSkoqch0sFI/M3ENu1pGZe8jNOjJzz8WUW9OU4jdEWGX3MRrTtsArMyvc26w0vKJR2rlzp7777jvNnDnTMS0yMlKSlJmZqaioKMf0rKwsRURElDiW3W6X3W4vMt3Pz6/IE5Wfny+bzSYfHx/5+JT/4VqFu44V1oCzK21mPj4+stlsxT7vFzPysI7M3ENu1pGZe8jNOjJzz8WQW25+2f7h3hszs1KPV3w7nzJlimrWrKkePXo4ptWtW1eRkZFKS0tzTDtx4oQWLVqkjh07lun6vfV4HLiP5xQAAADnwuNblAoKCjRlyhT17t1blSr9Xzk2m01Dhw7VuHHj1LBhQzVs2FDjxo1TUFBQmZ2Vzd/fXz4+Pvrrr79Uo0YN+fv7l+sucAUFBTpx4oSOHz/OFqVSOltmxhidOHFCf//9t3x8fDj2DAAAAG7xeKP03XffadeuXbrvvvuKzBs+fLiOHTumgQMH6sCBA2rfvr3mzZtXZtdQ8vHxUd26dZWRkaG//vqrTMa0whijY8eOKTAwkGOUSqm0mQUFBalOnTo0oAAAAHCLxxulrl27FntxVOnUVqXzfXFSf39/1alTRydPnnS6+G15yMvL0+LFi9W5c2ev23/TW5UmM19fX1WqVInmEwAAAG7zeKPkDTx10L+vr69OnjypgIAAGqVSIjMAAACUB/ZLAgAAAAAXNEoAAAAA4IJGCQAAAABc0CgBAAAAgAsaJQAAAABwQaMEAAAAAC5olAAAAADABY0SAAAAALigUQIAAAAAFzRKAAAAAOCCRgkAAAAAXNAoAQAAAIALGiUAAAAAcEGjBAAAAAAuaJQAAAAAwAWNEgAAAAC4oFECAAAAABc0SgAAAADggkYJAAAAAFzQKAEAAACACxolAAAAAHBBowQAAAAALmiUAAAAAMAFjRIAAAAAuKBRAgAAAAAXNEoAAAAA4IJGCQAAAABc0CgBAAAAgAsaJQAAAABwQaMEAAAAAC5olAAAAADABY0SAAAAALigUQIAAAAAFzRKAAAAAOCCRgkAAAAAXNAoAQAAAIALGiUAAAAAcEGjBAAAAAAuaJQAAAAAwAWNEgAAAAC4oFECAAAAABc0SgAAAADggkYJAAAAAFzQKAEAAACAC483Sunp6br77rtVrVo1BQUFqWXLlvrpp58c840xSklJUXR0tAIDA5WYmKg//vjDgxUDAAAAqOg82igdOHBA8fHx8vPz07fffqt169bptddeU5UqVRzLjB8/XhMmTNCkSZO0atUqRUZGKikpSYcPH/Zc4QAAAAAqtEqeXPnLL7+smJgYTZkyxTEtLi7O8X9jjFJTUzVq1CjdcsstkqRp06YpIiJC06dPV//+/cu7ZAAAAAAXAY82Sl9//bW6deum22+/XYsWLVKtWrU0cOBAPfDAA5Kk7du3KzMzU127dnXcx263KyEhQcuXLy+2UcrNzVVubq7jdnZ2tiQpLy9PeXl55/kRWVNYj7fV5c3IzD3kZh2ZuYfcrCMz95CbdWTmnospN7uvKZtxfE6N442ZWanJZowpm0TcEBAQIEkaNmyYbr/9dv34448aOnSo3nnnHd17771avny54uPjlZ6erujoaMf9HnzwQe3cuVNz584tMmZKSopGjx5dZPr06dMVFBR0/h4MAAAAAK+Wk5Oj5ORkHTp0SGFhYWdc1qNblAoKCtS2bVuNGzdOktSqVSv98ccfmjx5su69917Hcjabzel+xpgi0wqNHDlSw4YNc9zOzs5WTEyMunbtetYwylteXp7S0tKUlJQkPz8/T5dzQSAz95CbdWTmHnKzjszcQ27WkZl7LqbcmqYU3QjhDruP0Zi2BV6ZWeHeZqXh0UYpKipKl156qdO0Jk2a6IsvvpAkRUZGSpIyMzMVFRXlWCYrK0sRERHFjmm322W324tM9/Pz87onqpA31+atyMw95GYdmbmH3KwjM/eQm3Vk5p6LIbfc/OI3RLjLGzOzUo9Hz3oXHx+vjRs3Ok3btGmTYmNjJUl169ZVZGSk0tLSHPNPnDihRYsWqWPHjuVaKwAAAICLh0e3KD366KPq2LGjxo0bp169eunHH3/Uu+++q3fffVfSqV3uhg4dqnHjxqlhw4Zq2LChxo0bp6CgICUnJ3uydAAAAAAVmEcbpcsvv1yzZs3SyJEj9fzzz6tu3bpKTU3VP/7xD8cyw4cP17FjxzRw4EAdOHBA7du317x58xQaGurBygEAAABUZB5tlCTp+uuv1/XXX1/ifJvNppSUFKWkpJRfUQAAAAAuah49RgkAAAAAvBGNEgAAAAC4oFECAAAAABc0SgAAAADggkYJAAAAAFzQKAEAAACACxolAAAAAHBBowQAAAAALmiUAAAAAMAFjRIAAAAAuKBRAgAAAAAXNEoAAAAA4IJGCQAAAABc0CgBAAAAgAsaJQAAAABwQaMEAAAAAC4qeboAAAAAABXQi7WlguNlM1bKobIZxwK2KAEAAACACxolAAAAAHBBowQAAAAALmiUAAAAAMAFjRIAAAAAuKBRAgAAAAAXNEoAAAAA4IJGCQAAAABc0CgBAAAAgAsaJQAAAABwQaMEAAAAAC5olAAAAADABY0SAAAAALigUQIAAAAAFzRKAAAAAOCCRgkAAAAAXNAoAQAAAIALGiUAAAAAcEGjBAAAAAAuaJQAAAAAwAWNEgAAAAC4oFECAAAAABc0SgAAAADggkYJAAAAAFzQKAEAAACACxolAAAAAHBBowQAAAAALmiUAAAAAMCFRxullJQU2Ww2p5/IyEjHfGOMUlJSFB0drcDAQCUmJuqPP/7wYMUAAAAALgYe36J02WWXKSMjw/Hz22+/OeaNHz9eEyZM0KRJk7Rq1SpFRkYqKSlJhw8f9mDFAAAAACo6jzdKlSpVUmRkpOOnRo0akk5tTUpNTdWoUaN0yy23qGnTppo2bZpycnI0ffp0D1cNAAAAoCKr5OkCNm/erOjoaNntdrVv317jxo1TvXr1tH37dmVmZqpr166OZe12uxISErR8+XL179+/2PFyc3OVm5vruJ2dnS1JysvLU15e3vl9MBYV1uNtdXkzMnMPuVlHZu4hN+vIzD3kZh2Zuediys3ua8pmHJ9T4+T5BJTJeKcGK5v8rTyPNmNM2STihm+//VY5OTlq1KiR9uzZoxdeeEEbNmzQH3/8oY0bNyo+Pl7p6emKjo523OfBBx/Uzp07NXfu3GLHTElJ0ejRo4tMnz59uoKCgs7bYwEAAADg3XJycpScnKxDhw4pLCzsjMt6tFFydfToUdWvX1/Dhw/XFVdcofj4eP3111+KiopyLPPAAw9o9+7dmjNnTrFjFLdFKSYmRnv37j1rGOUtLy9PaWlpSkpKkp+fn6fLuSCQmXvIzToycw+5WUdm7iE368jMPRdTbk1Tit8QYZXdx2hM2wIl/TZYfgXHy2RMjfyzTIbJzs5W9erVS9UoeXzXu9MFBwerWbNm2rx5s2666SZJUmZmplOjlJWVpYiIiBLHsNvtstvtRab7+fl57Yvbm2vzVmTmHnKzjszcQ27WkZl7yM06MnPPxZBbbr6tTMfzKzhedo1SGWVv5Tn0+MkcTpebm6v169crKipKdevWVWRkpNLS0hzzT5w4oUWLFqljx44erBIAAABARefRLUqPP/64brjhBtWpU0dZWVl64YUXlJ2drd69e8tms2no0KEaN26cGjZsqIYNG2rcuHEKCgpScnKyJ8sGAAAAUMF5tFH6888/ddddd2nv3r2qUaOGrrjiCq1cuVKxsbGSpOHDh+vYsWMaOHCgDhw4oPbt22vevHkKDQ31ZNkAAAAAKjiPNkozZsw443ybzaaUlBSlpKSUT0EAAAAAIC87RgkAAAAAvAGNEgAAAAC4oFECAAAAABc0SgAAAADggkYJAAAAAFzQKAEAAACACxolAAAAAHDhVqO0detWPf3007rrrruUlZUlSZozZ47++OOPMi0OAAAAADzBcqO0aNEiNWvWTD/88INmzpypI0eOSJJ+/fVXPffcc2VeIAAAAACUN8uN0pNPPqkXXnhBaWlp8vf3d0y/6qqrtGLFijItDgAAAAA8wXKj9Ntvv+nmm28uMr1GjRrat29fmRQFAAAAAJ5kuVGqUqWKMjIyikxfs2aNatWqVSZFAQAAAIAnWW6UkpOTNWLECGVmZspms6mgoEDLli3T448/rnvvvfd81AgAAAAA5cpyozR27FjVqVNHtWrV0pEjR3TppZeqc+fO6tixo55++unzUSMAAAAAlKtKVu/g5+enjz/+WM8//7zWrFmjgoICtWrVSg0bNjwf9QEAAABAubPcKBWqX7++6tevX5a1AAAAAIBXsNwoGWP0+eefa8GCBcrKylJBQYHT/JkzZ5ZZcQAAAADgCZYbpSFDhujdd9/VVVddpYiICNlstvNRFwAAAAB4jOVG6aOPPtLMmTN13XXXnY96AAAAAMDjLJ/1rnLlyqpXr975qAUAAAAAvILlRiklJUWjR4/WsWPHzkc9AAAAAOBxlne9u/322/XJJ5+oZs2aiouLk5+fn9P8n3/+ucyKAwAAAABPsNwo9enTRz/99JPuvvtuTuYAAAAAoEKy3CjNnj1bc+fOVadOnc5HPQAAAADgcZaPUYqJiVFYWNj5qAUAAAAAvILlRum1117T8OHDtWPHjvNQDgAAAAB4nuVd7+6++27l5OSofv36CgoKKnIyh/3795dZcQAAAADgCZYbpdTU1PNQBgAAAODFXqwtFRw/93FSDp37GCgXlhul3r17n486AAAAAMBrlKpRys7OdpzAITs7+4zLcqIHAAAAABe6UjVKVatWVUZGhmrWrKkqVaoUe+0kY4xsNpvy8/PLvEgAAAAAKE+lapS+//57hYeHS5IWLFhwXgsCAAAAAE8rVaOUkJCgevXqadWqVUpISDjfNQEAAACAR5X6Oko7duxgtzoAAAAAFwXLF5wFAAAAgIrO0unB161bp8zMzDMu07x583MqCAAAAAA8zVKjdPXVV8sYU2S6zWbjrHcAAAAXgrK6cKrExVNRoVlqlH744QfVqFHjfNUCAAAAAF7BUqNUp04d1axZ83zVAgAAAABegZM5AAAAAICLUjdKCQkJ8vf3P5+1AAAAAIBXKPWudwsWLDifdQAAAACA12DXOwAAAABwQaMEAAAAAC5olAAAAADAhdc0Si+++KJsNpuGDh3qmGaMUUpKiqKjoxUYGKjExET98ccfnisSAAAAwEXB0nWUJCk/P19Tp07V/PnzlZWVpYKCAqf533//veUiVq1apXfffVfNmzd3mj5+/HhNmDBBU6dOVaNGjfTCCy8oKSlJGzduVGhoqOX1AAAAAEBpWN6iNGTIEA0ZMkT5+flq2rSpWrRo4fRj1ZEjR/SPf/xD7733nqpWreqYboxRamqqRo0apVtuuUVNmzbVtGnTlJOTo+nTp1teDwAAAACUluUtSjNmzNB//vMfXXfddWVSwMMPP6wePXrommuu0QsvvOCYvn37dmVmZqpr166OaXa7XQkJCVq+fLn69+9f7Hi5ubnKzc113M7OzpYk5eXlKS8vr0xqLiuF9XhbXd6MzNxDbtaRmXvIzToycw+5WefIzCegLActu7G8VJnn5sWZ2X1N2Yzjc2ocb3ytWfnMsBljLCUSHR2thQsXqlGjRpYLczVjxgyNHTtWq1atUkBAgBITE9WyZUulpqZq+fLlio+PV3p6uqKjox33efDBB7Vz507NnTu32DFTUlI0evToItOnT5+uoKCgc64ZAAAAwIUpJydHycnJOnTokMLCws64rOUtSo899phef/11TZo0STabze0id+/erSFDhmjevHkKCCi523RdhzHmjOsdOXKkhg0b5ridnZ2tmJgYde3a9axhlLe8vDylpaUpKSlJfn5+ni7ngkBm7iE368jMPeRmHZm5h9ysc2T222D5FRwvm0FH/lk243ixMs/NizNrmlL8hgir7D5GY9oWeOVrrXBvs9Kw3CgtXbpUCxYs0LfffqvLLrusyIfTzJkzSzXOTz/9pKysLLVp08YxLT8/X4sXL9akSZO0ceNGSVJmZqaioqIcy2RlZSkiIqLEce12u+x2e5Hpfn5+XvtB6s21eSsycw+5WUdm7iE368jMPeRmnV/B8bL78noRZV9muXlxZrn57m8EKY43vtasfF5YbpSqVKmim2++2erdirj66qv122+/OU3r27evLrnkEo0YMUL16tVTZGSk0tLS1KpVK0nSiRMntGjRIr388svnvH4AAAAAKInlRmnKlCllsuLQ0FA1bdrUaVpwcLCqVavmmD506FCNGzdODRs2VMOGDTVu3DgFBQUpOTm5TGoAAAAAgOJYbpTK0/Dhw3Xs2DENHDhQBw4cUPv27TVv3jyuoQQAAADgvHKrUfr888/1n//8R7t27dKJEyec5v38889uF7Nw4UKn2zabTSkpKUpJSXF7TAAAAACwyvIFZ9944w317dtXNWvW1Jo1a9SuXTtVq1ZN27ZtU/fu3c9HjQAAAABQriw3Sv/85z/17rvvatKkSfL399fw4cOVlpamwYMH69ChQ+ejRgAAAAAoV5YbpV27dqljx46SpMDAQB0+fFiSdM899+iTTz4p2+oAAAAAwAMsN0qRkZHat2+fJCk2NlYrV66UJG3fvl3GmLKtDgAAAAA8wHKj1KVLF/33v/+VJPXr10+PPvqokpKSdMcdd5TJ9ZUAAAAAwNMsn/Xu3XffVUFBgSRpwIABCg8P19KlS3XDDTdowIABZV4gAAAAAJQ3y42Sj4+PfHz+b0NUr1691KtXrzItCgAAAAA8yfKud5K0ZMkS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48bpu+++kyQ1bNhQY8aMUf/+/R1O5l505h96s6ddu3aqWLGi/vjHPyomJkaWZZU6ftdddzmUzN3ozT46s6d///7auXOnpk6dWmo7dUn64osvNGjQIN19992aNWuWQwmDw8WLF3Xp0qVSawyX10dv9nmpMwYlh+Tm5iosLEzVqlVzOkrQoDP/0NuNqVq1qrZt26amTZs6HSWo0Jt9dGZPZGSkVqxYccWQ9H82b96szp076/Tp04ENFgTOnz+vP/zhD5o/f/5P7kjG1cufRm/2ebUztgd3SK1atfjF1SY68w+93ZiEhARe9OkHerOPzuwre9XtRo+Vd//6r/+qNWvW6L333lPlypU1bdo0jR07VnXq1NHs2bOdjuda9GafZzszuOm++uorU1xcXPJ548aNpkePHiYhIcF07NjRfPTRRw6mcyc68w+92ZOfn1/ytXr1anPfffeZtWvXmpMnT5Y6lp+f73RUV6E3++jMf/369TMtWrQwW7ZsueLYli1bzN13322efPJJB5K5X/369c3atWuNMcaEh4ebr7/+2hhjzOzZs02XLl0cTOZu9GafVztjUAoAn89njh8/bowxZu3atcbn85nu3bubcePGmUceecT4fD7z6aefOpzSXejMP/Rmj2VZxufzlXyV/fzjNfx/9GYfnfnv1KlTpnPnzsayLBMVFWVuv/1207RpUxMVFWV8Pp/p0qWLycvLczqmK1WtWtUcPHjQGGNM3bp1zRdffGGMMebbb781VatWdTKaq9GbfV7tjF3vAsD86DGw119/Xb/5zW/07rvvlqy99NJLGj9+vDp16uREPFeiM//Qmz1r1651OkJQojf76Mx/kZGRWr58ufbu3av//u//Vk5OjiSpdu3auu+++3jW6xri4uJ08OBBxcbGKiEhQfPnz9c999yjpUuXXvUFvqA3f3i2M4cHtXLBsqySv/LHxMSYzZs3lzqemZlpatSo4UQ016Iz/9AbgPImJyfHjB071ukYrvT222+bSZMmGWOMWbNmjQkLCzOVKlUyPp/PpKWlOZzOvejNPq92xhWlADl79qxCQ0MVFhamypUrlzpWqVIlXbx40aFk7kVn/qG3G5ednW3r5Z5Hjx5V3bp1b2Ki4EBv9tHZzZOTk6OxY8fqlVdecTqK67z44osl33fo0EF79+7V1q1b1bhxY7ahvwZ6s8+rnbHrXYA0adJEUVFROnDggLZt21bqWGZmJv9B/Al05h96u3Ft2rTRc889p4yMjKuek5+fr6lTp6pZs2ZauHBhANO5F73ZR2dwgwYNGqhXr1666667dOHCBafjBA16s88rnXFFKQDK3pseExNT6vPBgwf13HPPBTKS69GZf+jNnqysLI0fP16dO3dWSEiIEhMTVadOHYWGhurUqVPas2ePMjMzlZiYqAkTJqhLly5OR3YFerOPzuCEpKQkzZkzR/Xq1Su1npGRoX79+mnfvn0OJXM3erPPq53xwlkA5V5BQYGWLVumjRs36uDBg7p48aJq1qypli1bqlOnTmrWrJnTEV2J3uyjs1/erl271KpVq6B9oeXNlJKSos8//1zvvfee+vTpo+LiYr366qv685//rKFDh2rixIlOR3QlerPPq50xKDmgsLBQJ06cUHFxcal1O/evlzd05h96AxDshg8ffs3jubm5mjt3LoPSVfz1r3/V73//e6WkpOjgwYPKzs7Wf/7nfyo5OdnpaK5Gb/Z5sTMGpQDat2+fnnnmGW3atKnUujFGlmXxj/xPoDP/0BsAr0hKSpJlWdc9jy3Yr+6ll17Sv/3bv6lixYpat26d7r//fqcjBQV6s89rnfGMUgA99dRTqlixoj7++GPFxMTc0D/85R2d+YfeAHjFunXrnI4QtE6dOqVnn31Wq1ev1vvvv6/169frV7/6ld58802lpqY6Hc+16M0+r3bGFaUAqlq1qrZt28bL8WygM//QGwCviIuL05YtW1SjRg2nowSdunXrqlGjRkpPT1ejRo0kSR9++KFSU1N177336pNPPnE4oTvRm31e7YztwQMoISFBJ0+edDpGUKEz/9AbAK84ePAgtwv76Te/+Y02bNhQ8ourJD322GPatWuXCgsLHUzmbvRmn1c744rSTXbmzJmS77du3apRo0Zp/Pjxat68uUJCQkqdW7169UDHcyU68w+9AfAin8+nnJwcRUdHOx0FQDnDoHST+Xy+Us+H/N/D9D/GA/al0Zl/6A2AF/l8Pq1Zs0a33HLLNc9r0aJFgBK5W3Z2tq2dTY8ePcqLyEVv/igPnbGZw03GLjz20Zl/6A2AV3Xs2FE/9Xddy7L4A1AZbdq0UUpKip577jndc889P3lOfn6+5s+fr0mTJun555/X0KFDA5zSfejNvvLQGVeUAACAa/l8PmVkZKhW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\n","text/plain":"
"},"metadata":{}}],"id":"64bcc5de-aae3-46aa-9474-1c90b9ff20a9"},{"cell_type":"markdown","source":"## Now leet's run the tests with \"informed\" parameters, this is a I/O that aligns to the cloud-optimized granules chunking strategy and consolidated metadata.\n","metadata":{"tags":[],"user_expressions":[]},"id":"0ea67b0b-5e7f-4d1f-bca9-1f3cae7fe309"},{"cell_type":"code","source":"optimized_h5py_benchmarks = []\noptimized_xarray_benchmarks = []\n\nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n print(f\"Processing: {link}\")\n try:\n log_filename = f\"logs/fsspec-xarray-{key}-{k}.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n \n io_params = {\n \"fsspec_params\": {},\n \"h5py_params\": {}\n }\n \n if \"repacked\" in link: \n io_params ={\n \"fsspec_params\": {\n \"cache_type\": \"blockcache\",\n \"block_size\": 8*1024*1024\n },\n \"h5py_params\" : {\n \"driver_kwds\": {\n \"page_buf_size\": 64*1024*1024,\n \"rdcc_nbytes\": 8*1024*1024\n }\n\n }\n }\n\n if \"kerchunk\" in link:\n continue\n \n start = time.time()\n ds = xr.open_dataset(fs.open(link, mode='rb', **io_params[\"fsspec_params\"]), group=dataset[\"group\"], engine=\"h5netcdf\", decode_cf=False)\n data_mean = ds[dataset[\"variable\"]].mean()\n elapsed = time.time() - start\n optimized_xarray_benchmarks.append(\n {\"tool\": \"xarray\",\n \"dataset\": key,\n \"cloud-aware\": \"yes\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n \n logging.getLogger().removeHandler(file_handler)\n file_handler.close()\n\n except Exception as e:\n print(e)\n \nfor key, dataset in test_dict.items():\n for k, link in dataset[\"links\"].items():\n try:\n if \"kerchunk\" in link:\n continue \n print (f\"Processing: {link}\")\n log_filename = f\"logs/fsspec-h5py-{key}-{k}_default.log\"\n \n # Create a new FileHandler for each iteration\n file_handler = logging.FileHandler(log_filename)\n file_handler.setLevel(logging.DEBUG)\n\n # Add the handler to the root logger\n logging.getLogger().addHandler(file_handler)\n # this is mostly IO so no perf_counter is needed\n start = time.time()\n io_params = {\n \"fsspec_params\": {},\n \"h5py_params\": {}\n }\n \n if \"repacked\" in link: \n io_params ={\n \"fsspec_params\": {\n \"cache_type\": \"blockcache\",\n \"block_size\": 8*1024*1024\n },\n \"h5py_params\" : {\n \"page_buf_size\": 64*1024*1024,\n \"rdcc_nbytes\": 8*1024*1024\n }\n } \n with h5py.File(fs.open(link, mode=\"rb\", **io_params[\"fsspec_params\"]), **io_params[\"h5py_params\"]) as f:\n path = f\"{dataset['group']}/{dataset['variable']}\"\n data = f[path][:]\n data_mean = data.mean()\n elapsed = time.time() - start\n optimized_h5py_benchmarks.append(\n {\"tool\": \"h5py\",\n \"dataset\": key,\n \"cloud-aware\": \"yes\",\n \"format\": k,\n \"file\": link,\n \"time\": elapsed,\n \"mean\": data_mean})\n\n logging.getLogger().removeHandler(file_handler) \n file_handler.close()\n \n\n except Exception as e:\n print(e)","metadata":{"trusted":true,"tags":[]},"execution_count":28,"outputs":[{"name":"stdout","output_type":"stream","text":"Processing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\nProcessing: s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\n"}],"id":"8151834b-0b57-4a3d-98b5-8cfaffa37dc4"},{"cell_type":"markdown","source":"## Plotting results","metadata":{"tags":[],"user_expressions":[]},"id":"04414c2e-0666-4701-8ecc-7842727ede22"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(optimized_h5py_benchmarks+h5coro_beanchmarks+optimized_xarray_benchmarks+kerchunk_benchmarks)\n\npivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\n\nplt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\nplt.title(\"Informed I/O parameters\", fontsize=10)\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":29,"outputs":[{"output_type":"display_data","data":{"image/png":"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+fLlr7isr6/vVcd77733NHjwYPsvrcDAQH3//fd65plntHz5cs2ZM+eaDkZetGiROnXqJA8PD913332KiIjQokWL1LJlS5UqVcryeF999ZXuv/9++fj46L777lO5cuX0008/aeTIkVq4cKEWL16c43GfOHFCLVu2VHh4uB5//HEdPHhQn3/+udq0aaMFCxbYG6HBgwdr2rRp2rJli55++mmVLFlSUu67b+UmISFBS5YsUbdu3dS2bVt99dVXevrppxUQEKAtW7boyy+/1B133KG2bdtq9uzZeuSRR1S5cuWr/sUxry0gX375pbZt26aAgAD7tN27d9u/9LZv317du3dXSkqKvvrqKy1YsECLFi1Ss2bN7MsX9PNzPXh4eGj48OFatGiRPv/8cw0dOvSaxlu+fLl++eUXeXp6qmbNmrr99tvz9V5xNGfOHCUmJuree+/V7bffrqVLl+rDDz/U6tWrtXr1avn7+9uXXbt2rTp06KCzZ8+qa9euiomJ0d69e/XZZ5/pxx9/1OrVq1WlSpVs4x87dkzNmzdXaGio7rvvPl28eFF169bViBEjtGTJEi1dujTbboRZr1dn3iO5rSskJESpqan2+t966y116NBB/fr10+LFizVp0iSlpqaqW7du6tWrl+688041a9ZM8+bN09ixYxUSEqLhw4fb17F9+3a9+uqratOmje666y4FBgZqx44dmjlzpubNm6eNGzcqKioqR87/+c9/9OOPP6pbt26Ki4vT/Pnz9f777+vYsWP67LPPciz71FNPyd/fX3fddZcqVaqkgwcPasWKFZozZ479vWaM0UMPPaSZM2eqevXq6tmzp3x8fJSYmKi+fftq27Zteuedd676Gjhx4oQ2bdqkjh07ysMj/3+rfemll/TGG2+oYsWKuueeexQSEqJly5bp+eef19q1a/Xll1/al33xxRc1duxYVa1aVT179lRwcLAOHjyo5cuX6+eff1br1q0lSZMmTdKAAQMUHh6uu+66S6VLl1ZSUpJ++eUXffPNN04fw9arVy998cUXqlu3rvr06SNfX1/t379fixcvVocOHVSnTp18jbNmzRq98cYb6tKliwYNGqSNGzdq1qxZWrFihdatW5ft91l+P8dKliypESNGKCEhQdI/n+FZsj4z9+7dq+nTpys2Njbb52jW+yUtLU0dO3bUkiVL1KBBA/Xt21fp6emaN2+eunXrpvfff18DBw7M8XieeuoprVmzRl26dNEdd9yR4/dx8+bNlZiYqJUrV6pDhw75ygi47gxQzMXFxRlJ5qeffrJ0vxEjRhhJZvHixfZpu3fvNl5eXqZcuXJm//799ulpaWkmNjbWSDIzZsywT1+8eLGRZEaMGJFj/D179hhJplevXvZpGRkZpkqVKsZms5nly5fbp2dmZpqePXsaScbK2zY1NdWULFnS+Pr6mi1btuQ63qhRo7LdJ2sdDz/8sMnMzLRPX7JkibHZbCYmJsZkZGTYp/fq1ctIMnv27Mm1hqioKBMVFZVtWla2oaGhZvfu3fbp+/fvNz4+PqZEiRKmevXqJiUlxT5v7dq1RpK58847cx3r8ucpN999953x8PAwjRs3NufOnbNPb9GihfHy8jILFy7MtvzOnTtNcHCwqVOnjn1aQT4/Wa+NRo0amREjRuT6c8899+T6+sl6rSUlJeU5/oULF4y3t7fx8PAw6enp9ulRUVHG09Mz1/XNmjUr2xhZ2Tr+hIeH58jrSqZOnWq/r+P7sE+fPkaSee211+zTLl68aKKjo01wcLDZvHlztuWXL19uPD09zR133JFtetb4ffr0MZcuXcpRQ16vk2t5j+S2rqznVZL55ptvsj2munXrGpvNZsqUKWN++eWXbDWUK1fOlC5dOttzdfLkSXPs2LEcj+Xnn382Hh4e5rHHHsv1MZYoUcLs2LHDPv3cuXOmevXqxmazmYMHD9qn//rrr8bT09NERETkeP9mZmZmW/bjjz82kkzfvn2z1ZiWlma6du1qJJn169fnqNXRvHnzjCQzfPjwXOdnvbYvt3DhQiPJdOrUyZw9ezZbjf379zeSzJw5c+zTQ0NDTYUKFbItm7X85Xk2bNjQ+Pj4ZPucyXL06NGrPhZjcn6+nTx50thsNtO4ceMcr41Lly6ZEydOXHXMy19D//3vf7PNGzlypJFkHn300WzTrXyO5VZ3buvP7feWMca89NJLRpKJj4/P9jsiNTXVNG7c2Pj4+GR77WT9jqhYsaLZt29fno/722+/NZLMq6++mucyQGGjUUKxV7NmTSMp2xeH/Mjti9Vrr71mJJm33norx/KrV682ksxtt91mn2a1UVq6dKmRZLp27Zpj+b179xpPT09LjdKnn35qJJknnngix7z9+/cbLy8vU7Vq1WzTJRlPT89sjWCWLl26GEnZmoRraZTi4+NzLN+2bVsjyUyfPj3HvCpVquQ51pUapS1btpigoCBToUKFbL/AN27caP/yl5tnn33WSDJbt241xhTs83P5l6Gr/TjTKBljTPny5Y0kc/jwYfu0qKioPNfTrVu3bPefO3eumT59utm7d685f/68+fPPP82oUaOMv7+/8fPzy9HE5CWrUWrXrl2OeQcPHjTe3t7ZXodff/11rg1Klrvvvtt4eHiYU6dO2adJMj4+PubIkSO53iev14mz75G81pX1vMbFxeWYl/X50adPnxzzHn300Su+jxzVqVPHREdHZ5uW9Rhz+6KZNe+7776zTxswYICRZKZMmXLV9dWtW9cEBgaa8+fP55j366+/Gknmueeeu+o4H330kZFkJkyYkOv83BqlO++800jK9TMpqzG555577NNCQ0NN5cqVTVpa2hVradiwoQkMDMxX85IXx8+3U6dOGUmmZcuWTo+Z9RqqUaNGtkbEmH+a3rJlyxp/f3/747P6OZZb3bmtP7ffWxkZGaZUqVImJiYmR23G/PMHKUnm/ffft0/L+h3x3nvvXfFxr1mzJtcmEHAldr0DLNi0aZMk5bpb1y233CJ/f39t3rzZ6fG3bNkiSbr11ltzzIuKilJkZGS2/cT37t2radOmZVuuZMmS9t0prlRvZGSkqlatqp07d+r06dMKDg7OsS5Ht956q+bNm6fNmzcXyAG3DRo0yDEtPDxcklS/fv1c561du9bSOg4fPqyuXbsqMzNT3333nSIiIuzz1qxZI0lKTk7O9TiyHTt22P+tXbu25ecnP/r166cPP/ww13mzZ8/WAw88YGm8yxljcp3u6+urCxcuXPX+jrsexcTE6OWXX1b58uX1+OOPa/To0dl2ebqa3HKLiIhQ1apVtWPHDvvrMOt52bFjR67PS3JysjIzM/XHH3+ocePG9umVK1e2fGIPZ98jV1uXM69tSTp48GC2XVeXLFmihIQErV27VkePHtWlS5fs83x8fHJdd8OGDXNMq1ixoqR/zjiX5ZdffpEktW/fPs/HIUnnzp3T1q1bFRERoTfffDPH/PT0dEn/9365kqwT5ljZTXXNmjUKDAzU5MmTc53v7++fbd09evTQhx9+qNq1a+u+++5TbGysmjdvnuOkJj169NALL7yg2rVr6/7771dcXJxatWpl38XMGSEh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/tRxSzHgShyjhBvC6NGjdeHCBb377ruqUaOG2rZtq9q1a8vb21t79uzRTz/9pGPHjuXavFyuatWqeuutt/Tcc8+pbt266tGjhwIDA/XDDz9ox44d6tatmx566CH78j4+Pho4cKDefPNNNWzYUN26ddPp06f1/fffKzY2NsdfhT08PPTxxx+rc+fOuv322+3X6fn555+VlJSkunXr5vrlNS8hISH65JNP9MADD6hZs2a67777VLZsWS1atEjr169X06ZN9fzzz+e4X926dbVkyRLdcsstatu2rQ4dOqTZs2fL29tbn3zySbbrn7Rt21bvvPOO+vXrp3vvvVeBgYGqVKmSevbsme86C1qvXr1kjFG9evX0xhtv5JgfFxdnP3h/1qxZatOmje6//34lJCSoUaNG8vPz0/79+7V69WodOXLE/mWioJ+fa/XOO+8oKChImZmZSk1N1bZt27Rs2TKlpaWpZcuWmj17ttP7+x87dkz16tVT48aNVadOHfvxdz/++KOOHTumdu3aWdqNSJK6dOmizp07695771VkZKSWLl2q1atXq169ehoyZIh9OV9fX82ZM0edOnVSbGysbrvtNvtB6Pv379fy5ctVunTpfJ084GqcfY8UhqeeekpPPfWUGjRooH/961+6dOmSEhMT7a/trJOLOKtOnTpKSEjQoEGDdPPNN6t79+6KiopScnKyli1bpi5dutivt9OvXz+tWbNG06dP18qVK3X77bcrIiJChw8f1o4dO7R27VrNnDnzqlsZbTab7rzzTn366adKSkq66vFRktSxY0e98sorGjVqlGJiYtSxY0dFRUXp2LFj2rVrl5YvX67Ro0erVq1aOn/+vG677TZVqVJFzZo1U6VKlXTmzBn98MMPSk5O1rBhw+wNxn333aeAgAC1atVKUVFRSk9PV2JiorZt26b77rtPlSpVspzpwYMH1axZM918881q2LChKlSooGPHjunbb79Venq6pWuatW/fXgMGDNC8efNUs2ZNbdy4UQsWLFBkZKR9i3EWK59j0j+f2+vXr1fXrl116623ysfHR61atVKrVq1Us2ZNRURE2D8/KlasKJvNpieeeEIlSpTQyJEjtXHjRk2YMEHz5s1TbGysypYtq4MHD2rr1q3asmWLVq9enecxVrkxxmjRokWqVauWfUsZ4BYK5uR5QNGwbt068+ijj5qY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mi1btpjMzEwjyVSoUMF8/vnnZufOnaZ79+4mOjratG3b1syfP99s27bN3HLLLaZjx472sebPn29CQkLMtGnTzO7du83ChQtNdHS0iY+PN8YYk5GRYWrXrm3i4uLMpk2bzNKlS02DBg2MJDN37tx8Z2GMMUOGDDF9+/Y1xhgzfvx4I8kcOnQox33T0tJMUFCQefrpp/McPyoqygQHB5s33njD7Ny500yYMMF4enraszXGmHfffdf8/PPP5q+//jKLFi0yNWrUME888YR9/tSpU423t7dp0aKFWblypdmxY4c5c+aMWbRokZkxY4bZtm2b2bZtm+nbt68pX768SU1Ntd/3emSdkpJiJJmpU6eapKQkk5KSkq/7ZdVTrlw5M3nyZLN7926zd+9e8+STT5r69eubdevWmT179pjExETz3Xff5ZkpABR1NEoA4KZya5RatWqVbZkmTZqYYcOG2W9369bN9OrVy3574cKFxtPT0+zfv98+7ffffzeSzC+//GKM+adR8vb2tn+RziLJvPzyy/bbq1evNpLM5MmT7dNmzZpl/Pz87LdvvfVWM2bMmGzjzJgxw4SHhxtjjFmwYIHx9PQ0Bw4csM//8ccfnWqUqlevbv+i3r9/f1OiRIk871+3bl3TqVOnPOdHRUVla0KMMea+++674n2++OILU7p0afvtqVOnGklm8+bNed7HGGMuXbpkgoODzffff2+fdj2yzhrXMdf83m/w4MHZlunatavp06fPFR8bABQnXi7YiAUAcFLdunWz3Q4PD1dKSkqey2/fvl2RkZGKjIy0T7vppptUsmRJbd++XU2aNJEkRUVFqWzZsldcX/ny5SVJderUyTbtwoULSk1NVUhIiDZs2KB169bp9ddfty+TkZGhCxcu6Ny5c9q+fbsqVaqkihUr2uc3b948vw8/2+P6+++/dfvtt+drefP/70p4JY51NG/eXAkJCfbbixcv1pgxY7Rt2zalpqbq0qVLunDhgs6ePavAwEBJko+PT47nKCUlRa+++qp+/vlnHT58WBkZGTp37pz279+fbbmCzjogICDXx5nf+zVu3Djb/Z544gndc8892rhxo9q3b6/u3burRYsWuYcJAMUAjRIAFCHe3t7ZbttstiueMCCvBsFxetYX/SutL2v53KZl1ZCZmamRI0fq7rvvzjGWn5+fjDE5pl+tgcnNd999p3bt2snf31+SVL16dZ06dUqHDh1SREREtmUvXryov/76S23btrW8nqza9u3bp86dO6t///4aNWqUQkNDtWLFCvXt2zfbiQ78/f1zPJ7evXvryJEjSkhIUFRUlHx9fdW8eXNdvHgx23IFnXVe8ns/x9dEp06dtG/fPs2bN08//fSTbrvtNj355JN655138lwXABRlNEoAUIzddNNN2r9/vw4cOGDfqrRt2zadOnVKtWrVKvD1NWzYUDt37lRMTMwV67m8oVm9erXl9Xz77bd67LHH7LfvueceDR06VOPGjdO4ceOyLfvhhx/q7NmzeuCBB6445po1a3LcrlmzpiRp/fr1unTpksaNGycPj3/Og/TFF1/kq9bly5frgw8+UOfOnSVJBw4c0NGjR/N13yu5WtbSP41WRkaG5fvlpWzZsurdu7d69+6tW2+9Vc8//zyNEoBii0YJAIqx22+/XXXr1tWDDz6ohIQEXbp0SQMGDFBsbGyOXasKwquvvqo77rhDkZGRuvfee+Xh4aFff/1VW7du1ejRo3X77berRo0aeuSRRzRu3DilpqZq+PDhltaRkpKidevWZbs+UKVKlTR27FgNGTJEfn5+evjhh+Xt7a1vv/1WL730kp577jk1a9bsiuOuXLlSY8eOVffu3ZWYmKgvv/xS8+bNkyRVrVpVly5d0vvvv6+uXbtq5cqV+vDDD/NVb0xMjGbMmKHGjRsrNTVVzz//vH1L2LW4WtbSP2e+W7RokVq2bClfX1+VKlUqX/fLa32NGjXSzTffrLS0NP3www/XpdkGAHfB6cEBoBjLuuBoqVKl1Lp1a91+++2qUqWKPv/88+uyvg4dOuiHH35QYmKimjRpoltuuUXjx49XVFSUJMnDw0Nz585VWlqamjZtqsceeyzbsTL58f3336tZs2Y5rhP1zDPPaO7cuVq+fLkaN26s2rVra+bMmZo0aVK+tno899xz2rBhgxo0aKBRo0Zp3Lhx6tChgySpfv36Gj9+vN566y3Vrl1bn332md5444181TtlyhSdOHFCDRo00MMPP6xBgwY5fY2ry10ta0kaN26cEhMTFRkZqQYNGuT7frnx8fHRiy++qLp166p169by9PTU7Nmzr/lxAIC7spncdhgHAMBN3XnnnWrVqpWGDh1aYGNGR0dr8ODBGjx4cIGNCQAo2tiiBAAoUlq1anXV440AALhWHKMEAChSCnJLEgAAeWHXOwAAAABwwK53AAAAAOCARgkAAAAAHBT7Y5QyMzN16NAhBQcHO3X1dwAAAADFgzFGp0+fVkREhP0C4nkp9o3SoUOH7FejBwAAAIADBw6oYsWKV1ym2DdKwcHBkv4JIyQkxMXVZJeenq6FCxeqffv28vb2dnU5RQKZOYfcrCMz55CbdWTmHHKzjsycQ27WuXNmqampioyMtPcIV1LsG6Ws3e1CQkLcslEKCAhQSEiI272I3BWZOYfcrCMz55CbdWTmHHKzjsycQ27WFYXM8nNIDidzAAAAAAAHNEoAAAAA4IBGCQAAAAAcFPtjlPIrIyND6enphbrO9PR0eXl56cKFC8rIyCjUdRdV+cnM29tbnp6ehVwZAAAAipMbvlEyxig5OVknT550ybrDwsJ04MABrvGUT/nNrGTJkgoLCyNXAAAAOOWGb5SymqRy5copICCgUL9YZ2Zm6syZMwoKCrrqBa/wj6tlZozRuXPnlJKSIkkKDw8v7BIBAABQDNzQjVJGRoa9SSpdunShrz8zM1MXL16Un58fjVI+5Sczf39/SVJKSorKlSvHbngAAACw7Ib+dp51TFJAQICLK0FBy3pOC/u4MwAAABQPN3SjlIXjWIofnlMAAABcCxolAAAAAHBAowQAAAAADmiU3Ezv3r1ls9ly/OzatcvVpWWzd+9e2Ww2bd682dWlAAAAAAXuhj7rnbvq2LGjpk6dmm1a2bJlLY9z8eJF+fj4FFRZAAAAwA2DLUpuyNfXV2FhYdl+PD09tXTpUjVt2lS+vr4KDw/XCy+8oEuXLtnvFxcXp4EDB+rZZ59VmTJl1K5dOy1ZskQ2m00LFixQgwYN5O/vr7Zt2yolJUU//vijatWqpZCQED3wwAM6d+6cfaz58+erVatWKlmypEqXLq077rhDu3fvts+vXLmyJKlBgway2WyKi4srtHwAAACA641GqYg4ePCgOnfurCZNmmjLli2aNGmSJk+erNGjR2dbbvr06fLy8tLKlSv10Ucf2afHx8dr4sSJWrVqlQ4cOKAePXooISFBM2fO1Lx585SYmKj333/fvvzZs2f17LPPat26dVq0aJE8PDx01113KTMzU5L0yy+/SJJ++uknJSUl6euvvy6EFAAAAIDCwa53buiHH35QUFCQ/XanTp1UvXp1RUZGauLEibLZbKpZs6YOHTqkYcOG6dVXX7VffDUmJkZjx4613zc5OVmSNHr0aLVs2VKS1LdvX7344ovavXu3qlSpIkn617/+pcWLF2vYsGGSpHvuuSdbTZMnT1a5cuW0bds21a5d274rYOnSpRUWFnadkgAAAABcgy1KbqhNmzbavHmz/WfChAnavn27mjdvnu36QC1bttSZM2f0999/26c1btw41zHr1q1r/3/58uUVEBBgb5KypqWkpNhv7969Wz179lSVKlUUEhJi39Vu//79BfY4AQAAAHfFFiU3FBgYqJiYmGzTjDE5LqJqjJGU/eKqgYGBuY7p7e1t/7/NZst2O2ta1m51ktS1a1dFRkbqk08+UUREhDIzM1W7dm1dvHjRuQcFAAAAFCFsUSoibrrpJq1atcreHEnSqlWrFBwcrAoVKhTouo4dO6bt27fr5Zdf1m233aZatWrpxIkT2ZbJOpteRkZGga4bAAAAcAdsUSoiBgwYoISEBD311FMaOHCgdu7cqREjRujZZ5+1H59UUEqVKqXSpUvr448/Vnh4uPbv368XXngh2zLlypWTv7+/5s+fr4oVK8rPz08lSpQo0DoAAABQhL1RUcq8UDBjxZ8qmHEscOkWpfj4+BwXVr38xADGGMXHxysiIkL+/v6Ki4vT77//7sKKXadChQr6f//v/+mXX35RvXr11L9/f/Xt21cvv/xyga/Lw8NDs2fP1oYNG1S7dm0988wzevvtt7Mt4+XlpQkTJuijjz5SRESEunXrVuB1AAAAAK7i8i1KN998s3766Sf7bU9PT/v/x44dq/Hjx2vatGmqXr26Ro8erXbt2mnnzp0KDg52RbnX3bRp0/KcFxsbaz8td26WLFmSY1pcXFy23fUkqXfv3urdu3e2afHx8YqPj7ffvv3227Vt27ZsyziO89hjj+mxxx7Lsx4AAACgqHL5MUpeXl7ZLqyaddppY4wSEhI0fPhw3X333apdu7amT5+uc+fOaebMmS6uGgAAAEBx5vItSn/++aciIiLk6+urZs2aacyYMapSpYr27Nmj5ORktW/f3r6sr6+vYmNjtWrVKvXr1y/X8dLS0pSWlma/nZqaKklKT09Xenp6tmXT09NljFFmZma2M74VlqwtNFk14Orym1lmZqaMMUpPT8+2lfJGlfXad3wPIG9k5hxys47MnENu1pGZc8jNOntm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AAAAACA/LF9wNuv02+fPn78e9QAAAACAy1neonTvvfdq1qxZKleunKKjo3OcOWLjxo0FVhwAAAAAuILlRql3797asGGDHnrooWs+mQMAAAAAuCPLjdK8efO0YMECtWrV6nrUAwAAAAAuZ/kYpcjIyKtexRYAAAAAijLLjdK4ceM0dOhQ7d279zqUAwAAAACuZ3nXu4ceekjnzp1T1apVFRAQkONkDsePHy+w4gAAAADAFSw3SgkJCdehDAAAAABwH5YbpV69el2POgAAAADAbeSrUUpNTbWfwCE1NfWKy3KiBwAAAABFXb4apVKlSikpKUnlypVTyZIlc712kjFGNptNGRkZBV4kAAAAABSmfDVKP//8s0JDQyVJixcvvq4FAQAAAICr5atRio2NVZUqVbRu3TrFxsZe75oAAAAAwKXyfR2lvXv3slsdAAAAgBuC5QvOAgAAAEBxZ+n04Nu2bVNycvIVl6lbt+41FQQAAAAArmapUbrttttkjMkx3WazcdY7AAAAAMWGpUZp7dq1Klu27PWqBQAAAADcgqVGqVKlSipXrtz1qgUAAAAA3AIncwAAAAAAB/lulGJjY+Xj43M9awEAAAAAt5DvXe8WL158PesAAAAAALfBrncAAAAA4IBGCQAAAAAc0CgBAAAAgAMaJQAAAABwYOk6SpKUkZGhadOmadGiRUpJSVFmZma2+T///HOBFQcAAAAArmC5UXr66ac1bdo0denSRbVr15bNZrsedQEAAACAy1hulGbPnq0vvvhCnTt3vh71AAAAAIDLWT5GycfHRzExMdejFgAAAABwC5Ybpeeee07vvfeejDHXox4AAAAAcDnLu96tWLFCixcv1o8//qibb75Z3t7e2eZ//fXXBVYcAAAAALiC5UapZMmSuuuuu65HLQAAAADgFiw3SlOnTr0edQAAAACA2+CCswAAAADgwPIWJUmaM2eOvvjiC+3fv18XL17MNm/jxo0FUhgAAAAAuIrlLUoTJkxQnz59VK5cOW3atElNmzZV6dKl9ddff6lTp07Xo0YAAAAAKFSWG6UPPvhAH3/8sSZOnCgfHx8NHTpUiYmJGjRokE6dOnU9agQAAACAQmW5Udq/f79atGghSfL399fp06clSQ8//LBmzZpVsNUBAAAAgAtYbpTCwsJ07NgxSVJUVJTWrFkjSdqzZw8XoQUAAABQ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2FDt27dXnz59FBER4eoy3Q65WVecM+P04NdZUlKSXn31VX322WcKCwtT06ZNVaFCBfn7++v48eP67bfftGHDBkVFRWnEiBG67777XF2yy5GZc8jNOjJzDrlZR2bOeffdd/X6668rOjpad955Z665LV++XHPnztUtt9yi999/X9WqVXN12S71zTffaNiwYTp16pQ6d+6cZ2arV69W7969NWrUKJUtW9bVZbscuVl3Q2RmcF2VLVvWPPfcc2br1q15LnPu3Dkzc+ZM07RpU/P2228XYnXuicycQ27WkZlzyM06MnPOv/71L/Prr79edbnz58+b//znP+aTTz4phKrcW5MmTcx3331nMjIyrrjc33//bZ5//nnzzjvvFFJl7o3crLsRMmOL0nV25MgRS92z1eWLIzJzDrlZR2bOITfryAwAih4aJQAA4PYWLVqk2267Ldd5EydO1MCBAwu5IgDFHWe9K0THjh2z///AgQN69dVX9fzzz2v58uUurMq9kZlzyM06MnMOuVlHZs655557tG7duhzTExIS9NJLL7mgIvf2559/6quvvtKePXskSfPmzVPr1q3VpEkTvf766+Lv5LkjN+uKdWYu3O3vhvHrr7+aqKgo4+HhYWrUqGE2bdpkypcvb4KCgkxISIjx9PQ0c+fOdXWZboXMnENu1pGZc8jNOjK7NlOmTDFlypQxv//+u33a22+/bUJCQsyyZctcWJn7+frrr42Xl5fx8fExvr6+Zvr06cbX19d07NjRdOnSxXh5eZk333zT1WW6HXKzrrhnRqNUCDp27GjuuOMOs3z5ctOvXz9ToUIF06dPH5ORkWEyMjLMgAEDTLNmzVxdplshM+eQm3Vk5hxys47Mrt3bb79tKlSoYPbs2WPefPNNExISYlauXOnqstxOo0aNzEsvvWQyMzPNlClTjL+/v3n33Xft8z/66CNTs2ZN1xXopsjNuuKeGY1SIShdurTZsmWLMcaY06dPG5vNZtatW2efv337dlOiRAkXVeeeyMw55GYdmTmH3Kwjs4LxwgsvmNKlS5uSJUuaNWvWuLoctxQUFGR27dpljDEmIyPDeHp6Zjvj4p49e4y/v7+rynNb5GZdcc+MC84WguPHjyssLEySFBQUpMDAQIWGhtrnlypVSqdPn3ZVeW6JzJxDbtaRmXPIzToys27ChAk5poWHhysgIECtW7fW2rVrtXbtWknSoEGDCrs8t3X27FkFBwdLkjw8POTv76+AgAD7fH9//2wX7sU/yM264p4ZjVIhsdlsV7yNnMjMOeRmHZk5h9ysIzNr3n333Vyne3p6auXKlVq5cqWkf3KkUfo/Npst22vL8TZyR27WFffMaJQKSe/eveXr6ytJunDhgvr376/AwEBJKtKd9vVEZs4hN+vIzDnkZh2ZWZN1Fi1YY4xR9erV7V9Yz5w5owYNGsjDw8M+HzmRm3XFPTOuo1QI+vTpk6/lpk6dep0rKTrIzDnkZh2ZOYfcrCMzFJbp06fna7levXpd50qKFnKzrrhnRqMEAADcXkZGhqZNm6ZFixYpJSVFmZmZ2eb//PPPLqoMQHHFrncAAMDtPf3005o2bZq6dOmi2rVrF6vjIK6306dPZ9sFysPDQ0FBQS6sqGggN+uKW2ZsUSoESUlJmjhxol5//XVJUqtWrXTu3Dn7fE9PT33zzTeqUKGCq0p0O2TmHHKzjsycQ27Wkdm1KVOmjD799FN17tzZ1aW4vc2bN2v48OGaN2+eJCk4ODjba81ms2n16tVq0qSJq0p0S+RmXXHPzMPVBdwIPvjgA508edJ+e8uWLbr11lvVrVs3devWTZ6ennme2edGRWbOITfryMw55GYdmV0bHx8fxcTEuLqMIuH9999Xq1atsk2bMWOGfv75Zy1atEg9e/bM9dTrNzpys67YZ+aCazfdcOrVq2cWLlxovx0UFGR2795tvz1//nxz0003uaI0t0VmziE368jMOeRmHZldm3feeccMGDDAZGZmuroUt1ejRg2zbNky+23H19qaNWtMpUqVXFGaWyM364p7ZhyjVAj27t2rqlWr2m+3a9fOfjpYSapRowanQHVAZs4hN+vIzDnkZh2ZXZsVK1Zo8eLF+vHHH3XzzTfL29s72/yvv/7aRZW5nwMHDqhSpUr226+99prKlCljvx0eHq7Dhw+7ojS3Rm7WFffMaJQKwaVLl3Tq1Cn7bccP8xMnTtjPN49/kJlzyM06MnMOuVlHZtemZMmSuuuuu1xdRpHg6+urv//+W1FRUZKkZ555Jtv8AwcOKCAgwBWluTVys664Z0ajVAhq1KihVatWqUGDBrnOX758uapXr17IVbk3MnMOuVlHZs4hN+vI7Npwfan8a9Cggb755hu1bNky1/lff/11nq/DGxm5WVfsM3P1vn83grFjx5rQ0FCzZcuWHPM2b95sQkNDzdixY11QmfsiM+eQm3Vk5hxys47MUFjmzJljvLy8zMSJE01GRoZ9+qVLl8yECROMt7e3+fLLL11YoXsiN+uKe2acHrwQpKen6/bbb9eqVavUrl071ahRQzabTTt27FBiYqKaN2+uRYsW5djf+kZGZs4hN+vIzDnkZh2ZXZvKlStf8dpJf/31VyFW4/6GDRumt99+W8HBwapSpYpsNpt2796tM2fO6Nlnn9Xbb7/t6hLdErlZV5wzo1EqJBcvXtT48eM1e/Zs/fHHH5KkatWq6YEHHtAzzzwjX19fF1fofsjMOeRmHZk5h9ysIzPnvffee9lup6ena9OmTZo/f76ef/55vfDCCy6qzH2tWbNGs2bN0p9//inp/15rt9xyi4src2/kZl1xzYxGCQAAFFn/+c9/tH79eo5hAlDgOL0OAAAosjp16qSvvvrK1WUUKWfPntWyZctcXQaKgQ0bNri6hOuKRskNbNmyRZ6enq4uw+3MmzdPjz32mIYOHart27dnm3fixAm1bdvWRZW5r+DgYPXt21erVq1ydSnFBu/PvPEetYb35/UxZ84chYaGurqMImXXrl1q06aNq8twO+np6Ro6dKhiYmLUtGnTHFspDx8+zO8DB02aNFHVqlU1ZswYHTx40NXlFDgaJTfBHpDZzZw5U926dVNycrJWr16thg0b6rPPPrPPv3jxopYuXerCCt3T2bNntXbtWrVq1Uq1atXSuHHjlJKS4uqyijzenznxHrWO9+e1adCggRo2bGj/adCggcLDw/XSSy/ppZdecnV5KAZef/11ffrpp+rfv7/at2+vZ555Rv369cu2DL8Pcrrttts0YcIERUdH64477tA333yjjIwMV5dVIDhGqRDcfffdV5x/6tQpLVmypNi8qApCw4YN1adPHz311FOS/vmLYZ8+fZSQkKC+ffvq8OHDioiIIDMHHh4eSk5OVlJSkv773/9q5syZOnPmjO644w499thj6tix4xXPGnUj4v3pHN6j1vH+vDYjR47MdtvDw0Nly5ZVXFycatas6aKq3NPVtrBlZGTozJkzvD8dVKtWTe+++67uuOMOSdLu3bvVqVMntWzZUlOmTFFKSgqfaw6yPtdCQ0P17bffasqUKVqwYIHKlCmjXr166dFHH1WNGjVcXabT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ceN0/fXXm44BADCIQQkAEHYsy/rZrwcffNB0RABAmKtnOgAAAE59+eWXNd8vXrxYL7zwgj799NOataioKBOxAAAewhUlAEDYadGiRc1X06ZNZVmW39qCBQvUoUMH1a9fX1dddZXmzZvn998XFxdr4MCBatSokZo0aaK7775bX331laH/GwCAGzEoAQA8ZdmyZXriiSf09NNPa+/evXr00Uc1YsQI5ebmSpJs29agQYNUVlamTZs2ae3atTp48KCGDBliODkAwE249Q4A4CmTJk3Sgw8+qMzMTElSVlaWtm3bpkmTJqlnz55at26d/vWvf+nw4cNq3bq1JGnevHnq1KmTduzYoW7dupmMDwBwCa4oAQA8pbCwUD169PBb69GjhwoLC2uOt27dumZIkqSkpCTFxMTUnAMAAIMSAMBzLMvy+2zbds3aD7//qXMAAGBQAgB4yjXXXKMtW7b4rW3dulXXXHONpH9fPSouLtbnn39ec7ygoEDl5eU15wAAwB4lAICnjB07VnfffbduuOEG9erVSytXrtTSpUu1bt06SVJaWpo6d+6s+++/X5MnT9a5c+eUmZmp2267TSkpKYbTAwDcgitKAABPGTRokKZMmaKJEyeqU6dOeuuttzR79mylpqZK+vdtee+++65iY2N16623Ki0tTe3bt9fixYvNBgcAuIpl27ZtOgQAAAAAuAlXlAAAAAAgAIMSAAAAAARgUAIAAACAAAxKAAAAABCAQQkAAAAAAjAoAQAAAEAABiUAAAAACMCgBAAAAAABGJQAAAAAIACDEgAAAAAEYFACAAAAgAD/B7vXIIJKWjZCAAAAAElFTkSuQmCC\n","text/plain":"
"},"metadata":{}}],"id":"2db2535a-8d3a-4e65-b21c-8db6b48074c8"},{"cell_type":"markdown","source":"## Pliting tool specific performance","metadata":{"tags":[],"user_expressions":[]},"id":"ea0db03e-5653-4908-ada1-16d723666e18"},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(regular_xarray_benchmarks+optimized_xarray_benchmarks)\n\npivot_df = df.pivot_table(index=['dataset','cloud-aware'], columns=['format'], values='time', aggfunc='mean')\n\n# Plotting\npivot_df.plot(kind='bar', figsize=(10, 6))\nplt.title('Xarray \"Cloud-awared\" Access Pattern Performance (less is better)')\nplt.xlabel('Tool')\nplt.ylabel('Mean Time')\nplt.xticks(rotation=90)\nplt.legend(title='Format')\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"tags":[]},"execution_count":32,"outputs":[{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAA0oAAAKLCAYAAADIGXhIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB5J0lEQVR4nO3df3yO9f////u5X+c22/y2GTO/87tIhGKSya8XlSQlP4ukSOVHKiM/XlRS6a1IeCXl9SoUCSNWQuZ3IeVHCLMShrHN9vz+4bvz4zw3bNl2zHnerpfLeeF8Hsd5HI/jOJ/nY+fjPI7jediMMUYAAAAAAAcvqwMAAAAAgMKGQgkAAAAAXFAoAQAAAIALCiUAAAAAcEGhBAAAAAAuKJQAAAAAwAWFEgAAAAC4oFACAAAAABcUSgAAAADggkIJhVqfPn1kt9v1008/ZZn273//WzabTUuWLLEgsvxTsWJFxcTESJKioqLUq1evLPOcOHFCI0aMUN26dRUUFCR/f39Vq1ZNgwcP1m+//eaYLyYmRjabrYAid7Z27VrZbDatXbvWkvUXNlFRUYqKinI8//333532j81m05w5c3K8vJ9++kk2m02+vr46fvx43gZbCEVFRclmszkeAQEBuvXWWzV16lRlZGTkalnHjh1TTEyMtm/fnmXasmXLHJ+/wibzM5X58Pb2VmhoqB566CHt2bMnz9f38ssvq0KFCvLx8VGxYsXyfPmeaOzYsapVq5ZTn7XZbIWuz+Vl/u7Vq5eCgoJuPKgrzJ8/X1OnTs3SnpycrJiYmHz7u7N69WoFBQXp6NGj+bJ8FD4USijUpk6dqrCwMPXs2VNpaWmO9p9++kmjR49Wr1691LFjRwsjLHibNm1S3bp1NWvWLHXp0kULFy7U8uXL9cILL2jr1q1q1KiR1SGiAHz44YeSpEuXLuk///mPxdEUjMqVK2vDhg3asGGDFixYoHLlyum5557TyJEjc7WcY8eOacyYMVctlMaMGZNHEeePCRMmaMOGDVqzZo2GDx+u2NhYNWvWLE+/vH355ZcaP368Hn/8ccXFxWnVqlV5tmxPdezYMU2ePFljx46Vl1fh/vrVoEEDbdiwQQ0aNLA6lGxdq1AaM2ZMvhVKrVq1UqNGjfTSSy/ly/JR+BTuTyo8XkhIiGbNmqXt27dr3LhxkqS0tDT16NFDoaGh2SbKf+rChQvZtqelpenSpUt5tp4bkZSUpE6dOsnf31/btm3T6NGjFR0draioKPXv31/ff/+9Zs6caXWYbiU5OdnqELJISUnRJ598oltvvVXlypXTRx99ZHVIBSIgIEB33nmn7rzzTv3rX//Sl19+qcqVK2vatGlOP6QURnnZj6pVq6Y777xTzZs319ChQzVlyhSdOnUqV0ckryYzzp9//lmS9Oyzz6pZs2Zq2LBhni3bU7399tsqVqyYHnjgAatDua6QkBDdeeedCgkJsTqUQuHK7wFPP/20PvnkEx05csTiqFAQKJRQ6N17770aMGCAJkyYoC1btigmJkY7duzQrFmzVLRoUad5x4wZo8aNG6tEiRIKCQlRgwYNNGvWLBljnOarWLGiOnTooIULF6p+/fry9/d3/Apls9n08ccf6/nnn1e5cuVkt9u1b98+/fnnnxo4cKBq1aqloKAglSlTRvfcc4++//57x3KNMapWrZratGmTZTvOnTunokWL6umnn/7H+2LmzJlKSEjQ5MmTVb58+Wzn6dKlyzWXkZGRocmTJ6tGjRqy2+0qU6aMHn/8cf3xxx9O81WsWDHb0/5cTyGTpF9++UX33XefAgMDVapUKQ0YMEBnz57N8XZt3rxZ3bp1U8WKFRUQEKCKFSvqkUce0aFDhxzzJCUlycfHR6+//rqj7a+//pKXl5eKFi3qVMw+++yzKl26tON9j42NVadOnVS+fHn5+/uratWq6t+/v/766y+nODJPVdy6dau6dOmi4sWLq0qVKpIuv7f/93//p9tuu00BAQEqXry4unTpogMHDjgtwxijyZMnKzIyUv7+/mrQoIG++eabHO+LnFi8eLFOnjypfv36qWfPnvr111+1bt26LPOlpKRo7Nixqlmzpvz9/VWyZEm1bNlS69evd8yTkZGhd99917FdxYoV05133qmvvvrKaVkLFixQkyZNVKRIEQUFBalNmzbatm2b0zwHDhxQt27dFB4eLrvdrtDQULVq1crpyM23336rqKgolSxZUgEBAapQoYIefPDBf/Ql2tfXV7fffruSk5P1559/at++ferdu7eqVaumwMBAlStXTh07dnQ6dXft2rW64447JEm9e/d2nMYWExOjXr166b333pMkp1Pcfv/9d0k57wNRUVGqU6eOvvvuOzVt2lSBgYHq06eP43TLN954Q1OmTFGl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ixebli1bmpCQEGO3201kZKTp0qWLWbVqlTHGmBMnTphevXqZGjVqmCJFipigoCBTr14989ZbbzlGeNuwYYO5//77TWRkpLHb7aZkyZKmRYsW5quvvrru9l9tePArnTp1yvTt29eUKVPGBAYGmrvuust8//332e77Tz/91NSoUcP4+vo69YOUlBTTr18/U7p0aWOz2bLkjpz0gavFmjni2+uvv55lmmtfzM618pOr671fxlwejaxIkSLZvv5qn4Wc5o/c7oOrbVvmUO7x8fGOtvXr15smTZqYwMBAU7p0adOvXz+zdevWLCMZXm37ssuLOfmsGJOz9/9q7r77btOuXbss7dm993/++ad59tlnTaVKlYyvr68pUaKEuf32282oUaMcI63NnTvXtGzZ0oSGhho/Pz8THh5uunbtanbu3OlYzogRI0zDhg1N8eLFHX8Xn3vuOfPXX39dM1bXUe9y8vm+msz3YefOnSYqKsoEBASYEiVKmKeeeirbUeNyso///vtv06VLF1OsWDHH5zTTqlWrTP369Y3dbjeSnP6GHDx40PTp08eUK1fO+Pr6mtKlS5umTZuacePGZdn2q33O9u3b55Rn4d5sxrjciRNAnmnYsKFsNlu21+YAADzHF198oYcffliHDh1SuXLlrA4H/9Arr7yi//znP9q/f798fDgxy93xDgN5LCkpST///LOWLl2qLVu2aNGiRVaHBACw2AMPPKA77rhDEydO1LRp06wOB//A6dOn9d577+ndd9+lSPIQvMtAHtu6datatmypkiVLavTo0Y5hewEAnstms2nmzJn66quvrjnCHgqvgwcPauTIkVnuEwj3xal3AAAAAOCCnzMAAAAAwAWFEgAAAAC4oFACAAAAABduP5hDRkaGjh07puDgYG4MBgAAAHgwY4zOnj2r8PDw6w6q4vaF0rFjxxQREWF1GAAAAAAKiSNHjqh8+fLXnMftC6Xg4GBJl3dGSEiIxdFYIy0tTStXrlR0dLR8fX2tDgcWoA+APgD6AOgDoA9cvt9lRESEo0a4FrcvlDJPtwsJCfHoQikwMFAhISEe+6HwdPQB0AdAHwB9APSB/ycnl+QwmAMAAAAAuKBQAgAAAAAXFEoAAAAA4MLtr1ECAAAArsYYo0uXLik9Pd3qUPJdWlqafHx8dPHiRbfdXm9vb/n4+OTJbYEolAAAAOCR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\n","text/plain":"
"},"metadata":{}}],"id":"47444e8a-6d59-42c2-baff-a3c85c447eb2"}]} \ No newline at end of file +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6c9b37e2-2daa-4283-a228-ea581498de0c", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## AB testing access time for ICESat-2 ATL03 HDF5 files in the cloud.\n", + "\n", + "This notebook requires that we have 2 versions of the same file:\n", + " * Original A: The original file with no modifications on a S3 location.\n", + " * Test Case B: A modified version of the orignal file to test for metadata consolidation, rechunking and other strategies to speed up access to the data in the file.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aaca84b1-46e9-4b41-a494-24da3a368f38", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "!mamba uninstall -y h5coro \n", + "%pip install git+https://github.com/ICESat2-SlideRule/h5coro.git" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b78fb94-10ae-48cb-8e30-521b2c8b7822", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import h5py\n", + "import fsspec\n", + "import logging\n", + "import re\n", + "import time\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "from h5coro import h5coro, s3driver, filedriver\n", + "driver = s3driver.S3Driver\n", + "\n", + "logger = logging.getLogger('fsspec')\n", + "logger.setLevel(logging.DEBUG)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "431d900d-0656-4b75-af6b-82f0f171d5f8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "for library in (xr, h5py, fsspec, h5coro):\n", + " print(f'{library.__name__} v{library.__version__}')" + ] + }, + { + "cell_type": "markdown", + "id": "7998cd99-6034-4a1b-9ae5-d651bc265bff", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "For listing files in CryoCloud\n", + "\n", + "```bash\n", + "aws s3 ls s3://nasa-cryo-persistent/h5cloud/ --recursive\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9850faac-f534-4bc2-9214-c8dababe0f52", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "test_dict = {\n", + " \"ATL03-1GB\": {\n", + " \"links\": {\n", + " \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/original/ATL03_20230618223036_13681901_006_01.h5\",\n", + " \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/average/repacked/ATL03_20230618223036_13681901_006_01.h5\"\n", + " },\n", + " \"group\": \"/gt1l/heights\",\n", + " \"variable\": \"h_ph\",\n", + " \"processing\": [\n", + " \"h5repack -S PAGE -G 8000000\"\n", + " ]\n", + " },\n", + " \"ATL03-7GB\": {\n", + " \"links\": {\n", + " \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20181120182818_08110112_006_02.h5\",\n", + " \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20181120182818_08110112_006_02_repacked.h5\",\n", + " },\n", + " \"group\": \"/gt1l/heights\",\n", + " \"variable\": \"h_ph\",\n", + " \"processing\": [\n", + " \"h5repack -S PAGE -G 8000000\"\n", + " ]\n", + " },\n", + " \"ATL03-7GB-kerchunk\": {\n", + " \"links\": {\n", + " \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/kerchunk/atl03_ATL03_20181120182818_08110112_006_02.json\",\n", + " \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/kerchunk/atl03_ATL03_20181120182818_08110112_006_02_repacked.json\",\n", + " },\n", + " \"group\": \"/gt1l/heights\",\n", + " \"variable\": \"h_ph\",\n", + " \"processing\": [\n", + " \"h5repack -S PAGE -G 8000000\"\n", + " ]\n", + " }, \n", + " \"ATL03-2GB\": {\n", + " \"links\": {\n", + " \"original\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/original/ATL03_20210402143840_01341107_006_02.h5\",\n", + " \"optimized\": \"s3://nasa-cryo-persistent/h5cloud/atl03/big/repacked/ATL03_20210402143840_01341107_006_02_repacked.h5\",\n", + " },\n", + " \"group\": \"/gt1l/heights\",\n", + " \"variable\": \"h_ph\",\n", + " \"processing\": [\n", + " \"h5repack -S PAGE -G 8000000\"\n", + " ]\n", + " }\n", + "}\n", + "\n", + "def kerchunk_result(file: str, dataset: str, variable: str):\n", + " fs = fsspec.filesystem(\n", + " \"reference\",\n", + " fo=file,\n", + " remote_protocol=\"s3\",\n", + " remote_options=dict(anon=False),\n", + " skip_instance_cache=True,\n", + " )\n", + " ds = xr.open_dataset(\n", + " fs.get_mapper(\"\"), engine=\"zarr\", consolidated=False, group=dataset\n", + " )\n", + " return ds[variable].mean()\n", + "\n", + "# This will use the embedded credentials in the hub to access the s3://nasa-cryo-persistent bucket\n", + "fs = fsspec.filesystem('s3')\n" + ] + }, + { + "cell_type": "markdown", + "id": "4d166627-6144-40bf-884d-2188e5c764ba", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## [h5coro](https://github.com/ICESat2-SlideRule/h5coro/)\n", + "\n", + "**h5coro** is optimized for reading HDF5 data in high-latency high-throughput environments. It accomplishes this through a few key design decisions:\n", + "* __All reads are concurrent.__ Each dataset and/or attribute read by **h5coro** is performed in its own thread.\n", + "* __Intelligent range gets__ are used to read as many dataset chunks as possible in each read operation. This drastically reduces the number of HTTP requests to S3 and means there is no longer a need to re-chunk the data (it actually works better on smaller chunk sizes due to the granularity of the request).\n", + "* __Block caching__ is used to minimize the number of GET requests made to S3. S3 has a large first-byte latency (we've measured it at ~60ms on our systems), which means there is a large penalty for each read operation performed. **h5coro** performs all reads to S3 as large block reads and then maintains data in a local cache for access to smaller amounts of data within those blocks.\n", + "* __The system is serverless__ and does not depend on any external services to read the data. This means it scales naturally as the user application scales, and it reduces overall system complexity.\n", + "* __No metadata repository is needed.__ The structure of the file are cached as they are read so that successive reads to other datasets in the same file will not have to re-read and re-build the directory structure of the file.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efe41d4a-1947-438b-a3c3-7ab954d75e13", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "h5coro_beanchmarks = []\n", + "\n", + "for key, dataset in test_dict.items():\n", + " for k, link in dataset[\"links\"].items():\n", + " print (f\"Processing: {link}\")\n", + " if \"kerchunk\" in link:\n", + " continue\n", + " group = dataset[\"group\"]\n", + " variable = dataset['variable'] \n", + " final_h5coro_array = []\n", + " start = time.time()\n", + " if link.startswith(\"s3://nasa-cryo-persistent/\"):\n", + " h5obj = h5coro.H5Coro(link.replace(\"s3://\", \"\"), s3driver.S3Driver)\n", + " else:\n", + " h5obj = h5coro.H5Coro(link.replace(\"s3://\", \"\"), s3driver.S3Driver, credentials={\"annon\": True})\n", + " ds = h5obj.readDatasets(datasets=[f'{group}/{variable}'], block=True)\n", + " data = ds[f'{group}/{variable}'][:]\n", + " data_mean = np.mean(data)\n", + " elapsed = time.time() - start\n", + " \n", + " h5coro_beanchmarks.append({\"tool\": \"h5coro\",\n", + " \"dataset\": key,\n", + " \"cloud-aware\": \"no\",\n", + " \"format\": k,\n", + " \"file\": link,\n", + " \"time\": elapsed,\n", + " \"mean\": data_mean})\n", + "\n", + "\n", + "df = pd.DataFrame.from_dict(h5coro_beanchmarks)\n", + "\n", + "pivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n", + "\n", + "# Plotting\n", + "pivot_df.plot(kind='bar', figsize=(10, 6))\n", + "plt.title('h5coro cloud optimized HDF5 performance')\n", + "plt.xlabel('Tool')\n", + "plt.ylabel('Mean Time')\n", + "plt.xticks(rotation=90)\n", + "plt.legend(title='Format')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8f0ba64d-d89c-4879-b965-f00d70956360", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "### Xarray + kerchunk, out of the box performance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ff56958f-8c1d-4fd7-b885-6efb81af8da7", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# this is going to keep our numbers without modifying the i/o paramters\n", + "regular_xarray_benchmarks = []\n", + "kerchunk_benchmarks = []\n", + "\n", + "for key, dataset in test_dict.items():\n", + " for k, link in dataset[\"links\"].items():\n", + " print (f\"Processing: {link}\")\n", + " try:\n", + " log_filename = f\"logs/fsspec-xarray-{key}-{k}-default.log\"\n", + " \n", + " # Create a new FileHandler for each iteration\n", + " file_handler = logging.FileHandler(log_filename)\n", + " file_handler.setLevel(logging.DEBUG)\n", + "\n", + " # Add the handler to the root logger\n", + " logging.getLogger().addHandler(file_handler)\n", + " \n", + " start = time.time()\n", + " if \"kerchunk\" in link:\n", + " data_mean = kerchunk_result(link, dataset[\"group\"], dataset[\"variable\"])\n", + " elapsed = time.time() - start\n", + " kerchunk_benchmarks.append(\n", + " {\"tool\": \"kerchunk\",\n", + " \"dataset\": key,\n", + " \"cloud-aware\": \"no\",\n", + " \"format\": k,\n", + " \"file\": link,\n", + " \"time\": elapsed,\n", + " \"mean\": data_mean}) \n", + " else:\n", + " ds = xr.open_dataset(fs.open(link, mode='rb'), group=dataset[\"group\"], engine=\"h5netcdf\", decode_cf=False)\n", + " data_mean = ds[dataset[\"variable\"]].mean() \n", + " elapsed = time.time() - start\n", + " regular_xarray_benchmarks.append(\n", + " {\"tool\": \"xarray\",\n", + " \"dataset\": key,\n", + " \"cloud-aware\": \"no\",\n", + " \"format\": k,\n", + " \"file\": link,\n", + " \"time\": elapsed,\n", + " \"mean\": data_mean}) \n", + " \n", + " logging.getLogger().removeHandler(file_handler)\n", + " file_handler.close()\n", + "\n", + " except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "id": "92a8e67d-026e-4c6b-aa7d-b19dc10f4afd", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "### Plotting Results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "149d5972-c5b9-4f29-979a-cf46c9654a06", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(kerchunk_benchmarks + regular_xarray_benchmarks)\n", + "\n", + "pivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n", + "\n", + "# Plotting\n", + "pivot_df.plot(kind='bar', figsize=(10, 6))\n", + "\n", + "plt.title(\"Out of the box I/O parameters\", fontsize=10)\n", + "plt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\n", + "\n", + "plt.xlabel('Tool')\n", + "plt.ylabel('Mean Time')\n", + "plt.xticks(rotation=90)\n", + "plt.legend(title='Format')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "fa6ac2b9-989c-4246-bb89-b54b711dd695", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## h5py out of the box performance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98c29558-de50-44af-87e9-074092fcd0ac", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "regular_h5py_benchmarks = []\n", + "\n", + "for key, dataset in test_dict.items():\n", + " for k, link in dataset[\"links\"].items():\n", + " try:\n", + " if \"kerchunk\" in link:\n", + " continue \n", + " print (f\"Processing: {link}\")\n", + " log_filename = f\"logs/fsspec-h5py-{key}-{k}_default.log\"\n", + " \n", + " # Create a new FileHandler for each iteration\n", + " file_handler = logging.FileHandler(log_filename)\n", + " file_handler.setLevel(logging.DEBUG)\n", + "\n", + " # Add the handler to the root logger\n", + " logging.getLogger().addHandler(file_handler)\n", + " # this is mostly IO so no perf_counter is needed\n", + " start = time.time()\n", + " with h5py.File(fs.open(link, mode=\"rb\")) as f:\n", + " path = f\"{dataset['group']}/{dataset['variable']}\"\n", + " data = f[path][:]\n", + " data_mean = data.mean()\n", + " elapsed = time.time() - start\n", + " regular_h5py_benchmarks.append(\n", + " {\"tool\": \"h5py\",\n", + " \"dataset\": key,\n", + " \"cloud-aware\": \"no\",\n", + " \"format\": k,\n", + " \"file\": link,\n", + " \"time\": elapsed,\n", + " \"mean\": data_mean})\n", + "\n", + " logging.getLogger().removeHandler(file_handler) \n", + " file_handler.close()\n", + " \n", + " except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "id": "f4232e98-1159-45eb-ba11-0f0dbb905d83", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "### Plotting Results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d8fa6dca-f408-4298-beca-f2839d4c3b67", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(regular_h5py_benchmarks)\n", + "\n", + "pivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n", + "\n", + "# Plotting\n", + "pivot_df.plot(kind='bar', figsize=(10, 6))\n", + "plt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\n", + "plt.title(\"Out of the box I/O parameters\", fontsize=10)\n", + "\n", + "plt.xlabel('Tool')\n", + "plt.ylabel('Mean Time')\n", + "plt.xticks(rotation=45)\n", + "plt.legend(title='Format')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "b20b2032-9ab4-46e1-b1f8-2e62b656a265", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Aggregated plot by tool and different file sizes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64bcc5de-aae3-46aa-9474-1c90b9ff20a9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(regular_h5py_benchmarks + kerchunk_benchmarks + regular_xarray_benchmarks + h5coro_beanchmarks)\n", + "\n", + "pivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n", + "\n", + "# Plotting\n", + "pivot_df.plot(kind='bar', figsize=(10, 6))\n", + "plt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\n", + "plt.title(\"Out of the box I/O parameters\", fontsize=10)\n", + "plt.xlabel('Tool')\n", + "plt.ylabel('Mean Time')\n", + "plt.xticks(rotation=90)\n", + "plt.legend(title='Format')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "0ea67b0b-5e7f-4d1f-bca9-1f3cae7fe309", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Now let's run the tests with \"informed\" parameters, this is a I/O that aligns to the cloud-optimized granules chunking strategy and consolidated metadata.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8151834b-0b57-4a3d-98b5-8cfaffa37dc4", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "optimized_h5py_benchmarks = []\n", + "optimized_xarray_benchmarks = []\n", + "\n", + "for key, dataset in test_dict.items():\n", + " for k, link in dataset[\"links\"].items():\n", + " print(f\"Processing: {link}\")\n", + " try:\n", + " log_filename = f\"logs/fsspec-xarray-{key}-{k}.log\"\n", + " \n", + " # Create a new FileHandler for each iteration\n", + " file_handler = logging.FileHandler(log_filename)\n", + " file_handler.setLevel(logging.DEBUG)\n", + "\n", + " # Add the handler to the root logger\n", + " logging.getLogger().addHandler(file_handler)\n", + " \n", + " io_params = {\n", + " \"fsspec_params\": {},\n", + " \"h5py_params\": {}\n", + " }\n", + " \n", + " if \"repacked\" in link: \n", + " io_params ={\n", + " \"fsspec_params\": {\n", + " \"cache_type\": \"blockcache\",\n", + " \"block_size\": 8*1024*1024\n", + " },\n", + " \"h5py_params\" : {\n", + " \"driver_kwds\": {\n", + " \"page_buf_size\": 64*1024*1024,\n", + " \"rdcc_nbytes\": 8*1024*1024\n", + " }\n", + "\n", + " }\n", + " }\n", + "\n", + " if \"kerchunk\" in link:\n", + " continue\n", + " \n", + " start = time.time()\n", + " ds = xr.open_dataset(fs.open(link, mode='rb', **io_params[\"fsspec_params\"]), group=dataset[\"group\"], engine=\"h5netcdf\", decode_cf=False)\n", + " data_mean = ds[dataset[\"variable\"]].mean()\n", + " elapsed = time.time() - start\n", + " optimized_xarray_benchmarks.append(\n", + " {\"tool\": \"xarray\",\n", + " \"dataset\": key,\n", + " \"cloud-aware\": \"yes\",\n", + " \"format\": k,\n", + " \"file\": link,\n", + " \"time\": elapsed,\n", + " \"mean\": data_mean})\n", + " \n", + " logging.getLogger().removeHandler(file_handler)\n", + " file_handler.close()\n", + "\n", + " except Exception as e:\n", + " print(e)\n", + " \n", + "for key, dataset in test_dict.items():\n", + " for k, link in dataset[\"links\"].items():\n", + " try:\n", + " if \"kerchunk\" in link:\n", + " continue \n", + " print (f\"Processing: {link}\")\n", + " log_filename = f\"logs/fsspec-h5py-{key}-{k}_default.log\"\n", + " \n", + " # Create a new FileHandler for each iteration\n", + " file_handler = logging.FileHandler(log_filename)\n", + " file_handler.setLevel(logging.DEBUG)\n", + "\n", + " # Add the handler to the root logger\n", + " logging.getLogger().addHandler(file_handler)\n", + " # this is mostly IO so no perf_counter is needed\n", + " start = time.time()\n", + " io_params = {\n", + " \"fsspec_params\": {},\n", + " \"h5py_params\": {}\n", + " }\n", + " \n", + " if \"repacked\" in link: \n", + " io_params ={\n", + " \"fsspec_params\": {\n", + " \"cache_type\": \"blockcache\",\n", + " \"block_size\": 8*1024*1024\n", + " },\n", + " \"h5py_params\" : {\n", + " \"page_buf_size\": 64*1024*1024,\n", + " \"rdcc_nbytes\": 8*1024*1024\n", + " }\n", + " } \n", + " with h5py.File(fs.open(link, mode=\"rb\", **io_params[\"fsspec_params\"]), **io_params[\"h5py_params\"]) as f:\n", + " path = f\"{dataset['group']}/{dataset['variable']}\"\n", + " data = f[path][:]\n", + " data_mean = data.mean()\n", + " elapsed = time.time() - start\n", + " optimized_h5py_benchmarks.append(\n", + " {\"tool\": \"h5py\",\n", + " \"dataset\": key,\n", + " \"cloud-aware\": \"yes\",\n", + " \"format\": k,\n", + " \"file\": link,\n", + " \"time\": elapsed,\n", + " \"mean\": data_mean})\n", + "\n", + " logging.getLogger().removeHandler(file_handler) \n", + " file_handler.close()\n", + " \n", + "\n", + " except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "id": "04414c2e-0666-4701-8ecc-7842727ede22", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Plotting results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2db2535a-8d3a-4e65-b21c-8db6b48074c8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(optimized_h5py_benchmarks+h5coro_beanchmarks+optimized_xarray_benchmarks+kerchunk_benchmarks)\n", + "\n", + "pivot_df = df.pivot_table(index=['tool','dataset'], columns=['format'], values='time', aggfunc='mean')\n", + "\n", + "# Plotting\n", + "pivot_df.plot(kind='bar', figsize=(10, 6))\n", + "\n", + "plt.suptitle('Cloud-optimized HDF5 performance (less is better)', fontsize=14)\n", + "plt.title(\"Informed I/O parameters\", fontsize=10)\n", + "plt.xlabel('Tool')\n", + "plt.ylabel('Mean Time')\n", + "plt.xticks(rotation=90)\n", + "plt.legend(title='Format')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "ea0db03e-5653-4908-ada1-16d723666e18", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Ploting tool specific performance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47444e8a-6d59-42c2-baff-a3c85c447eb2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(regular_xarray_benchmarks+optimized_xarray_benchmarks)\n", + "\n", + "pivot_df = df.pivot_table(index=['dataset','cloud-aware'], columns=['format'], values='time', aggfunc='mean')\n", + "\n", + "# Plotting\n", + "pivot_df.plot(kind='bar', figsize=(10, 6))\n", + "plt.title('Xarray \"Cloud-Aware\" Access Pattern Performance (less is better)')\n", + "plt.xlabel('Tool')\n", + "plt.ylabel('Mean Time')\n", + "plt.xticks(rotation=90)\n", + "plt.legend(title='Format')\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8395f794-0ea7-4c26-8f64-0d2f9659d841", + "metadata": { + "tags": [], + "user_expressions": [] + }, + "source": [ + "## Make one comparison plot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbe17a07-22e3-4b99-a50a-d3183425d15c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_dict(regular_h5py_benchmarks + \n", + " kerchunk_benchmarks + \n", + " regular_xarray_benchmarks + \n", + " h5coro_beanchmarks + \n", + " optimized_h5py_benchmarks + \n", + " optimized_xarray_benchmarks)\n", + "df[\"size\"] = df.dataset.str.extract(r\"-(\\dGB)\")\n", + "df[\"product\"] = df.dataset.str.extract(r\"(ATL\\d{2})\")\n", + "df.to_csv(\"benchmarks.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "90486527-a1f2-4a92-bee6-1b2f934aa24d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "pivot_df = df.pivot_table(index=[\"tool\", \"size\"], columns=[\"format\", \"cloud-aware\"], values=\"time\", aggfunc=\"mean\")\n", + "pivot_df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88badbc0-a277-4aee-9236-d74327032d0d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "\n", + "sns.set_style(\"darkgrid\", rc={'axes.facecolor': '0.9'})\n", + "# sns.set_palette(\"bright\", 4)\n", + "\n", + "fig, ax = plt.subplots(figsize=(15,6), layout=\"constrained\")\n", + "\n", + "pivot_df.plot(kind=\"bar\", ax=ax, \n", + " color=[\"tab:cyan\", \"tab:blue\", \"tab:pink\", \"tab:red\"],\n", + " xlabel=\"\", fontsize=15);\n", + "ax.legend(labels = [\"Optimized\", \"Optimized with informed io parameters\", \"Original\", \"Original with informed io parameters\"], fontsize=15)\n", + "ax.set_ylabel(\"Time (s)\", fontsize=20)\n", + "\n", + "# Make two level axis\n", + "def parse_text(s):\n", + " return re.sub(r\"[()]\", \"\", s).split(\", \")\n", + "\n", + "# Retrieve and parse axis labels and position\n", + "tool, size, x, y = map(np.array, zip(*[(*parse_text(l.get_text()), *l.get_position()) for l in ax.get_xticklabels()]))\n", + "# Make labels and x-positions for seconary axis\n", + "sec_x, sec_label = zip(*[(x[tool == tool_name].mean(), \"\\n\"+tool_name) for tool_name in np.unique(tool)])\n", + "# Assign ticks and labels\n", + "ax.set_xticks(x, size, rotation=0);\n", + "sec = ax.secondary_xaxis(location=0);\n", + "sec.set_xticks(sec_x, sec_label, fontsize=18);\n", + "sec.tick_params(length=0)\n", + "\n", + "sepa_x = np.array([x[tool == tool_name].min()-0.5 for tool_name in np.unique(tool)] + [x.max()+0.5])\n", + "[ax.axvline(xs, c='k', ymin=-.1, clip_on=False, zorder=3) for xs in sepa_x];\n", + "\n", + "fig.savefig(\"access_time.summary.png\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c8dd30a5-952e-428f-b908-9897fac81aa7", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ae595359-3e8a-4072-89b4-bd2e52d9ec12", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From aa5dd0b3dfa917b9a15d1d2b5009168d2bfe6452 Mon Sep 17 00:00:00 2001 From: Andy Barrett Date: Wed, 28 Feb 2024 20:00:22 +0000 Subject: [PATCH 11/11] Remove savefig so that canonical plotting is in plot_benchmark_results.ipynb --- notebooks/portable-full-comparison.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebooks/portable-full-comparison.ipynb b/notebooks/portable-full-comparison.ipynb index 8b1dfb8..400a027 100644 --- a/notebooks/portable-full-comparison.ipynb +++ b/notebooks/portable-full-comparison.ipynb @@ -753,7 +753,7 @@ "sepa_x = np.array([x[tool == tool_name].min()-0.5 for tool_name in np.unique(tool)] + [x.max()+0.5])\n", "[ax.axvline(xs, c='k', ymin=-.1, clip_on=False, zorder=3) for xs in sepa_x];\n", "\n", - "fig.savefig(\"access_time.summary.png\")" + "# Use plot_benchmark_results.ipynb to generate saveable png" ] }, {