Skip to content

Commit c32816a

Browse files
authored
Mkdocs (#93)
* migration to mkdocs materials * adding temporarily actions for mkdocs branch * fix to github action * fixing the github action and adding deps * fixing action * new path for build * removing strict parameter in docs build
1 parent aafe19f commit c32816a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+904
-4636
lines changed

.github/workflows/deploy.yml

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
1-
# This file was created automatically with `myst init --gh-pages` 🪄 💚
2-
31
name: aiida-atomistic GitHub Pages Deploy
42
on:
53
push:
6-
# Runs on pushes targeting the default branch
7-
branches: [main, develop]
8-
env:
9-
# `BASE_URL` determines the website is served from, including CSS & JS assets
10-
# You may need to change this to: `BASE_URL: ''`
11-
BASE_URL: /${{ github.event.repository.name }}
4+
branches: [main, develop, mkdocs]
125

136
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
147
permissions:
158
contents: read
169
pages: write
1710
id-token: write
18-
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19-
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
11+
12+
# Allow only one concurrent deployment; do NOT cancel in-progress runs.
2013
concurrency:
2114
group: 'pages'
2215
cancel-in-progress: false
16+
2317
jobs:
2418
build:
2519
environment:
@@ -28,25 +22,24 @@ jobs:
2822
runs-on: ubuntu-latest
2923
steps:
3024
- uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0 # required by git-revision-date-localized
3127
- name: Setup Pages
3228
uses: actions/configure-pages@v4
33-
- uses: actions/setup-python@v4
29+
- uses: actions/setup-python@v5
3430
with:
35-
python-version: '3.10'
31+
python-version: '3.11'
3632
- name: Install dependencies
3733
run: |
3834
python -m pip install --upgrade pip
39-
pip install -e .
40-
pip install -r docs/requirements.txt
41-
- name: Build Sphinx documentation
42-
run: |
43-
make html
44-
working-directory: ./docs
35+
pip install -e .[docs]
36+
- name: Build MkDocs documentation
37+
run: mkdocs build --site-dir ./build
4538
- name: Upload artifact
4639
uses: actions/upload-pages-artifact@v3
4740
with:
48-
path: './docs/build/html'
49-
# Deployment job
41+
path: './build'
42+
5043
deploy:
5144
environment:
5245
name: github-pages

docs/Makefile

Lines changed: 0 additions & 20 deletions
This file was deleted.

docs/source/dev_guides/dev_adding_properties.md renamed to docs/dev_guides/dev_adding_properties.md

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
This guide explains how to add new properties to `StructureData` and `StructureBuilder`.
44

5-
:::{note}
6-
If you want to add a temporary/experimental property, you can add it as [custom property](../how_to/define_custom.md).
7-
If instead you want to contribute to this package, this is the right page!
8-
:::
5+
!!! note
6+
If you want to add a temporary/experimental property, you can add it as [custom property](../how_to/define_custom.md).
7+
If instead you want to contribute to this package, this is the right page!
8+
99

1010
This guide covers two types of properties:
11+
1112
1. **Site properties** - Properties that vary per atom (e.g., `charge`)
1213
2. **Global properties** - Properties that apply to the entire structure (e.g., `tot_charge`)
1314

@@ -21,20 +22,20 @@ Go to the [aiida-atomistic GitHub repository](https://github.com/aiidateam/aiida
2122

2223
### 2. Clone Your Fork
2324

24-
```bash
25+
```text
2526
git clone https://github.com/YOUR-USERNAME/aiida-atomistic.git
2627
cd aiida-atomistic
2728
```
2829

2930
### 3. Create a Feature Branch
3031

31-
```bash
32+
```text
3233
git checkout -b add-new-property
3334
```
3435

3536
### 4. Install in Editable Mode
3637

37-
```bash
38+
```text
3839
pip install -e .
3940
```
4041

@@ -43,16 +44,14 @@ Now you can make changes and they'll be immediately reflected in your Python env
4344
### 5. Create a Pull Request
4445

4546
Go to your fork on GitHub and click "New Pull Request". Provide a clear description of:
47+
4648
- What property you're adding
4749
- Why it's useful
4850
- Any relevant scientific context
4951
- Link to related issues (if any)
5052

51-
:::{tip}
52-
Before creating a PR, it's a good idea to open an issue on the main repository to discuss whether the property should be added. The maintainers can provide guidance on the best implementation approach.
53-
:::
54-
55-
---
53+
!!! tip
54+
Before creating a PR, it's a good idea to open an issue on the main repository to discuss whether the property should be added. The maintainers can provide guidance on the best implementation approach.
5655

5756
## Adding a Site Property
5857

@@ -76,43 +75,44 @@ class Site(BaseModel):
7675
)
7776
```
7877

79-
:::{important}
80-
**Why `default=None` in Field and `"default"` in `json_schema_extra`?**
78+
!!! note "**Why `default=None` in Field and `"default"` in `json_schema_extra`?**"
8179

82-
We use a two-level default system:
80+
We use a two-level default system:
8381

84-
1. **Field `default=None`**: This is the Pydantic field default. Setting it to `None` means:
85-
- When you create a site without specifying `property_A`, the field is truly undefined (`None`)
86-
- This lets us distinguish between "property not set" vs "property set to zero"
87-
- Without this, if we used `default=0.0`, every site would appear to have `property_A` defined, even when unset
82+
1. **Field `default=None`**: This is the Pydantic field default. Setting it to `None` means:
8883

89-
2. **`json_schema_extra["default"]`**: This is used when expanding arrays:
90-
- When one site has `property_A=2.5` but another has `property_A=None`
91-
- The array needs a concrete value for the undefined site, if the above condition is verified
92-
- We use `Site.get_default_values()['property_A']` to get `0.0` as the fill value
93-
- Result: `charges = [2.5, 0.0]` (not `[2.5, None]` which breaks numpy arrays)
84+
- When you create a site without specifying `property_A`, the field is truly undefined (`None`)
85+
- This lets us distinguish between "property not set" vs "property set to zero"
86+
- Without this, if we used `default=0.0`, every site would appear to have `property_A` defined, even when unset
9487

95-
**Example:**
96-
```python
97-
# Without property_A set
98-
site1 = Site(symbol="Fe", position=[0, 0, 0])
99-
site1.property_A # None - we know it's undefined
88+
2. **`json_schema_extra["default"]`**: This is used when expanding arrays:
10089

101-
# With property_A set to zero
102-
site2 = Site(symbol="Fe", position=[0, 0, 0], property_A=0.0)
103-
site2.property_A # 0.0 - explicitly set
90+
- When one site has `property_A=2.5` but another has `property_A=None`
91+
- The array needs a concrete value for the undefined site, if the above condition is verified
92+
- We use `Site.get_default_values()['property_A']` to get `0.0` as the fill value
93+
- Result: `charges = [2.5, 0.0]` (not `[2.5, None]` which breaks numpy arrays)
10494

105-
# Array expansion uses json_schema_extra["default"]
106-
structure = StructureData(sites=[site1, site2])
107-
structure.properties.property_A_array # [1.0, 0.0] - we populated property_A_array[0] with the json_schema_extra["default"] = 1
108-
```
95+
**Example:**
96+
```python
97+
# Without property_A set
98+
site1 = Site(symbol="Fe", position=[0, 0, 0])
99+
site1.property_A # None - we know it's undefined
100+
101+
# With property_A set to zero
102+
site2 = Site(symbol="Fe", position=[0, 0, 0], property_A=0.0)
103+
site2.property_A # 0.0 - explicitly set
104+
105+
# Array expansion uses json_schema_extra["default"]
106+
structure = StructureData(sites=[site1, site2])
107+
structure.properties.property_A_array # [1.0, 0.0] - we populated property_A_array[0] with the json_schema_extra["default"] = 1
108+
```
109109

110-
This pattern allows:
110+
This pattern allows:
111+
112+
- Detecting if a property is truly set or not
113+
- Creating valid numpy arrays without `None` values
114+
- Distinguishing "zero" from "undefined"
111115

112-
- Detecting if a property is truly set or not
113-
- Creating valid numpy arrays without `None` values
114-
- Distinguishing "zero" from "undefined"
115-
:::
116116

117117
You can also a validation, if needed:
118118

@@ -158,19 +158,18 @@ def property_A_array(self) -> t.Optional[np.ndarray]:
158158
])
159159
```
160160

161-
:::{important}
162-
**Key Points:**
161+
!!! note "**Key Points**"
162+
163+
1. **Check for all None first**: If all sites have `property_A=None`, return `None` for the entire array. This indicates the property is truly undefined for the structure.
163164

164-
1. **Check for all None first**: If all sites have `property_A=None`, return `None` for the entire array. This indicates the property is truly undefined for the structure.
165+
2. **Use `Site.get_default_values()`**: Instead of hardcoding defaults, retrieve them from the Site field metadata:
166+
```python
167+
default_value = Site.get_default_values().get('property_A', 0.0)
168+
```
169+
This keeps the default value definition in one place (the Site field's `json_schema_extra`).
165170

166-
2. **Use `Site.get_default_values()`**: Instead of hardcoding defaults, retrieve them from the Site field metadata:
167-
```python
168-
default_value = Site.get_default_values().get('property_A', 0.0)
169-
```
170-
This keeps the default value definition in one place (the Site field's `json_schema_extra`).
171+
3. **Always include `singular_form`**: This metadata is **required** for loading structures from the database. See the metadata explanation below.
171172

172-
3. **Always include `singular_form`**: This metadata is **required** for loading structures from the database. See the metadata explanation below.
173-
:::
174173

175174
#### Step 3: storage backend decision and additional computed fields for efficient querying
176175

@@ -308,6 +307,7 @@ Add the property to the documentation:
308307
Global properties (like temperature, pressure) follow a simpler pattern than site properties since they don't need array expansion.
309308

310309
Key differences from site properties:
310+
311311
- No need for `"default"` in `json_schema_extra` (no array expansion needed)
312312
- Only need `default=None` in Field definition
313313
- No need for `Site.get_default_values()` in computed fields

docs/source/dev_guides/dev_plugin_migration.md renamed to docs/dev_guides/dev_plugin_migration.md

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -93,57 +93,56 @@ class MyCalculation(CalcJob):
9393
]
9494
```
9595

