Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
530caa2
Creating docdevs folter that will contain a series of scripts or mds …
MendezSebastianP Jan 12, 2026
ccb7df3
Adding guide: releasing
MendezSebastianP Jan 12, 2026
af66a9e
releasing: adding CI protocol. test.yaml: changing base protocol to t…
MendezSebastianP Jan 12, 2026
0426695
fixing checkboxes errors related
MendezSebastianP Jan 13, 2026
0a6db1c
updating dependency guide
MendezSebastianP Jan 13, 2026
52e6b1e
docs: new file: contributions.md, a guide about how to contribute to …
MendezSebastianP Jan 15, 2026
cc67d54
doc: improving the contributions guide: adding more text, and example…
MendezSebastianP Jan 16, 2026
aec05b3
Adding some files to codesource guide
MendezSebastianP Feb 6, 2026
9fa9576
updating poetry
MendezSebastianP Feb 6, 2026
26ff603
Adding ModelInterface, fixing BaseModel
MendezSebastianP Feb 9, 2026
7d1cfe7
Modifying DAG file and othe minor changes
MendezSebastianP Feb 10, 2026
691502b
Fix docs build: pin importlib-metadata < 8.0.0
MendezSebastianP Feb 10, 2026
b3a5cd3
fixing dependency problems
MendezSebastianP Feb 10, 2026
6d9a7de
Merge branch 'v2.1' into docdev
MendezSebastianP Feb 10, 2026
00a0690
fixing dependency problems x2
MendezSebastianP Feb 10, 2026
700bacb
fixing dependency problems x3
MendezSebastianP Feb 10, 2026
266b730
fixing dependency problems x4
MendezSebastianP Feb 10, 2026
c431bd1
fixing dependency problems x5
MendezSebastianP Feb 10, 2026
e220e21
fixing warnings building doc
MendezSebastianP Feb 10, 2026
d012b67
Fix RTD: remove shared env to prevent poetry crash on dependency down…
MendezSebastianP Feb 10, 2026
cc5b8cf
Adding riemanian md and modifying others
MendezSebastianP Feb 12, 2026
40a47fc
fixing DAG, architecture, diagrams. Creating Observational Model
MendezSebastianP Feb 13, 2026
4b4d884
Minor fixes in files and reformulations, removing too complex or spec…
MendezSebastianP Feb 16, 2026
c718734
more various fixes before presentation
MendezSebastianP Feb 19, 2026
f420e30
more various fixes before presentation
MendezSebastianP Feb 19, 2026
e318002
updating lasts mds
MendezSebastianP Feb 23, 2026
2adf5e3
Adding VariableTypes guide
MendezSebastianP Mar 6, 2026
3dc2d02
merging with v2.1
MendezSebastianP Mar 16, 2026
85980ef
Fixing the code source modules: less text and more clear. From Archit…
MendezSebastianP Mar 16, 2026
b666ff3
Improving the rest of the codebase guide. left: finish variabletypes …
MendezSebastianP Mar 16, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Tests

on:
push:
branches: ["master", "dev", "v2", "v2.1"]
branches: ["master", "dev", "v2*"]
pull_request:
branches: ["master", "dev", "v2", "v2.1"]
branches: ["master", "dev", "v2*"]

permissions:
contents: read
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ clean.doc:
@$(RM) -rf docs/auto_examples/
@$(RM) -rf docs/sg_execution_times.rst

.PHONY: doc-quick
doc-quick: install.doc
@$(SPHINX) -b html docs/ docs/_build/html

.PHONY: clean.py
clean.py:
@find . -name __pycache__ -exec $(RM) -r {} +
Expand Down
131 changes: 131 additions & 0 deletions docs/_animations/basemodel_animation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"""
BaseModel Animation - Manim Scene
==================================

This script generates an animation showing:
1. LogisticModel box appearing
2. Arrow pointing back to BaseModel
3. Methods appearing from BaseModel (fit, personalize, estimate)
4. BaseModel expanding to show attributes (dimension, features, is_initialized)

Usage:
poetry run manim -pql basemodel_animation.py BaseModelScene

Output:
Will be saved to docs/_static/images/animations/
"""

