diff --git a/.github/actions/setup-esgvoc/action.yml b/.github/actions/setup-esgvoc/action.yml new file mode 100644 index 0000000..26d89b0 --- /dev/null +++ b/.github/actions/setup-esgvoc/action.yml @@ -0,0 +1,21 @@ +name: Setup esgvoc +description: Install Python 3.12 and esgvoc CLI + +inputs: + extra-packages: + description: Additional pip packages to install (space-separated) + required: false + default: "" + +runs: + using: composite + steps: + - uses: actions/setup-python@v5.4.0 + with: + python-version: "3.12" + + - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + + - name: Install esgvoc + shell: bash + run: uv pip install --system "esgvoc>=4.0.0" ${{ inputs.extra-packages }} diff --git a/.github/workflows/cv-validate.py b/.github/workflows/cv-validate.py deleted file mode 100644 index 8e973c0..0000000 --- a/.github/workflows/cv-validate.py +++ /dev/null @@ -1,463 +0,0 @@ -#!/usr/bin/env python3 -import os -from pathlib import Path -import sys -from esgvoc.core.service.configuration.setting import ( - ServiceSettings, - UniverseSettings, - ProjectSettings, -) -from esgvoc.core.service import config_manager -from esgvoc.core.service.state import StateService - - -def configure_and_install_esgvoc(): - """Configure esgvoc with test branch and synchronize""" - try: - test_branch = os.environ.get("TEST_BRANCH") - repo_url = os.environ.get("REPO_URL") - esgvoc_branch = os.environ.get("ESGVOC_LIBRARY_BRANCH") - - if not test_branch or not repo_url: - raise ValueError( - "TEST_BRANCH and REPO_URL environment variables must be set" - ) - - print(f"Configuring esgvoc to use CV from branch: {test_branch}") - print(f"Repository: {repo_url}") - print(f"Using esgvoc library from branch: {esgvoc_branch}") - - # Create configuration for the CV project using test branch - project_config = ProjectSettings( - project_name="test_cv", github_repo=repo_url, branch=test_branch - ) - - # Create universe settings - universe_config = UniverseSettings( - github_repo="https://github.com/WCRP-CMIP/WCRP-universe", branch="esgvoc" - ) - - # Create main setting with our test configuration - custom_setting = ServiceSettings( - universe=universe_config, - projects={ - project_config.project_name: project_config, - }, - ) - - # Update the global current_state with our custom configuration - import esgvoc.core.service - - esgvoc.core.service.current_state = StateService(custom_setting) - - # Now synchronize with our custom settings - print("Initializing esgvoc with test configuration...") - esgvoc.core.service.current_state.synchronize_all() - print("โœ… ESGVoc configured and synchronized successfully!") - - except Exception as e: - print(f"โŒ ESGVoc configuration failed: {e}") - import traceback - - traceback.print_exc() - sys.exit(1) - - -def test_cv_with_esgvoc(): - """Run CV validation tests with esgvoc""" - try: - print("Running CV validation tests...") - - # Add your specific esgvoc validation logic here - # Example: result = esgvoc.validate_cv() - # if not result.is_valid: - # sys.exit(1) - test_can_read_all_term() - test_repo() - # test_can_read_all_term() - print("โœ… CV validation passed!") - - except Exception as e: - print(f"โŒ CV validation failed: {e}") - import traceback - - traceback.print_exc() - sys.exit(1) - - -def test_can_read_all_term(): - """Test that all collections and elements are queryable via esgvoc API""" - import esgvoc.api as ev - import json - - print("๐Ÿ” Testing esgvoc API access for all repository collections and elements...") - - project_name = "obs4REF" # fallback if file not found - - print(f"Testing project: {project_name}") - - errors = [] - - # Test 1: Verify project exists in esgvoc - try: - projects = ev.get_all_projects() - if project_name not in projects: - errors.append( - f"โŒ Project '{project_name}' not found in esgvoc. Available projects: {projects}" - ) - return # Can't continue without valid project - else: - print(f"โœ… Project '{project_name}' found in esgvoc") - except Exception as e: - errors.append(f"โŒ Failed to get projects from esgvoc: {e}") - return - - # Test 2: Get collections from esgvoc and compare with repository - try: - esgvoc_collections = ev.get_all_collections_in_project(project_name) - print( - f"Found {len(esgvoc_collections)} collections in esgvoc for project {project_name}" - ) - except Exception as e: - errors.append(f"โŒ Failed to get collections from esgvoc: {e}") - return - - # Get collections from repository (directories with .jsonld files) - repo_collections = [] - all_directories = [p for p in Path(".").iterdir() if p.is_dir()] - - for directory in all_directories: - files_in_dir = list(directory.iterdir()) - jsonld_files = [f for f in files_in_dir if f.name.endswith(".jsonld")] - if len(jsonld_files) > 0: - repo_collections.append(directory.name) - - print(f"Found {len(repo_collections)} collections in repository") - - # Test 3: Verify each repository collection is queryable in esgvoc - missing_in_esgvoc = [] - for collection_name in repo_collections: - if collection_name not in esgvoc_collections: - missing_in_esgvoc.append(collection_name) - else: - print(f"โœ… Collection '{collection_name}' found in esgvoc") - - if missing_in_esgvoc: - errors.append( - f"โŒ Collections found in repository but not in esgvoc: {missing_in_esgvoc}" - ) - - # Test 4: For each collection, verify all elements are queryable - for collection_name in repo_collections: - if collection_name in esgvoc_collections: - print(f"\n๐Ÿ“‚ Testing elements in collection: {collection_name}") - - # Get elements from repository - collection_dir = Path(".") / collection_name - files_in_dir = list(collection_dir.iterdir()) - json_element_files = [ - f - for f in files_in_dir - if f.name.endswith(".json") and not f.name.endswith(".jsonld") - ] - - repo_elements = [] - for json_file in json_element_files: - try: - with open(json_file, "r", encoding="utf-8") as f: - content = json.load(f) - element_id = content.get( - "id", json_file.stem - ) # fallback to filename - repo_elements.append(element_id) - except: - repo_elements.append( - json_file.stem - ) # fallback to filename if can't parse - - # Get elements from esgvoc - try: - esgvoc_terms = ev.get_all_terms_in_collection( - project_name, collection_name - ) - esgvoc_element_ids = [term.id for term in esgvoc_terms] - - print(f" Repository elements: {len(repo_elements)}") - print(f" ESGVoc elements: {len(esgvoc_element_ids)}") - - # Check each repository element exists in esgvoc - missing_elements = [] - for element_id in repo_elements: - if element_id not in esgvoc_element_ids: - missing_elements.append(element_id) - else: - print(f" โœ… Element '{element_id}' found in esgvoc") - - if missing_elements: - errors.append( - f"โŒ Collection '{collection_name}': Elements in repository but not in esgvoc: {missing_elements}" - ) - else: - print( - f" โœ… All elements in collection '{collection_name}' are queryable via esgvoc" - ) - - except Exception as e: - errors.append( - f"โŒ Failed to get terms from collection '{collection_name}': {e}" - ) - - # Test 5: Test general API functions - try: - all_terms = ev.get_all_terms_in_all_projects() - print( - f"\n๐Ÿ“Š ESGVoc API successfully returned {len(all_terms)} total terms across all projects" - ) - except Exception as e: - errors.append(f"โŒ Failed to get all terms from esgvoc: {e}") - - # Summary - print(f"\n๐Ÿ“Š ESGVoc API Validation Summary:") - if errors: - print(f"โŒ Found {len(errors)} errors:") - for error in errors: - print(f" {error}") - raise Exception(f"ESGVoc API validation failed with {len(errors)} errors") - else: - print("โœ… All collections and elements are properly queryable via esgvoc API!") - print(f"โœ… Validated {len(repo_collections)} collections") - print("โœ… All repository elements are accessible through esgvoc") - - -def test_repo(): - """Test repository structure and file requirements - generic for any CV""" - import json - - print("๐Ÿงช Testing repository structure...") - - # Get all directories - all_directories = [p for p in Path(".").iterdir() if p.is_dir()] - - # Identify collection directories by presence of .jsonld files - collection_directories = [] - directories_with_json_but_no_jsonld = [] - - for directory in all_directories: - files_in_dir = list(directory.iterdir()) - jsonld_files = [f for f in files_in_dir if f.name.endswith(".jsonld")] - json_files = [ - f - for f in files_in_dir - if f.name.endswith(".json") and not f.name.endswith(".jsonld") - ] - - if len(jsonld_files) > 0: - collection_directories.append(directory) - elif len(json_files) > 0: - # Directory has JSON files but no JSONLD context file - directories_with_json_but_no_jsonld.append(directory) - - print( - f"Found {len(collection_directories)} collection directories (with .jsonld files)" - ) - print( - f"Found {len(directories_with_json_but_no_jsonld)} directories with JSON but no context" - ) - - errors = [] - warnings = [] - - # Warn about directories that might be missing context files - for directory in directories_with_json_but_no_jsonld: - warnings.append( - f"โš ๏ธ DID YOU FORGET CONTEXT for directory '{directory.name}'? (has .json files but no .jsonld context)" - ) - - # Test each collection directory - for directory in collection_directories: - print(f"\n๐Ÿ“ Testing collection directory: {directory.name}") - - collection_errors = [] - - # Test 1: Check directory structure (at least one jsonld + one other element) - files_in_dir = list(directory.iterdir()) - jsonld_files = [f for f in files_in_dir if f.name.endswith(".jsonld")] - other_files = [f for f in files_in_dir if not f.name.endswith(".jsonld")] - - if len(jsonld_files) == 0: - collection_errors.append( - f"โŒ {directory.name}: No .jsonld context file found" - ) - elif len(jsonld_files) > 1: - warnings.append( - f"โš ๏ธ {directory.name}: Multiple .jsonld files found: {[f.name for f in jsonld_files]}" - ) - - if len(other_files) == 0: - collection_errors.append( - f"โŒ {directory.name}: No element files found (directory only contains context)" - ) - - # Test 2: Validate JSONLD context structure - for jsonld_file in jsonld_files: - try: - with open(jsonld_file, "r", encoding="utf-8") as f: - jsonld_content = json.load(f) - - if "@context" not in jsonld_content: - collection_errors.append( - f"โŒ {jsonld_file.name}: Missing '@context' field" - ) - continue - - context = jsonld_content["@context"] - if not isinstance(context, dict): - collection_errors.append( - f"โŒ {jsonld_file.name}: '@context' must be a dictionary" - ) - continue - - # Check for required fields in context - required_context_fields = ["id", "type", "@base"] - missing_fields = [ - field for field in required_context_fields if field not in context - ] - - if missing_fields: - collection_errors.append( - f"โŒ {jsonld_file.name}: Missing required fields in @context: {missing_fields}" - ) - - except json.JSONDecodeError as e: - collection_errors.append( - f"โŒ {jsonld_file.name}: Invalid JSON syntax - {e}" - ) - except Exception as e: - collection_errors.append( - f"โŒ {jsonld_file.name}: Error reading file - {e}" - ) - - # Test 3: Validate element files structure - json_element_files = [f for f in other_files if f.name.endswith(".json")] - - for element_file in json_element_files: - try: - with open(element_file, "r", encoding="utf-8") as f: - element_content = json.load(f) - - # Check for required fields in element - required_element_fields = ["id", "type", "@context"] - missing_fields = [ - field - for field in required_element_fields - if field not in element_content - ] - - if missing_fields: - collection_errors.append( - f"โŒ {element_file.name}: Missing required fields: {missing_fields}" - ) - - except json.JSONDecodeError as e: - collection_errors.append( - f"โŒ {element_file.name}: Invalid JSON syntax - {e}" - ) - except Exception as e: - collection_errors.append( - f"โŒ {element_file.name}: Error reading file - {e}" - ) - - # Print collection result - if collection_errors: - print(f"โŒ {directory.name}: Failed validation") - for error in collection_errors: - print(f" {error}") - errors.extend(collection_errors) - else: - print(f"โœ… {directory.name}: Passed validation") - - # Test 4: Validate project_specs.json source_collection references - print(f"\n๐Ÿ“„ Testing project_specs.json references...") - try: - with open("project_specs.json", "r", encoding="utf-8") as f: - project_specs = json.load(f) - - # Extract all source_collection references - source_collections = set() - - # Check drs_specs collections - if "drs_specs" in project_specs: - for drs_spec in project_specs["drs_specs"]: - if "parts" in drs_spec: - for part in drs_spec["parts"]: - if "collection_id" in part: - source_collections.add(part["collection_id"]) - - # Check global_attributes_specs collections - if ( - "global_attributes_specs" in project_specs - and "specs" in project_specs["global_attributes_specs"] - ): - for attr_name, attr_spec in project_specs["global_attributes_specs"][ - "specs" - ].items(): - if "source_collection" in attr_spec: - source_collections.add(attr_spec["source_collection"]) - - print( - f"Found {len(source_collections)} unique source_collection references in project_specs.json" - ) - - # Check if each referenced collection directory exists - existing_directories = {d.name for d in Path(".").iterdir() if d.is_dir()} - - for collection in source_collections: - if collection not in existing_directories: - errors.append( - f"โŒ project_specs.json references non-existent collection: '{collection}'" - ) - else: - print(f" โœ… {collection}: Referenced directory exists") - - except FileNotFoundError: - warnings.append( - "โš ๏ธ project_specs.json not found - skipping source_collection validation" - ) - except Exception as e: - errors.append(f"โŒ Error reading project_specs.json: {e}") - - # Display warnings - if warnings: - print(f"\nโš ๏ธ Warnings ({len(warnings)}):") - for warning in warnings: - print(f" {warning}") - - # Summary - print(f"\n๐Ÿ“Š Validation Summary:") - if errors: - print(f"โŒ Found {len(errors)} errors:") - for error in errors: - print(f" {error}") - raise Exception(f"Repository validation failed with {len(errors)} errors") - else: - print("โœ… All repository structure tests passed!") - print(f"โœ… Validated {len(collection_directories)} collection directories") - print("โœ… All required files have proper structure") - if "project_specs.json" in [f.name for f in Path(".").iterdir()]: - print("โœ… All project_specs.json references are valid") - - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("Usage: cv-validate.py [configure|test]") - sys.exit(1) - - command = sys.argv[1] - - if command == "configure": - configure_and_install_esgvoc() - elif command == "test": - test_cv_with_esgvoc() - else: - print("Invalid command. Use 'configure' or 'test'") - sys.exit(1) diff --git a/.github/workflows/cv-validation.yml b/.github/workflows/cv-validation.yml deleted file mode 100644 index af23f5f..0000000 --- a/.github/workflows/cv-validation.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: CV Validation with ESGVoc - -on: - push: - branches: [ REF, esgvoc, esgvoc_dev ] - -permissions: - contents: write - actions: read - -env: - TEST_BRANCH: "test_branch_${{ github.run_id }}" - PYTHON_VERSION: "3.11" - # Conditional esgvoc library branch: integration for esgvoc_dev, main for others - ESGVOC_LIBRARY_BRANCH: ${{ github.ref_name == 'esgvoc_dev' && 'integration' || 'main' }} - -jobs: - validate-cv: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Git authentication - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - - - name: Create and push to test branch - run: | - # Create test branch from current commit - git checkout -b ${{ env.TEST_BRANCH }} - - # Push test branch to origin - git push origin ${{ env.TEST_BRANCH }} - - echo "Test branch created: ${{ env.TEST_BRANCH }}" - echo "TEST_BRANCH_REF=${{ github.repository }}/${{ env.TEST_BRANCH }}" >> $GITHUB_ENV - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Install uv - run: | - curl -LsSf https://astral.sh/uv/install.sh | sh - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Install dependencies - run: | - uv venv - source .venv/bin/activate - - # Install esgvoc from the specified branch - uv pip install "esgvoc @ git+https://github.com/ESGF/esgf-vocab.git@${{ env.ESGVOC_LIBRARY_BRANCH }}" - - - name: Configure and Install ESGVoc - run: | - source .venv/bin/activate - export TEST_BRANCH="${{ env.TEST_BRANCH }}" - export REPO_URL="https://github.com/${{ github.repository }}" - export ESGVOC_LIBRARY_BRANCH="${{ env.ESGVOC_LIBRARY_BRANCH }}" - python .github/workflows/cv-validate.py configure - - - name: Test CV with ESGVoc - run: | - source .venv/bin/activate - python .github/workflows/cv-validate.py test - - - name: Cleanup test branch - if: always() - run: | - # Delete the test branch from remote - git push origin --delete ${{ env.TEST_BRANCH }} || true - - # Switch back to original branch and delete local test branch - git checkout ${{ github.ref_name }} - git branch -D ${{ env.TEST_BRANCH }} || true - - - name: Validation Summary - if: success() - run: | - echo "โœ… CV validation completed successfully!" - echo "The changes are compatible with esgvoc library (branch: ${{ env.ESGVOC_LIBRARY_BRANCH }})." - - - name: Validation Failed - if: failure() - run: | - echo "โŒ CV validation failed!" - echo "Please check the logs above for details." - exit 1 diff --git a/.github/workflows/publish-dev.yaml b/.github/workflows/publish-dev.yaml new file mode 100644 index 0000000..06d5128 --- /dev/null +++ b/.github/workflows/publish-dev.yaml @@ -0,0 +1,39 @@ +name: Test dev-latest snapshot + +on: + push: + branches: [esgvoc_dev] + pull_request: + branches: [esgvoc_dev] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-esgvoc + + - name: Test obs4ref build + env: + BRANCH: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref_name }} + REPO: ${{ github.event.pull_request.head.repo.full_name }} + run: | + REPO_FLAG="" + if [ -n "$REPO" ]; then + REPO_FLAG="--repo $REPO" + fi + esgvoc test run obs4ref $REPO_FLAG --branch "$BRANCH" --universe-branch esgvoc_dev + + - name: Print publish command + run: | + echo "============================================" + echo " Test passed! To publish, run manually:" + echo "" + echo " gh workflow run publish.yml \\" + echo " -R WCRP-CMIP/esgvoc_registry \\" + echo " -f project_id=obs4ref \\" + echo " -f bump_type=dev-latest \\" + echo " -f project_repo=Climate-REF/Obs4REF_CVs" + echo "============================================" diff --git a/attr_specs.yaml b/attr_specs.yaml index 97dd09a..228c2c7 100644 --- a/attr_specs.yaml +++ b/attr_specs.yaml @@ -1,82 +1,82 @@ - source_collection: activity_id - value_type: string_array + attr_field_value_type: string_array is_required: true - source_collection: creation_date - value_type: string + attr_field_value_type: string is_required: true - source_collection: contact - value_type: string + attr_field_value_type: string is_required: true - source_collection: conventions - field_name: Conventions - value_type: string_array + attr_field_name: Conventions + attr_field_value_type: string_array is_required: true - source_collection: dataset_contributor - value_type: string + attr_field_value_type: string is_required: true - source_collection: data_specs_version - value_type: string + attr_field_value_type: string is_required: true - source_collection: frequency - value_type: string + attr_field_value_type: string is_required: true - source_collection: grid_label - field_name: grid + attr_field_name: grid specific_key: description - value_type: string + attr_field_value_type: string is_required: true - source_collection: grid_label - value_type: string + attr_field_value_type: string is_required: true - source_collection: institution_id specific_key: description - field_name: institution - value_type: string + attr_field_name: institution + attr_field_value_type: string is_required: true - source_collection: institution_id - value_type: string + attr_field_value_type: string is_required: true - source_collection: license - value_type: string + attr_field_value_type: string is_required: true - source_collection: nominal_resolution specific_key: description - value_type: string + attr_field_value_type: string is_required: true - source_collection: processing_code_location - value_type: string + attr_field_value_type: string is_required: true - source_collection: product - value_type: string + attr_field_value_type: string is_required: true - source_collection: realm - value_type: string_array + attr_field_value_type: string_array is_required: true - source_collection: references - value_type: string + attr_field_value_type: string is_required: true - source_collection: region - value_type: string + attr_field_value_type: string is_required: true - source_collection: source_id - value_type: string + attr_field_value_type: string is_required: true - source_collection: source_id specific_key: label_extended - field_name: source - value_type: string + attr_field_name: source + attr_field_value_type: string is_required: true - source_collection: source_id specific_key: drs_name - field_name: source_label - value_type: string + attr_field_name: source_label + attr_field_value_type: string is_required: true - source_collection: tracking_id - value_type: string + attr_field_value_type: string is_required: true - source_collection: variable_id - value_type: string + attr_field_value_type: string is_required: true - source_collection: variant_label - value_type: string + attr_field_value_type: string is_required: true diff --git a/citation_url/gnl_url.json b/citation_url/gnl_url.json new file mode 100644 index 0000000..104f18e --- /dev/null +++ b/citation_url/gnl_url.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "gnl_url", + "type": "citation_url" +} diff --git a/frequency/1hrcm.json b/frequency/1hrcm.json new file mode 100644 index 0000000..aa00e48 --- /dev/null +++ b/frequency/1hrcm.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "1hrcm", + "type": "frequency" +} diff --git a/frequency/1hrpt.json b/frequency/1hrpt.json new file mode 100644 index 0000000..35d6d53 --- /dev/null +++ b/frequency/1hrpt.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "1hrpt", + "type": "frequency" +} diff --git a/frequency/3hrpt.json b/frequency/3hrpt.json new file mode 100644 index 0000000..ca888cc --- /dev/null +++ b/frequency/3hrpt.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "3hrpt", + "type": "frequency" +} diff --git a/frequency/6hrpt.json b/frequency/6hrpt.json new file mode 100644 index 0000000..aca1e7d --- /dev/null +++ b/frequency/6hrpt.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "6hrpt", + "type": "frequency" +} diff --git a/frequency/monc.json b/frequency/monc.json new file mode 100644 index 0000000..a95cd1f --- /dev/null +++ b/frequency/monc.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "monc", + "type": "frequency" +} diff --git a/frequency/monpt.json b/frequency/monpt.json new file mode 100644 index 0000000..728f82d --- /dev/null +++ b/frequency/monpt.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "monpt", + "type": "frequency" +} diff --git a/frequency/subhrpt.json b/frequency/subhrpt.json new file mode 100644 index 0000000..3451f6b --- /dev/null +++ b/frequency/subhrpt.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "subhrpt", + "type": "frequency" +} diff --git a/frequency/yrpt.json b/frequency/yrpt.json new file mode 100644 index 0000000..1951d88 --- /dev/null +++ b/frequency/yrpt.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "yrpt", + "type": "frequency" +} diff --git a/realm/atmoschem.json b/realm/atmoschem.json new file mode 100644 index 0000000..44e0d0f --- /dev/null +++ b/realm/atmoschem.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "atmoschem", + "type": "realm" +} diff --git a/realm/landice.json b/realm/landice.json new file mode 100644 index 0000000..ec12620 --- /dev/null +++ b/realm/landice.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "landice", + "type": "realm" +} diff --git a/realm/ocnbgchem.json b/realm/ocnbgchem.json new file mode 100644 index 0000000..d24b88a --- /dev/null +++ b/realm/ocnbgchem.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "ocnbgchem", + "type": "realm" +} diff --git a/realm/seaice.json b/realm/seaice.json new file mode 100644 index 0000000..9276278 --- /dev/null +++ b/realm/seaice.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "seaice", + "type": "realm" +} diff --git a/tracking_id/prefuuid.json b/tracking_id/prefuuid.json new file mode 100644 index 0000000..316646b --- /dev/null +++ b/tracking_id/prefuuid.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "prefuuid", + "type": "tracking_id" +} diff --git a/variable_id/baresoilfrac.json b/variable_id/baresoilfrac.json new file mode 100644 index 0000000..9f9c323 --- /dev/null +++ b/variable_id/baresoilfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "baresoilfrac", + "type": "variable" +} diff --git a/variable_id/burntfractionall.json b/variable_id/burntfractionall.json new file mode 100644 index 0000000..cbec133 --- /dev/null +++ b/variable_id/burntfractionall.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "burntfractionall", + "type": "variable" +} diff --git a/variable_id/c3pftfrac.json b/variable_id/c3pftfrac.json new file mode 100644 index 0000000..50d656b --- /dev/null +++ b/variable_id/c3pftfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "c3pftfrac", + "type": "variable" +} diff --git a/variable_id/c4pftfrac.json b/variable_id/c4pftfrac.json new file mode 100644 index 0000000..1e0c854 --- /dev/null +++ b/variable_id/c4pftfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "c4pftfrac", + "type": "variable" +} diff --git a/variable_id/ccwd.json b/variable_id/ccwd.json new file mode 100644 index 0000000..b48dafa --- /dev/null +++ b/variable_id/ccwd.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "ccwd", + "type": "variable" +} diff --git a/variable_id/ch4clim.json b/variable_id/ch4clim.json new file mode 100644 index 0000000..bde3f5d --- /dev/null +++ b/variable_id/ch4clim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "ch4clim", + "type": "variable" +} diff --git a/variable_id/ch4globalclim.json b/variable_id/ch4globalclim.json new file mode 100644 index 0000000..7a140fc --- /dev/null +++ b/variable_id/ch4globalclim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "ch4globalclim", + "type": "variable" +} diff --git a/variable_id/cleaf.json b/variable_id/cleaf.json new file mode 100644 index 0000000..edf77d6 --- /dev/null +++ b/variable_id/cleaf.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "cleaf", + "type": "variable" +} diff --git a/variable_id/clitter.json b/variable_id/clitter.json new file mode 100644 index 0000000..097bf45 --- /dev/null +++ b/variable_id/clitter.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "clitter", + "type": "variable" +} diff --git a/variable_id/clitterabove.json b/variable_id/clitterabove.json new file mode 100644 index 0000000..cc19fc9 --- /dev/null +++ b/variable_id/clitterabove.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "clitterabove", + "type": "variable" +} diff --git a/variable_id/clitterbelow.json b/variable_id/clitterbelow.json new file mode 100644 index 0000000..f4bffc1 --- /dev/null +++ b/variable_id/clitterbelow.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "clitterbelow", + "type": "variable" +} diff --git a/variable_id/co2clim.json b/variable_id/co2clim.json new file mode 100644 index 0000000..a6b0393 --- /dev/null +++ b/variable_id/co2clim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "co2clim", + "type": "variable" +} diff --git a/variable_id/co2massclim.json b/variable_id/co2massclim.json new file mode 100644 index 0000000..5d9e770 --- /dev/null +++ b/variable_id/co2massclim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "co2massclim", + "type": "variable" +} diff --git a/variable_id/cproduct.json b/variable_id/cproduct.json new file mode 100644 index 0000000..89085e1 --- /dev/null +++ b/variable_id/cproduct.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "cproduct", + "type": "variable" +} diff --git a/variable_id/croot.json b/variable_id/croot.json new file mode 100644 index 0000000..05c83a9 --- /dev/null +++ b/variable_id/croot.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "croot", + "type": "variable" +} diff --git a/variable_id/cropfrac.json b/variable_id/cropfrac.json new file mode 100644 index 0000000..2a00a8e --- /dev/null +++ b/variable_id/cropfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "cropfrac", + "type": "variable" +} diff --git a/variable_id/csoilfast.json b/variable_id/csoilfast.json new file mode 100644 index 0000000..14799b7 --- /dev/null +++ b/variable_id/csoilfast.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "csoilfast", + "type": "variable" +} diff --git a/variable_id/csoilmedium.json b/variable_id/csoilmedium.json new file mode 100644 index 0000000..f6e5651 --- /dev/null +++ b/variable_id/csoilmedium.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "csoilmedium", + "type": "variable" +} diff --git a/variable_id/csoilslow.json b/variable_id/csoilslow.json new file mode 100644 index 0000000..c400cae --- /dev/null +++ b/variable_id/csoilslow.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "csoilslow", + "type": "variable" +} diff --git a/variable_id/cveg.json b/variable_id/cveg.json new file mode 100644 index 0000000..3593193 --- /dev/null +++ b/variable_id/cveg.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "cveg", + "type": "variable" +} diff --git a/variable_id/ffire.json b/variable_id/ffire.json new file mode 100644 index 0000000..869364a --- /dev/null +++ b/variable_id/ffire.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "ffire", + "type": "variable" +} diff --git a/variable_id/fgrazing.json b/variable_id/fgrazing.json new file mode 100644 index 0000000..d827575 --- /dev/null +++ b/variable_id/fgrazing.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "fgrazing", + "type": "variable" +} diff --git a/variable_id/fharvest.json b/variable_id/fharvest.json new file mode 100644 index 0000000..f5bd82a --- /dev/null +++ b/variable_id/fharvest.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "fharvest", + "type": "variable" +} diff --git a/variable_id/flittersoil.json b/variable_id/flittersoil.json new file mode 100644 index 0000000..6eba1f8 --- /dev/null +++ b/variable_id/flittersoil.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "flittersoil", + "type": "variable" +} diff --git a/variable_id/fveglitter.json b/variable_id/fveglitter.json new file mode 100644 index 0000000..bb2c864 --- /dev/null +++ b/variable_id/fveglitter.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "fveglitter", + "type": "variable" +} diff --git a/variable_id/fvegsoil.json b/variable_id/fvegsoil.json new file mode 100644 index 0000000..35f4319 --- /dev/null +++ b/variable_id/fvegsoil.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "fvegsoil", + "type": "variable" +} diff --git a/variable_id/grassfrac.json b/variable_id/grassfrac.json new file mode 100644 index 0000000..816c0b1 --- /dev/null +++ b/variable_id/grassfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "grassfrac", + "type": "variable" +} diff --git a/variable_id/landcoverfrac.json b/variable_id/landcoverfrac.json new file mode 100644 index 0000000..3cab84b --- /dev/null +++ b/variable_id/landcoverfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "landcoverfrac", + "type": "variable" +} diff --git a/variable_id/n2oclim.json b/variable_id/n2oclim.json new file mode 100644 index 0000000..9bd211b --- /dev/null +++ b/variable_id/n2oclim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "n2oclim", + "type": "variable" +} diff --git a/variable_id/n2oglobalclim.json b/variable_id/n2oglobalclim.json new file mode 100644 index 0000000..14a782a --- /dev/null +++ b/variable_id/n2oglobalclim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "n2oglobalclim", + "type": "variable" +} diff --git a/variable_id/nppleaf.json b/variable_id/nppleaf.json new file mode 100644 index 0000000..45d3f12 --- /dev/null +++ b/variable_id/nppleaf.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "nppleaf", + "type": "variable" +} diff --git a/variable_id/npproot.json b/variable_id/npproot.json new file mode 100644 index 0000000..cfa7292 --- /dev/null +++ b/variable_id/npproot.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "npproot", + "type": "variable" +} diff --git a/variable_id/nppwood.json b/variable_id/nppwood.json new file mode 100644 index 0000000..73c1644 --- /dev/null +++ b/variable_id/nppwood.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "nppwood", + "type": "variable" +} diff --git a/variable_id/o3clim.json b/variable_id/o3clim.json new file mode 100644 index 0000000..d67d4c4 --- /dev/null +++ b/variable_id/o3clim.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "o3clim", + "type": "variable" +} diff --git a/variable_id/pasturefrac.json b/variable_id/pasturefrac.json new file mode 100644 index 0000000..20a0c88 --- /dev/null +++ b/variable_id/pasturefrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "pasturefrac", + "type": "variable" +} diff --git a/variable_id/residualfrac.json b/variable_id/residualfrac.json new file mode 100644 index 0000000..4947a33 --- /dev/null +++ b/variable_id/residualfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "residualfrac", + "type": "variable" +} diff --git a/variable_id/rgrowth.json b/variable_id/rgrowth.json new file mode 100644 index 0000000..3bae65e --- /dev/null +++ b/variable_id/rgrowth.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "rgrowth", + "type": "variable" +} diff --git a/variable_id/rmaint.json b/variable_id/rmaint.json new file mode 100644 index 0000000..d2c66cc --- /dev/null +++ b/variable_id/rmaint.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "rmaint", + "type": "variable" +} diff --git a/variable_id/sfcwindmax.json b/variable_id/sfcwindmax.json new file mode 100644 index 0000000..865cb39 --- /dev/null +++ b/variable_id/sfcwindmax.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "sfcwindmax", + "type": "variable" +} diff --git a/variable_id/shrubfrac.json b/variable_id/shrubfrac.json new file mode 100644 index 0000000..558edd9 --- /dev/null +++ b/variable_id/shrubfrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "shrubfrac", + "type": "variable" +} diff --git a/variable_id/treefrac.json b/variable_id/treefrac.json new file mode 100644 index 0000000..1f02b73 --- /dev/null +++ b/variable_id/treefrac.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "treefrac", + "type": "variable" +} diff --git a/variable_id/treefracprimdec.json b/variable_id/treefracprimdec.json new file mode 100644 index 0000000..49dccbc --- /dev/null +++ b/variable_id/treefracprimdec.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "treefracprimdec", + "type": "variable" +} diff --git a/variable_id/treefracprimever.json b/variable_id/treefracprimever.json new file mode 100644 index 0000000..11cbe09 --- /dev/null +++ b/variable_id/treefracprimever.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "treefracprimever", + "type": "variable" +} diff --git a/variable_id/treefracsecdec.json b/variable_id/treefracsecdec.json new file mode 100644 index 0000000..394fc44 --- /dev/null +++ b/variable_id/treefracsecdec.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "treefracsecdec", + "type": "variable" +} diff --git a/variable_id/treefracsecever.json b/variable_id/treefracsecever.json new file mode 100644 index 0000000..67adf62 --- /dev/null +++ b/variable_id/treefracsecever.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "treefracsecever", + "type": "variable" +} diff --git a/version/creationdatenb.json b/version/creationdatenb.json new file mode 100644 index 0000000..cd1ddb5 --- /dev/null +++ b/version/creationdatenb.json @@ -0,0 +1,5 @@ +{ + "@context": "000_context.jsonld", + "id": "creationdatenb", + "type": "directory_date" +}