96-
:::{important}
97-
**Use Plural Forms for Site Properties**
96+
!!! note "**Use Plural Forms for Site Properties**"
9897

99-
When defining `supported_properties`, you must use the **plural form** for site-based properties (properties that vary per atom).
100-
For example:
98+
When defining `supported_properties`, you must use the **plural form** for site-based properties (properties that vary per atom).
99+
For example:
101100

102-
- `'charges'` (not `'charge'`)
103-
- `'masses'` (not `'mass'`)
104-
- `'magmoms'` (not `'magmom'`)
105-
- `'positions'` (not `'position'`)
101+
- `'charges'` (not `'charge'`)
102+
- `'masses'` (not `'mass'`)
103+
- `'magmoms'` (not `'magmom'`)
104+
- `'positions'` (not `'position'`)
106105

107-
Global properties (that apply to the entire structure) use their standard name:
106+
Global properties (that apply to the entire structure) use their standard name:
108107

109-
- `'cell'`
110-
- `'pbc'`
111-
- `'temperature'`
108+
- `'cell'`
109+
- `'pbc'`
110+
- `'temperature'`
112111

113-
**How to Find Property Names:**
112+
**How to Find Property Names:**
114113

115-
To see all available properties and their correct names:
114+
To see all available properties and their correct names:
116115

