Skip to content

Commit 4dcd838

Browse files
Merge pull request #78 from ber-data/datetime_attr_value
DateTimeValue and some attr/value reorganisation
2 parents 4ee7dfd + d583b5f commit 4dcd838

File tree

3 files changed

+129
-127
lines changed

3 files changed

+129
-127
lines changed

src/schema/datamodel/bertron_schema_pydantic.py

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ class AttributeValue(ConfiguredBaseModel):
156156
'from_schema': 'https://w3id.org/ber-data/bertron_types'})
157157

158158
attribute: Attribute = Field(default=..., description="""The attribute being represented.""", json_schema_extra = { "linkml_meta": {'alias': 'attribute', 'domain_of': ['AttributeValue']} })
159-
raw_value: Optional[str] = Field(default=None, description="""The raw value.""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value', 'domain_of': ['AttributeValue', 'NamedQuantityValue']} })
159+
raw_value: Optional[str] = Field(default=None, description="""The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value',
160+
'domain_of': ['AttributeValue'],
161+
'mappings': ['nmdc:raw_value']} })
160162

161163

162164
class Attribute(ConfiguredBaseModel):
@@ -173,63 +175,35 @@ class Attribute(ConfiguredBaseModel):
173175

174176
class QuantityValue(AttributeValue):
175177
"""
176-
A simple quantity, e.g. 2cm
178+
A simple quantity, e.g. 2cm.
177179
"""
178180
linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'class_uri': 'nmdc:QuantityValue',
179181
'from_schema': 'https://w3id.org/ber-data/bertron_types',
180182
'mappings': ['schema:QuantityValue'],
181-
'slot_usage': {'numeric_value': {'description': 'The number part of the '
182-
'quantity',
183-
'name': 'numeric_value'},
184-
'raw_value': {'description': 'Unnormalized atomic string '
183+
'slot_usage': {'raw_value': {'description': 'Unnormalized atomic string '
185184
'representation, suggested syntax '
186185
'{number} {unit}',
187-
'name': 'raw_value'},
188-
'unit': {'description': 'The unit of the quantity',
189-
'name': 'unit'}}})
186+
'name': 'raw_value'}}})
190187