from manim import *

class BaseModelScene(Scene):
def construct(self):
# Title
title = Text("BaseModel: The Foundation", font_size=36).to_edge(UP)
self.play(Write(title))
self.wait(0.5)

# 1. LogisticModel appears
logistic_box = Rectangle(
height=1.5,
width=3,
fill_color=BLUE_E,
fill_opacity=0.7,
stroke_color=BLUE
)
logistic_text = Text("LogisticModel", font_size=24, color=WHITE)
logistic_group = VGroup(logistic_box, logistic_text).shift(RIGHT * 3)

self.play(FadeIn(logistic_group, shift=DOWN))
self.wait(0.5)

# 2. BaseModel appears
base_box = Rectangle(
height=1.5,
width=3,
fill_color=ORANGE,
fill_opacity=0.7,
stroke_color=YELLOW
)
base_text = Text("BaseModel", font_size=24, color=WHITE)
base_group = VGroup(base_box, base_text).shift(LEFT * 3)

self.play(FadeIn(base_group, shift=DOWN))
self.wait(0.5)

# 3. Arrow pointing from LogisticModel to BaseModel (inheritance)
arrow = Arrow(
logistic_group.get_left(),
base_group.get_right(),
buff=0.1,
color=GREEN,
stroke_width=6
)
arrow_label = Text("inherits from", font_size=18, color=GREEN).next_to(arrow, UP)

self.play(GrowArrow(arrow), Write(arrow_label))
self.wait(0.5)

# 4. Methods appear from BaseModel
methods_title = Text("Core Methods:", font_size=20, color=YELLOW).next_to(base_group, DOWN, buff=0.5)

method_fit = Text("• fit()", font_size=18, color=WHITE).next_to(methods_title, DOWN, buff=0.2)
method_personalize = Text("• personalize()", font_size=18, color=WHITE).next_to(method_fit, DOWN, buff=0.1)
method_estimate = Text("• estimate()", font_size=18, color=WHITE).next_to(method_personalize, DOWN, buff=0.1)

methods_group = VGroup(methods_title, method_fit, method_personalize, method_estimate)

self.play(Write(methods_title))
self.wait(0.3)
self.play(Write(method_fit))
self.wait(0.2)
self.play(Write(method_personalize))
self.wait(0.2)
self.play(Write(method_estimate))
self.wait(0.5)

# 5. BaseModel expands and shows attributes
# Fade out methods and arrow
self.play(
FadeOut(methods_group),
FadeOut(arrow),
FadeOut(arrow_label),
FadeOut(logistic_group)
)

# Move BaseModel to center and expand
self.play(base_group.animate.move_to(ORIGIN))
self.play(base_group.animate.scale(1.5))
self.wait(0.3)

# Show attributes
attrs_title = Text("Attributes:", font_size=22, color=YELLOW).next_to(base_group, DOWN, buff=0.7)

attr_dimension = Text("• dimension: int", font_size=18, color=WHITE).next_to(attrs_title, DOWN, buff=0.2)
attr_features = Text("• features: list[str]", font_size=18, color=WHITE).next_to(attr_dimension, DOWN, buff=0.1)
attr_initialized = Text("• is_initialized: bool", font_size=18, color=WHITE).next_to(attr_features, DOWN, buff=0.1)

attrs_group = VGroup(attrs_title, attr_dimension, attr_features, attr_initialized)

self.play(Write(attrs_title))
self.wait(0.3)
self.play(Write(attr_dimension))
self.wait(0.2)
self.play(Write(attr_features))
self.wait(0.2)
self.play(Write(attr_initialized))
self.wait(1)