117-
```python
118-
from aiida_atomistic import StructureData
116+
```python
117+
from aiida_atomistic import StructureData
119118

120-
# Get all supported properties
121-
props = StructureData.get_supported_properties()
119+
# Get all supported properties
120+
props = StructureData.get_supported_properties()
122121

123-
# Site properties (use plural forms in supported_properties)
124-
print(props['site'])
125-
# {'charge', 'mass', 'magmom', 'magnetization', 'weight', ...}
122+
# Site properties (use plural forms in supported_properties)
123+
print(props['site'])
124+
# {'charge', 'mass', 'magmom', 'magnetization', 'weight', ...}
126125

127-
# Global properties (use as-is in supported_properties)
128-
print(props['global'])
129-
# {'cell', 'pbc', 'tot_charge', 'temperature', ...}
126+
# Global properties (use as-is in supported_properties)
127+
print(props['global'])
128+
# {'cell', 'pbc', 'tot_charge', 'temperature', ...}
130129

131-
# Computed properties (arrays from site properties - use plural)
132-
print(props['computed'])
133-
# {'charges', 'masses', 'magmoms', 'positions', 'symbols', ...}
134-
```
130+
# Computed properties (arrays from site properties - use plural)
131+
print(props['computed'])
132+
# {'charges', 'masses', 'magmoms', 'positions', 'symbols', ...}
133+
```
135134

