diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 232eed53..7f30ded1 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,5 +21,5 @@ jobs: path: .cache restore-keys: | mkdocs-material- - - run: pip install .[dev] + - run: pip install .[docs] - run: mkdocs gh-deploy --force diff --git a/README.md b/README.md index 624b9924..e1022bb3 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ -# Lassie +# Qseek *The friendly earthquake detector* -[![Build and test](https://github.com/miili/lassie-v2/actions/workflows/build.yaml/badge.svg)](https://github.com/miili/lassie-v2/actions/workflows/build.yaml) -[![Documentation](https://img.shields.io/badge/read-documentation-blue)](https://pyrocko.github.io/lassie-v2/) +[![Build and test](https://github.com/pyrocko/qseek/actions/workflows/build.yaml/badge.svg)](https://github.com/pyrocko/qseek/actions/workflows/build.yaml) +[![Documentation](https://img.shields.io/badge/read-documentation-blue)](https://pyrocko.github.io/qseek/) ![Python 3.10+](https://img.shields.io/badge/python-3.10%203.11-blue.svg) Code style: black [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://pre-commit.com/) -Lassie is an earthquake detection and localisation framework based on stacking and migration method. It combines neural network phase picks with an iterative octree localisation approach for accurate localisation of seismic events. +Qseek is an earthquake detection and localisation framework based on stacking and migration, a beamforming method. It combines neural network phase picks with an iterative octree localisation approach for accurate localisation of seismic events. Key features are of the earthquake detection and localisation framework are: @@ -25,24 +25,24 @@ Key features are of the earthquake detection and localisation framework are: * Automatic extraction of modelled and picked travel times * Calculation and application of station corrections / station delay times -Lassie is built on top of [Pyrocko](https://pyrocko.org). +Qseek is built on top of [Pyrocko](https://pyrocko.org). -For more information check out the documentation at https://pyrocko.github.io/lassie-v2/. +For more information check out the documentation at https://pyrocko.github.io/qseek/. ## Installation Simple installation from GitHub. ```sh -pip install git+https://github.com/pyrocko/lassie-v2 +pip install git+https://github.com/pyrocko/qseek ``` ## Project Initialisation -Initialize a new project in a fresh directory. +Show the default config. ```sh -lassie init my-project/ +qseek config ``` Edit the `my-project.json` @@ -50,7 +50,7 @@ Edit the `my-project.json` Start the earthquake detection with ```sh -lassie search search.json +qseek search search.json ``` ## Packaging @@ -62,7 +62,7 @@ The simplest and recommended way of installing from source: Local development through pip. ```sh -cd lassie-v2 +cd qseek pip3 install .[dev] ``` @@ -74,12 +74,12 @@ pre-commit install ## Citation -Please cite lassie as: +Please cite Qseek as: -> TBD +> Marius Paul Isken, Peter Niemz, Jannes Münchmeyer, Sebastian Heimann, Simone Cesca, Torsten Dahm, Qseek: A data-driven Framework for Machine-Learning Earthquake Detection, Localization and Characterization, Seismica, 2024, *submitted* ## License Contribution and merge requests by the community are welcome! -Lassie-v2 was written by Marius Paul Isken and is licensed under the GNU GENERAL PUBLIC LICENSE v3. +Qseek was written by Marius Paul Isken and is licensed under the GNU GENERAL PUBLIC LICENSE v3. diff --git a/docs/benchmark.md b/docs/benchmark.md index 773b2710..b3c2f1ae 100644 --- a/docs/benchmark.md +++ b/docs/benchmark.md @@ -2,7 +2,7 @@ ## Computation Performance -Lassie is built for searching in large-N data sets. The implementation is leveraging Python [`asyncio`](https://docs.python.org/3/library/asyncio.html) heavily to implement threading and keeping the CPU busy. It is built on top of highly performant Pyrocko functions implemented in C language. The inference is using [PyTorch](https://pytorch.org/) which enables GPU computation of the seismic imaging functions. +Qseek is built for searching in large-N data sets. The implementation is leveraging Python [`asyncio`](https://docs.python.org/3/library/asyncio.html) heavily to implement threading and keeping the CPU busy. It is built on top of highly performant Pyrocko functions implemented in C language. The inference is using [PyTorch](https://pytorch.org/) which enables GPU computation of the seismic imaging functions. This enables high throughput of seismic data in different scenarios. @@ -22,7 +22,7 @@ A list of other projects using stacking and migration approach to back-project s ### Lassie-v1 -Lassie - The friendly Earthquake detector in version 1. The re-writen version of Lassie utilizes the same heavy-duty functions for stacking and migration as Lassie v1. +Lassie - The friendly Earthquake detector in version 1. Qseek utilizes the same optimized heavy-duty functions for stacking and migration as Lassie v1. [Lassie-v1 on Pyrocko Git](https://git.pyrocko.org/pyrocko/lassie) @@ -30,7 +30,13 @@ Lassie - The friendly Earthquake detector in version 1. The re-writen version of QuakeMigrate uses a waveform migration and stacking algorithm to search for coherent seismic phase arrivals across a network of instruments. It produces—from raw data—catalogues of earthquakes with locations, origin times, phase arrival picks, and local magnitude estimates, as well as rigorous estimates of the associated uncertainties. -[QuakeMigrate on GitHub](https://git.pyrocko.org/pyrocko/lassie) +[QuakeMigrate on GitHub](https://github.com/QuakeMigrate/QuakeMigrate) + +### BPMF + +Complete framework for earthquake detection and location: Backprojection and matched-filtering (BPMF), with methods for automatic picking, relocation and efficient waveform stacking. + +[BPMF on GitHub](https://github.com/ebeauce/Seismic_BPMF) ### Loki @@ -40,6 +46,6 @@ LOKI (LOcation of seismic events through traveltime staKIng) is a code that perf ### MALMI -MALMI (MAchine Learning aided earthquake MIgration location). +MALMI (MAchine Learning aided earthquake MIgration location), variant of Loki for detecting and locating earthquakes using ML image functions provided by SeisBench. [MALMI on GitHub](https://github.com/speedshi/MALMI) diff --git a/docs/components/configuration.md b/docs/components/configuration.md index ecc5d44c..f57ed9d6 100644 --- a/docs/components/configuration.md +++ b/docs/components/configuration.md @@ -1,4 +1,4 @@ -# Lassie Configuration +# Qseek Configuration At center is a JSON configuration file which is parsed by [Pydantic](https://docs.pydantic.dev/). The following pages will detail how to setup this JSON file for the search. @@ -12,17 +12,17 @@ The search configuration. **This is the entrypoint for the EQ detection and loca More information on the submodules (e.g. Octree, Data Provider and other) can be found on subpages in the navigation. ```python exec='on' -from lassie.utils import generate_docs -from lassie.search import Search +from qseek.utils import generate_docs +from qseek.search import Search print(generate_docs(Search())) ``` ## Minimal Config -This is a minimal config which can used to start a Lassie search. +This is a minimal config which can used to start a Qseek search. -```json title="Minimal Lassie Config" +```json title="Minimal Qseek Config" { "project_dir": ".", "stations": { @@ -94,44 +94,31 @@ This is a minimal config which can used to start a Lassie search. Structure of the search and optimisation of the octree, which is focusing in on seismic energy. ```mermaid -flowchart TD - - -subgraph Data Input - waveforms(["Seismic Waveforms"]) - image[" - Phase Image Function - PhaseNet, EQTransformer, ... - "] -end -subgraph Migration - quadtree["Quadtree"] - travelTimes[" - Seismic Travel Time Model - 1D Raytracer, ... - "] -end -subgraph Detection - search["Stacking Image Functions"] - detection["EQ Event Detection & Localisation"] -end -featureExtraction[" - Feature Extraction - Local Magnitude, Ground Motion, ... -"] -stationCorrections[" - Traveltime residuals from Image - → Station Corrections -"] - -waveforms --> image -image --> search -quadtree --> travelTimes -travelTimes -->search -detection -- Refine Quadtree --> search -search --> detection -detection --> featureExtraction -detection --> stationCorrections +%%{init: {'theme': 'neutral', 'themeVariables': { 'fontSize': '14pt'}}}%% +flowchart LR + subgraph Seismic Data + waveforms(["fa:fa-water Seismic\nWaveforms"]) + image{{"fa:fa-bolt Waveform Image Function\nPhaseNet / EQTransformer / ..."}} + waveforms --> image + end + subgraph Travel Time Model + travelTimes(["fa:fa-layer-group Seismic\nTravel Time Model"]) + stationCorrections{{"fab:fa-arrows-to-dot Station Corrections\nSST / SSST"}} + travelTimes -->|add| stationCorrections + end + subgraph Stacking and Migration + octree["fa:fa-cubes\nOctree Grid"] + detection["fa:fa-bullseye Detection\nand Localisation"] + end + featureExtraction("fa:fa-info Extract Event Features\nMagnitudes, Ground Motion, ...") + correctionExtraction("fa:fa-stopwatch Extract\nStation Corrections") + + image --> octree + stationCorrections --> octree + detection -.->|"fa:fa-cube\nRefine"| octree + octree --> detection + detection --> featureExtraction & correctionExtraction + ``` *Building blocks of the specific stacking and migration method for earthquake detection, localisation and characterisation.* diff --git a/docs/components/general.md b/docs/components/general.md index 62479d20..d84eb726 100644 --- a/docs/components/general.md +++ b/docs/components/general.md @@ -6,10 +6,15 @@ Paths can be relative to the location of the config file or absolute. **File pat ## Date and Time -Serialisation of time, dates and date times and durations follow [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format with timezone information. E.g. `2023-10-28T01:21:21.003+00:00`. +Serialisation of time, dates and date times and durations follow [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format with timezone information. E.g. `2023-10-28T01:21:21.003Z`. Duration are serialized like `PT600S`, this example shows a duration of 600 seconds, 10 minutes. + +!!!+ note Timezone Info + All datetimes are timezone aware! For UTC this is the `Z` or `+00:00` suffix. + Also other offsets can be defined according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601). + ```json title="Example of datetimes and durations" { "start_time": "2023-10-28T01:21:21.003+00:00", @@ -25,8 +30,8 @@ Geographic locations have a geographic reference and a relative shift in meters. All **distances, depths and elevations are given in meters**. ```python exec='on' -from lassie.utils import generate_docs -from lassie.models.location import Location +from qseek.utils import generate_docs +from qseek.models.location import Location print(generate_docs(Location(lat= 52.3825, lon=13.0644))) ``` diff --git a/docs/components/image_function.md b/docs/components/image_function.md index 10582bf3..99e2c90c 100644 --- a/docs/components/image_function.md +++ b/docs/components/image_function.md @@ -1,6 +1,6 @@ # Image Function -For image functions this version of Lassie relies heavily on machine learning pickers delivered by [SeisBench](https://github.com/seisbench/seisbench). +For image functions this version of Qseek relies heavily on machine learning pickers delivered by [SeisBench](https://github.com/seisbench/seisbench). ## PhaseNet Image Function @@ -8,8 +8,8 @@ For image functions this version of Lassie relies heavily on machine learning pi *Zhu, Weiqiang, and Gregory C. Beroza. "PhaseNet: A Deep-Neural-Network-Based Seismic Arrival Time Picking Method." arXiv preprint arXiv:1803.03211 (2018).* ```python exec='on' -from lassie.utils import generate_docs -from lassie.images.phase_net import PhaseNet +from qseek.utils import generate_docs +from qseek.images.phase_net import PhaseNet print(generate_docs(PhaseNet())) ``` diff --git a/docs/components/octree.md b/docs/components/octree.md index 27dcc802..7787a252 100644 --- a/docs/components/octree.md +++ b/docs/components/octree.md @@ -1,14 +1,14 @@ # Octree -A 3D space is searched for sources of seismic energy. Lassie created an octree structure which is iteratively refined when energy is detected, to focus on the source' location. This speeds up the search and improves the resolution of the localisations. +A 3D space is searched for sources of seismic energy. Qseek created an octree structure which is iteratively refined when energy is detected, to focus on the source' location. This speeds up the search and improves the resolution of the localisations. ![Octree Concept](../images/octree-concept.webp) *Surface projection of the refined octree focusing on the seismic source region. In this example four levels of refinement are can be seen, refining the 3D octree from the initial 4000 nodes to 8823 nodes.* ```python exec='on' -from lassie.utils import generate_docs -from lassie.octree import Octree +from qseek.utils import generate_docs +from qseek.octree import Octree print(generate_docs(Octree())) ``` diff --git a/docs/components/ray_tracer.md b/docs/components/ray_tracer.md index 45fc27ac..1c59d9fc 100644 --- a/docs/components/ray_tracer.md +++ b/docs/components/ray_tracer.md @@ -1,6 +1,6 @@ # Ray Tracers -The calculation of seismic travel times is a cornerstone for the migration and stacking approach. Lassie supports different ray tracers for travel time calculation, which can be adapted for different geological settings. +The calculation of seismic travel times is a cornerstone for the migration and stacking approach. Qseek supports different ray tracers for travel time calculation, which can be adapted for different geological settings. ## Constant Velocity @@ -13,8 +13,8 @@ $$ This module is used for simple use cases and cross-referencing testing. ```python exec='on' -from lassie.utils import generate_docs -from lassie.tracers.constant_velocity import ConstantVelocityTracer +from qseek.utils import generate_docs +from qseek.tracers.constant_velocity import ConstantVelocityTracer print(generate_docs(ConstantVelocityTracer())) ``` @@ -27,8 +27,8 @@ Calculation of travel times in 1D layered media is based on the [Pyrocko Cake](h *Pyrocko Cake 1D ray tracer for travel time calculation in 1D layered media* ```python exec='on' -from lassie.utils import generate_docs -from lassie.tracers.cake import CakeTracer +from qseek.utils import generate_docs +from qseek.tracers.cake import CakeTracer print(generate_docs(CakeTracer(), exclude={'earthmodel': {'raw_file_data'}})) ``` @@ -45,8 +45,8 @@ We implement the fast marching method for calculating first arrivals of waves in *Conceptual 2D visualisation for seismic traveltimes calculation in heterogenous media using the fast-marching method for the Eikonal solution is presented. Traveltimes from the receiving station at the surface (indicated by a yellow triangle) towards the subsurface grid are calculated, resulting in station-specifig traveltimes for all potential source locations simultaneously.* ```python exec='on' -from lassie.utils import generate_docs -from lassie.insights.tracers.fast_marching import FastMarchingTracer +from qseek.utils import generate_docs +from qseek.insights.tracers.fast_marching import FastMarchingTracer print(generate_docs(FastMarchingTracer())) ``` diff --git a/docs/components/seismic_data.md b/docs/components/seismic_data.md index 9c6b95d6..84aa1011 100644 --- a/docs/components/seismic_data.md +++ b/docs/components/seismic_data.md @@ -2,13 +2,13 @@ ## Waveform Data -The seismic can be delivered in MiniSeed or any other format compatible with Pyrocko. Lassie utilizes the Pyrocko Squirrel for fast and asynchronous data access. +The seismic can be delivered in MiniSeed or any other format compatible with Pyrocko. Qseek utilizes the Pyrocko Squirrel for fast and asynchronous data access. To prepare your data for EQ detection and localisation, **organize it in a MiniSeed file or an [SDS structure](https://www.seiscomp.de/doc/base/concepts/waveformarchives.html)**. ```python exec='on' -from lassie.utils import generate_docs -from lassie.waveforms import PyrockoSquirrel +from qseek.utils import generate_docs +from qseek.waveforms.squirrel import PyrockoSquirrel print(generate_docs(PyrockoSquirrel())) ``` @@ -25,8 +25,8 @@ Supported data formats are: Metadata does not need to include response information for pure detection and localisation. If local magnitudes M~L~ are extracted, response information is required. ```python exec='on' -from lassie.utils import generate_docs -from lassie.models.station import Stations +from qseek.utils import generate_docs +from qseek.models.station import Stations print(generate_docs(Stations())) ``` diff --git a/docs/components/station_corrections.md b/docs/components/station_corrections.md index 810c1073..c98d2dbe 100644 --- a/docs/components/station_corrections.md +++ b/docs/components/station_corrections.md @@ -3,8 +3,16 @@ Station corrections can be extract from previous runs to refine the localisation accuracy. The corrections can also help to improve the semblance find more events in a dataset. ```python exec='on' -from lassie.utils import generate_docs -from lassie.station_corrections import StationCorrections +from qseek.utils import generate_docs +from qseek.insights import StationCorrections print(generate_docs(StationCorrections())) ``` + + +```python exec='on' +from qseek.utils import generate_docs +from qseek.insights import SourceSpecificStationCorrections + +print(generate_docs(SourceSpecificStationCorrections())) +``` diff --git a/docs/getting_started.md b/docs/getting_started.md index 74e84290..a2ff40c5 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -5,102 +5,39 @@ The installation is straight-forward: ```sh title="From GitHub" -pip install git+https://github.com/pyrocko/lassie-v2 +pip install git+https://github.com/pyrocko/qseek ``` -## Running Lassie +## Running Qseek -The main entry point in the executeable is the `lassie` command. The provided command line interface (CLI) and a JSON config file is all what is needed to run the program. +The main entry point in the executeable is the `qseek` command. The provided command line interface (CLI) and a JSON config file is all what is needed to run the program. ```bash exec='on' result='ansi' source='above' -lassie --help +qseek --help ``` ## Initializing a New Project -Once installed you can run the lassie executeable to initialize a new project. +Once installed you can run the `qseek` executeable to initialize a new project. ```sh title="Initialize new Project" -lassie init my-project +qseek config > my-search.json ``` -Check out the `search.json` config file and add your waveform data and velocity models. +Check out the `my-search.json` config file and add your waveform data and velocity models. ??? abstract "Minimal Configuration Example" - Here is a minimal JSON configuration for Lassie - ```json - { - "project_dir": ".", - "stations": { - "station_xmls": [], - "pyrocko_station_yamls": ["search/pyrocko-stations.yaml"], - }, - "data_provider": { - "provider": "PyrockoSquirrel", - "environment": ".", - "waveform_dirs": ["data/"], - }, - "octree": { - "location": { - "lat": 0.0, - "lon": 0.0, - "east_shift": 0.0, - "north_shift": 0.0, - "elevation": 0.0, - "depth": 0.0 - }, - "root_node_size": 2000.0, - "n_levels": 3, - "east_bounds": [ - -10000.0, - 10000.0 - ], - "north_bounds": [ - -10000.0, - 10000.0 - ], - "depth_bounds": [ - 0.0, - 20000.0 - ], - "absorbing_boundary": 1000.0 - }, - "image_functions": [ - { - "image": "PhaseNet", - "model": "ethz", - "torch_use_cuda": false, - "phase_map": { - "P": "constant:P", - "S": "constant:S" - }, - } - ], - "ray_tracers": [ - { - "tracer": "ConstantVelocityTracer", - "phase": "constant:P", - "velocity": 5000.0 - } - ], - "station_corrections": {}, - "event_features": [], - "sampling_rate": 100, - "detection_threshold": 0.05, - "detection_blinding": "PT2S", - "node_split_threshold": 0.9, - "window_length": "PT300S", - "n_threads_parstack": 0, - "n_threads_argmax": 4, - } + Here is a minimal JSON configuration for Qseek + ```bash exec='on' result='json' + qseek config ``` For more details and information about the component, head over to [details of the modules](components/seismic_data.md). ## Starting the Search -Once happy, start the lassie CLI. +Once happy, start the `qseek` CLI. ```sh title="Start earthquake detection" -lassie search search.json +qseek search my-search.json ``` diff --git a/docs/images/octree-concept.webp b/docs/images/octree-concept.webp index 3a91c95f..7fdc71dc 100644 Binary files a/docs/images/octree-concept.webp and b/docs/images/octree-concept.webp differ diff --git a/docs/index.md b/docs/index.md index 97e69af2..2b9fffa9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,12 @@ -# Welcome to Lassie 🐕‍🦺 +# Welcome to Qseek 🐕‍🦺 -Lassie is an earthquake detection and localisation framework. It combines modern **machine learning phase detection and robust migration and stacking techniques**. +Qseek is an earthquake detection and localisation framework. It combines modern **machine learning phase detection and robust migration and stacking techniques**. The detector is leveraging [Pyrocko](https://pyrocko.org) and [SeisBench](https://github.com/seisbench/seisbench), it is highly-performant and can search massive data sets for seismic activity efficiently. !!! abstract "Citation" - TDB + Marius Paul Isken, Peter Niemz, Jannes Münchmeyer, Sebastian Heimann, Simone Cesca, Torsten Dahm, Qseek: A data-driven Framework for Machine-Learning Earthquake Detection, Localization and Characterization, Seismica, 2024, *submitted* + ![Reykjanes detections](images/reykjanes-demo.webp) diff --git a/docs/theme/announce.html b/docs/theme/announce.html index 594d6af7..1a9be47d 100644 --- a/docs/theme/announce.html +++ b/docs/theme/announce.html @@ -1 +1 @@ -Lassie is in Beta 🧫 Please handle with care +Qseek is in Beta 🧫 Please handle with care diff --git a/docs/visualizing_results.md b/docs/visualizing_results.md index 850c9bb2..250cce09 100644 --- a/docs/visualizing_results.md +++ b/docs/visualizing_results.md @@ -1,6 +1,6 @@ # Visualizing Detections -The event detections are exported in Lassie-native JSON, Pyrocko YAML format and as CSV files. +The event detections are exported in Qseek-native JSON, Pyrocko YAML format and as CSV files. ## Pyrocko Sparrow diff --git a/mkdocs.yml b/mkdocs.yml index 2d6b68ba..f5d4549b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,9 +1,9 @@ -site_name: Lassie - Earthquake Detector +site_name: Qseek - Earthquake Detection and Localization site_description: The friendly earthquake detector site_author: Marius Paul Isken -repo_url: https://github.com/pyrocko/lassie-v2 -repo_name: pyrocko/lassie-v2 +repo_url: https://github.com/pyrocko/qseek +repo_name: pyrocko/qeek edit_uri: edit/main/docs/ theme: @@ -13,13 +13,13 @@ theme: - scheme: default primary: blue grey toggle: - icon: material/toggle-switch + icon: material/eye name: Switch to dark mode # Palette toggle for dark mode - scheme: slate primary: blue grey toggle: - icon: material/toggle-switch-off-outline + icon: material/eye-outline name: Switch to light mode icon: repo: fontawesome/brands/git-alt @@ -60,7 +60,7 @@ extra_javascript: - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js watch: - - lassie + - src/qseek plugins: - search diff --git a/pyproject.toml b/pyproject.toml index b6a7199f..b6c746df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,9 +71,9 @@ dev = [ ] docs = [ - "mkdocs-material>=9.4.8", + "mkdocs-material>=9.5.13", "mkdocstrings[python]>=0.23", - "qseek-insights", + "markdown-exec>=1.8.0", ] completion = ["argcomplete>=3.2"] diff --git a/src/qseek/utils.py b/src/qseek/utils.py index eaa69e65..a765b353 100644 --- a/src/qseek/utils.py +++ b/src/qseek/utils.py @@ -24,7 +24,7 @@ ) import numpy as np -from pydantic import AfterValidator, ByteSize, constr +from pydantic import AfterValidator, BaseModel, ByteSize, constr from pyrocko.util import UnavailableDecimation from rich.logging import RichHandler @@ -553,3 +553,42 @@ class ChannelSelectors: NSL_RE = r"^[a-zA-Z0-9]{0,2}\.[a-zA-Z0-9]{0,5}\.[a-zA-Z0-9]{0,3}$" + + +def generate_docs(model: BaseModel, exclude: dict | set | None = None) -> str: + """Takes model and dumps markdown for documentation""" + + def generate_submodel(model: BaseModel) -> list[str]: + lines = [] + for name, field in model.model_fields.items(): + if field.description is None: + continue + lines += [ + f" - **`{name}`** *`{field.annotation}`*\n", + f" {field.description}", + ] + return lines + + model_name = model.__class__.__name__ + lines = [f"### {model_name} Module"] + if model.__class__.__doc__ is not None: + lines += [f"{model.__class__.__doc__}\n"] + lines += [f'=== "Config {model_name}"'] + for name, field in model.model_fields.items(): + if field.description is None: + continue + lines += [ + f" **`{name}`**\n", + f" : {field.description}\n", + ] + + def dump_json() -> list[str]: + dump = model.model_dump_json(by_alias=False, indent=2, exclude=exclude) + lines = dump.split("\n") + return [f" {line}" for line in lines] + + lines += ['=== "JSON Block"'] + lines += [f" ```json title='JSON block for {model_name}'"] + lines.extend(dump_json()) + lines += [" ```"] + return "\n".join(lines)