# Final message
final_text = Text(
"BaseModel initializes structure\\nand defines interface",
font_size=20,
color=GREEN
).to_edge(DOWN, buff=0.5)

self.play(Write(final_text))
self.wait(2)


# Configuration for output
config.output_file = "../../_static/images/animations/basemodel_animation"
config.media_dir = "../../_static/images/animations"
62 changes: 61 additions & 1 deletion docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,64 @@
}
.sphx-glr-thumbcontainer .xref.std.std-ref {
display: none;
}
}

/* Override sphinxcontrib-mermaid JavaScript-injected styles */
/* Target the container wrapper */
.mermaid-container {
width: 100% !important;
max-width: 1200px !important;
min-height: 700px !important;
margin: 30px auto !important;
display: flex !important;
}

/* Target the pre element that wraps mermaid */
.mermaid-container > pre,
pre.mermaid {
width: 100% !important;
min-height: 700px !important;
display: block !important;
}

/* Override the hardcoded 500px height from JavaScript */
.mermaid-container > pre > svg,
pre.mermaid > svg {
height: 700px !important;
min-height: 700px !important;
width: 100% !important;
max-width: 100% !important;
}

/* Colored dots for variable type legend */
.vdot {
display: inline-block;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
border: 1px solid #555;
vertical-align: middle;
margin-right: 0.2em;
}

/* DAG variable tables: 25% name+type, 75% description */
.dag-var-table th:first-child,
.dag-var-table td:first-child { width: 25%; }
.dag-var-table th:last-child,
.dag-var-table td:last-child { width: 75%; }

/* DAG zoomable image - click to zoom in/out */
.dag-zoomable {
cursor: zoom-in;
transition: transform 0.3s ease;
max-width: 100%;
height: auto;
}

.dag-zoomable.zoomed {
cursor: zoom-out;
transform: scale(1.5);
transform-origin: center;
z-index: 1000;
position: relative;
}
15 changes: 15 additions & 0 deletions docs/_static/custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,19 @@ document.addEventListener("DOMContentLoaded", function() {
el.style.cursor = 'pointer';
}
});

// Make checklist checkboxes interactive
document.querySelectorAll('input.task-list-item-checkbox').forEach((cb, i) => {
const key = `checklist-${location.pathname}-${i}`;
cb.disabled = false;
cb.checked = localStorage.getItem(key) === 'true';
cb.onchange = () => localStorage.setItem(key, cb.checked);
});

// DAG image zoom on click
document.querySelectorAll('img.dag-zoomable').forEach(function(img) {
img.addEventListener('click', function() {
this.classList.toggle('zoomed');
});
});
});
Binary file added docs/_static/images/DAG_Multivariate.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/accept_current.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/add_merge.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/arch1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/arch2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/dag_geometrical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/dag_nll.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/dag_spatial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/dag_temporal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/mcmc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/merge_conflict.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/images/source_control_fast.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,27 @@ def find_var(varname: str, *py_file_paths):
"sphinx_gallery.gen_gallery",
"myst_nb",
"sphinxcontrib.bibtex",
"sphinxcontrib.mermaid",
"sphinx_tabs.tabs",
"sphinx_design",
]

bibtex_bibfiles = ["references.bib"]

# -- mermaid configuration ---------------------------------------------------
# Configure mermaid diagram rendering
mermaid_params = ['--theme', 'default', '--width', '1200', '--backgroundColor', 'transparent']
mermaid_sequence_config = False
mermaid_verbose = False

# -- autoapi configuration ---------------------------------------------------
# https://sphinx-autoapi.readthedocs.io/en/latest/reference/config.html

myst_enable_extensions = [
"amsmath",
"dollarmath",
"colon_fence",
"tasklist",
]
nb_execution_timeout = 600
autoapi_dirs = ["../src"]
Expand Down
117 changes: 117 additions & 0 deletions docs/docdev/Dependency_management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
orphan: true
---
# Dependency Management & Security Policy