136-
**Why Plural?**
135+
**Why Plural?**
137136

138-
Site properties in the `Site` model are singular (`charge`, `mass`), but they're accessed as arrays through computed fields with plural names (`charges`, `masses`). The validation checks for the array forms since that's what your plugin actually uses:
137+
Site properties in the `Site` model are singular (`charge`, `mass`), but they're accessed as arrays through computed fields with plural names (`charges`, `masses`). The validation checks for the array forms since that's what your plugin actually uses:
138+
139+
```python
140+
# In your plugin, you access:
141+
structure.properties.charges # Array of all charges, what you will use
142+
# Not:
143+
structure.properties.sites[0].charge # Individual site charge (you don't validate this)
144+
```
139145

140-
```python
141-
# In your plugin, you access:
142-
structure.properties.charges # Array of all charges, what you will use
143-
# Not:
144-
structure.properties.sites[0].charge # Individual site charge (you don't validate this)
145-
```
146-
:::
147146

148147
#### Step 2: Add Validation Logic
149148

@@ -201,13 +200,13 @@ class MyCalculation(CalcJob):
201200
)
202201
```
203202

204-
:::{note}
205-
You can also put the validation in the WorkChains using the given CalcJob, to stop prematurely instead of performing some steps and then exit only when trying to submit with the wrong structure.
206-
:::
203+
!!! tip
204+
You can also put the validation in the WorkChains using the given CalcJob, to stop prematurely instead of performing some steps and then exit only when trying to submit with the wrong structure.
205+
206+
207+
!!! tip
208+
Of course, you will also need to add the logic to write your input file starting from the structure properties, which before were defined in the `parameters` input `orm.Dict` (at least in the aiida-quantumespresso plugin).
207209

208-
:::{note}
209-
Of course, you will also need to add the logic to write your input file starting from the structure properties, which before were defined in the `parameters` input `orm.Dict` (at least in the aiida-quantumespresso plugin).
210-
:::
211210

212211
### Real-World Example: aiida-quantumespresso
213212

docs/source/dev_guides/dev_repository_storage.md renamed to docs/dev_guides/dev_repository_storage.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ the ZIP central directory. It does **not** decompress any other entry.
8888
Accessing `positions` in a file that also contains `charges`, `magmoms`, and
8989
`symbols` only decompresses `positions.npy`.
9090

91-
:::{note}
92-
The full load (no `keys` argument) is cached on the node object after the
93-
first call, so repeated access to `.properties` does not re-read the file.
94-
:::
91+
!!! note
92+
The full load (no `keys` argument) is cached on the node object after the
93+
first call, so repeated access to `.properties` does not re-read the file.
94+
9595

9696
---
9797

0 commit comments

Comments
 (0)