Skip to content

PNE-6482 Support default_labels in MaterialRun constructor #989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 27, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/citrine/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "3.17.0"
__version__ = "3.18.0"
32 changes: 30 additions & 2 deletions src/citrine/resources/material_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from citrine._serialization.properties import String, LinkOrElse
from citrine._utils.functions import format_escaped_url
from citrine.resources.data_concepts import _make_link_by_uid
from citrine.resources.data_concepts import CITRINE_TAG_PREFIX
from citrine.resources.material_spec import MaterialSpecCollection
from citrine.resources.object_runs import ObjectRun, ObjectRunCollection
from gemd.entity.file_link import FileLink
Expand Down Expand Up @@ -49,6 +50,16 @@ class MaterialRun(
The material specification of which this is an instance.
file_links: List[FileLink], optional
Links to associated files, with resource paths into the files API.
default_labels: List[str], optional
An optional set of default labels to apply to this material run.
Default labels are used to:
- Populate labels on the ingredient run, if none are explicitly
specified, when the material run is later used as an ingredient
- Marking the material run as a potential replacement ingredient for a
particular label when generating new candidates using a
design space. Note that during design, default labels are only applicable
if the material run has no associated ingredient run within the
training set in question.

"""

Expand All @@ -74,12 +85,14 @@ def __init__(self,
process: Optional[GEMDProcessRun] = None,
sample_type: Optional[str] = "unknown",
spec: Optional[GEMDMaterialSpec] = None,
file_links: Optional[List[FileLink]] = None):
file_links: Optional[List[FileLink]] = None,
default_labels: Optional[List[str]] = None):
if uids is None:
uids = dict()
all_tags = _inject_default_label_tags(tags, default_labels)
super(ObjectRun, self).__init__()
GEMDMaterialRun.__init__(self, name=name, uids=uids,
tags=tags, process=process,
tags=all_tags, process=process,
sample_type=sample_type, spec=spec,
file_links=file_links, notes=notes)

Expand Down Expand Up @@ -216,3 +229,18 @@ def list_by_template(self,
specs = spec_collection.list_by_template(uid=_make_link_by_uid(uid))
return (run for runs in (self.list_by_spec(spec) for spec in specs)
for run in runs)


_CITRINE_DEFAULT_LABEL_PREFIX = f'{CITRINE_TAG_PREFIX}::mat_label'


def _inject_default_label_tags(
original_tags: Optional[List[str]],
default_labels: Optional[List[str]]) -> List[str]:
all_tags: List[str] = []
if original_tags is not None:
all_tags.extend(original_tags)
if default_labels is not None:
all_tags.extend([f"{_CITRINE_DEFAULT_LABEL_PREFIX}::{label}"
for label in default_labels])
return all_tags
15 changes: 15 additions & 0 deletions tests/resources/test_material_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from citrine.resources.data_concepts import CITRINE_SCOPE
from citrine.resources.material_run import MaterialRunCollection
from citrine.resources.material_run import MaterialRun as CitrineRun
from citrine.resources.material_run import _inject_default_label_tags
from citrine.resources.gemd_resource import GEMDResourceCollection

from gemd.demo.cake import make_cake, change_scope
Expand Down Expand Up @@ -53,6 +54,20 @@ def test_invalid_collection_construction():
mr = MaterialRunCollection(dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'),
session=session)

def test_inject_default_label_tags():
original_tags = ["alpha", "beta", "gamma"]
default_labels = ["label 0", "label 1"]
all_tags = _inject_default_label_tags(original_tags, default_labels)
expected = [
"alpha",
"beta",
"gamma",
"citr_auto::mat_label::label 0",
"citr_auto::mat_label::label 1"
]
assert set(all_tags) == set(expected)


def test_register_material_run(collection, session):
# Given
session.set_response(MaterialRunDataFactory(name='Test MR 123'))
Expand Down
3 changes: 3 additions & 0 deletions tests/utils/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,9 @@ class Meta:
sample_type = factory.Faker("enum", enum_cls=SampleType)
spec = factory.SubFactory(LinkByUIDFactory)
file_links = factory.List([factory.SubFactory(FileLinkFactory)])
default_labels = factory.List(
[factory.Faker("color_name"), factory.Faker("color_name")]
)


class LinkByUIDDataFactory(factory.DictFactory):
Expand Down
Loading