191188
maximum_numeric_value: Optional[float] = Field(default=None, description="""The maximum value part, expressed as number, of the quantity value when the value covers a range.""", json_schema_extra = { "linkml_meta": {'alias': 'maximum_numeric_value',
192-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
189+
'domain_of': ['QuantityValue'],
193190
'is_a': 'numeric_value',
194191
'mappings': ['nmdc:maximum_numeric_value']} })
195192
minimum_numeric_value: Optional[float] = Field(default=None, description="""The minimum value part, expressed as number, of the quantity value when the value covers a range.""", json_schema_extra = { "linkml_meta": {'alias': 'minimum_numeric_value',
196-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
193+
'domain_of': ['QuantityValue'],
197194
'is_a': 'numeric_value',
198195
'mappings': ['nmdc:minimum_numeric_value']} })
199-
numeric_value: Optional[float] = Field(default=None, description="""The number part of the quantity""", json_schema_extra = { "linkml_meta": {'alias': 'numeric_value',
200-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
201-
'mappings': ['nmdc:numeric_value', 'qud:quantityValue', 'schema:value']} })
202-
unit: Optional[str] = Field(default=None, description="""The unit of the quantity""", json_schema_extra = { "linkml_meta": {'alias': 'unit',
203-
'aliases': ['scale'],
204-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
205-
'mappings': ['nmdc:unit', 'qud:unit', 'schema:unitCode']} })
206-
attribute: Attribute = Field(default=..., description="""The attribute being represented.""", json_schema_extra = { "linkml_meta": {'alias': 'attribute', 'domain_of': ['AttributeValue']} })
207-
raw_value: Optional[str] = Field(default=None, description="""Unnormalized atomic string representation, suggested syntax {number} {unit}""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value', 'domain_of': ['AttributeValue', 'NamedQuantityValue']} })
208-
209-
210-
class NamedQuantityValue(ConfiguredBaseModel):
211-
"""
212-
A quantity value where the attribute is already specified.
213-
"""
214-
linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'from_schema': 'https://w3id.org/ber-data/bertron_types'})
215-
216-
maximum_numeric_value: Optional[float] = Field(default=None, description="""The maximum value part, expressed as number, of the quantity value when the value covers a range.""", json_schema_extra = { "linkml_meta": {'alias': 'maximum_numeric_value',
217-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
218-
'is_a': 'numeric_value',
219-
'mappings': ['nmdc:maximum_numeric_value']} })
220-
minimum_numeric_value: Optional[float] = Field(default=None, description="""The minimum value part, expressed as number, of the quantity value when the value covers a range.""", json_schema_extra = { "linkml_meta": {'alias': 'minimum_numeric_value',
221-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
222-
'is_a': 'numeric_value',
223-
'mappings': ['nmdc:minimum_numeric_value']} })
224-
numeric_value: Optional[float] = Field(default=None, description="""Links a quantity value to a number""", json_schema_extra = { "linkml_meta": {'alias': 'numeric_value',
225-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
196+
numeric_value: Optional[float] = Field(default=None, description="""The numerical part of a quantity value.""", json_schema_extra = { "linkml_meta": {'alias': 'numeric_value',
197+
'domain_of': ['QuantityValue'],
226198
'mappings': ['nmdc:numeric_value', 'qud:quantityValue', 'schema:value']} })
227199
unit: Optional[str] = Field(default=None, description="""Links a QuantityValue to a unit. Units should be taken from the UCUM unit collection or the Unit Ontology.""", json_schema_extra = { "linkml_meta": {'alias': 'unit',
228200
'aliases': ['scale'],
229-
'domain_of': ['QuantityValue', 'NamedQuantityValue'],
230-
'mappings': ['nmdc:unit', 'qud:unit', 'schema:unitCode']} })
231-
raw_value: Optional[str] = Field(default=None, description="""The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value',
232-
'domain_of': ['AttributeValue', 'NamedQuantityValue'],
201+
'domain_of': ['QuantityValue'],
202+
'mappings': ['nmdc:unit', 'qud:unit', 'schema:unitCode', 'UO:0000000']} })
203+
unit_cv_id: Optional[str] = Field(default=None, description="""The unit of the quantity, expressed as a CURIE from the Unit Ontology.""", json_schema_extra = { "linkml_meta": {'alias': 'unit_cv_id', 'domain_of': ['QuantityValue']} })
204+
attribute: Attribute = Field(default=..., description="""The attribute being represented.""", json_schema_extra = { "linkml_meta": {'alias': 'attribute', 'domain_of': ['AttributeValue']} })
205+
raw_value: Optional[str] = Field(default=None, description="""Unnormalized atomic string representation, suggested syntax {number} {unit}""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value',
206+
'domain_of': ['AttributeValue'],
233207
'mappings': ['nmdc:raw_value']} })
234208

235209

@@ -240,10 +214,38 @@ class TextValue(AttributeValue):
240214
linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'class_uri': 'nmdc:TextValue',
241215
'from_schema': 'https://w3id.org/ber-data/bertron_types'})
242216

243-
value: Optional[str] = Field(default=None, description="""The value, as a text string.""", json_schema_extra = { "linkml_meta": {'alias': 'value', 'domain_of': ['TextValue']} })
217+
value: Optional[str] = Field(default=None, description="""The value, as a text string.""", json_schema_extra = { "linkml_meta": {'alias': 'value', 'domain_of': ['TextValue', 'DateTimeValue']} })
244218
value_cv_id: Optional[str] = Field(default=None, description="""For values that are in a controlled vocabulary (CV), this attribute should capture the controlled vocabulary ID for the value.""", json_schema_extra = { "linkml_meta": {'alias': 'value_cv_id', 'domain_of': ['TextValue']} })
245219
attribute: Attribute = Field(default=..., description="""The attribute being represented.""", json_schema_extra = { "linkml_meta": {'alias': 'attribute', 'domain_of': ['AttributeValue']} })
246-
raw_value: Optional[str] = Field(default=None, description="""The raw value.""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value', 'domain_of': ['AttributeValue', 'NamedQuantityValue']} })
220+
raw_value: Optional[str] = Field(default=None, description="""The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value',
221+
'domain_of': ['AttributeValue'],
222+
'mappings': ['nmdc:raw_value']} })
223+
224+
225+
class DateTimeValue(AttributeValue):
226+
"""
227+
A date or date and time value.
228+
"""
229+
linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'class_uri': 'nmdc:DateTimeValue',
230+
'from_schema': 'https://w3id.org/ber-data/bertron_types',
231+
'slot_usage': {'value': {'description': 'The date or date/time value, '
232+
'expressed in ISO 8601-compatible '
233+
'form. Dates should be expressed as '
234+
'YYYY-MM-DD; times should be '
235+
'expressed as HH:MM:SS with optional '
236+
'milliseconds and an indication of '
237+
'the timezone.',
238+
'examples': [{'value': '2025-11-09'},
239+
{'value': '2025-09-16T22:48:54Z'}],
240+
'name': 'value'}}})
241+
242+
value: Optional[str] = Field(default=None, description="""The date or date/time value, expressed in ISO 8601-compatible form. Dates should be expressed as YYYY-MM-DD; times should be expressed as HH:MM:SS with optional milliseconds and an indication of the timezone.""", json_schema_extra = { "linkml_meta": {'alias': 'value',
243+
'domain_of': ['TextValue', 'DateTimeValue'],
244+
'examples': [{'value': '2025-11-09'}, {'value': '2025-09-16T22:48:54Z'}]} })
245+
attribute: Attribute = Field(default=..., description="""The attribute being represented.""", json_schema_extra = { "linkml_meta": {'alias': 'attribute', 'domain_of': ['AttributeValue']} })
246+
raw_value: Optional[str] = Field(default=None, description="""The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"""", json_schema_extra = { "linkml_meta": {'alias': 'raw_value',
247+
'domain_of': ['AttributeValue'],
248+
'mappings': ['nmdc:raw_value']} })
247249

248250

249251
class Entity(ConfiguredBaseModel):
@@ -393,8 +395,8 @@ class DataCollection(ConfiguredBaseModel):
393395
AttributeValue.model_rebuild()
394396
Attribute.model_rebuild()
395397
QuantityValue.model_rebuild()
396-
NamedQuantityValue.model_rebuild()
397398
TextValue.model_rebuild()
399+
DateTimeValue.model_rebuild()
398400
Entity.model_rebuild()
399401
Coordinates.model_rebuild()
400402
Name.model_rebuild()

src/schema/jsonschema/bertron_schema.json

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,35 @@
122122
"title": "DataCollection",
123123
"type": "object"
124124
},
125+
"DateTimeValue": {
126+
"additionalProperties": false,
127+
"description": "A date or date and time value.",
128+
"properties": {
129+
"attribute": {
130+
"$ref": "#/$defs/Attribute",
131+
"description": "The attribute being represented."
132+
},
133+
"raw_value": {
134+
"description": "The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"",
135+
"type": [
136+
"string",
137+
"null"
138+
]
139+
},
140+
"value": {
141+
"description": "The date or date/time value, expressed in ISO 8601-compatible form. Dates should be expressed as YYYY-MM-DD; times should be expressed as HH:MM:SS with optional milliseconds and an indication of the timezone.",
142+
"type": [
143+
"string",
144+
"null"
145+
]
146+
}
147+
},
148+
"required": [
149+
"attribute"
150+
],
151+
"title": "DateTimeValue",
152+
"type": "object"
153+
},
125154
"Entity": {
126155
"additionalProperties": false,
127156
"description": "An object retrieved by BERtron from a BER data API.",
@@ -277,52 +306,9 @@
277306
"title": "NameType",
278307
"type": "string"
279308
},
280-
"NamedQuantityValue": {
281-
"additionalProperties": false,
282-
"description": "A quantity value where the attribute is already specified.",
283-
"properties": {
284-
"maximum_numeric_value": {
285-
"description": "The maximum value part, expressed as number, of the quantity value when the value covers a range.",
286-
"type": [
287-
"number",
288-
"null"
289-
]
290-
},
291-
"minimum_numeric_value": {
292-
"description": "The minimum value part, expressed as number, of the quantity value when the value covers a range.",
293-
"type": [
294-
"number",
295-
"null"
296-
]
297-
},
298-
"numeric_value": {
299-
"description": "Links a quantity value to a number",
300-
"type": [
301-
"number",
302-
"null"
303-
]
304-
},
305-
"raw_value": {
306-
"description": "The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"",
307-
"type": [
308-
"string",
309-
"null"
310-
]
311-
},
312-
"unit": {
313-
"description": "Links a QuantityValue to a unit. Units should be taken from the UCUM unit collection or the Unit Ontology.",
314-
"type": [
315-
"string",
316-
"null"
317-
]
318-
}
319-
},
320-
"title": "NamedQuantityValue",
321-
"type": "object"
322-
},
323309
"QuantityValue": {
324310
"additionalProperties": false,
325-
"description": "A simple quantity, e.g. 2cm",
311+
"description": "A simple quantity, e.g. 2cm.",
326312
"properties": {
327313
"attribute": {
328314
"$ref": "#/$defs/Attribute",
@@ -343,7 +329,7 @@
343329
]
344330
},
345331
"numeric_value": {
346-
"description": "The number part of the quantity",
332+
"description": "The numerical part of a quantity value.",
347333
"type": [
348334
"number",
349335
"null"
@@ -357,7 +343,14 @@
357343
]
358344
},
359345
"unit": {
360-
"description": "The unit of the quantity",
346+
"description": "Links a QuantityValue to a unit. Units should be taken from the UCUM unit collection or the Unit Ontology.",
347+
"type": [
348+
"string",
349+
"null"
350+
]
351+
},
352+
"unit_cv_id": {
353+
"description": "The unit of the quantity, expressed as a CURIE from the Unit Ontology.",
361354
"type": [
362355
"string",
363356
"null"
@@ -379,7 +372,7 @@
379372
"description": "The attribute being represented."
380373
},
381374
"raw_value": {
382-
"description": "The raw value.",
375+
"description": "The value that was specified for an annotation in raw form, i.e. a string. E.g. \"2 cm\" or \"2-4 cm\"",
383376
"type": [
384377
"string",
385378
"null"

src/schema/linkml/bertron_types.yaml

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ default_range: string
1515

1616
slots:
1717

18+
attribute:
19+
description: The attribute being represented.
20+
range: Attribute
21+
required: true
22+
1823
numeric_value:
19-
description: Links a quantity value to a number
24+
description: The numerical part of a quantity value.
2025
range: float
2126
mappings:
2227
- nmdc:numeric_value
@@ -45,11 +50,24 @@ slots:
4550
description: Links a QuantityValue to a unit. Units should be taken from the UCUM unit collection or the Unit Ontology.
4651
aliases:
4752
- scale
48-
range: unit
53+
range: string
4954
mappings:
5055
- nmdc:unit
5156
- qud:unit
5257
- schema:unitCode
58+
- UO:0000000
59+
60+
unit_cv_id:
61+
description: The unit of the quantity, expressed as a CURIE from the Unit Ontology.
62+
range: curie
63+
64+
value:
65+
description: The value, as a text string.
66+
range: string
67+
68+
value_cv_id:
69+
description: For values that are in a controlled vocabulary (CV), this attribute should capture the controlled vocabulary ID for the value.
70+
range: curie
5371

5472
classes:
5573

@@ -61,14 +79,9 @@ classes:
6179
class_uri: nmdc:AttributeValue
6280
description: >-
6381
The value for any value of attribute for an entity. This object can hold both the un-normalized atomic value and the structured value.
64-
attributes:
65-
attribute:
66-
description: The attribute being represented.
67-
range: Attribute
68-
required: true
69-
raw_value:
70-
range: string
71-
description: The raw value.
82+
slots:
83+
- attribute
84+
- raw_value
7285

7386
Attribute:
7487
description: A domain, measurement, attribute, property, or any descriptor for additional properties to be added to an entity. Where available, please use OBO Foundry ontologies or other controlled vocabularies for attributes; the label should be the term name from the ontology and the id should be the fully-qualified CURIE.
@@ -86,40 +99,41 @@ classes:
8699
QuantityValue:
87100
class_uri: nmdc:QuantityValue
88101
is_a: AttributeValue
89-
description: A simple quantity, e.g. 2cm
102+
description: A simple quantity, e.g. 2cm.
90103
slots:
91104
- maximum_numeric_value
92105
- minimum_numeric_value
93106
- numeric_value
94107
- unit
108+
- unit_cv_id
95109
slot_usage:
96110
raw_value:
97111
description: Unnormalized atomic string representation, suggested syntax {number} {unit}
98-
unit:
99-
description: The unit of the quantity
100-
numeric_value:
101-
description: The number part of the quantity
102112
mappings:
103113
- schema:QuantityValue
104114

105-
NamedQuantityValue:
106-
description: A quantity value where the attribute is already specified.
107-
slots:
108-
- maximum_numeric_value
109-
- minimum_numeric_value
110-
- numeric_value
111-
- unit
112-
- raw_value
113-
114115
TextValue:
115116
class_uri: nmdc:TextValue
116117
is_a: AttributeValue
117118
description: A quality, described using a text string.
118-
attributes:
119+
slots:
120+
- value
121+
- value_cv_id
122+
123+
DateTimeValue:
124+
class_uri: nmdc:DateTimeValue
125+
is_a: AttributeValue
126+
description: A date or date and time value.
127+
slots:
128+
- value
129+
slot_usage:
119130
value:
120-
description: The value, as a text string.
121-
value_cv_id:
122-
description: For values that are in a controlled vocabulary (CV), this attribute should capture the controlled vocabulary ID for the value.
131+
description: The date or date/time value, expressed in ISO 8601-compatible form. Dates should be expressed as YYYY-MM-DD; times should be expressed as HH:MM:SS with optional milliseconds and an indication of the timezone.
132+
# TODO: add pattern for ISO 8601 timestamps
133+
examples:
134+
- value: "2025-11-09"
135+
- value: "2025-09-16T22:48:54Z"
136+
123137

124138
types:
125139
decimal degree:
@@ -128,10 +142,3 @@ types:
128142
base: float
129143
see_also:
130144
- https://en.wikipedia.org/wiki/Decimal_degrees
131-
132-
unit:
133-
base: str
134-
uri: xsd:string
135-
mappings:
136-
- qud:Unit
137-
- UO:0000000

0 commit comments

Comments
 (0)