diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..d3849b2 --- /dev/null +++ b/.flake8 @@ -0,0 +1,10 @@ +[flake8] +# Ignore specific warnings or errors. +ignore = E501 + +# Optionally, increase the max line length (if you prefer to set a limit instead of ignoring entirely). +max-line-length = 120 + +# Exclude specific files or directories. +exclude = tests/, docs/, .venv/ + diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d32a365..9e5c2a2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -10,11 +10,40 @@ on: workflow_dispatch: jobs: + + test: + runs-on: ubuntu-latest + steps: + - name: Check out the code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install Poetry + uses: abatilo/actions-poetry@v3 + with: + poetry-version: 1.3.2 + + - name: Install Software + run: | + poetry build + poetry install + + - name: Run Tests + run: | + poetry run flake8 podaac + poetry run pylint podaac + poetry run pytest + # First job in the workflow installs and verifies the software deploy_sit: name: Deploy SIT # The type of runner that the job will run on runs-on: ubuntu-latest + needs: test steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it @@ -38,6 +67,7 @@ jobs: name: Deploy UAT # The type of runner that the job will run on runs-on: ubuntu-latest + needs: test steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it @@ -61,6 +91,7 @@ jobs: name: Deploy OPS # The type of runner that the job will run on runs-on: ubuntu-latest + needs: test steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it diff --git a/.github/workflows/test_configs.yml b/.github/workflows/test_configs.yml new file mode 100644 index 0000000..37c0ca1 --- /dev/null +++ b/.github/workflows/test_configs.yml @@ -0,0 +1,33 @@ +name: Test Configs + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Check out the code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install Poetry + uses: abatilo/actions-poetry@v3 + with: + poetry-version: 1.3.2 + + - name: Install Software + run: | + poetry build + poetry install + + - name: Run Tests + run: | + poetry run flake8 podaac + poetry run pylint podaac + poetry run pytest diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..6dd4fbf --- /dev/null +++ b/.pylintrc @@ -0,0 +1,20 @@ +[MASTER] +# List of directories to ignore (relative to the current directory). +ignore=tests + +[MESSAGES CONTROL] +# Disable the following messages by symbolic name or ID. +disable=line-too-long, # C0301: Line too long + broad-exception-caught, # W0718: Catching too general exception Exception + unspecified-encoding, # W1514: Using open without explicitly specifying an encoding + redefined-argument-from-local, # R1704: Redefining argument with a local name + no-value-for-parameter # E1120: No value for argument in function call + +[FORMAT] +# Maximum allowed line length (optional override if you want to enforce a slightly longer limit). +max-line-length=120 + +[REPORTS] +# Disable the output of the report summary. +reports=no + diff --git a/CHANGELOG.md b/CHANGELOG.md index 36f5f83..9fa9772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added config for NASA_SSH_REF_ALONGTRACK_V1 + +## [Released] - 2024-12-04 + +### Added + - Added Schema validations + - Added a new forge tig configuration generator + - Added in test to validate json structure and schema validate the configurations + - Updated configurations for new forge-py ### Changed ### Deprecated ### Removed diff --git a/Jenkins/Jenkinsfile b/Jenkins/Jenkinsfile deleted file mode 100644 index 693243d..0000000 --- a/Jenkins/Jenkinsfile +++ /dev/null @@ -1,141 +0,0 @@ -pipeline { - agent none - options { - preserveStashes(buildCount: 5) - } - environment{ - ARTIFACTORY_DOCKER_REGISTRY = "cae-artifactory.jpl.nasa.gov:16003" - } - stages{ - stage("Checkout"){ - agent { - label "devops1" - } - steps{ - checkout([ - $class: 'GitSCM', - branches: scm.branches, - extensions: scm.extensions + [ - [$class: 'CleanBeforeCheckout'], - [$class: 'WipeWorkspace'], - [$class: 'LocalBranch', localBranch: '**'], - [$class: 'PruneStaleBranch'] - ], - userRemoteConfigs: scm.userRemoteConfigs - ]) - script{ - the_env = sh(returnStdout: true, script: "printenv").trim() - } - writeYaml file: 'build-info.yaml', data: ['build_environment': the_env ], overwrite: true - stash name: 'build-info', includes: 'build-info.yaml' - } - } - stage("Run Build"){ - agent { - label 'devops1' - } - stages{ - stage("Version"){ - stages { - stage("Pre Alpha"){ - when { - anyOf{ - branch 'feature/*' - changeRequest target: 'develop' - } - } - steps{ - unstash name: 'build-info' - script{ - build_info = readYaml file: 'build-info.yaml' - build_info.deploy_env = "sit" - } - writeYaml file: 'build-info.yaml', data: build_info, overwrite: true - stash name: 'build-info', includes: 'build-info.yaml' - } - } - stage("Alpha"){ - when { - branch 'develop' - } - steps{ - unstash name: 'build-info' - script{ - build_info = readYaml file: 'build-info.yaml' - build_info.deploy_env = "sit" - } - writeYaml file: 'build-info.yaml', data: build_info, overwrite: true - stash name: 'build-info', includes: 'build-info.yaml' - } - } - stage("Release Candidate"){ - when { - changeRequest target: 'master' - } - steps{ - unstash name: 'build-info' - script{ - build_info = readYaml file: 'build-info.yaml' - build_info.deploy_env = "uat" - } - writeYaml file: 'build-info.yaml', data: build_info, overwrite: true - stash name: 'build-info', includes: 'build-info.yaml' - } - } - stage("Release"){ - when { - branch 'master' - } - steps{ - unstash name: 'build-info' - script{ - build_info = readYaml file: 'build-info.yaml' - build_info.deploy_env = "ops" - } - writeYaml file: 'build-info.yaml', data: build_info, overwrite: true - stash name: 'build-info', includes: 'build-info.yaml' - } - } - } - } - } - } - stage("Deploy"){ - when { - anyOf{ - branch 'develop' - branch 'master' - changeRequest target: 'master' - changelog '^/jenkins deploy' - } - } - agent { - docker { - image "${env.ARTIFACTORY_DOCKER_REGISTRY}/podaac/service/deploy-terraform-0.12.31" - label 'devops1' - alwaysPull true - args '-v /home/cm/.aws:/home/dockeruser/.aws:ro' - } - } - environment { - GIT_COMMIT_SHORT = sh(script: "printf \$(git rev-parse --short ${GIT_COMMIT})", returnStdout: true).trim() - } - steps{ - unstash name: 'build-info' - script{ - build_info = readYaml file: 'build-info.yaml' - } - echo "Publishing Configurations to ${build_info.deploy_env} S3" - dir('terraform'){ - sh "terraform init -reconfigure -input=false -backend-config=bucket=podaac-services-${build_info.deploy_env}-terraform -backend-config=profile=ngap-service-${build_info.deploy_env}" - sh "terraform output hitide-bucket-name" - script{ - bucket_name = sh(returnStdout: true, script: "terraform output hitide-bucket-name").trim() - } - } - sh("aws s3 sync ./config-files s3://${bucket_name}/dataset-configs --delete --profile ngap-service-${build_info.deploy_env} --metadata githash=${GIT_COMMIT_SHORT} --size-only") - sh("aws s3 sync ./palettes s3://${bucket_name}/palettes --delete --profile ngap-service-${build_info.deploy_env} --metadata githash=${GIT_COMMIT_SHORT} --size-only") - } - } - } -} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..218c4a7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 California Institute of Technology + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 275dccb..e66468b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,127 @@ -# forge-tig-configuration -Configuration files for collections processed by FORGE and TIG +# HiTide Configuration Generator -* refer to the unprocessed-files.txt about list of unprocessed files (may need to be done manually) +## Overview +HiTide Configuration Generator is a Python CLI tool that generates and validates configuration files for HiTide from Excel spreadsheets. It provides a flexible and type-safe way to create configuration settings for generating footprint and thumbnails. -Copyright 2023, by the California Institute of Technology. ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged. Any commercial use must be negotiated with the Office of Technology Transfer at the California Institute of Technology. - -This software may be subject to U.S. export control laws. By accepting this software, the user agrees to comply with all applicable U.S. export laws and regulations. User has the responsibility to obtain export licenses, or other export authority as may be required before exporting such information to foreign countries or providing access to foreign persons. \ No newline at end of file +## Features + +- Generate configuration from Excel spreadsheets +- Type-safe value conversion +- JSON schema validation +- Flexible configuration generation +- CLI interface for easy use + +## Prerequisites + +- Python 3.10+ +- Poetry +- pip + +## Installation + +1. Clone the repository: +```bash +git clone https://github.com/podaac/forge-tig-configuration.git +cd forge-tig-configuration +``` + +2. Install Poetry (if not already installed): +```bash +pip install poetry +``` + +3. Install project dependencies: +```bash +poetry install +``` + +## Usage + +### Activating the Virtual Environment + +To activate the Poetry virtual environment: +```bash +poetry shell +``` + +### CLI Command + +```bash +generate_config -f +``` + +#### Command Options + +- `-f, --file`: **[Required]** Path to the Excel file containing configuration settings +- `-h, --help`: Show help message + +### Excel File Structure + +Your Excel file should contain three sheets: + +1. `required-settings`: Global configuration settings +2. `forge-py`: Strategy and processing configurations +3. `tig`: Image generation variables + +#### Example Excel Sheets + +- **required-settings**: Contains key-value pairs for global settings +- **forge-py**: Configuration for footprint strategy and processing parameters +- **tig**: List of image variables for processing + +#### How to use example speadsheet + +- Fill in data for each sheet, leave empty if the field doesn't apply. +- Documentation for forge-py configurations https://github.com/podaac/forge-py + +## Configuration Generation Process + +1. Reads specified Excel file +2. Converts data types safely +3. Merges configurations from different sheets +4. Applies JSON schema validation +5. Generates a configuration file named after the `shortName` + +## Output + +- Prints JSON configuration to console +- Generates a `.cfg` file named after the `shortName` + +## Error Handling + +- Validates input against JSON schema +- Provides detailed error messages for configuration issues +- Handles type conversions and edge cases + +## Development + +### Running Tests + +```bash +poetry run pytest tests/ +``` + +### Adding Dependencies + +To add a new project dependency: +```bash +poetry add +``` + +To add a development dependency: +```bash +poetry add --group dev +``` + +### Contributing + +1. Fork the repository +2. Create your feature branch (`git checkout -b feature/AmazingFeature`) +3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) +4. Push to the branch (`git push origin feature/AmazingFeature`) +5. Open a Pull Request + +## License + +Distributed under the Apatche License. See `LICENSE` for more information. \ No newline at end of file diff --git a/archive/old_algorithm/AVHRR19_G-NAVO-L2P-v1.0.cfg b/archive/old_algorithm/AVHRR19_G-NAVO-L2P-v1.0.cfg deleted file mode 100644 index b96e4c8..0000000 --- a/archive/old_algorithm/AVHRR19_G-NAVO-L2P-v1.0.cfg +++ /dev/null @@ -1,74 +0,0 @@ -{ - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": false, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "findValid": true, - "strategy": "polar", - "b": "*:*,0:*", - "s2": "0:*,*:*", - "t": "0:0,0:*", - "s1": "0:*,0:0" - }, - "imgVariables": [ - { - "id": "sea_surface_temperature", - "title": "sea surface sub-skin temperature", - "units": "K", - "min": "275", - "max": "305", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_bias", - "title": "SSES bias", - "units": "K", - "min": "-1.25", - "max": "1.25", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_standard_deviation", - "title": "SSES standard deviation", - "units": "K", - "min": "-0.5", - "max": "2", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "wind_speed", - "title": "Wind Speed", - "units": "m s-1", - "min": "0", - "max": "30", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "dt_analysis", - "title": "deviation from sst reference climatology", - "units": "K", - "min": "-12.5", - "max": "12.5", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "quality_level", - "title": "quality_level", - "units": "", - "min": "1", - "max": "5", - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 4, - "res": 8 - } -} diff --git a/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v1.0.cfg b/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v1.0.cfg deleted file mode 100644 index 378e46f..0000000 --- a/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v1.0.cfg +++ /dev/null @@ -1,66 +0,0 @@ -{ - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": false, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "findValid": true, - "strategy": "polarsides", - "b": "*:*,0:*", - "s2": "0:*,*:*", - "t": "0:0,0:*", - "s1": "0:*,0:0" - }, - "imgVariables": [ - { - "id": "sea_surface_temperature", - "title": "sea surface sub-skin temperature", - "units": "K", - "min": "275", - "max": "305", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_bias", - "title": "SSES bias", - "units": "K", - "min": "-1.25", - "max": "1.25", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_standard_deviation", - "title": "SSES standard deviation", - "units": "K", - "min": "-0.5", - "max": "2", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "dt_analysis", - "title": "deviation from sst reference climatology", - "units": "K", - "min": "-12.5", - "max": "12.5", - "palette": "paletteMedspirationIndexed" - }, - { - "id": "quality_level", - "title": "quality_level", - "units": "", - "min": "1", - "max": "5", - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 4, - "res": 8 - } -} \ No newline at end of file diff --git a/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v2.0.cfg b/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v2.0.cfg deleted file mode 100644 index dda79be..0000000 --- a/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v2.0.cfg +++ /dev/null @@ -1,75 +0,0 @@ -{ - "shortName": "AVHRRMTA_G-NAVO-L2P-v2.0", - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": true, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "findValid": true, - "strategy": "polarsides", - "t": "0:0,0:*", - "s1": "0:*,0:0", - "b": "*:*,0:*", - "s2": "0:*,*:*" - }, - "imgVariables": [ - { - "id": "sea_surface_temperature", - "title": "sea water temperature at 1 meter depth", - "units": "kelvin", - "min": 275.0, - "max": 305.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_bias", - "title": "SSES bias error", - "units": "kelvin", - "min": -1.25, - "max": 1.25, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_standard_deviation", - "title": "SSES standard deviation error", - "units": "kelvin", - "min": -0.5, - "max": 2.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "dt_analysis", - "title": "deviation from sst reference climatology", - "units": "kelvin", - "min": -12.5, - "max": 12.5, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "l2p_flags", - "title": "L2P flags", - "units": "", - "min": 0.0, - "max": 512.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "quality_level", - "title": "quality level of SST pixel", - "units": "", - "min": 0.0, - "max": 5.0, - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 16, - "res": 8 - } -} \ No newline at end of file diff --git a/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v2.0.cfg.1 b/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v2.0.cfg.1 deleted file mode 100644 index dda79be..0000000 --- a/archive/old_algorithm/AVHRRMTA_G-NAVO-L2P-v2.0.cfg.1 +++ /dev/null @@ -1,75 +0,0 @@ -{ - "shortName": "AVHRRMTA_G-NAVO-L2P-v2.0", - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": true, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "findValid": true, - "strategy": "polarsides", - "t": "0:0,0:*", - "s1": "0:*,0:0", - "b": "*:*,0:*", - "s2": "0:*,*:*" - }, - "imgVariables": [ - { - "id": "sea_surface_temperature", - "title": "sea water temperature at 1 meter depth", - "units": "kelvin", - "min": 275.0, - "max": 305.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_bias", - "title": "SSES bias error", - "units": "kelvin", - "min": -1.25, - "max": 1.25, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_standard_deviation", - "title": "SSES standard deviation error", - "units": "kelvin", - "min": -0.5, - "max": 2.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "dt_analysis", - "title": "deviation from sst reference climatology", - "units": "kelvin", - "min": -12.5, - "max": 12.5, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "l2p_flags", - "title": "L2P flags", - "units": "", - "min": 0.0, - "max": 512.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "quality_level", - "title": "quality level of SST pixel", - "units": "", - "min": 0.0, - "max": 5.0, - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 16, - "res": 8 - } -} \ No newline at end of file diff --git a/archive/old_algorithm/AVHRRMTB_G-NAVO-L2P-v2.0.cfg b/archive/old_algorithm/AVHRRMTB_G-NAVO-L2P-v2.0.cfg deleted file mode 100644 index c312e63..0000000 --- a/archive/old_algorithm/AVHRRMTB_G-NAVO-L2P-v2.0.cfg +++ /dev/null @@ -1,78 +0,0 @@ -{ - "shortName": "AVHRRMTB_G-NAVO-L2P-v2.0", - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": true, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "findValid": true, - "strategy": "polarsides", - "t": "0:0,0:*", - "s1": "0:*,0:0", - "b": "*:*,0:*", - "s2": "0:*,*:*" - }, - "imgVariables": [ - { - "id": "sea_surface_temperature", - "title": "sea water temperature at 1 meter depth", - "units": "kelvin", - "min": 275.0, - "max": 305.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_bias", - "title": "SSES bias error", - "units": "kelvin", - "min": -1.25, - "max": 1.25, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "sses_standard_deviation", - "title": "SSES standard deviation error", - "units": "kelvin", - "min": -0.5, - "max": 2.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "dt_analysis", - "title": "deviation from sst reference climatology", - "units": "kelvin", - "min": -12.5, - "max": 12.5, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "l2p_flags", - "title": "L2P flags", - "units": "", - "min": 0.0, - "max": 512.0, - "palette": "paletteMedspirationIndexed", - "fill_missing": true, - "fill_value": 2048, - "ppd": 8 - }, - { - "id": "quality_level", - "title": "quality level of SST pixel", - "units": "", - "min": 0.0, - "max": 5.0, - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 16, - "res": 8 - } -} \ No newline at end of file diff --git a/archive/old_algorithm/PRIM_SMAP_L2_V1.cfg b/archive/old_algorithm/PRIM_SMAP_L2_V1.cfg deleted file mode 100644 index ed1288f..0000000 --- a/archive/old_algorithm/PRIM_SMAP_L2_V1.cfg +++ /dev/null @@ -1,58 +0,0 @@ -{ - "shortName": "PRIM_SMAP_L2_V1", - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": true, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "strategy": "periodic", - "t": "0:0,0:*", - "s1": "0:*,0:0", - "b": "*:*,0:*", - "s2": "0:*,*:*" - }, - "imgVariables": [ - { - "id": "PRIM_S0", - "title": "Sea surface salinity estimated using PRIM", - "units": "1e-3", - "min": 30.0, - "max": 40.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "PRIM_S1m", - "title": "Salinity at 1 meter depth estimated using RIM", - "units": "1e-3", - "min": 0.0, - "max": 40.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "PRIM_S5m", - "title": "Salinity at 5 meters depth estimated using RIM", - "units": "1e-3", - "min": 0.0, - "max": 40.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "PSS", - "title": "Probability of Salinity Stratification", - "units": "1", - "min": 0.0, - "max": 1.0, - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 4, - "res": 8 - } -} \ No newline at end of file diff --git a/archive/old_algorithm/PRIM_SMAP_L2_V1.cfg.1 b/archive/old_algorithm/PRIM_SMAP_L2_V1.cfg.1 deleted file mode 100644 index ed1288f..0000000 --- a/archive/old_algorithm/PRIM_SMAP_L2_V1.cfg.1 +++ /dev/null @@ -1,58 +0,0 @@ -{ - "shortName": "PRIM_SMAP_L2_V1", - "latVar": "lat", - "lonVar": "lon", - "timeVar": "time", - "is360": true, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "strategy": "periodic", - "t": "0:0,0:*", - "s1": "0:*,0:0", - "b": "*:*,0:*", - "s2": "0:*,*:*" - }, - "imgVariables": [ - { - "id": "PRIM_S0", - "title": "Sea surface salinity estimated using PRIM", - "units": "1e-3", - "min": 30.0, - "max": 40.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "PRIM_S1m", - "title": "Salinity at 1 meter depth estimated using RIM", - "units": "1e-3", - "min": 0.0, - "max": 40.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "PRIM_S5m", - "title": "Salinity at 5 meters depth estimated using RIM", - "units": "1e-3", - "min": 0.0, - "max": 40.0, - "palette": "paletteMedspirationIndexed" - }, - { - "id": "PSS", - "title": "Probability of Salinity Stratification", - "units": "1", - "min": 0.0, - "max": 1.0, - "palette": "paletteMedspirationIndexed" - } - ], - "image": { - "ppd": 4, - "res": 8 - } -} \ No newline at end of file diff --git a/archive/old_algorithm/SMAP_RSS_L2_SSS_V6.cfg b/archive/old_algorithm/SMAP_RSS_L2_SSS_V6.cfg deleted file mode 100644 index dbd6945..0000000 --- a/archive/old_algorithm/SMAP_RSS_L2_SSS_V6.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "shortName": "SMAP_RSS_L2_SSS_V6", - "latVar": "cellat", - "lonVar": "cellon", - "timeVar": "time", - "is360": true, - "tiles": { - "steps": [ - 30, - 14 - ] - }, - "footprint": { - "strategy": "smap", - "t": "0:0,0:*,0:0", - "s1": "0:*,0:0,0:0", - "b": "*:*,0:*,0:0", - "s2": "0:*,*:*,0:0" - }, - "imgVariables": [ - { - "id": "sss_smap", - "title": "SMAP sea surface salinity smoothed to approx 70km resolution", - "units": "1e-3", - "min": 30.0, - "max": 40.0, - "palette": "palette_AQUARIUS_SSS", - "fill_missing": true - }, - { - "id": "sss_smap_unc", - "title": "total formal uncertainty estimate of SMAP sea surface salinity smoothed to approx 70km resolution", - "units": "1e-3", - "min": 0.0, - "max": 40.0, - "palette": "palette_AQUARIUS_SSS", - "fill_missing": true - } - ], - "image": { - "ppd": 4, - "res": 8 - } -} \ No newline at end of file diff --git a/config-files/ALTIKA_SARAL_L2_OST_XOGDR.cfg b/config-files/ALTIKA_SARAL_L2_OST_XOGDR.cfg index f17a5c1..14d2155 100644 --- a/config-files/ALTIKA_SARAL_L2_OST_XOGDR.cfg +++ b/config-files/ALTIKA_SARAL_L2_OST_XOGDR.cfg @@ -1,4 +1,5 @@ { + "shortName": "ALTIKA_SARAL_L2_OST_XOGDR", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AMSR2-REMSS-L2P-v7.2.cfg b/config-files/AMSR2-REMSS-L2P-v7.2.cfg index 54f548d..24f24a1 100644 --- a/config-files/AMSR2-REMSS-L2P-v7.2.cfg +++ b/config-files/AMSR2-REMSS-L2P-v7.2.cfg @@ -1,4 +1,5 @@ { + "shortName": "AMSR2-REMSS-L2P-v7.2", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AMSR2-REMSS-L2P-v8.2.cfg b/config-files/AMSR2-REMSS-L2P-v8.2.cfg index c545829..74bb82b 100644 --- a/config-files/AMSR2-REMSS-L2P-v8.2.cfg +++ b/config-files/AMSR2-REMSS-L2P-v8.2.cfg @@ -1,4 +1,5 @@ { + "shortName": "AMSR2-REMSS-L2P-v8.2", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AMSR2-REMSS-L2P-v8a.cfg b/config-files/AMSR2-REMSS-L2P-v8a.cfg index 54f548d..43f9d5e 100644 --- a/config-files/AMSR2-REMSS-L2P-v8a.cfg +++ b/config-files/AMSR2-REMSS-L2P-v8a.cfg @@ -1,4 +1,5 @@ { + "shortName": "AMSR2-REMSS-L2P-v8a", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AMSR2-REMSS-L2P_RT-v8.2.cfg b/config-files/AMSR2-REMSS-L2P_RT-v8.2.cfg index c545829..b56fc35 100644 --- a/config-files/AMSR2-REMSS-L2P_RT-v8.2.cfg +++ b/config-files/AMSR2-REMSS-L2P_RT-v8.2.cfg @@ -1,4 +1,5 @@ { + "shortName": "AMSR2-REMSS-L2P_RT-v8.2", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AMSR2-REMSS-L2P_RT_v8a.cfg b/config-files/AMSR2-REMSS-L2P_RT_v8a.cfg index 54f548d..5e8de07 100644 --- a/config-files/AMSR2-REMSS-L2P_RT_v8a.cfg +++ b/config-files/AMSR2-REMSS-L2P_RT_v8a.cfg @@ -1,4 +1,5 @@ { + "shortName": "AMSR2-REMSS-L2P_RT_v8a", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AMSRE-REMSS-L2P-v7a.cfg b/config-files/AMSRE-REMSS-L2P-v7a.cfg index 54f548d..e28c712 100644 --- a/config-files/AMSRE-REMSS-L2P-v7a.cfg +++ b/config-files/AMSRE-REMSS-L2P-v7a.cfg @@ -1,4 +1,5 @@ { + "shortName": "AMSRE-REMSS-L2P-v7a", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AQUARIUS_L2_SSS_CAP_V5.cfg b/config-files/AQUARIUS_L2_SSS_CAP_V5.cfg index f04869d..857e08d 100644 --- a/config-files/AQUARIUS_L2_SSS_CAP_V5.cfg +++ b/config-files/AQUARIUS_L2_SSS_CAP_V5.cfg @@ -1,4 +1,5 @@ { + "shortName": "AQUARIUS_L2_SSS_CAP_V5", "latVar": "beam_clat", "lonVar": "beam_clon", "timeVar": "sec", diff --git a/config-files/AQUARIUS_L2_SSS_V5.cfg b/config-files/AQUARIUS_L2_SSS_V5.cfg index c976bf5..1be0a61 100644 --- a/config-files/AQUARIUS_L2_SSS_V5.cfg +++ b/config-files/AQUARIUS_L2_SSS_V5.cfg @@ -1,4 +1,5 @@ { + "shortName": "AQUARIUS_L2_SSS_V5", "latVar": "Navigation/beam_clat", "lonVar": "Navigation/beam_clon", "timeVar": "Block Attributes/secGPS", @@ -40,7 +41,7 @@ "title": "Sea Surface Salinity uncertainty (random)", "units": "PSU", "min": "0", - "max": ".5", + "max": "0.5", "palette": "palette_AQUARIUS_SSS", "id": "Aquarius Data/SSS_unc_ran" }, @@ -93,4 +94,4 @@ "id": "Aquarius Data/SSS_unc" } ] -} \ No newline at end of file +} diff --git a/config-files/ASCATA-L2-25km.cfg b/config-files/ASCATA-L2-25km.cfg index d5b4719..97dbf1e 100644 --- a/config-files/ASCATA-L2-25km.cfg +++ b/config-files/ASCATA-L2-25km.cfg @@ -1,4 +1,5 @@ { + "shortName": "ASCATA-L2-25km", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/ASCATA-L2-Coastal.cfg b/config-files/ASCATA-L2-Coastal.cfg index ee98494..36ccf73 100644 --- a/config-files/ASCATA-L2-Coastal.cfg +++ b/config-files/ASCATA-L2-Coastal.cfg @@ -1,4 +1,5 @@ { + "shortName": "ASCATA-L2-Coastal", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/ASCATB-L2-25km.cfg b/config-files/ASCATB-L2-25km.cfg index d5b4719..a1f6266 100644 --- a/config-files/ASCATB-L2-25km.cfg +++ b/config-files/ASCATB-L2-25km.cfg @@ -1,4 +1,5 @@ { + "shortName": "ASCATB-L2-25km", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/ASCATB-L2-Coastal.cfg b/config-files/ASCATB-L2-Coastal.cfg index ee98494..6bb1776 100644 --- a/config-files/ASCATB-L2-Coastal.cfg +++ b/config-files/ASCATB-L2-Coastal.cfg @@ -1,4 +1,5 @@ { + "shortName": "ASCATB-L2-Coastal", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/ASCATC-L2-25km.cfg b/config-files/ASCATC-L2-25km.cfg index d5b4719..275c40b 100644 --- a/config-files/ASCATC-L2-25km.cfg +++ b/config-files/ASCATC-L2-25km.cfg @@ -1,4 +1,5 @@ { + "shortName": "ASCATC-L2-25km", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/ASCATC-L2-Coastal.cfg b/config-files/ASCATC-L2-Coastal.cfg index ee98494..fa11f47 100644 --- a/config-files/ASCATC-L2-Coastal.cfg +++ b/config-files/ASCATC-L2-Coastal.cfg @@ -1,4 +1,5 @@ { + "shortName": "ASCATC-L2-Coastal", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AVHRR19_G-NAVO-L2P-v1.0.cfg b/config-files/AVHRR19_G-NAVO-L2P-v1.0.cfg index feac78b..a51bdb4 100644 --- a/config-files/AVHRR19_G-NAVO-L2P-v1.0.cfg +++ b/config-files/AVHRR19_G-NAVO-L2P-v1.0.cfg @@ -28,8 +28,8 @@ ] }, "open_cv": { - "pixel_height":1000, - "simplify":0.3, + "pixel_height": 1000, + "simplify": 0.3, "min_area": 30, "fill_kernel": [30,30] } diff --git a/config-files/AVHRRF_MA-STAR-L2P-v2.80.cfg b/config-files/AVHRRF_MA-STAR-L2P-v2.80.cfg index 0dc5c09..1cbed48 100644 --- a/config-files/AVHRRF_MA-STAR-L2P-v2.80.cfg +++ b/config-files/AVHRRF_MA-STAR-L2P-v2.80.cfg @@ -1,4 +1,5 @@ { + "shortName": "AVHRRF_MA-STAR-L2P-v2.80", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AVHRRF_MB-STAR-L2P-v2.80.cfg b/config-files/AVHRRF_MB-STAR-L2P-v2.80.cfg index 0dc5c09..b2f5e0e 100644 --- a/config-files/AVHRRF_MB-STAR-L2P-v2.80.cfg +++ b/config-files/AVHRRF_MB-STAR-L2P-v2.80.cfg @@ -1,4 +1,5 @@ { + "shortName": "AVHRRF_MB-STAR-L2P-v2.80", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AVHRRF_MC-STAR-L2P-v2.80.cfg b/config-files/AVHRRF_MC-STAR-L2P-v2.80.cfg index 0dc5c09..3c3b136 100644 --- a/config-files/AVHRRF_MC-STAR-L2P-v2.80.cfg +++ b/config-files/AVHRRF_MC-STAR-L2P-v2.80.cfg @@ -1,4 +1,5 @@ { + "shortName": "AVHRRF_MC-STAR-L2P-v2.80", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/AVHRRMTB_G-NAVO-L2P-v2.0.cfg b/config-files/AVHRRMTB_G-NAVO-L2P-v2.0.cfg index c312e63..4c17e15 100644 --- a/config-files/AVHRRMTB_G-NAVO-L2P-v2.0.cfg +++ b/config-files/AVHRRMTB_G-NAVO-L2P-v2.0.cfg @@ -11,12 +11,19 @@ ] }, "footprint": { - "findValid": true, - "strategy": "polarsides", - "t": "0:0,0:*", - "s1": "0:*,0:0", - "b": "*:*,0:*", - "s2": "0:*,*:*" + "strategy": "alpha_shape", + "alpha_shape": { + "alpha": 0.04, + "thinning": { + "method": "standard", + "value": 220 + }, + "cutoff_lat": 80, + "smooth_poles": [ + 78, + 80 + ] + } }, "imgVariables": [ { diff --git a/config-files/AVHRR_SST_METOP_B-OSISAF-L2P-v1.0.cfg b/config-files/AVHRR_SST_METOP_B-OSISAF-L2P-v1.0.cfg index 149443d..86ae368 100644 --- a/config-files/AVHRR_SST_METOP_B-OSISAF-L2P-v1.0.cfg +++ b/config-files/AVHRR_SST_METOP_B-OSISAF-L2P-v1.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "AVHRR_SST_METOP_B-OSISAF-L2P-v1.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/COWVR_STPH8_L1_TSDR_V10.0.cfg b/config-files/COWVR_STPH8_L1_TSDR_V10.0.cfg index 8bc8d31..c67a86e 100644 --- a/config-files/COWVR_STPH8_L1_TSDR_V10.0.cfg +++ b/config-files/COWVR_STPH8_L1_TSDR_V10.0.cfg @@ -1,12 +1,17 @@ { "shortName": "COWVR_STPH8_L1_TSDR_V10.0", - "latVar": "obs_lat", - "lonVar": "obs_lon", + "latVar": "GeolocationAndFlags/obs_lat", + "lonVar": "GeolocationAndFlags/obs_lon", "is360": false, "footprint": { - "thinning_fac": 200, - "alpha": 0.03, - "group": "GeolocationAndFlags" + "strategy": "alpha_shape", + "alpha_shape": { + "thinning": { + "value": 200, + "method": "standard" + }, + "alpha": 0.03 + } }, "footprinter": "forge-py" -} \ No newline at end of file +} diff --git a/config-files/COWVR_STPH8_L1_TSDR_V9.0.cfg b/config-files/COWVR_STPH8_L1_TSDR_V9.0.cfg index 449376b..faa4669 100644 --- a/config-files/COWVR_STPH8_L1_TSDR_V9.0.cfg +++ b/config-files/COWVR_STPH8_L1_TSDR_V9.0.cfg @@ -1,12 +1,18 @@ { "shortName": "COWVR_STPH8_L1_TSDR_V9.0", - "latVar": "obs_lat", - "lonVar": "obs_lon", + "latVar": "GeolocationAndFlags/obs_lat", + "lonVar": "GeolocationAndFlags/obs_lon", "is360": false, "footprint": { - "thinning_fac": 200, - "alpha": 0.03, - "group": "GeolocationAndFlags" + "strategy": "alpha_shape", + "alpha_shape": { + "thinning": { + "value": 200, + "method": "standard" + }, + "alpha": 0.03, + "fill_value": -99999.0 + } }, "footprinter": "forge-py" -} \ No newline at end of file +} diff --git a/config-files/COWVR_STPH8_L2_EDR_V10.0.cfg b/config-files/COWVR_STPH8_L2_EDR_V10.0.cfg index 739a03a..6ab7aec 100644 --- a/config-files/COWVR_STPH8_L2_EDR_V10.0.cfg +++ b/config-files/COWVR_STPH8_L2_EDR_V10.0.cfg @@ -1,12 +1,17 @@ { "shortName": "COWVR_STPH8_L2_EDR_V10.0", - "latVar": "obs_lat", - "lonVar": "obs_lon", + "latVar": "GeolocationAndFlags/obs_lat", + "lonVar": "GeolocationAndFlags/obs_lon", "is360": false, "footprint": { - "thinning_fac": 200, - "alpha": 0.03, - "group": "GeolocationAndFlags" + "strategy": "alpha_shape", + "alpha_shape": { + "thinning": { + "value": 200, + "method": "standard" + }, + "alpha": 0.03 + } }, "footprinter": "forge-py" -} \ No newline at end of file +} diff --git a/config-files/COWVR_STPH8_L2_EDR_V9.0.cfg b/config-files/COWVR_STPH8_L2_EDR_V9.0.cfg index c545f3b..8094a3c 100644 --- a/config-files/COWVR_STPH8_L2_EDR_V9.0.cfg +++ b/config-files/COWVR_STPH8_L2_EDR_V9.0.cfg @@ -1,12 +1,21 @@ { "shortName": "COWVR_STPH8_L2_EDR_V9.0", - "latVar": "obs_lat", - "lonVar": "obs_lon", + "latVar": "GeolocationAndFlags/obs_lat", + "lonVar": "GeolocationAndFlags/obs_lon", "is360": false, "footprint": { - "thinning_fac": 200, - "alpha": 0.03, - "group": "GeolocationAndFlags" + "strategy": "alpha_shape", + "alpha_shape": { + "thinning": { + "value": [ + 1, + 1 + ], + "method": "bin_avg" + }, + "alpha": 0.03, + "fill_value": -99999.0 + } }, "footprinter": "forge-py" } \ No newline at end of file diff --git a/config-files/JASON-1_L2_OST_GPN_E.cfg b/config-files/JASON-1_L2_OST_GPN_E.cfg index a7b1b63..0f607e3 100644 --- a/config-files/JASON-1_L2_OST_GPN_E.cfg +++ b/config-files/JASON-1_L2_OST_GPN_E.cfg @@ -1,4 +1,5 @@ { + "shortName": "JASON-1_L2_OST_GPN_E", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/JASON-1_L2_OST_GPR_E.cfg b/config-files/JASON-1_L2_OST_GPR_E.cfg index 8a3821b..e79078d 100644 --- a/config-files/JASON-1_L2_OST_GPR_E.cfg +++ b/config-files/JASON-1_L2_OST_GPR_E.cfg @@ -1,4 +1,5 @@ { + "shortName": "JASON-1_L2_OST_GPR_E", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/JASON-1_L2_OST_GPS_E.cfg b/config-files/JASON-1_L2_OST_GPS_E.cfg index a7b1b63..4ac4ded 100644 --- a/config-files/JASON-1_L2_OST_GPS_E.cfg +++ b/config-files/JASON-1_L2_OST_GPS_E.cfg @@ -1,4 +1,5 @@ { + "shortName": "JASON-1_L2_OST_GPS_E", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/JASON_3_L2_OST_OGDR_GPS.cfg b/config-files/JASON_3_L2_OST_OGDR_GPS.cfg index e04ae88..96b2bc1 100644 --- a/config-files/JASON_3_L2_OST_OGDR_GPS.cfg +++ b/config-files/JASON_3_L2_OST_OGDR_GPS.cfg @@ -1,4 +1,5 @@ { + "shortName": "JASON_3_L2_OST_OGDR_GPS", "latVar": "/data_01/latitude", "lonVar": "/data_01/longitude", "timeVar": "/data_01/time", diff --git a/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_NRT_F.cfg b/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_NRT_F.cfg index e1344e7..7aae2fa 100644 --- a/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_NRT_F.cfg +++ b/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_NRT_F.cfg @@ -1,5 +1,5 @@ { - "shortName": "JASON_CS_S6A_L2_ALT_HR_RED_OST_STC_F", + "shortName": "JASON_CS_S6A_L2_ALT_HR_RED_OST_NRT_F", "latVar": "data_01/latitude", "lonVar": "data_01/longitude", "timeVar": "data_01/time", diff --git a/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_STC_F.cfg b/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_STC_F.cfg index 7aae2fa..e1344e7 100644 --- a/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_STC_F.cfg +++ b/config-files/JASON_CS_S6A_L2_ALT_HR_RED_OST_STC_F.cfg @@ -1,5 +1,5 @@ { - "shortName": "JASON_CS_S6A_L2_ALT_HR_RED_OST_NRT_F", + "shortName": "JASON_CS_S6A_L2_ALT_HR_RED_OST_STC_F", "latVar": "data_01/latitude", "lonVar": "data_01/longitude", "timeVar": "data_01/time", diff --git a/config-files/MERGED_TP_J1_OSTM_OST_CYCLES_V42.cfg b/config-files/MERGED_TP_J1_OSTM_OST_CYCLES_V42.cfg index 56c9e2a..6c83bd4 100644 --- a/config-files/MERGED_TP_J1_OSTM_OST_CYCLES_V42.cfg +++ b/config-files/MERGED_TP_J1_OSTM_OST_CYCLES_V42.cfg @@ -1,4 +1,5 @@ { + "shortName": "MERGED_TP_J1_OSTM_OST_CYCLES_V42", "latVar": "latitude", "lonVar": "longitude", "timeVar": "time", diff --git a/config-files/MODIS_A-JPL-L2P-v2014.0.cfg b/config-files/MODIS_A-JPL-L2P-v2014.0.cfg index 899b521..a097053 100644 --- a/config-files/MODIS_A-JPL-L2P-v2014.0.cfg +++ b/config-files/MODIS_A-JPL-L2P-v2014.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "MODIS_A-JPL-L2P-v2014.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/MODIS_A-JPL-L2P-v2019.0.cfg b/config-files/MODIS_A-JPL-L2P-v2019.0.cfg index 6fb8af5..074aee2 100644 --- a/config-files/MODIS_A-JPL-L2P-v2019.0.cfg +++ b/config-files/MODIS_A-JPL-L2P-v2019.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "MODIS_A-JPL-L2P-v2019.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/MODIS_T-JPL-L2P-v2014.0.cfg b/config-files/MODIS_T-JPL-L2P-v2014.0.cfg index 899b521..8107e59 100644 --- a/config-files/MODIS_T-JPL-L2P-v2014.0.cfg +++ b/config-files/MODIS_T-JPL-L2P-v2014.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "MODIS_T-JPL-L2P-v2014.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/MODIS_T-JPL-L2P-v2019.0.cfg b/config-files/MODIS_T-JPL-L2P-v2019.0.cfg index 899b521..70a1422 100644 --- a/config-files/MODIS_T-JPL-L2P-v2019.0.cfg +++ b/config-files/MODIS_T-JPL-L2P-v2019.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "MODIS_T-JPL-L2P-v2019.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/NAVO-L2P-AVHRR19_G.cfg b/config-files/NAVO-L2P-AVHRR19_G.cfg index 7893b9a..230dc38 100644 --- a/config-files/NAVO-L2P-AVHRR19_G.cfg +++ b/config-files/NAVO-L2P-AVHRR19_G.cfg @@ -1,4 +1,5 @@ { + "shortName": "NAVO-L2P-AVHRR19_G", "latVar": "lat", "lonVar": "lon", "timeVar": "time", @@ -90,4 +91,4 @@ "ppd": 4, "res": 8 } -} \ No newline at end of file +} diff --git a/config-files/OS2_OSCAT_LEVEL_2B_OWV_COMP_12_V2.cfg b/config-files/OS2_OSCAT_LEVEL_2B_OWV_COMP_12_V2.cfg index 26ab7b0..773bc9e 100644 --- a/config-files/OS2_OSCAT_LEVEL_2B_OWV_COMP_12_V2.cfg +++ b/config-files/OS2_OSCAT_LEVEL_2B_OWV_COMP_12_V2.cfg @@ -1,4 +1,5 @@ { + "shortName": "OS2_OSCAT_LEVEL_2B_OWV_COMP_12_V2", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/QSCAT_LEVEL_2B_OWV_COMP_12.cfg b/config-files/QSCAT_LEVEL_2B_OWV_COMP_12.cfg index ea00126..1c39a47 100644 --- a/config-files/QSCAT_LEVEL_2B_OWV_COMP_12.cfg +++ b/config-files/QSCAT_LEVEL_2B_OWV_COMP_12.cfg @@ -1,4 +1,5 @@ { + "shortName": "QSCAT_LEVEL_2B_OWV_COMP_12", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_KUSST_LCRES_4.1.cfg b/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_KUSST_LCRES_4.1.cfg index ea00126..7f0edc6 100644 --- a/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_KUSST_LCRES_4.1.cfg +++ b/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_KUSST_LCRES_4.1.cfg @@ -1,4 +1,5 @@ { + "shortName": "QSCAT_LEVEL_2B_OWV_COMP_12_KUSST_LCRES_4.1", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_LCR_3.1.cfg b/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_LCR_3.1.cfg index ea00126..0ce8ee5 100644 --- a/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_LCR_3.1.cfg +++ b/config-files/QSCAT_LEVEL_2B_OWV_COMP_12_LCR_3.1.cfg @@ -1,4 +1,5 @@ { + "shortName": "QSCAT_LEVEL_2B_OWV_COMP_12_LCR_3.1", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/SMAP_JPL_L2B_NRT_SSS_CAP_V5.cfg b/config-files/SMAP_JPL_L2B_NRT_SSS_CAP_V5.cfg index 27ca8e5..a5ccb63 100644 --- a/config-files/SMAP_JPL_L2B_NRT_SSS_CAP_V5.cfg +++ b/config-files/SMAP_JPL_L2B_NRT_SSS_CAP_V5.cfg @@ -1,4 +1,5 @@ { + "shortName": "SMAP_JPL_L2B_NRT_SSS_CAP_V5", "latVar": "lat", "lonVar": "lon", "timeVar": "row_time", diff --git a/config-files/SMAP_RSS_L2_SSS_V4.cfg b/config-files/SMAP_RSS_L2_SSS_V4.cfg index 24dab79..b7c5651 100644 --- a/config-files/SMAP_RSS_L2_SSS_V4.cfg +++ b/config-files/SMAP_RSS_L2_SSS_V4.cfg @@ -1,4 +1,5 @@ { + "shortName": "SMAP_RSS_L2_SSS_V4", "latVar": "cellat", "lonVar": "cellon", "timeVar": "time", diff --git a/config-files/SMAP_RSS_L2_SSS_V6.cfg b/config-files/SMAP_RSS_L2_SSS_V6.cfg index 667074e..1c9a7df 100644 --- a/config-files/SMAP_RSS_L2_SSS_V6.cfg +++ b/config-files/SMAP_RSS_L2_SSS_V6.cfg @@ -11,8 +11,17 @@ ] }, "footprint": { - "alpha": 0.03, - "thinning_fac": 30 + "strategy": "alpha_shape", + "alpha_shape": { + "alpha": 0.03, + "thinning": { + "method": "bin_avg", + "value": [ + 1, + 1 + ] + } + } }, "footprinter": "forge-py", "imgVariables": [ diff --git a/config-files/SWOT_SIMULATED_L2_KARIN_SSH_ECCO_LLC4320_SCIENCE_V1.cfg b/config-files/SWOT_SIMULATED_L2_KARIN_SSH_ECCO_LLC4320_SCIENCE_V1.cfg index 1d2547f..2ac2e8b 100644 --- a/config-files/SWOT_SIMULATED_L2_KARIN_SSH_ECCO_LLC4320_SCIENCE_V1.cfg +++ b/config-files/SWOT_SIMULATED_L2_KARIN_SSH_ECCO_LLC4320_SCIENCE_V1.cfg @@ -1,5 +1,5 @@ { - "shortName": "SIMULATED_L2_KARIN_SSH_ECCO_LLC4320_SCIENCE_V1", + "shortName": "SWOT_SIMULATED_L2_KARIN_SSH_ECCO_LLC4320_SCIENCE_V1", "latVar": "latitude", "lonVar": "longitude", "timeVar": "time", diff --git a/config-files/TMI-REMSS-L2P-v4.cfg b/config-files/TMI-REMSS-L2P-v4.cfg index 54f548d..085e0f2 100644 --- a/config-files/TMI-REMSS-L2P-v4.cfg +++ b/config-files/TMI-REMSS-L2P-v4.cfg @@ -1,4 +1,5 @@ { + "shortName": "TMI-REMSS-L2P-v4", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/VIIRS_N20-OSPO-L2P-v2.61.cfg b/config-files/VIIRS_N20-OSPO-L2P-v2.61.cfg index 0cd1210..356f396 100644 --- a/config-files/VIIRS_N20-OSPO-L2P-v2.61.cfg +++ b/config-files/VIIRS_N20-OSPO-L2P-v2.61.cfg @@ -1,4 +1,5 @@ { + "shortName": "VIIRS_N20-OSPO-L2P-v2.61", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/VIIRS_NPP-JPL-L2P-v2016.2.cfg b/config-files/VIIRS_NPP-JPL-L2P-v2016.2.cfg index 4bdacce..029c5d6 100644 --- a/config-files/VIIRS_NPP-JPL-L2P-v2016.2.cfg +++ b/config-files/VIIRS_NPP-JPL-L2P-v2016.2.cfg @@ -1,4 +1,5 @@ { + "shortName": "VIIRS_NPP-JPL-L2P-v2016.2", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/VIIRS_NPP-NAVO-L2P-v1.0.cfg b/config-files/VIIRS_NPP-NAVO-L2P-v1.0.cfg index 0cd1210..0b4f4be 100644 --- a/config-files/VIIRS_NPP-NAVO-L2P-v1.0.cfg +++ b/config-files/VIIRS_NPP-NAVO-L2P-v1.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "VIIRS_NPP-NAVO-L2P-v1.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/VIIRS_NPP-NAVO-L2P-v2.0.cfg b/config-files/VIIRS_NPP-NAVO-L2P-v2.0.cfg index 0cd1210..33a053b 100644 --- a/config-files/VIIRS_NPP-NAVO-L2P-v2.0.cfg +++ b/config-files/VIIRS_NPP-NAVO-L2P-v2.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "VIIRS_NPP-NAVO-L2P-v2.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/VIIRS_NPP-NAVO-L2P-v3.0.cfg b/config-files/VIIRS_NPP-NAVO-L2P-v3.0.cfg index 0cd1210..91e6388 100644 --- a/config-files/VIIRS_NPP-NAVO-L2P-v3.0.cfg +++ b/config-files/VIIRS_NPP-NAVO-L2P-v3.0.cfg @@ -1,4 +1,5 @@ { + "shortName": "VIIRS_NPP-NAVO-L2P-v3.0", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/config-files/VIIRS_NPP-OSPO-L2P-v2.41.cfg b/config-files/VIIRS_NPP-OSPO-L2P-v2.41.cfg index 0cd1210..b24fd37 100644 --- a/config-files/VIIRS_NPP-OSPO-L2P-v2.41.cfg +++ b/config-files/VIIRS_NPP-OSPO-L2P-v2.41.cfg @@ -1,4 +1,5 @@ { + "shortName": "VIIRS_NPP-OSPO-L2P-v2.41", "latVar": "lat", "lonVar": "lon", "timeVar": "time", diff --git a/example_config.xlsx b/example_config.xlsx new file mode 100644 index 0000000..6b29536 Binary files /dev/null and b/example_config.xlsx differ diff --git a/podaac/podaac_forge_tig_config_generator/__init__.py b/podaac/podaac_forge_tig_config_generator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/podaac/podaac_forge_tig_config_generator/generate_config.py b/podaac/podaac_forge_tig_config_generator/generate_config.py new file mode 100644 index 0000000..434dbda --- /dev/null +++ b/podaac/podaac_forge_tig_config_generator/generate_config.py @@ -0,0 +1,160 @@ +"""script used to generate forge tig configuration""" + +import ast +import json +import os +from typing import Dict, Any, Optional +import click +import numpy as np +import pandas as pd +from jsonschema import validate + + +class HiTideConfigGenerator: + """Class to generate configurations""" + + REQUIRED_SETTINGS_SHEET = "required-settings" + FORGE_PY_SHEET = "forge-py" + TIG_SHEET = "tig" + + @staticmethod + def _convert_value(value: Any) -> Any: + """Convert non-standard types to JSON-serializable types.""" + if pd.isna(value): + return None + if isinstance(value, (pd.Timestamp, np.datetime64)): + return str(value) + if isinstance(value, (np.bool_, bool)): + return bool(value) + if isinstance(value, (np.integer, int)): + return int(value) + if isinstance(value, (np.floating, float)): + return float(value) + return value + + @classmethod + def filter_config_to_schema(cls, config: Dict[str, Any], schema: Dict[str, Any]) -> Dict[str, Any]: + """Filter configuration to match only schema-defined fields.""" + def recursive_filter(current_config, current_schema): + if current_schema.get('type') == 'object': + filtered_obj = {} + for key, value in current_config.items(): + prop_schema = current_schema.get('properties', {}).get(key, {}) + if prop_schema: + if prop_schema.get('type') == 'object' and isinstance(value, dict): + filtered_value = recursive_filter(value, prop_schema) + if filtered_value: + filtered_obj[key] = filtered_value + elif prop_schema.get('type') == 'array' and isinstance(value, list): + filtered_obj[key] = [ + recursive_filter(item, prop_schema.get('items', {})) + for item in value if item + ] + else: + filtered_obj[key] = value + return filtered_obj + return current_config + + return recursive_filter(config, schema) + + @classmethod + def generate_configuration(cls, file_path: str) -> Optional[Dict[str, Any]]: + """Generate configuration from Excel file.""" + # Load required data + required_settings = cls.read_sheet_as_dict(file_path, cls.REQUIRED_SETTINGS_SHEET) + forge_py = cls.read_sheet_as_dict(file_path, cls.FORGE_PY_SHEET) + tig_data = cls.read_sheet_as_list(file_path, cls.TIG_SHEET) + + if not all([required_settings, forge_py, tig_data]): + return None + + # Construct strategy configuration + strategy = forge_py.pop("strategy", None) + thinning_method = forge_py.pop("thinning_method", None) + thinning_value = forge_py.pop("thinning_value", None) + + if thinning_method and thinning_value: + try: + thinning_value = ast.literal_eval(thinning_value) + except (ValueError, SyntaxError): + pass # Leave thinning_value as is if parsing fails + forge_py["thinning"] = {"method": thinning_method, "value": thinning_value} + + strategy_dict = {"footprint": {"strategy": strategy, strategy: forge_py}} + + # Default settings + defaults = { + 'tiles': {'steps': [30, 14]}, + 'image': {'ppd': 4, 'res': 8}, + 'footprinter': 'forge-py' + } + + # Merge configurations + config = {**required_settings, **strategy_dict, **tig_data, **defaults} + + # Load and apply schema filtering + schema = cls.load_schema() + return cls.filter_config_to_schema(config, schema) + + @classmethod + def read_sheet_as_dict(cls, file_path: str, sheet_name: str) -> Optional[Dict[str, Any]]: + """Read Excel sheet and convert to dictionary with type-safe conversion.""" + try: + df = pd.read_excel(file_path, sheet_name=sheet_name, engine='openpyxl') + if df.empty: + raise ValueError(f"Sheet '{sheet_name}' is empty") + + first_row = df.iloc[0] + return {k: cls._convert_value(v) for k, v in first_row.items() if pd.notna(v)} + except Exception as e: + click.echo(f"Error reading {sheet_name}: {e}", err=True) + return None + + @classmethod + def read_sheet_as_list(cls, file_path: str, sheet_name: str) -> Optional[Dict[str, Any]]: + """Read sheet as list of non-empty dictionaries.""" + try: + df = pd.read_excel(file_path, sheet_name=sheet_name, engine='openpyxl') + df.dropna(how='all', inplace=True) + return {'imgVariables': [ + {k: cls._convert_value(v) for k, v in row.items() if pd.notna(v) and v != ""} + for row in df.to_dict(orient="records") + ]} + except Exception as e: + click.echo(f"Error reading {sheet_name}: {e}", err=True) + return None + + @staticmethod + def load_schema() -> Dict[str, Any]: + """Load JSON schema for validation.""" + schema_path = os.path.join(os.path.dirname(__file__), "schema.json") + with open(schema_path, "r") as file: + return json.load(file) + + +@click.command() +@click.option('-f', '--file', help='Excel file with configuration settings', required=True) +def generate_hitide_config(file: str): + """Generate and validate HiTide configuration.""" + generator = HiTideConfigGenerator() + config = generator.generate_configuration(file) + + if not config: + click.echo("Configuration generation failed.", err=True) + return + + try: + schema = generator.load_schema() + validate(instance=config, schema=schema) + click.echo(json.dumps(config, indent=2)) + short_name = config.get('shortName') + file = f"{short_name}.cfg" + with open(file, 'w') as file: + json.dump(config, file, indent=4) + + except Exception as e: + click.echo(f"Validation error: {e}", err=True) + + +if __name__ == '__main__': + generate_hitide_config() diff --git a/podaac/podaac_forge_tig_config_generator/schema.json b/podaac/podaac_forge_tig_config_generator/schema.json new file mode 100644 index 0000000..0e838d1 --- /dev/null +++ b/podaac/podaac_forge_tig_config_generator/schema.json @@ -0,0 +1,290 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "shortName": { + "type": "string", + "description": "Short name of the dataset, required." + }, + "latVar": { + "type": "string", + "description": "Path to the latitude variable in the data, required." + }, + "lonVar": { + "type": "string", + "description": "Path to the longitude variable in the data, required." + }, + "timeVar": { + "type": "string", + "description": "Name of the time variable, optional." + }, + "is360": { + "type": "boolean", + "description": "Indicates if longitude is in 0-360 format, required." + }, + "tiles": { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "type": "integer", + "additionalProperties": false, + "description": "Step size for each tile, represented as integers." + }, + "minItems": 2, + "maxItems": 3, + "additionalProperties": false, + "description": "An array of two integers representing the tile step sizes." + } + }, + "required": ["steps"], + "additionalProperties": false, + "description": "Tile configuration with step sizes for the grid." + }, + "global_grid": { + "type": "boolean", + "description": "Indicates whether the grid is global or not. Optional." + }, + "footprinter": { + "type": "string", + "enum": ["forge-py"], + "description": "The footprinter to use, must be 'forge-py'." + }, + "tolerance": { + "type": "number", + "description": "Tolerance value (optional). Can be a float or integer." + }, + "footprint": { + "type": "object", + "properties": { + "findValid": { + "type": "boolean", + "description": "Indicates whether to find valid footprint values." + }, + "b": { + "type": "string", + "description": "The 'b' footprint pattern." + }, + "s2": { + "type": "string", + "description": "The 's2' footprint pattern." + }, + "t": { + "type": "string", + "description": "The 't' footprint pattern." + }, + "s1": { + "type": "string", + "description": "The 's1' footprint pattern." + }, + "removeOrigin": { + "type": "boolean", + "description": "Unknown usage for forge" + }, + "strategy": { + "type": "string", + "enum": ["open_cv", "alpha_shape", "linestring", "periodic", "swot_linestring", "smap", "polarsides", "polar"], + "description": "Footprint calculation strategy, required." + }, + "open_cv": { + "type": "object", + "properties": { + "pixel_height": { + "type": "integer", + "minimum": 1, + "description": "Height of the pixel grid, optional." + }, + "simplify": { + "type": "number", + "minimum": 0, + "description": "Simplification tolerance for a polygon, optional." + }, + "min_area": { + "type": "integer", + "minimum": 0, + "description": "Minimum area for a polygon or it will be removed, optional." + }, + "fill_kernel": { + "type": "array", + "items": { + "type": "integer", + "minimum": 1 + }, + "minItems": 2, + "maxItems": 2, + "description": "Kernel size for filling small gaps, optional." + } + }, + "additionalProperties": false, + "description": "Parameters for the OpenCV strategy, optional." + }, + "alpha_shape": { + "type": "object", + "properties": { + "alpha": { + "type": "number", + "minimum": 0, + "description": "Alpha parameter for the alpha shape algorithm, optional." + }, + "thinning": { + "type": "object", + "properties": { + "method": { + "type": "string", + "enum": ["bin_avg", "standard"], + "description": "Thinning method, optional." + }, + "value": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + ] + } + }, + "additionalProperties": false, + "description": "Parameters for thinning, optional." + }, + "cutoff_lat": { + "type": "number", + "description": "Latitude cutoff for the footprint, optional." + }, + "smooth_poles": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2, + "description": "Latitude range for smoothing near poles, optional." + }, + "simplify": { + "type": "number", + "minimum": 0, + "description": "Simplification tolerance for a polygon, optional." + }, + "min_area": { + "type": "number", + "minimum": 0, + "description": "Minimum area for a polygon or it will be removed, optional." + }, + "fill_value": { + "type": "number", + "description": "Fill value for invalid areas, optional." + } + }, + "additionalProperties": false, + "description": "Parameters for the alpha shape strategy, optional." + } + }, + "additionalProperties": false, + "description": "Footprint calculation parameters, optional." + }, + "imgVariables": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "ID of the image variable, required." + }, + "title": { + "type": "string", + "description": "Title of the image variable, optional." + }, + "units": { + "type": "string", + "description": "Units of the image variable, optional." + }, + "fill_missing": { + "type": "boolean", + "description": "Fill in the image if the data resolution is too high and needs to be filled in spots" + }, + "fill_value": { + "type": "number", + "description": "Fill value for a variable if theres no fill value" + }, + "is_swot_expert": { + "type": "boolean", + "description": "boolean to indicate if variable is a swot expert variable for a specific algorithm" + }, + "ppd": { + "type": "integer", + "description": "Pixels per degree (ppd) for the variable." + }, + "min": { + "oneOf": [ + { + "type": "number", + "description": "Minimum value of the variable as a number (integer or float)." + }, + { + "type": "string", + "pattern": "^-?\\d+(\\.\\d+)?$", + "description": "Minimum value of the variable as a string. Must be a valid number." + } + ] + }, + "max": { + "oneOf": [ + { + "type": "number", + "description": "Maximum value of the variable as a number (integer or float)." + }, + { + "type": "string", + "pattern": "^-?\\d+(\\.\\d+)?$", + "description": "Maximum value of the variable as a string. Must be a valid number." + } + ] + }, + "palette": { + "type": "string", + "description": "Palette used for visualization, optional." + }, + "legends": { + "type": "array", + "items": { + "type": "string", + "description": "Legend file name, expected to be a string representing a file path. Note should be invalid for new tig should be removed" + }, + "description": "List of legend files." + } + }, + "required": ["id", "min", "max", "palette"], + "additionalProperties": false, + "description": "Properties of an image variable." + }, + "description": "List of image variables, optional." + }, + "image": { + "type": "object", + "properties": { + "ppd": { + "type": "integer", + "description": "Pixels per degree (ppd) for the image." + }, + "res": { + "type": "integer", + "description": "Resolution of the image (res)." + } + }, + "required": ["ppd", "res"], + "additionalProperties": false, + "description": "Image configuration with pixels per degree and resolution." + } + + }, + "required": ["shortName", "latVar", "lonVar", "is360"], + "additionalProperties": false +} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..998bff0 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,707 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "astroid" +version = "3.3.5" +description = "An abstract syntax tree for Python with inference support." +optional = false +python-versions = ">=3.9.0" +files = [ + {file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"}, + {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} + +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "dill" +version = "0.3.9" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, + {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + +[[package]] +name = "et-xmlfile" +version = "2.0.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa"}, + {file = "et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "flake8" +version = "7.1.1" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"}, + {file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.12.0,<2.13.0" +pyflakes = ">=3.2.0,<3.3.0" + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isort" +version = "5.13.2" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, +] + +[package.extras] +colors = ["colorama (>=0.4.6)"] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.9" +files = [ + {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, + {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "numpy" +version = "2.1.3" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd"}, + {file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3"}, + {file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098"}, + {file = "numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c"}, + {file = "numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4"}, + {file = "numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23"}, + {file = "numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09"}, + {file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a"}, + {file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b"}, + {file = "numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee"}, + {file = "numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0"}, + {file = "numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9"}, + {file = "numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564"}, + {file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512"}, + {file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b"}, + {file = "numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc"}, + {file = "numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0"}, + {file = "numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9"}, + {file = "numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe"}, + {file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43"}, + {file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56"}, + {file = "numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a"}, + {file = "numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef"}, + {file = "numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f"}, + {file = "numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0"}, + {file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408"}, + {file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6"}, + {file = "numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f"}, + {file = "numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17"}, + {file = "numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48"}, + {file = "numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb"}, + {file = "numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761"}, +] + +[[package]] +name = "openpyxl" +version = "3.1.5" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, + {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "packaging" +version = "24.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, +] + +[[package]] +name = "pandas" +version = "2.2.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, + {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, + {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, + {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, + {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, + {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, + {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, + {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, + {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, + {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, + {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, + {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, + {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, + {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, + {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, + {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, + {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, + {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, + {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, + {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, + {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, + {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, + {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, + {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, + {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, + {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, + {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, + {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pycodestyle" +version = "2.12.1" +description = "Python style guide checker" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"}, + {file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"}, +] + +[[package]] +name = "pyflakes" +version = "3.2.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, + {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, +] + +[[package]] +name = "pylint" +version = "3.3.2" +description = "python code static checker" +optional = false +python-versions = ">=3.9.0" +files = [ + {file = "pylint-3.3.2-py3-none-any.whl", hash = "sha256:77f068c287d49b8683cd7c6e624243c74f92890f767f106ffa1ddf3c0a54cb7a"}, + {file = "pylint-3.3.2.tar.gz", hash = "sha256:9ec054ec992cd05ad30a6df1676229739a73f8feeabf3912c995d17601052b01"}, +] + +[package.dependencies] +astroid = ">=3.3.5,<=3.4.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = [ + {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, +] +isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + +[[package]] +name = "pytest" +version = "8.3.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2024.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, +] + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "rpds-py" +version = "0.22.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rpds_py-0.22.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ab27dd4edd84b13309f268ffcdfc07aef8339135ffab7b6d43f16884307a2a48"}, + {file = "rpds_py-0.22.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9d5b925156a746dc1f5f52376fdd1fbdd3f6ffe1fcd6f5e06f77ca79abb940a3"}, + {file = "rpds_py-0.22.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201650b309c419143775c15209c620627de3c09a27c7fb58375325aec5cce260"}, + {file = "rpds_py-0.22.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31264187fc934ff1024a4f56775f33c9252d3f4f3e27ec07d1995a26b52702c3"}, + {file = "rpds_py-0.22.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97c5ffe47ccf92d8b17e10f8a5ce28d015aa1196edc3359684cf31504eae6a14"}, + {file = "rpds_py-0.22.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9ac7280bd045f472b50306d7efeee051b69e3a2dd1b90f46bd7e86e63b1efa2"}, + {file = "rpds_py-0.22.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f941fb86195f97be7f6efe04a21b223f05dfe4d1dfb159999e2f8d101e44cc4"}, + {file = "rpds_py-0.22.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f91bfc39f7a64168e08ab831fa497ec5438c1d6c6e2f9e12848d95ad11ac8523"}, + {file = "rpds_py-0.22.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:effcae2152afe7937a28376dbabb25c770ef99ed4e16a4ffeb8e6a4f7c4f06aa"}, + {file = "rpds_py-0.22.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2177e59c033bf0d1bf7de1ced561205963583caf3242c6c700a723034bfb5f8e"}, + {file = "rpds_py-0.22.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:66f4f48a89cdd30ab3a47335df81c76e9a63799d0d84b29c0618371c66fa37b0"}, + {file = "rpds_py-0.22.1-cp310-cp310-win32.whl", hash = "sha256:b07fa9e634234e84096adfa4be3828c8f26e238679c122824b2b3d7131bec578"}, + {file = "rpds_py-0.22.1-cp310-cp310-win_amd64.whl", hash = "sha256:ca4657e9fd0b1b5376942d403d634ce188f79064f0873aa853ab05b10185ceec"}, + {file = "rpds_py-0.22.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:608c84699b2db09c6a8743845b1a3dad36fae53eaaecb241d45b13dff74405fb"}, + {file = "rpds_py-0.22.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9dae4eb9b5534e09ba6c6ab496a757e5e394b7e7b08767d25ca37e8d36491114"}, + {file = "rpds_py-0.22.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09a1f000c5f6e08b298275bae00921e9fbbf2a35dae0a86db2821c058c2201a9"}, + {file = "rpds_py-0.22.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:580ccbf11f02f948add4cb641843030a89f1463d7c0740cbfc9aca91e9dc34b3"}, + {file = "rpds_py-0.22.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96559e05bdf938b2048353e10a7920b98f853cefe4482c2064a718d7d0a50bd7"}, + {file = "rpds_py-0.22.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128cbaed7ba26116820bcb992405d6a13ea18c8fca1b8c4f59906d858e91e979"}, + {file = "rpds_py-0.22.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:734783dd7da58f76222f458346ddebdb3621686a1a2a667db5049caf0c9956b9"}, + {file = "rpds_py-0.22.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c9ce6b83597d45bec44a2690857ede62fc98223772135f8a7fa90884eb726501"}, + {file = "rpds_py-0.22.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bca4428c4a957b78ded3e6e62884ab03f029dce8fa8d34818da0f80f61332b49"}, + {file = "rpds_py-0.22.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1ded65691a1d3fd7d2aa89d2c91aa51f941601bb2ce099739909034d957fef4b"}, + {file = "rpds_py-0.22.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72407065ad459db9f3d052ea8c51e02534f02533fc61e51cbab3bd94166f086c"}, + {file = "rpds_py-0.22.1-cp311-cp311-win32.whl", hash = "sha256:eb013aa01b404219f28dc973d9e6310fd4db216d7299253dd355629952e0564e"}, + {file = "rpds_py-0.22.1-cp311-cp311-win_amd64.whl", hash = "sha256:8bd9ec1db79a664f4cbb12878693b73416f4d2cb425d3e27eccc1bdfbdc826ef"}, + {file = "rpds_py-0.22.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:8ec41049c90d204a6561238a9ad6c7263ebb7009d9759c98b58078d9d2fec9ba"}, + {file = "rpds_py-0.22.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:102be79c4cc47a4aeb5912401185c404cd2601c15a7163bbecff7f1bfe20b669"}, + {file = "rpds_py-0.22.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a603155db408f773637f9e3a712c6e3cbc521aaa8fa2b99f9ba6106c59a2496"}, + {file = "rpds_py-0.22.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5dbff9402c2bdf00bf0df9905694b3c292a3847c725651938a72f554351a5fcb"}, + {file = "rpds_py-0.22.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96b3759d8ab2323324e0a92b2f44834f9d88089b8d1ab6f533b61f4be3411cef"}, + {file = "rpds_py-0.22.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3029f481b31f329b1fdb4ec4b56935d82210ddd9c6f86ea5a87c06f1e97b161"}, + {file = "rpds_py-0.22.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d280b4bf09f719b89fd9aab3b71067acc0d0449b7d1eba99a2ade4939cef8296"}, + {file = "rpds_py-0.22.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6c8e97e19aa7b0b0d801a159f932ce4435f1049c8c38e2bb372bb5bee559ce50"}, + {file = "rpds_py-0.22.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:50e4b5d291105f7063259fe0125b1af902fb34499444d7c5c521dd8328b00939"}, + {file = "rpds_py-0.22.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d3777c446bb1c5fcd82dc3f8776e1a146cd91e80cc1892f8634575ace438d22f"}, + {file = "rpds_py-0.22.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:447ae1104fb32197b9262f772d565d38e834cc2e9edd89350b37b88fed636e70"}, + {file = "rpds_py-0.22.1-cp312-cp312-win32.whl", hash = "sha256:55d371b9d8b0c2a68a50413a8cb01c3c3ce1ea4f768bf77b66669a9a486e101e"}, + {file = "rpds_py-0.22.1-cp312-cp312-win_amd64.whl", hash = "sha256:413a30a99d8683dace3765885920ed27ab662efbb6c98d81db76c397ad1ffd71"}, + {file = "rpds_py-0.22.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa2ba0176037c915d8660a4e46581d645e2c22b5373e466bc8640a794d45861a"}, + {file = "rpds_py-0.22.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4ba6c66fbc6015b2f99e7176fec41793cecb00c4cc357cad038dff85e6ac42ab"}, + {file = "rpds_py-0.22.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15fa4ca658f8ad22645d3531682b17e5580832efbfa87304c3e62214c79c1e8a"}, + {file = "rpds_py-0.22.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7833ef6f5d6cb634f296abfd93452fb3eb44c4e9a6ae95c1021eab704c1cee2"}, + {file = "rpds_py-0.22.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0467838c90435b80793cde486a318fc916ee57f2af54e4b10c72b20cbdcbaa9"}, + {file = "rpds_py-0.22.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d962e2e89b3a95e3597a34b8c93ced1e98958502c5b8096c9fd69deff279f561"}, + {file = "rpds_py-0.22.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ce729f1dc8a4a190c34b69f75377bddc004079b2963ab722ab91fafe040be6d"}, + {file = "rpds_py-0.22.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8080467df22feca0fc9c46567001777c6fbc2b4a2683a7137420896051874ca1"}, + {file = "rpds_py-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0f9eb37d3a60b262a98ab51ee899cac039de9ca0ce68dcf1a6518a09719020b0"}, + {file = "rpds_py-0.22.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:153248f48d6f90a295a502f53ec544a3ffbd21b0bb32f5dca39c4b93a764d6a2"}, + {file = "rpds_py-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a53592cdf98cec3dfcdb24ffec8a4797e7656b65700099af43ec7df023b6de4"}, + {file = "rpds_py-0.22.1-cp313-cp313-win32.whl", hash = "sha256:e8056adcefa2dcb67e8bc91ea5eee26df66e8b297a8cd6ff0903f85c70908fa0"}, + {file = "rpds_py-0.22.1-cp313-cp313-win_amd64.whl", hash = "sha256:a451dba533be77454ebcffc85189108fc05f279100835ac76e7989edacb89156"}, + {file = "rpds_py-0.22.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:2ea23f1525d4f64286dbe0947c929d45c3ffe963b2dbed1d3844a2e4938bda42"}, + {file = "rpds_py-0.22.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3aaa22487477de9618ce3b37f99fbe81219ba96f3c2ca84f576f0ab451b83aba"}, + {file = "rpds_py-0.22.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8954b9ffe60f479a0c0ba40987db2546c735ab02a725ea7fd89342152d4d821d"}, + {file = "rpds_py-0.22.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c8502a02ae3ae67084f5a0bf5a8253b19fa7a887f824e41e016cdb0ac532a06f"}, + {file = "rpds_py-0.22.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a083221b6a4ecdef38a60c95d8d3223d99449cb4da2544e9644958dc16664eb9"}, + {file = "rpds_py-0.22.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:542eb246d5be31b5e0a9c8ddb9539416f9b31f58f75bd4ee328bff2b5c58d6fd"}, + {file = "rpds_py-0.22.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffae97d28ea4f2c613a751d087b75a97fb78311b38cc2e9a2f4587e473ace167"}, + {file = "rpds_py-0.22.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0ff8d5b13ce2357fa8b33a0a2e3775aa71df5bf7c8ba060634c9d15ab12f357"}, + {file = "rpds_py-0.22.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0f057a0c546c42964836b209d8de9ea1a4f4b0432006c6343cbe633d8ca14571"}, + {file = "rpds_py-0.22.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:48ee97c7c6027fd423058675b5a39d0b5f7a1648250b671563d5c9f74ff13ff0"}, + {file = "rpds_py-0.22.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:babec324e8654a59122aaa66936a9a483faa03276db9792f51332475c2dddc4a"}, + {file = "rpds_py-0.22.1-cp313-cp313t-win32.whl", hash = "sha256:e69acdbc132c9592c8dc393af85e38e206ca847c7019a953ff625191c3a12312"}, + {file = "rpds_py-0.22.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c783e4ed68200f4e03c125690d23158b1c49c4b186d458a18debc109bbdc3c2e"}, + {file = "rpds_py-0.22.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2143c3aed85992604d758bbe67da839fb4aab3dd2e1c6dddab5b3ca7162b34a2"}, + {file = "rpds_py-0.22.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f57e2d0f8022783426121b586d7c842ea40ea832a29e28ca36c881b54c74fb28"}, + {file = "rpds_py-0.22.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c0c324879d483504b07f7b18eb1b50567c434263bbe4866ecce33056162668a"}, + {file = "rpds_py-0.22.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1c40e02cc4f3e18fd39344edb10eebe04bd11cfd13119606b5771e5ea51630d3"}, + {file = "rpds_py-0.22.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f76c6f319e57007ad52e671ec741d801324760a377e3d4992c9bb8200333ebac"}, + {file = "rpds_py-0.22.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5cae9b415ea8a6a563566dbf46650222eccc5971c7daa16fbee63aef92ae543"}, + {file = "rpds_py-0.22.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b09209cdfcacf5eba9cf80367130532e6c02e695252e1f64d3cfcc2356e6e19f"}, + {file = "rpds_py-0.22.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dbe428d0ac6eacaf05402adbaf137f59ad6063848182d1ff294f95ce0f24005b"}, + {file = "rpds_py-0.22.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:626b9feb01bff049a5aec4804f0c58db12585778b4902e5376a95b01f80a7a16"}, + {file = "rpds_py-0.22.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec1ccc2a9f764cd632fb8ab28fdde166250df54fc8d97315a4a6948dc5367639"}, + {file = "rpds_py-0.22.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ef92b1fbe6aa2e7885eb90853cc016b1fc95439a8cc8da6d526880e9e2148695"}, + {file = "rpds_py-0.22.1-cp39-cp39-win32.whl", hash = "sha256:c88535f83f7391cf3a45af990237e3939a6fdfbedaed2571633bfdd0bceb36b0"}, + {file = "rpds_py-0.22.1-cp39-cp39-win_amd64.whl", hash = "sha256:7839b7528faa4d134c183b1f2dd1ee4dc2ca2f899f4f0cfdf00fc04c255262a7"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a0ed14a4162c2c2b21a162c9fcf90057e3e7da18cd171ab344c1e1664f75090e"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:05fdeae9010533e47715c37df83264df0122584e40d691d50cf3607c060952a3"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4659b2e4a5008715099e216050f5c6976e5a4329482664411789968b82e3f17d"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a18aedc032d6468b73ebbe4437129cb30d54fe543cde2f23671ecad76c3aea24"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149b4d875ef9b12a8f5e303e86a32a58f8ef627e57ec97a7d0e4be819069d141"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdaee3947eaaa52dae3ceb9d9f66329e13d8bae35682b1e5dd54612938693934"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36ce951800ed2acc6772fd9f42150f29d567f0423989748052fdb39d9e2b5795"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ab784621d3e2a41916e21f13a483602cc989fd45fff637634b9231ba43d4383b"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:c2a214bf5b79bd39a9de1c991353aaaacafda83ba1374178309e92be8e67d411"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:85060e96953647871957d41707adb8d7bff4e977042fd0deb4fc1881b98dd2fe"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c6f3fd617db422c9d4e12cb8d84c984fe07d6d9cb0950cbf117f3bccc6268d05"}, + {file = "rpds_py-0.22.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f2d1b58a0c3a73f0361759642e80260a6d28eee6501b40fe25b82af33ef83f21"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:76eaa4c087a061a2c8a0a92536405069878a8f530c00e84a9eaf332e70f5561f"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:959ae04ed30cde606f3a0320f0a1f4167a107e685ef5209cce28c5080590bd31"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:198067aa6f3d942ff5d0d655bb1e91b59ae85279d47590682cba2834ac1b97d2"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3e7e99e2af59c56c59b6c964d612511b8203480d39d1ef83edc56f2cb42a3f5d"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0545928bdf53dfdfcab284468212efefb8a6608ca3b6910c7fb2e5ed8bdc2dc0"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef7282d8a14b60dd515e47060638687710b1d518f4b5e961caad43fb3a3606f9"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe3f245c2f39a5692d9123c174bc48f6f9fe3e96407e67c6d04541a767d99e72"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efb2ad60ca8637d5f9f653f9a9a8d73964059972b6b95036be77e028bffc68a3"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d8306f27418361b788e3fca9f47dec125457f80122e7e31ba7ff5cdba98343f8"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:4c8dc7331e8cbb1c0ea2bcb550adb1777365944ffd125c69aa1117fdef4887f5"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:776a06cb5720556a549829896a49acebb5bdd96c7bba100191a994053546975a"}, + {file = "rpds_py-0.22.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e4f91d702b9ce1388660b3d4a28aa552614a1399e93f718ed0dacd68f23b3d32"}, + {file = "rpds_py-0.22.1.tar.gz", hash = "sha256:157a023bded0618a1eea54979fe2e0f9309e9ddc818ef4b8fc3b884ff38fedd5"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10" +content-hash = "8987a4cda712cdd89e29dcd6a80918754db6b1f745aeda573f80dfffd686ef80" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4f4d9a7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,27 @@ +[tool.poetry] +name = "podaac-forge-tig-config-generator" +version = "0.1.0" +description = "" +authors = ["Simon Liu "] +readme = "README.md" + +packages = [ + { include = "podaac" }, +] + +[tool.poetry.dependencies] +python = "^3.10" +pytest = "^8.3.3" +jsonschema = "^4.23.0" +pandas = "^2.2.3" +openpyxl = "^3.1.5" +click = "^8.1" +pylint = "^3.3.2" +flake8 = "^7.1.1" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +generate_config = 'podaac.podaac_forge_tig_config_generator.generate_config:generate_hitide_config' diff --git a/terraform/main.tf b/terraform/main.tf deleted file mode 100644 index 8b184ff..0000000 --- a/terraform/main.tf +++ /dev/null @@ -1,12 +0,0 @@ -# configure the S3 backend for storing state. This allows different -# team members to control and update terraform state. -terraform { - backend "s3" { - # This must be updated for each unique deployment/stage! - # should be of the form services/APP_NAME/STAGE/terraform.tfstate - # We can't use variables in the key name here, so we need to be extra - # careful with this! - key = "services/hitide/terraform.tfstate" - region = "us-west-2" - } -} \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_configs.py b/tests/test_configs.py new file mode 100644 index 0000000..5650de6 --- /dev/null +++ b/tests/test_configs.py @@ -0,0 +1,27 @@ +import os +import json +import pytest +from functools import lru_cache +from jsonschema import validate, ValidationError +from podaac.podaac_forge_tig_config_generator import generate_config + +@lru_cache(maxsize=1) +def get_schema(): + """Cache schema loading for performance.""" + return generate_config.HiTideConfigGenerator.load_schema() + +def validate_config(config_file): + """Validate single configuration file.""" + with open(config_file, "r") as f: + config = json.load(f) + validate(instance=config, schema=get_schema()) + +@pytest.mark.parametrize("config_file", [ + os.path.join('config-files', f) for f in os.listdir('config-files') if f.endswith('.cfg') +]) +def test_json_schema(config_file): + """Validate JSON configurations against schema.""" + try: + validate_config(config_file) + except (json.JSONDecodeError, ValidationError) as e: + pytest.fail(f"Validation failed for {config_file}: {e}") \ No newline at end of file diff --git a/unprocessed-files.txt b/unprocessed-files.txt deleted file mode 100644 index a46c2cc..0000000 --- a/unprocessed-files.txt +++ /dev/null @@ -1,16 +0,0 @@ - INFO:__main__:There are 14 of files unprocessed: - ERROR:__main__:Unprocessed: PODAAC-GHMDT-2PJ01.cfg - ERROR:__main__:Unprocessed: PODAAC-GHG16-2PO27.cfg - ERROR:__main__:Unprocessed: PODAAC-GHAMS-2PR01.cfg - ERROR:__main__:Unprocessed: PODAAC-SMP30-2SOCS.cfg - ERROR:__main__:Unprocessed: PODAAC-SMP3A-2SOCS.cfg - ERROR:__main__:Unprocessed: PODAAC-GHVRS-2PN16.cfg - ERROR:__main__:Unprocessed: PODAAC-GHMDA-2PJ01.cfg - ERROR:__main__:Unprocessed: AVHRR_SST_METOP_B-OSISAF-L2P-v1.0.cfg - ERROR:__main__:Unprocessed: PODAAC-OSCAR-03D01.cfg - ERROR:__main__:Unprocessed: PODAAC-GHGMR-4FJ04.cfg - ERROR:__main__:Unprocessed: PODAAC-J1SHA-NETGC.cfg - ERROR:__main__:Unprocessed: PODAAC-J1SHA-NETCC.cfg - ERROR:__main__:Unprocessed: PODAAC-AQR40-3S1CS.cfg - ERROR:__main__:Unprocessed: PODAAC-GHATS-2PU01.cfg - INFO:__main__:Successfully ran the program and close DB connection \ No newline at end of file