Skip to content

Commit f98c68c

Browse files
authored
Merge pull request #989 from CitrineInformatics/task/pne-6482-default-labels
PNE-6482 Support `default_labels` in MaterialRun constructor
2 parents e1090a5 + 4d9caff commit f98c68c

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

src/citrine/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.17.0"
1+
__version__ = "3.18.0"

src/citrine/resources/material_run.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from citrine._serialization.properties import String, LinkOrElse
88
from citrine._utils.functions import format_escaped_url
99
from citrine.resources.data_concepts import _make_link_by_uid
10+
from citrine.resources.data_concepts import CITRINE_TAG_PREFIX
1011
from citrine.resources.material_spec import MaterialSpecCollection
1112
from citrine.resources.object_runs import ObjectRun, ObjectRunCollection
1213
from gemd.entity.file_link import FileLink
@@ -49,6 +50,16 @@ class MaterialRun(
4950
The material specification of which this is an instance.
5051
file_links: List[FileLink], optional
5152
Links to associated files, with resource paths into the files API.
53+
default_labels: List[str], optional
54+
An optional set of default labels to apply to this material run.
55+
Default labels are used to:
56+
- Populate labels on the ingredient run, if none are explicitly
57+
specified, when the material run is later used as an ingredient
58+
- Marking the material run as a potential replacement ingredient for a
59+
particular label when generating new candidates using a
60+
design space. Note that during design, default labels are only applicable
61+
if the material run has no associated ingredient run within the
62+
training set in question.
5263
5364
"""
5465

@@ -74,12 +85,14 @@ def __init__(self,
7485
process: Optional[GEMDProcessRun] = None,
7586
sample_type: Optional[str] = "unknown",
7687
spec: Optional[GEMDMaterialSpec] = None,
77-
file_links: Optional[List[FileLink]] = None):
88+
file_links: Optional[List[FileLink]] = None,
89+
default_labels: Optional[List[str]] = None):
7890
if uids is None:
7991
uids = dict()
92+
all_tags = _inject_default_label_tags(tags, default_labels)
8093
super(ObjectRun, self).__init__()
8194
GEMDMaterialRun.__init__(self, name=name, uids=uids,
82-
tags=tags, process=process,
95+
tags=all_tags, process=process,
8396
sample_type=sample_type, spec=spec,
8497
file_links=file_links, notes=notes)
8598

@@ -216,3 +229,22 @@ def list_by_template(self,
216229
specs = spec_collection.list_by_template(uid=_make_link_by_uid(uid))
217230
return (run for runs in (self.list_by_spec(spec) for spec in specs)
218231
for run in runs)
232+
233+
234+
_CITRINE_DEFAULT_LABEL_PREFIX = f'{CITRINE_TAG_PREFIX}::mat_label'
235+
236+
237+
def _inject_default_label_tags(
238+
original_tags: Optional[List[str]], default_labels: Optional[List[str]]
239+
) -> Optional[List[str]]:
240+
if default_labels is None:
241+
all_tags = original_tags
242+
else:
243+
labels_as_tags = [
244+
f"{_CITRINE_DEFAULT_LABEL_PREFIX}::{label}" for label in default_labels
245+
]
246+
if original_tags is None:
247+
all_tags = labels_as_tags
248+
else:
249+
all_tags = list(original_tags) + labels_as_tags
250+
return all_tags

tests/resources/test_material_run.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from citrine.resources.data_concepts import CITRINE_SCOPE
1010
from citrine.resources.material_run import MaterialRunCollection
1111
from citrine.resources.material_run import MaterialRun as CitrineRun
12+
from citrine.resources.material_run import _inject_default_label_tags
1213
from citrine.resources.gemd_resource import GEMDResourceCollection
1314

1415
from gemd.demo.cake import make_cake, change_scope
@@ -53,6 +54,44 @@ def test_invalid_collection_construction():
5354
mr = MaterialRunCollection(dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'),
5455
session=session)
5556

57+
58+
@pytest.mark.parametrize(
59+
"original_tags, default_labels, expected",
60+
[
61+
(None, None, None),
62+
(None, [], []),
63+
([], None, []),
64+
([], [], []),
65+
(
66+
None,
67+
["label 0", "label 1"],
68+
["citr_auto::mat_label::label 0", "citr_auto::mat_label::label 1"],
69+
),
70+
(
71+
[],
72+
["label 0", "label 1"],
73+
["citr_auto::mat_label::label 0", "citr_auto::mat_label::label 1"],
74+
),
75+
(["alpha", "beta", "gamma"], None, ["alpha", "beta", "gamma"]),
76+
(["alpha", "beta", "gamma"], [], ["alpha", "beta", "gamma"]),
77+
(
78+
["alpha", "beta", "gamma"],
79+
["label 0", "label 1"],
80+
[
81+
"alpha",
82+
"beta",
83+
"gamma",
84+
"citr_auto::mat_label::label 0",
85+
"citr_auto::mat_label::label 1",
86+
],
87+
),
88+
],
89+
)
90+
def test_inject_default_label_tags(original_tags, default_labels, expected):
91+
result = _inject_default_label_tags(original_tags, default_labels)
92+
assert result == expected
93+
94+
5695
def test_register_material_run(collection, session):
5796
# Given
5897
session.set_response(MaterialRunDataFactory(name='Test MR 123'))

0 commit comments

Comments
 (0)