## Overview

Leaspy uses **Poetry** for dependency management and packaging. This ensures reproducible builds, precise control over library versions, and strict separation of development vs. production dependencies.

## Core Philosophy: Conservative Updates

We prioritize **stability** and **backward compatibility** over using the absolute latest versions of dependencies.

* **Avoid "Update All":** We do not blindly run `poetry update` to upgrade all packages at once. This frequently introduces silent breaking changes.
* **Targeted Fixes:** We update packages primarily to:
1. Fix specific security vulnerabilities (CVEs).
2. Support new required Python versions.
3. Access specific new features needed by Leaspy.

## Security Vulnerability Workflow

When a security vulnerability is identified (e.g., by Dependabot or manual audit):

1. **Diagnose Risk:** Determine if Leaspy is actually vulnerable.
* *Example:* A vulnerability in a web server component of a library is irrelevant if we only use its math functions.
* If the risk is negligible and the update carries high regression risk (e.g., PyTorch), we may accept the risk rather than update.

2. **Targeted Update:** Update *only* the affected package to the lowest secure version.
```bash
# Update a single package to the latest allowed version
poetry update <package_name>
```

3. **Traceability (The "Lost Forest" Solution):**
* Do **not** create permanent markdown files for temporary security audits.
* Instead, create a **GitHub Issue** detailing the CVEs, the decision process, and the versions fixed.
* Reference this issue in your PR/Commit message.
* **Close the issue immediately.** It serves as a permanent, searchable record without cluttering the active backlog.

4. **Validation:**
Run the test suite to confirm the update didn't break functionality.
```bash
pytest
```

5. **Verify Documentation Builds:**
After updating security-vulnerable packages, verify that building documentation doesn't downgrade them.
```bash
make doc
```
Watch the output for **downgrade warnings** like:
```
- Downgrading urllib3 (2.6.3 -> 2.4.0)
- Downgrading requests (2.32.5 -> 2.32.3)
- Downgrading pillow (12.1.0 -> 11.2.1)
```

**If downgrades occur:**
* Documentation dependencies may have incompatible version constraints
* Add the fixed packages to `[tool.poetry.group.docs.dependencies]` in `pyproject.toml` with minimum version constraints:
```toml
urllib3 = ">=2.6.3"
requests = ">=2.32.5"
pillow = ">=12.1.0"
```
* Run `poetry lock` and rebuild with `make doc` to confirm the issue is resolved

## Specific Package Policies

### PyTorch (`torch`)
We treat PyTorch updates with extreme caution due to its history of breaking API changes in minor releases.

* **Policy:** We explicitly pin strict upper bounds (e.g., `>=2.2.0,<2.8`).
* **Rationale:** Preventing accidental upgrades ensures that models trained on one version remain loadable on another, and that numerical stability is preserved.

## Developer protocol

### Initial Setup
```bash
conda create -n leaspy python=3.9
conda activate leaspy
poetry install
```

### Adding a Dependency
```bash
# Production dependency
poetry add <package_name>

# Dev/Doc dependency
poetry add --group dev <package_name>
```

### Syncing Lock File
If you verify or edit `pyproject.toml` manually, you must update the lock file or CI will fail.
```bash
poetry lock
```

### Verifying Security
Check that the lock file is valid and consistent, it is normal if nothing is shown, only errors or warnings will be shown if they exist:
```bash
make check.lock
```

### Running Tests
Run the full test suite to verify changes before commiting:
```bash
pytest
```

### Building Documentation
Verify that documentation builds successfully and that no packages are downgraded:
```bash
make doc
```
Watch for downgrade warnings in the output. If security-fixed packages are being downgraded, add them to `[tool.poetry.group.docs.dependencies]` in `pyproject.toml` with appropriate version constraints, run `poetry lock`, and rebuild.
Loading
Loading