|
| 1 | +# Chemical entities |
| 2 | + |
| 3 | +The Chemical Entities AP module ([chemical_entities_ap.yaml](schema/chemical_entities_ap.yaml)) imports the Material Entities AP module and thus adds chemical identity to the material entity layer. It allows describing chemical substances as material things that are mixable, soluble and most importantly composed of certain chemical structures. |
| 4 | + |
| 5 | +## Design Pattern |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## ChemicalEntity |
| 11 | + |
| 12 | +The `ChemicalEntity` shape is mapped to `CHEBI:23367` (labeled _molecular entity_ in CHEBI; aliased as such in the schema) and extends `Entity` from DCAT-AP+, **not** `MaterialEntity`. It was labeled `ChemicalEntity` because chemists often find CHEBI's label misleading as it suggests only molecules, excluding ions, radicals, complexes, and conformers that are all in scope of `CHEBI:23367`. |
| 13 | + |
| 14 | +!!! note "Why ChemicalEntity extends Entity, not MaterialEntity" |
| 15 | + Ontologically, a CHEBI chemical entity *is* a BFO material entity, and a reasoner can infer this from the ontology axioms. But ChemDCAT-AP is a shape specification, not an ontology. If `ChemicalEntity` extended `MaterialEntity`, it would inherit the `MaterialisticMixin` slots (`has_temperature`, `has_mass`, `has_volume`, `has_density`, `has_pressure`, `has_physical_state`) via LinkML's `is_a` inheritance. These physical property slots do not make sense at the molecular level (an individual molecule does not have a temperature or a density) and would confuse schema users into thinking they should populate them. Extending `Entity` directly avoids this: molecular-level classes get only the slots they need (structure descriptors), while macroscopic substance classes get physical properties through the `ChemicalSubstanceMixin` applied to `MaterialEntity` subclasses. |
| 16 | + |
| 17 | +### Structure descriptor slots |
| 18 | + |
| 19 | +`ChemicalEntity` introduces six slots for chemical identity, all sub-slots of the DCAT-AP+ `has_qualitative_attribute` or `has_quantitative_attribute`: |
| 20 | + |
| 21 | +| Slot | Range class | class_uri | What it captures | |
| 22 | +|---------------------|--------------------|------------------|----------------------------| |
| 23 | +| `inchi` | `InChi` | `CHEMINF:000113` | InChI structure descriptor | |
| 24 | +| `inchikey` | `InChIKey` | `CHEMINF:000059` | InChI key descriptor | |
| 25 | +| `smiles` | `SMILES` | `CHEMINF:000018` | SMILES line notation | |
| 26 | +| `molecular_formula` | `MolecularFormula` | `CHEMINF:000042` | Hill system formula | |
| 27 | +| `iupac_name` | `IUPACName` | `CHEMINF:000107` | Systematic IUPAC name | |
| 28 | +| `has_molar_mass` | `MolarMass` | `AFR:0002409` | Molar mass quantity | |
| 29 | + |
| 30 | +The first five are `QualitativeAttribute` subclasses (string-valued descriptors); `MolarMass` is a `QuantitativeAttribute` subclass (numeric-valued with unit). All use `slot_uri: SIO:000008` (has attribute). All descriptor slots are `recommended: true`, meaning they should be provided when available but are not required for validation. |
| 31 | + |
| 32 | +!!! tip "Use dedicated slots, not generic `has_qualitative_attribute`" |
| 33 | + ChemDCAT-AP defines `inchi`, `smiles`, etc. as dedicated sub-slots with typed ranges. Use these instead of the generic `has_qualitative_attribute` with a `rdf_type` classification. The dedicated slots produce more explicit instance data, enable tighter validation, and are easier to query. |
| 34 | + |
| 35 | +### Compositional structure |
| 36 | + |
| 37 | +`ChemicalEntity` overrides `has_part` (inherited from `Entity`) to constrain its range to `ChemicalEntity` and its mapping is changed to `BFO:0000051`. This enables recursive molecular composition: a complex can declare its ligands as parts, each with their own structure descriptors. |
| 38 | + |
| 39 | +## ChemicalSubstanceMixin |
| 40 | + |
| 41 | +An abstract mixin that extends `MaterialisticMixin` with chemistry-specific substance properties. It is applied to `MaterialEntity` subclasses that represent macroscopic chemical substances. |
| 42 | + |
| 43 | +| Slot | Range | Inherited from | |
| 44 | +|---|---|---| |
| 45 | +| `has_concentration` | `Concentration` | ChemicalSubstanceMixin | |
| 46 | +| `has_ph_value` | `PHValue` | ChemicalSubstanceMixin | |
| 47 | +| `has_amount` | `AmountOfSubstance` | ChemicalSubstanceMixin | |
| 48 | +| `composed_of` | `ChemicalEntity[]` | ChemicalSubstanceMixin | |
| 49 | +| `has_temperature` | `Temperature` | MaterialisticMixin | |
| 50 | +| `has_mass` | `Mass` | MaterialisticMixin | |
| 51 | +| `has_volume` | `Volume` | MaterialisticMixin | |
| 52 | +| `has_density` | `Density` | MaterialisticMixin | |
| 53 | +| `has_pressure` | `Pressure` | MaterialisticMixin | |
| 54 | +| `has_physical_state` | `PhysicalStateEnum` | MaterialisticMixin | |
| 55 | +| `alternative_label` | `string` | MaterialisticMixin | |
| 56 | + |
| 57 | +The `composed_of` slot (a sub-slot of `has_part`, mapped to `BFO:0000051`) links a substance to its constituent `ChemicalEntity` instances. This is the bridge between the macroscopic substance and the molecular-level identity. |
| 58 | + |
| 59 | +### Chemistry-specific attribute classes |
| 60 | + |
| 61 | +| Class | class_uri | Parent | Mappings | |
| 62 | +|---|---|---|---| |
| 63 | +| `Concentration` | `CHMO:0002820` | `QuantitativeAttribute` | exact: `EDAM:2140`, `NCIT:C41185`, `VOC4CAT:0007244`, `AFR:0002036` | |
| 64 | +| `AmountOfSubstance` | `qudt:Quantity` | `QuantitativeAttribute` | close: `PATO:0000070` | |
| 65 | +| `PHValue` | `SIO:001089` | `QuantitativeAttribute` | exact: `NCIT:C45997`, `AFR:0001142` | |
| 66 | + |
| 67 | +These follow the DCAT-AP+ [QuantitativeAttribute pattern](https://nfdi-de.github.io/dcat-ap-plus/latest/design-patterns/#quantitativeattribute). Each narrows the semantic intent while preserving the structural `value` + `has_quantity_type` + `unit` shape. |
| 68 | + |
| 69 | +!!! warning "Enum bindings for `has_quantity_type` and `unit` are still experimental" |
| 70 | + The schema declares bindings that constrain `has_quantity_type` and `unit` values to QUDT QuantityKind and Unit vocabularies respectively. These bindings are not enforced by `linkml-validate`. They will be validated using the [linkml-term-validator](https://linkml.io/linkml-term-validator/), which is meant to supports dynamic enums and binding validation. Yet, this still needs to be implemented in the ChemDCAT-AP pipeline. |
| 71 | + |
| 72 | +## SubstanceSample |
| 73 | + |
| 74 | +Mapped to `SIO:001378` (analyte), `SubstanceSample` extends `MaterialSample` (from `material_entities_ap`) and uses the `ChemicalSubstanceMixin`. It is the central class for any evaluated chemical substance in ChemDCAT-AP. It combines three capabilities: |
| 75 | + |
| 76 | +- **Provenance linking** (via `EvaluatedEntity`): it is meant to be used as the range of `evaluated_entity` and `is_about_entity` in specializations of `DataGeneratingActivity` respectively `Dataset` (see [dataset and activity shapes](dataset-activity-shapes.md)). |
| 77 | +- **Physical properties** (via `MaterialisticMixin`, inherited through `ChemicalSubstanceMixin`): temperature, mass, volume, density, pressure, physical state. |
| 78 | +- **Chemical identity** (via `ChemicalSubstanceMixin`): `composed_of` linking to `ChemicalEntity` instances with structure descriptors, plus concentration, pH, and amount of substance. |
| 79 | + |
| 80 | +Use `SubstanceSample` whenever your data describes a chemical substance that was the subject of a measurement or analysis. This covers NMR samples, catalysis test substances, reaction aliquots, and any other analytically characterized chemical material. For substances that participate in a reaction but are not themselves the evaluated subject, use the reaction participant classes (`StartingMaterial`, `Reagent`, etc.) instead. |
| 81 | + |
| 82 | +### Example: a SubstanceSample with chemical identity |
| 83 | + |
| 84 | +From the test dataset, a Chemotion Repository compound: |
| 85 | + |
| 86 | +```yaml |
| 87 | +id: https://dx.doi.org/10.14272/UGRXAOUDHZOHPF-UHFFFAOYSA-N.2 |
| 88 | +title: "CRS-50440" |
| 89 | +rdf_type: |
| 90 | + id: CHEBI:59999 |
| 91 | + title: "chemical substance" |
| 92 | +other_identifier: |
| 93 | + - notation: https://www.chemotion-repository.net/pid/50440 |
| 94 | +has_temperature: |
| 95 | + - rdf_type: |
| 96 | + id: NMR:1400025 |
| 97 | + title: "sample temperature in magnet" |
| 98 | + has_quantity_type: http://qudt.org/vocab/quantitykind/Temperature |
| 99 | + unit: https://qudt.org/vocab/unit/K |
| 100 | + value: 300.0 |
| 101 | +composed_of: |
| 102 | + - id: https://dx.doi.org/10.14272/UGRXAOUDHZOHPF-UHFFFAOYSA-N.2#EvaluatedCompound |
| 103 | + description: "compound assigned to the sample" |
| 104 | + other_identifier: |
| 105 | + - notation: https://pubchem.ncbi.nlm.nih.gov/compound/26248854 |
| 106 | + inchikey: |
| 107 | + - value: "UGRXAOUDHZOHPF-UHFFFAOYSA-N" |
| 108 | + title: "assigned InChiKey" |
| 109 | + inchi: |
| 110 | + - value: "InChI=1S/C11H12N2S/c1-12-7-10-8-14-11(13-10)9-5-3-2-4-6-9/h2-6,8,12H,7H2,1H3" |
| 111 | + title: "assigned InChi" |
| 112 | + smiles: |
| 113 | + - value: " CNCc1csc(n1)c1ccccc1" |
| 114 | + title: "assigned SMILES" |
| 115 | + molecular_formula: |
| 116 | + - value: "C11H12N2S" |
| 117 | + title: "assigned molecular formula" |
| 118 | + iupac_name: |
| 119 | + - value: "N-methyl-1-(2-phenyl-1,3-thiazol-4-yl)methanamine" |
| 120 | + description: Chemotion IUPAC name |
| 121 | + - value: "Methyl[(2-phenyl-1,3-thiazol-4-yl)methyl]amine" |
| 122 | + description: PubChem IUPAC name |
| 123 | + has_molar_mass: |
| 124 | + - has_quantity_type: http://qudt.org/vocab/quantitykind/MolarMass |
| 125 | + unit: https://qudt.org/vocab/unit/GM-PER-MOL |
| 126 | + value: 204.072119 |
| 127 | + description: Molar mass as specified in the Chemotion repository. |
| 128 | + - has_quantity_type: http://qudt.org/vocab/quantitykind/MolarMass |
| 129 | + unit: https://qudt.org/vocab/unit/GM-PER-MOL |
| 130 | + value: 204.29 |
| 131 | + description: Molar mass as specified in PubChem. |
| 132 | +``` |
| 133 | +
|
| 134 | +Key observations: |
| 135 | +
|
| 136 | +- The `SubstanceSample` (macroscopic level) links to its `ChemicalEntity` (molecular level) via `composed_of`. |
| 137 | +- The `ChemicalEntity` carries all structure descriptors. Each descriptor slot allows multiple values (e.g. two `iupac_name` entries from different sources, two `has_molar_mass` entries with different precision). |
| 138 | +- The sample's temperature uses `rdf_type` to classify it as specifically the sample temperature in the NMR magnet (`NMR:1400025`), not just any temperature. Similarly, the `SubstanceSample` is additionally typed to be an instance of CHEBI's _chemical substance_ class. This is the [ClassifierMixin](https://nfdi-de.github.io/dcat-ap-plus/latest/design-patterns/#pattern-3-flexible-classification-classifiermixin) at work. |
| 139 | + |
| 140 | +## PolymerSample and PolymerMixin |
| 141 | + |
| 142 | +`PolymerSample` extends `SubstanceSample` and mixes in `PolymerMixin`. It follows the same pattern as `SubstanceSample` itself: a substance class gains domain-specific properties through a mixin. |
| 143 | + |
| 144 | +`PolymerMixin` extends `ChemicalSubstanceMixin` but currently defines no additional slots. It is a placeholder for future polymer-specific properties (degree of polymerization, molecular weight distribution, branching, etc.) that will follow the same mixin-based pattern used throughout ChemDCAT-AP. |
| 145 | + |
| 146 | +!!! warning "Stub: shared `class_uri`" |
| 147 | + `PolymerSample` currently shares `class_uri: SIO:001378` with its parent `SubstanceSample`. A more specific mapping is planned for a future release. The schema flags this as a TODO. |
| 148 | + |
| 149 | +## Atom |
| 150 | + |
| 151 | +`Atom` (mapped to `CHEBI:33250`) extends `Entity` directly. It is a currently minimal shape whose only addition is that `rdf_type` is `required: true`, forcing every instance to declare which specific atom type it is via the [ClassifierMixin](https://nfdi-de.github.io/dcat-ap-plus/latest/design-patterns/#pattern-3-flexible-classification-classifiermixin). The slot description indicates that the value should come from CHEBI's atom branch (`CHEBI:33250` and its subclasses, e.g. `CHEBI:26708` for a sodium atom), but this constraint is not yet enforced programmatically. Future versions of ChemDCAT-AP will use LinkML [slot bindings](https://linkml.io/linkml-model/latest/docs/bindings/) and the [linkml-term-validator](https://linkml.io/linkml-term-validator/) to validate this. |
| 152 | + |
| 153 | +!!! note "Why Atom extends Entity, not ChemicalEntity" |
| 154 | + Since `ChemicalEntity` is grounded in CHEBI' _molecular entity_, and CHEBI's atom class (`CHEBI:33250`) is not a subclass of molecular entity in CHEBI's class hierarchy, subsuming `Atom` under `ChemicalEntity` would be ontologically incorrect. Extending `Entity` directly fixes this issue. |
0 commit comments