feat: Migrate community_significance and frame_sample_rate slots to new structures

- Removed community_significance slot and migrated its functionality to has_or_had_significance, utilizing the Significance class for structured representation.
- Introduced has_or_had_significance slot with detailed examples and descriptions.
- Archived community_significance slot and its YAML file.
- Removed frame_sample_rate slot, migrating its functionality to the analyzes_or_analyzed slot, now supporting the VideoFrame class for frame analysis.
- Created VideoFrame class to encapsulate frame analysis parameters, including sample rate and total frames processed.
- Updated relevant schemas and examples to reflect these changes, ensuring compliance with migration rules.
- Regenerated manifest to include new structures and updated counts.
This commit is contained in:
kempersc 2026-01-22 15:51:02 +01:00
parent ba2c766dd0
commit 4c3978ab2f
11 changed files with 336 additions and 74 deletions

View file

@ -1,5 +1,5 @@
{
"generated": "2026-01-22T12:00:07.511Z",
"generated": "2026-01-22T14:15:56.373Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 2969,
"categoryCounts": {

View file

@ -1,5 +1,5 @@
{
"generated": "2026-01-22T14:15:56.373Z",
"generated": "2026-01-22T14:51:02.979Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": 2969,
"categoryCounts": {

View file

@ -15,7 +15,11 @@ imports:
- linkml:types
- ./CustodianType
# ARCHIVED 2026-01-16: ../enums/TasteScentHeritageTypeEnum - replaced by TasteScentSubType/TasteScentSubTypes classes
- ../slots/community_significance
# REMOVED 2026-01-22: ../slots/community_significance - migrated to has_or_had_significance + Significance (Rule 53)
- ../slots/has_or_had_significance
- ./Significance
- ./SignificanceType
- ./SignificanceTypes
- ../slots/has_or_had_custodian_type
- ../slots/heritage_practice
- ../slots/knowledge_transmission
@ -209,7 +213,8 @@ classes:
- crm:E55_Type
- schema:Place
slots:
- community_significance
# REMOVED 2026-01-22: community_significance - migrated to has_or_had_significance + Significance (Rule 53)
- has_or_had_significance
- has_or_had_custodian_type
- heritage_practice
- knowledge_transmission
@ -274,16 +279,33 @@ classes:
description: Perfume house transmission
- value: Family succession, Public demos, PDO training
description: Traditional dairy transmission
community_significance:
range: string
# MIGRATED 2026-01-22: community_significance → has_or_had_significance + Significance (Rule 53)
has_or_had_significance:
description: |
Why this culinary/olfactory heritage matters to local/regional/national identity.
MIGRATED from community_significance per slot_fixes.yaml (Rule 53, 2026-01-22).
Uses Significance class for structured representation including:
- Type (CommunitySignificance, EconomicSignificance, TerroirSignificance, etc.)
- Description of the significance
range: Significance
multivalued: true
inlined: true
inlined_as_list: true
required: false
examples:
- value: UNESCO Trappist tradition, Belgian identity, Pilgrimage
description: Westvleteren significance
- value: Grasse UNESCO heritage, French parfumerie, Tourism
description: Perfume house significance
- value: Protected PDO, Dutch cheese identity, Regional economy
description: Traditional cheese significance
- value:
has_or_had_type: CommunitySignificance
has_or_had_description: "UNESCO-recognized Trappist tradition, Belgian cultural identity, Beer pilgrimage site"
description: Westvleteren brewery - community/cultural significance
- value:
has_or_had_type: TerroirSignificance
has_or_had_description: "Grasse UNESCO heritage, French parfumerie tradition, Olfactory tourism"
description: Perfume house - terroir/cultural significance
- value:
has_or_had_type: EconomicSignificance
has_or_had_description: "Protected Gouda PDO, Dutch cheese identity, Economic importance to region"
description: Traditional cheese - economic significance
has_or_had_hyponym: # was: taste_scent_subtype - migrated per Rule 53/56 (2026-01-16)
description: Specific subtype from the taste/scent heritage taxonomy (15 Wikidata-aligned types).
range: TasteScentSubType

View file

@ -12,7 +12,12 @@ imports:
- ../slots/has_annotation_type
- ../slots/detection_count
- ../slots/detection_threshold
- ../slots/frame_sample_rate
# MIGRATED 2026-01-22: frame_sample_rate → analyzes_or_analyzed + VideoFrame + has_or_had_quantity + Quantity (Rule 53)
- ./VideoFrame
- ../slots/has_or_had_quantity
- ../slots/has_or_had_unit
- ./Quantity
- ./Unit
- ../slots/includes_bounding_box
- ../slots/includes_segmentation_mask
- ../slots/keyframe_extraction
@ -23,39 +28,9 @@ imports:
- ../slots/analyzes_or_analyzed
- ./SpecificityAnnotation
- ./TemplateSpecificityScore # was: TemplateSpecificityScores - migrated per Rule 53 (2026-01-17)
- ./TemplateSpecificityType
- ./TemplateSpecificityTypes
- ../enums/AnnotationTypeEnum
- ../slots/analyzes_or_analyzed
- ../slots/detection_count
- ../slots/detection_threshold
- ../slots/frame_sample_rate
- ../slots/has_annotation_motivation
- ../slots/has_annotation_segment
- ../slots/has_annotation_type
- ../slots/includes_bounding_box
- ../slots/includes_segmentation_mask
- ../slots/keyframe_extraction
- ../slots/model_architecture
- ../slots/model_task
- ../slots/specificity_annotation
- ../slots/has_or_had_score # was: template_specificity - migrated per Rule 53 (2026-01-17)
- ../slots/analyzes_or_analyzed
- ../slots/detection_count
- ../slots/detection_threshold
- ../slots/frame_sample_rate
- ../slots/has_annotation_motivation
- ../slots/has_annotation_segment
- ../slots/has_annotation_type
- ../slots/includes_bounding_box
- ../slots/includes_segmentation_mask
- ../slots/keyframe_extraction
- ../slots/model_architecture
- ../slots/model_task
- ../slots/specificity_annotation
- ../slots/has_or_had_score # was: template_specificity - migrated per Rule 53 (2026-01-17)
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
@ -106,7 +81,7 @@ classes:
- has_annotation_type
- detection_count
- detection_threshold
- frame_sample_rate
# REMOVED 2026-01-22: frame_sample_rate - migrated to analyzes_or_analyzed + VideoFrame + has_or_had_quantity (Rule 53)
- includes_bounding_box
- includes_segmentation_mask
- keyframe_extraction
@ -145,21 +120,43 @@ classes:
examples:
- value: 342
description: 342 total detections found
frame_sample_rate:
range: float
required: false
minimum_value: 0.0
examples:
- value: 1.0
description: Analyzed 1 frame per second
# MIGRATED 2026-01-22: frame_sample_rate → analyzes_or_analyzed + VideoFrame + has_or_had_quantity (Rule 53)
# frame_sample_rate:
# range: float
# required: false
# minimum_value: 0.0
# examples:
# - value: 1.0
# description: Analyzed 1 frame per second
analyzes_or_analyzed:
description: Total frames analyzed during video annotation processing.
range: integer
description: |
MIGRATED 2026-01-22: Now supports VideoFrame class for frame_sample_rate migration.
Frame analysis information including:
- Total frames analyzed (integer, legacy pattern)
- Frame sample rate and analysis parameters (VideoFrame class)
MIGRATED SLOTS:
- frame_sample_rate → VideoFrame.has_or_had_quantity with unit "samples per second"
range: VideoFrame
inlined: true
required: false
minimum_value: 0
examples:
- value: 1800
description: Analyzed 1,800 frames (30 min video at 1 fps)
- value:
has_or_had_quantity:
quantity_value: 1.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "samples per second"
frame_count: 1800
description: Analyzed 1,800 frames at 1 fps (30 min video)
- value:
has_or_had_quantity:
quantity_value: 5.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "fps"
description: 5 frames per second sample rate
keyframe_extraction:
range: boolean
required: false

View file

@ -0,0 +1,160 @@
# VideoFrame - Video frame class for analysis
# Created per slot_fixes.yaml migration for: frame_sample_rate
# Creation date: 2026-01-22
#
# Rule compliance:
# - Rule 38: Slot centralization with semantic URIs
# - Rule 39: RiC-O temporal naming conventions
# - Rule 53: Generic reusable slots
id: https://nde.nl/ontology/hc/class/VideoFrame
name: VideoFrame
title: VideoFrame Class
prefixes:
linkml: https://w3id.org/linkml/
hc: https://nde.nl/ontology/hc/
schema: http://schema.org/
oa: http://www.w3.org/ns/oa#
imports:
- linkml:types
- ../slots/has_or_had_quantity
- ../slots/has_or_had_unit
- ./Quantity
- ./Unit
default_prefix: hc
classes:
VideoFrame:
class_uri: schema:VideoObject
description: |
A video frame or set of frames analyzed during video processing.
**PURPOSE**:
Represents frames from a video that have been analyzed by computer vision
or multimodal AI models. Used to track frame-based analysis parameters
such as sample rate (frames per second analyzed) and total frames processed.
**USE CASES**:
- Video annotation (object detection, scene analysis)
- Frame sampling configuration
- Analysis throughput tracking
- Computer vision pipeline configuration
**FRAME SAMPLE RATE**:
The sample rate determines how many frames are analyzed per second of video:
| Sample Rate | Frames/sec | Use Case |
|-------------|------------|----------|
| 0.1 fps | 1 every 10s | Overview/thumbnails |
| 1.0 fps | 1 per second | Standard analysis |
| 5.0 fps | 5 per second | Detailed analysis |
| 30.0 fps | Every frame | Exhaustive analysis |
Higher sample rates capture more detail but increase compute cost.
**MIGRATION SUPPORT**:
This class supports migration from the frame_sample_rate slot per
slot_fixes.yaml. Use with has_or_had_quantity + Quantity + has_or_had_unit + Unit.
exact_mappings:
- oa:Target
close_mappings:
- schema:VideoObject
slots:
- has_or_had_quantity
- has_or_had_unit
slot_usage:
has_or_had_quantity:
description: |
Frame sample rate expressed as quantity with unit.
MIGRATED from frame_sample_rate slot per slot_fixes.yaml (Rule 53, 2026-01-22).
Use Quantity class with:
- quantity_value: the numeric sample rate (e.g., 1.0, 5.0, 30.0)
- quantity_type: FRAME_SAMPLE_RATE
- has_or_had_unit: "samples per second" or "fps"
range: Quantity
inlined: true
multivalued: false
examples:
- value: |
quantity_value: 1.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "samples per second"
description: 1 frame per second sample rate
- value: |
quantity_value: 5.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "fps"
has_or_had_label:
- label_text: "frames per second"
description: 5 fps sample rate
has_or_had_unit:
description: |
Unit of measurement for frame sample rate.
Typically "samples per second" or "fps".
range: Unit
inlined: true
attributes:
frame_count:
range: integer
description: |
Total number of frames in this video or segment.
Used for calculating total frames analyzed from sample rate.
minimum_value: 0
frame_width:
range: integer
description: Frame width in pixels.
minimum_value: 1
frame_height:
range: integer
description: Frame height in pixels.
minimum_value: 1
annotations:
custodian_types: '["D"]'
custodian_types_rationale: >-
Video frames are primarily relevant for digital platforms (D) that
host or process video content.
custodian_types_primary: D
specificity_score: 0.7
specificity_rationale: >-
Moderately specific - applies only to video analysis contexts.
examples:
- value: |
VideoFrame:
has_or_had_quantity:
quantity_value: 1.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "samples per second"
frame_count: 1800
description: Video analyzed at 1 fps over 30 minutes (1800 frames).
- value: |
VideoFrame:
has_or_had_quantity:
quantity_value: 5.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "fps"
frame_width: 1920
frame_height: 1080
description: 5 fps analysis of HD video.
comments:
- Created from slot_fixes.yaml migration (2026-01-22)
- Use with analyzes_or_analyzed slot to track frame analysis
- Sample rate affects both coverage and compute cost

View file

@ -2,6 +2,7 @@
#
# Created per slot_fixes.yaml migration for: total_frames_analyzed
# Creation date: 2026-01-14
# Updated 2026-01-22: Extended to support VideoFrame class for frame_sample_rate migration
id: https://nde.nl/ontology/hc/slot/analyzes_or_analyzed
name: analyzes_or_analyzed
@ -17,6 +18,7 @@ default_prefix: hc
imports:
- linkml:types
- ../classes/VideoFrame
slots:
analyzes_or_analyzed:
@ -26,12 +28,32 @@ slots:
**USAGE**:
Used for:
- Frames analyzed in video processing
- Frames analyzed in video processing (VideoFrame class)
- Documents analyzed
- Items processed
range: integer
**MIGRATION SUPPORT**:
This slot now supports VideoFrame class for frame_sample_rate migration
per slot_fixes.yaml (Rule 53, 2026-01-22).
**Examples**:
- Integer: Total frames count (legacy pattern)
- VideoFrame: Structured frame analysis with sample rate
range: Any
any_of:
- range: integer
- range: VideoFrame
inlined: true
examples:
- value: 24000
description: Total video frames analyzed
description: Total video frames analyzed (integer count)
- value: |
has_or_had_quantity:
quantity_value: 1.0
quantity_type: FRAME_SAMPLE_RATE
has_or_had_unit:
unit_value: "samples per second"
frame_count: 1800
description: Video frame analysis at 1 fps (VideoFrame instance)

View file

@ -103,7 +103,7 @@
"__ARCHIVED_20260122__common_name.yaml",
"__ARCHIVED_20260122__common_name_language.yaml",
"__ARCHIVED_20260122__common_variant.yaml",
"community_significance.yaml",
"__ARCHIVED_20260122__community_significance.yaml",
"complex_name.yaml",
"compliance_status.yaml",
"component_type.yaml",
@ -499,7 +499,6 @@
"follower_count.yaml",
"following_count.yaml",
"footnote.yaml",
"frame_sample_rate.yaml",
"from_location.yaml",
"full_extracted_text.yaml",
"full_name.yaml",

View file

@ -10793,6 +10793,26 @@ fixes:
- label: SignificanceTypes
type: class
note: this includes CommunitySignificance
processed:
status: true
date: '2026-01-22'
agent: claude-claude-sonnet-4-20250514
notes: |
**Migration #40: community_significance** ✅ COMPLETE
**Pattern**: community_significance → has_or_had_significance + Significance + has_or_had_type + SignificanceType + includes_or_included + SignificanceTypes
**Files Created**:
- has_or_had_significance.yaml: Generic slot for significance relationships (crm:P17i_was_motivation_for)
- Significance.yaml: Class for structured significance representation
- SignificanceType.yaml: Abstract base class for significance type taxonomy (Rule 0b)
- SignificanceTypes.yaml: Concrete subclasses (CommunitySignificance, EconomicSignificance, HistoricalSignificance, ScientificSignificance, AestheticSignificance, TerroirSignificance, DiplomaticSignificance)
**Files Modified**:
- TasteScentHeritageType.yaml: Migrated community_significance to has_or_had_significance + Significance
- Updated imports, slots, slot_usage with structured examples
**Archived**: modules/slots/archive/community_significance_archived_20260122.yaml
- original_slot_id: https://nde.nl/ontology/hc/slot/completion_token
revision:
- label: has_or_had_token
@ -13737,6 +13757,12 @@ fixes:
- label: Unit
type: class
value: frames per second
processed:
status: true
notes: "FULLY_MIGRATED 2026-01-22: frame_rate → has_or_had_quantity + Quantity + has_or_had_unit + Unit (Rule 53).
VideoPost.yaml migrated to use Quantity class with has_or_had_unit for frame rate (fps).
Reused existing has_or_had_quantity, Quantity, has_or_had_unit, Unit.
Old slot archived to archive/frame_rate_archived_20260122.yaml"
- original_slot_id: https://nde.nl/ontology/hc/slot/frame_sample_rate
revision:
- label: analyzes_or_analyzed
@ -13752,6 +13778,14 @@ fixes:
- label: Unit
type: class
value: samples per second
processed:
status: true
notes: "FULLY_MIGRATED 2026-01-22: frame_sample_rate → analyzes_or_analyzed + VideoFrame + has_or_had_quantity + Unit (Rule 53).
Created VideoFrame.yaml class for video frame analysis.
Updated analyzes_or_analyzed slot to support VideoFrame range (any_of).
VideoAnnotation.yaml migrated to use VideoFrame for frame sample rate.
Reused existing has_or_had_quantity, Quantity, has_or_had_unit, Unit.
Old slot archived to archive/frame_sample_rate_archived_20260122.yaml"
- original_slot_id: https://nde.nl/ontology/hc/slot/from_location
revision:
- label: has_or_had_origin

View file

@ -3,11 +3,16 @@
Regenerate manifest.json for LinkML schema frontend.
This script scans the LinkML schema directory and generates a complete manifest
of all class and enum files for the frontend to load.
of all class, enum, and slot files for the frontend to load.
The manifest structure matches what the frontend LinkMLSchemaService expects:
- schemaRoot: Base path for schema files
- totalFiles: Total count of all files
- categoryCounts: Per-category file counts
- categories: Array of category objects with files
"""
import json
import os
from datetime import datetime, timezone
from pathlib import Path
@ -26,7 +31,18 @@ def get_yaml_files(directory: Path) -> list[str]:
return sorted([f.stem for f in directory.glob("*.yaml")])
def get_main_yaml_files(directory: Path) -> list[str]:
"""Get top-level .yaml files in schema directory."""
if not directory.exists():
return []
return sorted([f.stem for f in directory.glob("*.yaml") if f.is_file()])
def main():
# Get all main schema files (top-level .yaml files)
main_files = get_main_yaml_files(SCHEMA_DIR)
print(f"Found {len(main_files)} main schema files")
# Get all class files
class_files = get_yaml_files(CLASSES_DIR)
print(f"Found {len(class_files)} class files")
@ -39,20 +55,32 @@ def main():
slot_files = get_yaml_files(SLOTS_DIR)
print(f"Found {len(slot_files)} slot files")
# Build manifest structure
# Calculate totals
total_files = len(main_files) + len(class_files) + len(enum_files) + len(slot_files)
# Build manifest structure matching frontend expectations
manifest = {
"generated": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
"version": "1.0.0",
"generated": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z",
"schemaRoot": "/schemas/20251121/linkml",
"totalFiles": total_files,
"categoryCounts": {
"main": len(main_files),
"class": len(class_files),
"enum": len(enum_files),
"slot": len(slot_files),
"module": 4 # Fixed count for module imports
},
"categories": [
{
"name": "main",
"displayName": "Main Schema",
"displayName": "Main Schemas",
"files": [
{
"name": "Heritage Custodian Ontology",
"path": "01_custodian_name_modular.yaml",
"name": name,
"path": f"{name}.yaml",
"category": "main"
}
for name in main_files
]
},
{
@ -62,7 +90,7 @@ def main():
{
"name": name,
"path": f"modules/classes/{name}.yaml",
"category": "classes"
"category": "class"
}
for name in class_files
]
@ -74,7 +102,7 @@ def main():
{
"name": name,
"path": f"modules/enums/{name}.yaml",
"category": "enums"
"category": "enum"
}
for name in enum_files
]
@ -86,7 +114,7 @@ def main():
{
"name": name,
"path": f"modules/slots/{name}.yaml",
"category": "slots"
"category": "slot"
}
for name in slot_files
]
@ -99,11 +127,11 @@ def main():
json.dump(manifest, f, indent=2)
print(f"\n✅ Manifest written to {MANIFEST_PATH}")
print(f" - Main schema: 1 file")
print(f" - Main schemas: {len(main_files)} files")
print(f" - Classes: {len(class_files)} files")
print(f" - Enums: {len(enum_files)} files")
print(f" - Slots: {len(slot_files)} files")
print(f" - Total: {1 + len(class_files) + len(enum_files) + len(slot_files)} files")
print(f" - Total: {total_files} files")
if __name__ == "__main__":