Skip to content

Commit 8207261

Browse files
authored
Merge pull request #1025 from CitrineInformatics/hds-docs
HDS Doc updates
2 parents 0010a6d + 168809c commit 8207261

1 file changed

Lines changed: 164 additions & 0 deletions

File tree

docs/source/workflows/design_spaces.rst

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,170 @@ The enumerated design space defined in this way might product the following cand
123123
Hierarchical Design Space
124124
-------------------------
125125

126+
A :class:`~citrine.informatics.design_spaces.hierarchical_design_space.HierarchicalDesignSpace` produces candidates that represent full material histories.
127+
Unlike a :class:`~citrine.informatics.design_spaces.product_design_space.ProductDesignSpace`, which produces flat candidates with composition represented only by raw ingredients, a hierarchical design space generates candidates with a tree structure: a terminal (root) material connected to sub-materials through formulation ingredients.
128+
129+
The design space is defined by a **root** node and zero or more **subspace** nodes, each represented by a :class:`~citrine.informatics.design_spaces.hierarchical_design_space.MaterialNodeDefinition`.
130+
The root node defines the attributes and formulation contents of the terminal material in each candidate.
131+
Subspaces define any new materials that appear in the history of the terminal material.
132+
133+
Commonly, each node in a hierarchical design space contains a :class:`~citrine.informatics.design_spaces.formulation_design_space.FormulationDesignSpace` as its ``formulation_subspace``, which defines the ingredients, labels, and constraints for that level of the material history.
134+
See `Formulation Design Space <#formulation-design-space>`__ below for details on configuring formulation subspaces.
135+
136+
Nodes are connected through formulation ingredient names.
137+
If the root node contains a formulation subspace with an ingredient named ``"New Mixture-001"``, and a sub-node has its ``name`` set to ``"New Mixture-001"``, the resulting candidate will include that sub-node's material as an ingredient in the root material's formulation.
138+
This linking can be extended to sub-nodes referencing other sub-nodes, allowing arbitrarily deep material history shapes.
139+
140+
Material Node Definitions
141+
~~~~~~~~~~~~~~~~~~~~~~~~~
142+
143+
Each :class:`~citrine.informatics.design_spaces.hierarchical_design_space.MaterialNodeDefinition` describes a single node in the material history and has the following fields:
144+
145+
- ``name``: A unique identifier used to reference materials produced by this node.
146+
When a formulation subspace on another node includes this name as an ingredient, the nodes become linked in the resulting candidate.
147+
- ``attributes``: A list of :class:`~citrine.informatics.dimensions.Dimension` objects defining the processing parameters on the materials produced by this node.
148+
These dimensions are explored independently during Candidate Generation.
149+
- ``formulation_subspace``: An optional :class:`~citrine.informatics.design_spaces.formulation_design_space.FormulationDesignSpace` defining the ingredients, labels, and constraints for formulations on materials produced by this node.
150+
- ``template_link``: An optional :class:`~citrine.informatics.design_spaces.hierarchical_design_space.TemplateLink` linking the node to material and process templates on the Citrine Platform.
151+
- ``scope``: An optional custom scope used to identify the materials produced by this node.
152+
- ``display_name``: An optional display name for identifying the node on the Citrine Platform (does not appear in generated candidates).
153+
154+
Template Links
155+
~~~~~~~~~~~~~~
156+
157+
A :class:`~citrine.informatics.design_spaces.hierarchical_design_space.TemplateLink` associates a node with on-platform material and process templates via their UUIDs.
158+
Template names can optionally be provided for readability.
159+
160+
Data Sources
161+
~~~~~~~~~~~~
162+
163+
:class:`~citrine.informatics.data_sources.DataSource` objects can be included on the design space to allow design over "known" materials.
164+
When constructing candidates, the Citrine Platform looks up ingredient names from formulation subspaces in the provided data sources and injects their composition and properties into the material history.
165+
When constructing a default hierarchical design space, the platform includes any data sources found on the associated predictor configuration.
166+
167+
See our documentation on :doc:`Data Sources <data_sources>` for more information.
168+
169+
Creating a Hierarchical Design Space
170+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171+
172+
The easiest way to build a hierarchical design space is to use :func:`~citrine.resources.design_space.DesignSpaceCollection.create_default` with ``mode=DefaultDesignSpaceMode.HIERARCHICAL``.
173+
This inspects the predictor's training data to infer the material history shape and automatically constructs the root node, sub-nodes, dimensions, and formulation subspaces:
174+
175+
.. code:: python
176+
177+
from citrine.informatics.design_spaces import DefaultDesignSpaceMode
178+
179+
design_space = project.design_spaces.create_default(
180+
predictor_id=predictor_id,
181+
predictor_version=predictor_version,
182+
mode=DefaultDesignSpaceMode.HIERARCHICAL,
183+
)
184+
185+
registered_design_space = project.design_spaces.register(design_space)
186+
187+
If you already have a registered :class:`~citrine.informatics.design_spaces.product_design_space.ProductDesignSpace`, you can convert it into an equivalent hierarchical design space using :func:`~citrine.resources.design_space.DesignSpaceCollection.convert_to_hierarchical`:
188+
189+
.. code:: python
190+
191+
hierarchical_ds = project.design_spaces.convert_to_hierarchical(
192+
product_design_space.uid,
193+
predictor_id=predictor_id,
194+
predictor_version=predictor_version,
195+
)
196+
197+
registered_design_space = project.design_spaces.register(hierarchical_ds)
198+
199+
Manual Construction Example
200+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
201+
202+
The following example creates a hierarchical design space for a coating material manually.
203+
The root node represents the final coating, which is a formulation of a binder and a pigment mixture.
204+
The pigment mixture is defined as a sub-node with its own formulation and a processing temperature attribute.
205+
206+
.. code:: python
207+
208+
from citrine.informatics.constraints import IngredientCountConstraint
209+
from citrine.informatics.data_sources import GemTableDataSource
210+
from citrine.informatics.descriptors import FormulationDescriptor, RealDescriptor
211+
from citrine.informatics.design_spaces import (
212+
FormulationDesignSpace,
213+
HierarchicalDesignSpace,
214+
)
215+
from citrine.informatics.design_spaces.hierarchical_design_space import (
216+
MaterialNodeDefinition,
217+
)
218+
from citrine.informatics.dimensions import ContinuousDimension
219+
220+
# Define the formulation descriptor used across the design space
221+
formulation_descriptor = FormulationDescriptor.hierarchical()
222+
223+
# --- Sub-node: Pigment Mixture ---
224+
# This node defines a mixture of two pigments with a processing temperature.
225+
pigment_formulation = FormulationDesignSpace(
226+
name="Pigment blend",
227+
description="Blend of pigment A and pigment B",
228+
formulation_descriptor=formulation_descriptor,
229+
ingredients={"Pigment A", "Pigment B"},
230+
labels={"pigment": {"Pigment A", "Pigment B"}},
231+
constraints={
232+
IngredientCountConstraint(
233+
formulation_descriptor=formulation_descriptor, min=2, max=2
234+
)
235+
},
236+
)
237+
238+
temp_descriptor = RealDescriptor(
239+
key="Mixing Temperature", lower_bound=273, upper_bound=500, units="K"
240+
)
241+
temp_dimension = ContinuousDimension(
242+
descriptor=temp_descriptor, lower_bound=300, upper_bound=400
243+
)
244+
245+
pigment_node = MaterialNodeDefinition(
246+
name="Pigment Mixture",
247+
attributes=[temp_dimension],
248+
formulation_subspace=pigment_formulation,
249+
display_name="Pigment Mixture",
250+
)
251+
252+
# --- Root node: Final Coating ---
253+
# The coating is a formulation of a binder and the pigment mixture defined above.
254+
# The ingredient name "Pigment Mixture" matches the sub-node's name,
255+
# which links them in the resulting candidates.
256+
coating_formulation = FormulationDesignSpace(
257+
name="Coating formulation",
258+
description="Binder plus pigment mixture",
259+
formulation_descriptor=formulation_descriptor,
260+
ingredients={"Binder", "Pigment Mixture"},
261+
labels={"resin": {"Binder"}, "filler": {"Pigment Mixture"}},
262+
constraints={
263+
IngredientCountConstraint(
264+
formulation_descriptor=formulation_descriptor, min=2, max=2
265+
)
266+
},
267+
)
268+
269+
root_node = MaterialNodeDefinition(
270+
name="Final Coating",
271+
formulation_subspace=coating_formulation,
272+
display_name="Final Coating",
273+
)
274+
275+
# --- Assemble the hierarchical design space ---
276+
design_space = HierarchicalDesignSpace(
277+
name="Coating design space",
278+
description="Designs coatings from binder and a pigment mixture",
279+
root=root_node,
280+
subspaces=[pigment_node],
281+
data_sources=[
282+
GemTableDataSource(table_id=table_id, table_version=table_version)
283+
],
284+
)
285+
286+
registered_design_space = project.design_spaces.register(design_space)
287+
288+
In this example, each candidate produced by the design space will contain a terminal coating material whose formulation includes a "Binder" (resolved from the data source) and a "Pigment Mixture" (a newly designed material with its own formulation and mixing temperature).
289+
126290
Data Source Design Space
127291
------------------------
128292

0 commit comments

Comments
 (0)