Skip to content

Commit 99ae0d5

Browse files
docs(units): add documentation for units CLI commands
- Add README covering QUDT integration, CLI usage, technical implementation, and workflow examples. - Check in the generated units under examples - Add documentation to the docs-gen Signed-off-by: Mustafa Kaptan <[email protected]>
1 parent b5eb795 commit 99ae0d5

File tree

594 files changed

+13519
-10
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

594 files changed

+13519
-10
lines changed

docs-gen/content/docs/data-modeling-guideline/pre-defined-elements.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,39 @@ chapter: false
77
![fig:s2dm_pre_defined_elements](/images/s2dm_pre_def_elements.png)
88

99
### Units
10-
Units are represented as enum values. For example:
10+
Units are represented as GraphQL enum values with semantic references to standardized unit definitions. For example:
1111
```graphql
12-
enum VelocityUnitEnum {
13-
KILOMETER_PER_HOUR
14-
METERS_PER_SECOND
12+
enum VelocityUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/Velocity", versionTag: "3.1.5") {
13+
"""Kilometer per Hour | UCUM: km/h"""
14+
KM_PER_HR @reference(uri: "http://qudt.org/vocab/unit/KM-PER-HR", versionTag: "3.1.5")
15+
16+
"""Meter per Second | UCUM: m/s"""
17+
M_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/M-PER-SEC", versionTag: "3.1.5")
1518
}
1619
```
17-
The name of the enum itself refers to the quantity kind (e.g., `Velocity`).
18-
A set of commonly used units is provided in the file [`unit_enums.graphql`](https://github.com/COVESA/s2dm/blob/main/src/s2dm/spec/unit_enums.graphql).
1920

20-
> [!NOTE]
21-
> [It is planned](https://github.com/COVESA/s2dm/issues/43) to adopt and reuse an existing standard data model for units.
22-
> At the moment, the units file is inspired by [COVESA VSS Units file](https://github.com/COVESA/vehicle_signal_specification/blob/main/spec/units.md).
23-
> The tentative model that will be used in the future is the [QUDT units](http://www.qudt.org/doc/DOC_VOCAB-UNITS-ALL.html).
21+
S2DM provides two approaches for unit definitions:
22+
23+
#### External Units (QUDT Integration)
24+
S2DM integrates with the [QUDT (Quantities, Units, Dimensions and Types)](https://qudt.org/) reference model to provide standardized, up-to-date unit definitions. These units are automatically synchronized from the authoritative QUDT repository using the S2DM CLI tool.
25+
26+
#### Custom Units
27+
For domain-specific or non-standard units, you can define custom unit enums following the same structure as QUDT units.
28+
29+
#### Directory Structure
30+
When using both external and custom units, organize them as follows:
31+
```
32+
path/to/units/
33+
├── external_qudt/ # QUDT units (generated via CLI)
34+
│ ├── LengthUnitEnum.graphql
35+
│ ├── VelocityUnitEnum.graphql
36+
│ └── metadata.json
37+
└── custom/ # Custom domain-specific units
38+
└── MyCustomUnitEnum.graphql
39+
```
40+
41+
> [!TIP]
42+
> See the [Units CLI documentation](../tools/units-cli) for detailed instructions on synchronizing QUDT units and managing unit definitions.
2443
2544

2645
### Custom scalars
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
title: Units CLI
3+
weight: 20
4+
chapter: false
5+
---
6+
7+
# QUDT Units CLI
8+
9+
The S2DM Units CLI provides integration with the [QUDT (Quantities, Units, Dimensions and Types)](https://qudt.org/) reference model to generate standardized GraphQL unit enums. This replaces static unit definitions with a dynamic system that synchronizes directly from the authoritative QUDT repository.
10+
11+
## Features
12+
13+
- **Dynamic Unit Synchronization**: Fetch unit definitions from QUDT's GitHub repository
14+
- **Version Management**: Support for specific QUDT versions with automatic latest version detection
15+
- **Semantic References**: Generated enums include `@reference` directives linking to QUDT IRIs with version tags
16+
- **UCUM Integration**: Includes UCUM codes in descriptive comments for standardization
17+
- **SDL Validation**: Generated GraphQL enums are validated for correctness
18+
- **Automatic Cleanup**: Removes stale files before sync to ensure fresh state
19+
20+
## Commands
21+
22+
### `s2dm units sync`
23+
24+
Synchronizes unit definitions from the QUDT repository and generates GraphQL enum files.
25+
26+
**Syntax:**
27+
```bash
28+
s2dm units sync --output-dir <path> [--version <version>] [--dry-run]
29+
```
30+
31+
**Examples:**
32+
```bash
33+
# Sync latest version
34+
s2dm units sync --output-dir units
35+
36+
# Sync specific version
37+
s2dm units sync --version 3.1.5 --output-dir units
38+
39+
# Check what would be generated without creating files
40+
s2dm units sync --output-dir units --dry-run
41+
42+
# Sync to custom directory
43+
s2dm units sync --version 3.1.5 --output-dir path/to/units/external_qudt
44+
```
45+
46+
**Options:**
47+
- `--output-dir` (required): Directory where generated unit enums will be written
48+
- `--version` (optional): QUDT version string. Defaults to latest release if not specified
49+
- `--dry-run` (optional): Show how many enum files would be generated without creating them
50+
51+
**Output:**
52+
- Creates `<QuantityKindUnitEnum>.graphql` files (e.g., `LengthUnitEnum.graphql`)
53+
- Generates `metadata.json` with version information
54+
- Reports number of enum files generated
55+
56+
### `s2dm units check-version`
57+
58+
Compares the local synced QUDT version with the latest available version.
59+
60+
**Syntax:**
61+
```bash
62+
s2dm units check-version --units-dir <path>
63+
```
64+
65+
**Example:**
66+
```bash
67+
s2dm units check-version --units-dir units/external_qudt
68+
```
69+
70+
**Options:**
71+
- `--units-dir` (required): Directory containing generated unit enums
72+
73+
**Output:**
74+
- `✓ Everything is up to date.` if current version matches latest
75+
- `⚠ There is a newer release available: X.Y.Z` if update is needed
76+
77+
## Generated Enum Format
78+
79+
Each generated enum follows this structure:
80+
81+
```graphql
82+
# Generated from QUDT units catalog version 3.1.5
83+
enum LengthUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/Length", versionTag: "3.1.5") {
84+
"""Meter | UCUM: m"""
85+
M @reference(uri: "http://qudt.org/vocab/unit/M", versionTag: "3.1.5")
86+
87+
"""Kilometer | UCUM: km"""
88+
KILOM @reference(uri: "http://qudt.org/vocab/unit/KiloM", versionTag: "3.1.5")
89+
90+
"""Centimeter | UCUM: cm"""
91+
CENTIM @reference(uri: "http://qudt.org/vocab/unit/CentiM", versionTag: "3.1.5")
92+
...
93+
}
94+
```
95+
96+
**Key Elements:**
97+
- **Enum name**: `<QuantityKind>UnitEnum` in PascalCase
98+
- **@reference on enum**: Links to QUDT quantity kind IRI with version tag
99+
- **@reference on values**: Links to QUDT unit IRI with version tag
100+
- **Triple-quote docstrings**: Include human-readable label and UCUM code
101+
- **Value names**: Use QUDT URI segments converted to SCREAMING_SNAKE_CASE
102+
103+
## Directory Structure
104+
105+
When using both QUDT and custom units, organize them as follows:
106+
107+
```
108+
units/
109+
├── external_qudt/ # QUDT units (generated)
110+
│ ├── metadata.json # Version metadata
111+
│ ├── LengthUnitEnum.graphql # Length units
112+
│ ├── VelocityUnitEnum.graphql # Velocity units
113+
│ └── ... (500+ more unit enums)
114+
└── custom/ # Custom units (manual)
115+
├── MyDomainUnitEnum.graphql # Custom domain units
116+
└── SpecialUnitEnum.graphql # Special use case units
117+
```
118+
119+
## Workflow Example
120+
121+
1. **Initial Setup**: Sync units from QUDT
122+
```bash
123+
s2dm units sync --version 3.1.5 --output-dir units/external_qudt
124+
```
125+
126+
2. **Use Units in Schema Development**: Reference generated enums
127+
```graphql
128+
type Vehicle {
129+
speed(unit: VelocityUnitEnum = KM_PER_HR): Float
130+
acceleration(unit: AccelerationUnitEnum = M_PER_SEC2): Float
131+
}
132+
```
133+
134+
3. **Check for Updates**: Periodically check for new QUDT versions
135+
```bash
136+
s2dm units check-version --units-dir units/external_qudt
137+
```
138+
139+
4. **Update When Needed**: Sync newer versions as they become available
140+
```bash
141+
s2dm units sync --version 3.2.0 --output-dir units/external_qudt
142+
```
143+
144+
## Integration with Registry Commands
145+
146+
The units system integrates seamlessly with S2DM registry commands. The registry commands automatically detect and use unit enums from your schema composition:
147+
148+
```bash
149+
# Generate concept IDs (automatically detects unit enums)
150+
s2dm registry id -s schema.graphql
151+
152+
# Initialize registry (automatically includes unit enums)
153+
s2dm registry init -s schema.graphql -o registry.json
154+
155+
# Update registry (automatically includes unit enums)
156+
s2dm registry update -s new_schema.graphql -r registry.json
157+
```
158+
159+
## Why URI-Based Symbols?
160+
161+
S2DM uses QUDT URI segments instead of labels for enum values because:
162+
163+
- **Consistency**: URI segments are standardized and don't vary across languages
164+
- **Reliability**: Labels can be inconsistent, missing, or contain formatting issues
165+
- **Brevity**: URI segments are shorter and more practical for code usage (e.g., `M` vs `METER`)
166+
- **Semantic Accuracy**: URI segments represent the canonical QUDT identifier
167+
168+
## Technical Details
169+
170+
### Data Source
171+
- **Repository**: [qudt/qudt-public-repo](https://github.com/qudt/qudt-public-repo)
172+
- **File**: `src/main/rdf/vocab/unit/VOCAB_QUDT-UNITS-ALL.ttl`
173+
- **Format**: RDF Turtle (TTL)
174+
175+
### Deduplication
176+
- Uses `DISTINCT` in SPARQL queries to eliminate exact duplicates
177+
- Filters out deprecated units to prevent symbol conflicts
178+
- Prefers entries with UCUM codes when duplicates remain
179+
180+
### Error Handling
181+
- **Network Issues**: Graceful failure with informative error messages
182+
- **Invalid Units**: Units that cannot generate valid symbols are skipped
183+
- **SDL Validation**: Generated GraphQL enums are validated for correctness
184+
- **Version Check**: Safe handling of GitHub API rate limits
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Generated from QUDT units catalog version 3.1.5
2+
enum APIGravityUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/APIGravity", versionTag: "v3.1.5") {
3+
"""Degree Api"""
4+
DEGREE_API @reference(uri: "http://qudt.org/vocab/unit/DEGREE_API", versionTag: "v3.1.5")
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Generated from QUDT units catalog version 3.1.5
2+
enum AbsoluteActivityUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/AbsoluteActivity", versionTag: "v3.1.5") {
3+
"""Becquerel Second per Cubic Meter | UCUM: Bq.s.m-3"""
4+
BQ_SEC_PER_M3 @reference(uri: "http://qudt.org/vocab/unit/BQ-SEC-PER-M3", versionTag: "v3.1.5")
5+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Generated from QUDT units catalog version 3.1.5
2+
enum AbsorbedDoseRateUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/AbsorbedDoseRate", versionTag: "v3.1.5") {
3+
"""Erg per Gram Second | UCUM: erg.g-1.s-1"""
4+
ERG_PER_GM_SEC @reference(uri: "http://qudt.org/vocab/unit/ERG-PER-GM-SEC", versionTag: "v3.1.5")
5+
6+
"""Gray per Hour | UCUM: Gy.h-1"""
7+
GRAY_PER_HR @reference(uri: "http://qudt.org/vocab/unit/GRAY-PER-HR", versionTag: "v3.1.5")
8+
9+
"""Gray per Minute | UCUM: Gy.min-1"""
10+
GRAY_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/GRAY-PER-MIN", versionTag: "v3.1.5")
11+
12+
"""Gray per Second | UCUM: Gy.s-1"""
13+
GRAY_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/GRAY-PER-SEC", versionTag: "v3.1.5")
14+
15+
"""Microgray per Hour | UCUM: uGy.h-1"""
16+
MICROGRAY_PER_HR @reference(uri: "http://qudt.org/vocab/unit/MicroGRAY-PER-HR", versionTag: "v3.1.5")
17+
18+
"""Microgray per Minute | UCUM: uGy.min-1"""
19+
MICROGRAY_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/MicroGRAY-PER-MIN", versionTag: "v3.1.5")
20+
21+
"""Microgray per Second | UCUM: uGy.s-1"""
22+
MICROGRAY_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/MicroGRAY-PER-SEC", versionTag: "v3.1.5")
23+
24+
"""Microsievert per Hour | UCUM: uSv.h-1"""
25+
MICROSV_PER_HR @reference(uri: "http://qudt.org/vocab/unit/MicroSV-PER-HR", versionTag: "v3.1.5")
26+
27+
"""Microsievert per Minute | UCUM: uSv.min-1"""
28+
MICROSV_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/MicroSV-PER-MIN", versionTag: "v3.1.5")
29+
30+
"""Microsievert per Second | UCUM: uSv.s-1"""
31+
MICROSV_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/MicroSV-PER-SEC", versionTag: "v3.1.5")
32+
33+
"""Milligray per Hour | UCUM: mGy.h-1"""
34+
MILLIGRAY_PER_HR @reference(uri: "http://qudt.org/vocab/unit/MilliGRAY-PER-HR", versionTag: "v3.1.5")
35+
36+
"""Milligray per Minute | UCUM: mGy.min-1"""
37+
MILLIGRAY_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/MilliGRAY-PER-MIN", versionTag: "v3.1.5")
38+
39+
"""Milligray per Second | UCUM: mGy.s-1"""
40+
MILLIGRAY_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/MilliGRAY-PER-SEC", versionTag: "v3.1.5")
41+
42+
"""Millirad per Hour | UCUM: mRAD.h-1"""
43+
MILLIRAD_R_PER_HR @reference(uri: "http://qudt.org/vocab/unit/MilliRAD_R-PER-HR", versionTag: "v3.1.5")
44+
45+
"""Millisievert per Hour | UCUM: mSv.h-1"""
46+
MILLISV_PER_HR @reference(uri: "http://qudt.org/vocab/unit/MilliSV-PER-HR", versionTag: "v3.1.5")
47+
48+
"""Millisievert per Minute | UCUM: mSv.min-1"""
49+
MILLISV_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/MilliSV-PER-MIN", versionTag: "v3.1.5")
50+
51+
"""Millisievert per Second | UCUM: mSv.s-1"""
52+
MILLISV_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/MilliSV-PER-SEC", versionTag: "v3.1.5")
53+
54+
"""Milliwatt per Milligram | UCUM: mW.mg-1"""
55+
MILLIW_PER_MILLIGM @reference(uri: "http://qudt.org/vocab/unit/MilliW-PER-MilliGM", versionTag: "v3.1.5")
56+
57+
"""Nanogray per Hour"""
58+
NANOGRAY_PER_HR @reference(uri: "http://qudt.org/vocab/unit/NanoGRAY-PER-HR", versionTag: "v3.1.5")
59+
60+
"""Nanogray per Minute"""
61+
NANOGRAY_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/NanoGRAY-PER-MIN", versionTag: "v3.1.5")
62+
63+
"""Nanogray per Second"""
64+
NANOGRAY_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/NanoGRAY-PER-SEC", versionTag: "v3.1.5")
65+
66+
"""Nanosievert per Hour"""
67+
NANOSV_PER_HR @reference(uri: "http://qudt.org/vocab/unit/NanoSV-PER-HR", versionTag: "v3.1.5")
68+
69+
"""Nanosievert per Minute"""
70+
NANOSV_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/NanoSV-PER-MIN", versionTag: "v3.1.5")
71+
72+
"""Nanosievert per Second"""
73+
NANOSV_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/NanoSV-PER-SEC", versionTag: "v3.1.5")
74+
75+
"""Rem per Second | UCUM: REM.s-1"""
76+
REM_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/REM-PER-SEC", versionTag: "v3.1.5")
77+
78+
"""Sievert per Hour | UCUM: Sv.h-1"""
79+
SV_PER_HR @reference(uri: "http://qudt.org/vocab/unit/SV-PER-HR", versionTag: "v3.1.5")
80+
81+
"""Sievert per Minute | UCUM: Sv.min-1"""
82+
SV_PER_MIN @reference(uri: "http://qudt.org/vocab/unit/SV-PER-MIN", versionTag: "v3.1.5")
83+
84+
"""Sievert per Second | UCUM: Sv.s-1"""
85+
SV_PER_SEC @reference(uri: "http://qudt.org/vocab/unit/SV-PER-SEC", versionTag: "v3.1.5")
86+
87+
"""Watt per Gram | UCUM: W.g-1"""
88+
W_PER_GM @reference(uri: "http://qudt.org/vocab/unit/W-PER-GM", versionTag: "v3.1.5")
89+
90+
"""Watt per Kilogram | UCUM: W.kg-1"""
91+
W_PER_KILOGM @reference(uri: "http://qudt.org/vocab/unit/W-PER-KiloGM", versionTag: "v3.1.5")
92+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated from QUDT units catalog version 3.1.5
2+
enum AbsorbedDoseUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/AbsorbedDose", versionTag: "v3.1.5") {
3+
"""Centigray"""
4+
CENTIGRAY @reference(uri: "http://qudt.org/vocab/unit/CentiGRAY", versionTag: "v3.1.5")
5+
6+
"""Gray | UCUM: Gy"""
7+
GRAY @reference(uri: "http://qudt.org/vocab/unit/GRAY", versionTag: "v3.1.5")
8+
9+
"""Kilogray"""
10+
KILOGRAY @reference(uri: "http://qudt.org/vocab/unit/KiloGRAY", versionTag: "v3.1.5")
11+
12+
"""Megagray"""
13+
MEGAGRAY @reference(uri: "http://qudt.org/vocab/unit/MegaGRAY", versionTag: "v3.1.5")
14+
15+
"""Microgray | UCUM: uGy"""
16+
MICROGRAY @reference(uri: "http://qudt.org/vocab/unit/MicroGRAY", versionTag: "v3.1.5")
17+
18+
"""Milligray | UCUM: mGy"""
19+
MILLIGRAY @reference(uri: "http://qudt.org/vocab/unit/MilliGRAY", versionTag: "v3.1.5")
20+
21+
"""Millirad"""
22+
MILLIRAD_R @reference(uri: "http://qudt.org/vocab/unit/MilliRAD_R", versionTag: "v3.1.5")
23+
24+
"""Nanogray"""
25+
NANOGRAY @reference(uri: "http://qudt.org/vocab/unit/NanoGRAY", versionTag: "v3.1.5")
26+
27+
"""Rad | UCUM: RAD"""
28+
RAD_R @reference(uri: "http://qudt.org/vocab/unit/RAD_R", versionTag: "v3.1.5")
29+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Generated from QUDT units catalog version 3.1.5
2+
enum AbsorptanceUnitEnum @reference(uri: "http://qudt.org/vocab/quantitykind/Absorptance", versionTag: "v3.1.5") {
3+
"""Unitless"""
4+
UNITLESS @reference(uri: "http://qudt.org/vocab/unit/UNITLESS", versionTag: "v3.1.5")
5+
}

0 commit comments

Comments
 (0)