diff --git a/.black.toml b/.black.toml index e046b07..f9593ef 100644 --- a/.black.toml +++ b/.black.toml @@ -1,6 +1,6 @@ [tool.black] target-version = [ - "py312", + "py313", ] line-length = 88 color = true diff --git a/.coveragerc b/.coveragerc index 26d01b7..01ee167 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,9 +1,9 @@ [run] branch = true -source = tests +source = "tests" [paths] -source = metalflare +source = "simlify" [report] show_missing = true diff --git a/.mypy.ini b/.mypy.ini index 6294e57..3cc0ebe 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -1,5 +1,5 @@ [mypy] -python_version = "3.12" +python_version = "3.13" pretty = true show_traceback = true color_output = true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index d702dbc..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,31 +0,0 @@ -default_language_version: - python: python3.12 - -default_stages: [commit, push] - -repos: - - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 - hooks: - - id: mixed-line-ending - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-executables-have-shebangs - - id: check-json - - id: check-toml - - id: check-yaml - exclude: "mkdocs.yml" - - id: detect-private-key - - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - name: isort (python) - - - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.4.2 - hooks: - - id: black - language_version: python3.12 diff --git a/.ruff.toml b/.ruff.toml index 54e7393..871f44f 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -1,4 +1,4 @@ -target-version = "py312" +target-version = "py313" line-length = 88 indent-width = 4 exclude = [ diff --git a/docs/.nav.yml b/docs/.nav.yml index 5d555de..945c0ec 100644 --- a/docs/.nav.yml +++ b/docs/.nav.yml @@ -1,7 +1,26 @@ +# More information: +# https://lukasgeiter.github.io/mkdocs-awesome-nav/ + nav: - Home: index.md - - Concepts: concepts - - Case studies: case-studies + - Concepts: + - concepts/index.md + - Case studies: + - ./case-studies/index.md + - HIV protease: + - ./case-studies/hiv-protease/index.md + - Background: ./case-studies/hiv-protease/background.md + - Protein preparation: + - ./case-studies/hiv-protease/protein/index.md + - Structure selection: ./case-studies/hiv-protease/protein/selection.md + - PDB cleaning: ./case-studies/hiv-protease/protein/clean.md + - System preparation: + - ./case-studies/hiv-protease/system/index.md + - CLI: + - ./cli/index.md + - PDB: + - ./cli/pdb/index.md + - "filter": ./cli/pdb/filter/index.md - API: api sort: @@ -10,3 +29,4 @@ sort: by: title direction: asc flatten_single_child_sections: true +preserve_directory_name: false diff --git a/docs/case-studies/.nav.yml b/docs/case-studies/.nav.yml deleted file mode 100644 index d7edf56..0000000 --- a/docs/case-studies/.nav.yml +++ /dev/null @@ -1,3 +0,0 @@ -nav: - - index.md - - HIV Protease: hiv-protease diff --git a/docs/case-studies/hiv-protease/.nav.yml b/docs/case-studies/hiv-protease/.nav.yml deleted file mode 100644 index beb1276..0000000 --- a/docs/case-studies/hiv-protease/.nav.yml +++ /dev/null @@ -1,2 +0,0 @@ -nav: - - HIV protease: index.md diff --git a/docs/case-studies/hiv-protease/background.md b/docs/case-studies/hiv-protease/background.md new file mode 100644 index 0000000..710e1b6 --- /dev/null +++ b/docs/case-studies/hiv-protease/background.md @@ -0,0 +1,26 @@ +# Background + +HIV-1 protease plays a critical role in the maturation of HIV particles, making it an essential component in the virus's replication process. +HIV-1 protease enables the formation of infectious viral particles by cleaving viral polyproteins into functional proteins. +Understanding this enzyme's structure, dynamics, and function is paramount for developing effective inhibitors and advancing HIV treatment strategies. + +The significance of HIV-1 protease extends beyond its immediate role in viral replication: + +1. **Public health impact:** HIV/AIDS remains a global health challenge, affecting millions of people worldwide. Insights gained from studying HIV-1 protease contribute to the ongoing efforts to combat this pandemic. +2. **Drug design:** As a prime target for antiretroviral drugs, detailed knowledge of HIV-1 protease's structure and dynamics is crucial for rational drug design and developing new therapeutic strategies. +3. **Resistance mechanisms:** HIV's rapid mutation rate often leads to drug resistance. MD simulations can help elucidate the molecular basis of these resistance mechanisms, informing the design of more robust inhibitors. + +From a biophysical perspective, HIV-1 protease presents several exciting characteristics that make it an excellent subject for MD simulations: + +1. **Structural flexibility:** The enzyme exhibits significant conformational changes during its catalytic cycle, particularly in the "flap" regions that control access to the active site. + MD simulations can capture these dynamic processes, providing insights into the enzyme's mechanism. +2. **Homodimeric nature:** HIV-1 protease functions as a homodimer, with the active site formed at the interface between two identical subunits. + This symmetry adds an interesting dimension to the simulation setup and analysis. +3. **Substrate specificity:** The enzyme recognizes and cleaves specific sequences in viral polyproteins. + MD simulations can help elucidate the molecular basis of this specificity and how mutations might affect it. +4. **Water-Mediated Interactions:** Water molecules play a crucial role in the enzyme's catalytic mechanism and mediating protein-ligand interactions. + Explicit solvent MD simulations are particularly valuable for studying these effects. +5. **Allosteric effects:** Recent studies have suggested the presence of allosteric sites in HIV-1 protease, opening new avenues for drug design. + MD simulations can help identify and characterize these sites. + + diff --git a/docs/case-studies/hiv-protease/index.md b/docs/case-studies/hiv-protease/index.md index 7c42e17..0cf245d 100644 --- a/docs/case-studies/hiv-protease/index.md +++ b/docs/case-studies/hiv-protease/index.md @@ -3,178 +3,3 @@ This guide focuses on using Amber to simulate HIV-1 protease, a crucial enzyme in the life cycle of the human immunodeficiency virus (HIV) and a prime target for antiretroviral therapy. The following sections will cover the practical aspects of using Amber for HIV-1 protease simulations, including system preparation, force field selection, simulation protocols, and data analysis techniques. -## Background - -HIV-1 protease plays a critical role in the maturation of HIV particles, making it an essential component in the virus's replication process. -HIV-1 protease enables the formation of infectious viral particles by cleaving viral polyproteins into functional proteins. -Understanding this enzyme's structure, dynamics, and function is paramount for developing effective inhibitors and advancing HIV treatment strategies. - -The significance of HIV-1 protease extends beyond its immediate role in viral replication: - -1. **Public health impact:** HIV/AIDS remains a global health challenge, affecting millions of people worldwide. Insights gained from studying HIV-1 protease contribute to the ongoing efforts to combat this pandemic. -2. **Drug design:** As a prime target for antiretroviral drugs, detailed knowledge of HIV-1 protease's structure and dynamics is crucial for rational drug design and developing new therapeutic strategies. -3. **Resistance mechanisms:** HIV's rapid mutation rate often leads to drug resistance. MD simulations can help elucidate the molecular basis of these resistance mechanisms, informing the design of more robust inhibitors. - -From a biophysical perspective, HIV-1 protease presents several exciting characteristics that make it an excellent subject for MD simulations: - -1. **Structural flexibility:** The enzyme exhibits significant conformational changes during its catalytic cycle, particularly in the "flap" regions that control access to the active site. - MD simulations can capture these dynamic processes, providing insights into the enzyme's mechanism. -2. **Homodimeric nature:** HIV-1 protease functions as a homodimer, with the active site formed at the interface between two identical subunits. - This symmetry adds an interesting dimension to the simulation setup and analysis. -3. **Substrate specificity:** The enzyme recognizes and cleaves specific sequences in viral polyproteins. - MD simulations can help elucidate the molecular basis of this specificity and how mutations might affect it. -4. **Water-Mediated Interactions:** Water molecules play a crucial role in the enzyme's catalytic mechanism and mediating protein-ligand interactions. - Explicit solvent MD simulations are particularly valuable for studying these effects. -5. **Allosteric effects:** Recent studies have suggested the presence of allosteric sites in HIV-1 protease, opening new avenues for drug design. - MD simulations can help identify and characterize these sites. - -## Protein preparation - -System preparation is a crucial step in molecular dynamics (MD) simulations that significantly impacts the quality and reliability of results. -This process involves selecting an appropriate starting structure and setting up the system to accurately represent physiological conditions. -Proper preparation minimizes artifacts and ensures that simulations reflect the true behavior of the protein in its biological context. - -### Protein selection - -By meticulously selecting a starting structure based on these criteria, we establish a strong foundation for our MD simulations of HIV-1 protease. -This careful selection process increases the likelihood of obtaining biologically relevant and computationally robust results, which are crucial for understanding the protein's behavior and for applications such as drug design and the study of resistance mechanisms. -Remember that the chosen structure will serve as the basis for all subsequent steps in the simulation process, including system setup, energy minimization, and production runs. -Therefore, the time invested in selecting an appropriate structure is well spent and can save considerable effort and computational resources in the long run. - -We will use the Protein Data Bank (PDB) as our primary source of structural data. -When selecting a structure, consider the following criteria: - -1. **Resolution:** Prioritize high-resolution structures (typically < 2.0 Å) for more accurate atomic positions. - Lower resolution (i.e., > 2.0 Å) structures may lead to simulation inaccuracies due to less precise atomic coordinates. -2. **Validation Scores:** Use the PDB validation reports to assess structure quality. - Key metrics include: - - Clashscore: Lower values indicate fewer steric clashes between atoms. - - Ramachandran outliers: Fewer outliers suggest better backbone geometry. - - Rotamer outliers: Fewer outliers indicate more reliable side-chain conformations. - - Overall quality at a glance: Provides a quick assessment of the structure's quality. -3. **Completeness:** Choose structures with minimal missing atoms or residues to reduce uncertainties in the simulation. -4. **Apo structure:** Use a ligand-free (apo) structure to study the intrinsic dynamics of HIV-1 protease without bias from bound ligands or inhibitors. -5. **HIV variant:** Select a structure representing the most common HIV variant, such as HIV-1 subtype B, which is prevalent in North America, Western Europe, and Australia. -6. **Experimental method:** While X-ray crystallography is common, consider high-quality structures from other methods like cryo-electron microscopy (cryo-EM) or NMR spectroscopy if they offer advantages in physiological relevance or completeness. -7. **Publication date and citations:** Balance recent structures benefiting from improved techniques with well-established, highly cited structures that allow comparison with previous studies. -8. **Physiological relevance:** Prefer structures determined under conditions mimicking physiological environments, such as appropriate pH and temperature. -9. **Authors and laboratory reputation:** Structures from laboratories with expertise in HIV protease can provide additional confidence in data quality. - -To begin the search, we used the following parameters in the PDB: - -- **Full Text**: `HIV Protease` -- **Polymer Entity Type** is `Protein` -- **Refinement Resolution** is between `0.5` to `2` (upper included). -- **Enzyme Classification Name** is `Hydrolases`. -- **Scientific Name of the Source Organism** is `Human immunodeficiency virus 1`. - -!!! note - - It's worth noting that while we aim for an apo structure to avoid bias, in some cases, the highest quality available structures may be ligand-bound. - If this is the case, we'll need to carefully remove the ligand and consider running a short equilibration simulation to allow the protein to relax into its unbound state. - -[You can go here to view the search results.][hiv-search]. -At the time of writing there were 302 results, but there are only a few that do not have any drug-like ligands: [`1TW7`](https://www.rcsb.org/structure/1TW7), [`2PC0`](https://www.rcsb.org/structure/2PC0), and [`2G69`](https://www.rcsb.org/structure/2G69). -Both [`1TW7`](https://www.rcsb.org/structure/1TW7) and [`2G69`](https://www.rcsb.org/structure/2G69) have one or more mutations studying drug resistance mechanism, so we will ignore these for now. -This leaves [`2PC0`](https://www.rcsb.org/structure/2PC0) as our protein. - -
- - - -### Trimming PDB file - -???+ note "Prelude" - - ```text - --8<-- "docs/case-studies/hiv-protease/files/structures/2PC0.pdb::53" - ``` - -???+ note "Temperature factors" - - ```text - --8<-- "docs/case-studies/hiv-protease/files/structures/2PC0.pdb:55:58" - ``` - -### Removing water molecules - -```text ---8<-- "docs/case-studies/hiv-protease/files/structures/2PC0.pdb:1735:1738" -``` - -```bash ---8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:27:27" -``` - -### Removing non-protein molecules - -```bash ---8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:28:29" -``` - -### Removing duplicate atom lines - -```bash ---8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:32:52" -``` - -### Turning models into chains - -```bash ---8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:55:56" -``` - -### Renumber - -```bash ---8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:58:58" -``` - -### Result - -
- - - -## System preparation - -TODO: Introduce tleap and amber - - - -[hiv-search]: https://www.rcsb.org/search?request=%7B%22query%22%3A%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22full_text%22%2C%22parameters%22%3A%7B%22value%22%3A%22HIV%20Protease%22%7D%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%5D%2C%22logical_operator%22%3A%22and%22%2C%22label%22%3A%22full_text%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22entity_poly.rcsb_entity_polymer_type%22%2C%22value%22%3A%22Protein%22%2C%22operator%22%3A%22exact_match%22%7D%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22entity_poly.rcsb_entity_polymer_type%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22rcsb_entry_info.resolution_combined%22%2C%22value%22%3A%7B%22from%22%3A0.5%2C%22to%22%3A2%2C%22include_lower%22%3Atrue%2C%22include_upper%22%3Atrue%7D%2C%22operator%22%3A%22range%22%7D%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22rcsb_entry_info.resolution_combined%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22rcsb_polymer_entity.rcsb_ec_lineage.name%22%2C%22value%22%3A%22Hydrolases%22%2C%22operator%22%3A%22exact_match%22%7D%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22rcsb_polymer_entity.rcsb_ec_lineage.name%22%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22rcsb_entity_source_organism.ncbi_scientific_name%22%2C%22value%22%3A%22Human%20immunodeficiency%20virus%201%22%2C%22operator%22%3A%22exact_match%22%7D%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22rcsb_entity_source_organism.ncbi_scientific_name%22%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%5D%2C%22logical_operator%22%3A%22and%22%2C%22label%22%3A%22text%22%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%2C%22return_type%22%3A%22entry%22%2C%22request_options%22%3A%7B%22paginate%22%3A%7B%22start%22%3A0%2C%22rows%22%3A25%7D%2C%22results_content_type%22%3A%5B%22experimental%22%5D%2C%22sort%22%3A%5B%7B%22sort_by%22%3A%22score%22%2C%22direction%22%3A%22desc%22%7D%5D%2C%22scoring_strategy%22%3A%22combined%22%7D%2C%22request_info%22%3A%7B%22query_id%22%3A%229bf9fe45638e11d563f8a0807116b29a%22%7D%7D diff --git a/docs/case-studies/hiv-protease/protein/clean.md b/docs/case-studies/hiv-protease/protein/clean.md new file mode 100644 index 0000000..77a74a8 --- /dev/null +++ b/docs/case-studies/hiv-protease/protein/clean.md @@ -0,0 +1,84 @@ +# PDB cleaning + +## Filtering lines + +PDB files often contain structure metadata about how the structure was prepared, processed, published, etc. in the header of the file. +You should be familiar with what the header contains about your structure. +Once you decide to use a structure, however, you can safely ignore these lines. + +??? note "Header" + + ```text + --8<-- "docs/case-studies/hiv-protease/files/structures/2PC0.pdb::53" + ``` + +`ATOM` and `HETATM` records contain the structural information we are most interested in. +However, there are sometimes `ANISOU` records that specify temperature factors of atoms. +Structure quality can be inferred from these values but ultimately should be removed before further processing. + +???+ note "Temperature factors" + Example atom records and temperature factors for atoms `1` and `2` in a proline. + + ```text + --8<-- "docs/case-studies/hiv-protease/files/structures/2PC0.pdb:55:58" + ``` + +## Removing water molecules + +```text +--8<-- "docs/case-studies/hiv-protease/files/structures/2PC0.pdb:1735:1738" +``` + +```bash +--8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:27:27" +``` + +## Removing non-protein molecules + +```bash +--8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:28:29" +``` + +## Removing duplicate atom lines + +```bash +--8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:32:52" +``` + +## Turning models into chains + +```bash +--8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:55:56" +``` + +## Renumber + +```bash +--8<-- "docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh:58:58" +``` + +## Result + +
+ + + + diff --git a/docs/case-studies/hiv-protease/protein/index.md b/docs/case-studies/hiv-protease/protein/index.md new file mode 100644 index 0000000..5a1d06c --- /dev/null +++ b/docs/case-studies/hiv-protease/protein/index.md @@ -0,0 +1,6 @@ +# Protein preparation + +System preparation is a crucial step in molecular dynamics (MD) simulations that significantly impacts the quality and reliability of results. +This process involves selecting an appropriate starting structure and setting up the system to accurately represent physiological conditions. +Proper preparation minimizes artifacts and ensures that simulations reflect the true behavior of the protein in its biological context. + diff --git a/docs/case-studies/hiv-protease/protein/selection.md b/docs/case-studies/hiv-protease/protein/selection.md new file mode 100644 index 0000000..4e229f9 --- /dev/null +++ b/docs/case-studies/hiv-protease/protein/selection.md @@ -0,0 +1,67 @@ +# Protein selection + +By meticulously selecting a starting structure based on these criteria, we establish a strong foundation for our MD simulations of HIV-1 protease. +This careful selection process increases the likelihood of obtaining biologically relevant and computationally robust results, which are crucial for understanding the protein's behavior and for applications such as drug design and the study of resistance mechanisms. +Remember that the chosen structure will serve as the basis for all subsequent steps in the simulation process, including system setup, energy minimization, and production runs. +Therefore, the time invested in selecting an appropriate structure is well spent and can save considerable effort and computational resources in the long run. + +We will use the Protein Data Bank (PDB) as our primary source of structural data. +When selecting a structure, consider the following criteria: + +1. **Resolution:** Prioritize high-resolution structures (typically < 2.0 Å) for more accurate atomic positions. + Lower resolution (i.e., > 2.0 Å) structures may lead to simulation inaccuracies due to less precise atomic coordinates. +2. **Validation Scores:** Use the PDB validation reports to assess structure quality. + Key metrics include: + - Clashscore: Lower values indicate fewer steric clashes between atoms. + - Ramachandran outliers: Fewer outliers suggest better backbone geometry. + - Rotamer outliers: Fewer outliers indicate more reliable side-chain conformations. + - Overall quality at a glance: Provides a quick assessment of the structure's quality. +3. **Completeness:** Choose structures with minimal missing atoms or residues to reduce uncertainties in the simulation. +4. **Apo structure:** Use a ligand-free (apo) structure to study the intrinsic dynamics of HIV-1 protease without bias from bound ligands or inhibitors. +5. **HIV variant:** Select a structure representing the most common HIV variant, such as HIV-1 subtype B, which is prevalent in North America, Western Europe, and Australia. +6. **Experimental method:** While X-ray crystallography is common, consider high-quality structures from other methods like cryo-electron microscopy (cryo-EM) or NMR spectroscopy if they offer advantages in physiological relevance or completeness. +7. **Publication date and citations:** Balance recent structures benefiting from improved techniques with well-established, highly cited structures that allow comparison with previous studies. +8. **Physiological relevance:** Prefer structures determined under conditions mimicking physiological environments, such as appropriate pH and temperature. +9. **Authors and laboratory reputation:** Structures from laboratories with expertise in HIV protease can provide additional confidence in data quality. + +To begin the search, we used the following parameters in the PDB: + +- **Full Text**: `HIV Protease` +- **Polymer Entity Type** is `Protein` +- **Refinement Resolution** is between `0.5` to `2` (upper included). +- **Enzyme Classification Name** is `Hydrolases`. +- **Scientific Name of the Source Organism** is `Human immunodeficiency virus 1`. + +!!! note + + It's worth noting that while we aim for an apo structure to avoid bias, in some cases, the highest quality available structures may be ligand-bound. + If this is the case, we'll need to carefully remove the ligand and consider running a short equilibration simulation to allow the protein to relax into its unbound state. + +[You can go here to view the search results.][hiv-search] +At the time of writing there were 302 results, but there are only a few that do not have any drug-like ligands: [`1TW7`](https://www.rcsb.org/structure/1TW7), [`2PC0`](https://www.rcsb.org/structure/2PC0), and [`2G69`](https://www.rcsb.org/structure/2G69). +Both [`1TW7`](https://www.rcsb.org/structure/1TW7) and [`2G69`](https://www.rcsb.org/structure/2G69) have one or more mutations studying drug resistance mechanism, so we will ignore these for now. +This leaves [`2PC0`](https://www.rcsb.org/structure/2PC0) as our protein. + +
+ + + +[hiv-search]: https://www.rcsb.org/search?request=%7B%22query%22%3A%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22full_text%22%2C%22parameters%22%3A%7B%22value%22%3A%22HIV%20Protease%22%7D%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%5D%2C%22logical_operator%22%3A%22and%22%2C%22label%22%3A%22full_text%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22entity_poly.rcsb_entity_polymer_type%22%2C%22value%22%3A%22Protein%22%2C%22operator%22%3A%22exact_match%22%7D%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22entity_poly.rcsb_entity_polymer_type%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22rcsb_entry_info.resolution_combined%22%2C%22value%22%3A%7B%22from%22%3A0.5%2C%22to%22%3A2%2C%22include_lower%22%3Atrue%2C%22include_upper%22%3Atrue%7D%2C%22operator%22%3A%22range%22%7D%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22rcsb_entry_info.resolution_combined%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22rcsb_polymer_entity.rcsb_ec_lineage.name%22%2C%22value%22%3A%22Hydrolases%22%2C%22operator%22%3A%22exact_match%22%7D%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22rcsb_polymer_entity.rcsb_ec_lineage.name%22%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%2C%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22group%22%2C%22nodes%22%3A%5B%7B%22type%22%3A%22terminal%22%2C%22service%22%3A%22text%22%2C%22parameters%22%3A%7B%22attribute%22%3A%22rcsb_entity_source_organism.ncbi_scientific_name%22%2C%22value%22%3A%22Human%20immunodeficiency%20virus%201%22%2C%22operator%22%3A%22exact_match%22%7D%7D%5D%2C%22logical_operator%22%3A%22or%22%2C%22label%22%3A%22rcsb_entity_source_organism.ncbi_scientific_name%22%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%5D%2C%22logical_operator%22%3A%22and%22%2C%22label%22%3A%22text%22%7D%5D%2C%22logical_operator%22%3A%22and%22%7D%2C%22return_type%22%3A%22entry%22%2C%22request_options%22%3A%7B%22paginate%22%3A%7B%22start%22%3A0%2C%22rows%22%3A25%7D%2C%22results_content_type%22%3A%5B%22experimental%22%5D%2C%22sort%22%3A%5B%7B%22sort_by%22%3A%22score%22%2C%22direction%22%3A%22desc%22%7D%5D%2C%22scoring_strategy%22%3A%22combined%22%7D%2C%22request_info%22%3A%7B%22query_id%22%3A%229bf9fe45638e11d563f8a0807116b29a%22%7D%7D + diff --git a/docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh b/docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh index a69dd11..200c9ce 100755 --- a/docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh +++ b/docs/case-studies/hiv-protease/scripts/01-clean-pdb.sh @@ -21,7 +21,7 @@ OUTPUT_PATH=$SAVE_DIR/$PDB_ID-cleaned.pdb cp $INPUT_PATH $OUTPUT_PATH -simlify-pdb-filter $OUTPUT_PATH --output $OUTPUT_PATH +simlify pdb filter $OUTPUT_PATH --output $OUTPUT_PATH # Remove water molecules and other ligands. sed -i "/HOH/d" "$OUTPUT_PATH" diff --git a/docs/case-studies/hiv-protease/system/index.md b/docs/case-studies/hiv-protease/system/index.md new file mode 100644 index 0000000..d200cb5 --- /dev/null +++ b/docs/case-studies/hiv-protease/system/index.md @@ -0,0 +1,4 @@ +# System preparation + +TODO: Introduce tleap and amber + diff --git a/docs/cli/index.md b/docs/cli/index.md new file mode 100644 index 0000000..71004f3 --- /dev/null +++ b/docs/cli/index.md @@ -0,0 +1,3 @@ +# Command line interface + + diff --git a/docs/cli/pdb/filter/index.md b/docs/cli/pdb/filter/index.md new file mode 100644 index 0000000..1a60b49 --- /dev/null +++ b/docs/cli/pdb/filter/index.md @@ -0,0 +1,38 @@ +# `filter` + +## Arguments + +### `--records` + +Every PDB file contains [many records](https://www.wwpdb.org/documentation/file-format-content/format33/v3.3.html) for depositors to use. +The main ones we care about are the ones in the [coordinate section](https://www.wwpdb.org/documentation/file-format-content/format33/sect9.html) including: [`ATOM`](https://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#ATOM), [`HETATM`](https://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#HETATM), [`TER`](https://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#TER), [`MODEL`](https://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#MODEL), [`ENDMDL`](https://www.wwpdb.org/documentation/file-format-content/format33/sect9.html#ENDMDL) +We can specify the records we want to keep using the `--records` argument. + +```bash +--records ATOM,HETATM,TER,MODEL,ENDMDL +``` + +!!! warning + + Records should always be separated by commas and there should no spaces between the records. + For example, `--records ATOM, HETATM` and `--records ATOM;HETATM` will fail. + +By default, not specifying this option will result in `ATOM`, `HETATM`, `TER`, `MODEL`, and `ENDMDL` being kept. + +### `--output` + +Specifies where to write the new PDB file with only the specified records. + +### `pdb_path` + +Path to the PDB file to filter. + +## Examples + +Here are some examples of filtering lines from PDB files. + +### Keeping coordinate information + +```bash +simlify pdb filter --output filtered.pdb --records ATOM HETATM TER MODEL original.pdb +``` diff --git a/docs/cli/pdb/index.md b/docs/cli/pdb/index.md new file mode 100644 index 0000000..c72f51f --- /dev/null +++ b/docs/cli/pdb/index.md @@ -0,0 +1,4 @@ +# PDB + +TODO: Write about what these tools do. + diff --git a/docs/concepts/.nav.yml b/docs/concepts/.nav.yml deleted file mode 100644 index a0b53a0..0000000 --- a/docs/concepts/.nav.yml +++ /dev/null @@ -1,2 +0,0 @@ -nav: - - Concepts: index.md diff --git a/docs/css/base.css b/docs/css/base.css index 1217e08..a028c85 100644 --- a/docs/css/base.css +++ b/docs/css/base.css @@ -1,7 +1,7 @@ /*Make the content wider and relative to window size.*/ .md-grid { - max-width: 85% + max-width: 80% } :root { diff --git a/mkdocs.yml b/mkdocs.yml index 53390ec..04d08f2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,14 +79,6 @@ plugins: parameter_headings: false show_symbol_type_heading: true show_symbol_type_toc: true - - mkdocs-jupyter: - no_input: False - include_requirejs: true - include_source: True - ignore: ["*.py"] - remove_tag_config: - remove_input_tags: - - hide_code - awesome-nav - glightbox - macros @@ -95,7 +87,6 @@ plugins: timezone: America/Detroit fallback_to_build_date: true - extra: generator: false diff --git a/pixi.lock b/pixi.lock index 6975df3..ae54f63 100644 --- a/pixi.lock +++ b/pixi.lock @@ -15,13 +15,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py313ha014f3b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.59.0-py313h3dea7bd_0.conda @@ -31,7 +31,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/h5py-3.14.0-nompi_py313hfaf8fd4_100.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h2a13503_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.6-nompi_h6e4c0c1_103.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.8-py313h33d0bda_1.conda @@ -40,11 +39,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-32_h59b9bed_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-33_h59b9bed_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-32_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-33_he106b2a_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.14.1-h332b0f4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda @@ -53,33 +52,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-32_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-33_h7ac8fdf_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h0134ee8_117.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h21f7587_118.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h943b412_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h2cb61b6_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.11.2-h6991a6a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.5-py313h683a580_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mdanalysis-2.9.0-py313ha87cce1_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 @@ -90,8 +89,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.7.2-nompi_py313h6d1955d_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.2-py313hf6604e3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.2-h26f9b46_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.1-py313h08cd8bf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.1-pyhd8ed1ab_1.conda @@ -100,7 +99,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py313h4b2b08d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.5-hec9711d_102_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda @@ -134,9 +133,9 @@ environments: - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a8/e8/86e7741adb43261aff409b53c53c8bac2797bfca055d64dd65dc731d5141/numcodecs-0.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b8/d9/5e2753784ea30d84b3e769a56f5e50ac5a89c129e87baa16ac0773eb4ef7/polars-1.31.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ec/14/ee34ebe3eb842c83ca1d2d3af6ee02b08377e056ffad156c9a2b15a6d05c/polars-1.32.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ osx-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -145,13 +144,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.5-hf13058a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.4-py313h8f4588c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313hc551f4f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313hc551f4f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.59.0-py313h4db2fa4_0.conda @@ -168,11 +167,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.4-ha6bc127_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-32_h7f60823_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-33_h7f60823_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.1.0-h6e16a3a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-32_hff6cab4_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-33_hff6cab4_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.14.1-h5dec5d8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.8-h3d58e20_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.24-hcc1b750_0.conda @@ -186,24 +185,24 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h51e75f0_103.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h4b5e92a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-32_h236ab99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-33_h236ab99_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h924628f_117.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h6054f6d_118.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.64.0-hc7306c3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_hbf64a52_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h3c4a55f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.3-h875aaf5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h84aeda2_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.4-h39a8b3b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-h1167cee_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-h93c44a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-he1bc88e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.11.2-h31df5bb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.3-py313he981572_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.5-py313h5771d13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mdanalysis-2.9.0-py313h2e7108f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 @@ -214,8 +213,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.7.2-nompi_py313h623cd79_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.2-py313hdb1a8e5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.1-hc426f3f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h036ada5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.2-h6e31bce_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.1-py313h366a99e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.1-pyhd8ed1ab_1.conda @@ -224,7 +223,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.33.2-py313hb35714d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.5-hc3a4c56_102_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda @@ -258,9 +257,9 @@ environments: - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/1e/73ffb1074f03d52cb1c4f4deaba26a2008ca45262f3622ed26dbec7a7362/numcodecs-0.16.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3d/6e/bdd0937653c1e7a564a09ae3bc7757ce83fedbf19da600c8b35d62c0182a/polars-1.31.0-cp39-abi3-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/61/b251ce6755d0d3c6f4c8cb245941b80901624fce7efeb95b37c170da2565/polars-1.32.2-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -269,13 +268,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.5-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.4-py313h93df234_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.59.0-py313ha0c97b7_0.conda @@ -292,11 +291,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.4-h51d1e36_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-32_h10e41b3_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-33_h10e41b3_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.1.0-h5505292_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-32_hb3479ef_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-33_hb3479ef_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.14.1-h73640d1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-20.1.8-hf598326_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.24-h5773f1b_0.conda @@ -310,24 +309,24 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-14.2.0-h6c33f7e_103.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-hfe07756_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-32_hc9a63f6_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-33_hc9a63f6_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h3352478_117.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h2d3d5cf_118.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.64.0-h6d7220d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_hf332438_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h3783ad8_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.3-h4237e3c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h280e0eb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h2f21f7c_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h52572c6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h4a9ca0c_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.11.2-h1336266_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.3-py313haaf02c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.5-py313h919948c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mdanalysis-2.9.0-py313h668b085_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 @@ -338,8 +337,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.7.2-nompi_py313h2bc0fea_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.2-py313h674b998_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h8a3d83b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.1-h81ee809_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.2-he92f556_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.1-py313hd1f53c0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.1-pyhd8ed1ab_1.conda @@ -348,7 +347,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.11.7-pyh3cfb1c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.33.2-py313hf3ab51e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.5-hf3f3da0_102_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda @@ -382,9 +381,9 @@ environments: - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/42/72/5affb1ce92b7a6becee17921de7c6b521a48fa61fc3d36d9f1eea2cf83f5/numcodecs-0.16.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/77/fe/81aaca3540c1a5530b4bc4fd7f1b6f77100243d7bb9b7ad3478b770d8b3e/polars-1.31.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/22/74/ea073a88073cd6025b12850484f51d30dad695b51432a3f0a0439e2f8094/polars-1.32.2-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ dev: channels: @@ -401,7 +400,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/astroid-3.3.11-py312h7900ff3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.1-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/biopython-1.85-py312h66e93f0_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_3.conda @@ -409,23 +408,23 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py312h2ec8cdc_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py312h06ac9bb_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py312hc0a28a1_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cmarkgfm-2024.11.20-py312h66e93f0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py312hd9148b4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.10.0-py312h8a5da7c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py312hd9148b4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.10.2-py312h8a5da7c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.11-py312hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-45.0.5-py312hda17c39_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-45.0.6-py312hee9fe19_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dill-0.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hf1063bd_110.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda @@ -460,12 +459,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-32_h59b9bed_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-33_h59b9bed_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libboost-1.86.0-h6c02f8c_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-32_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-33_he106b2a_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.14.1-h332b0f4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda @@ -474,52 +473,52 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.11.2-default_h3d81e11_1002.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.3-hf39c6af_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h3d81e11_1000.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-32_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-33_h7ac8fdf_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h0134ee8_117.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h21f7587_118.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h943b412_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h04c0eec_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.11.2-h6991a6a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.8-h4922eb0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.8-h4922eb0_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py312h178313f_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py312hd3ec401_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.5-py312he3d6523_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mdanalysis-2.9.0-py312hf9745cd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mrcfile-1.5.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.1-py312h68727a3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.17.0-py312h4c3975b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.17.1-py312h4c3975b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf-fortran-4.6.2-nompi_h5aa5643_101.conda @@ -527,10 +526,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nh3-0.3.0-py39hd511f7d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.4.1-heeeca48_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.2-py312h33ff503_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.2-h26f9b46_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.1-py312hf79963d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/parmed-4.3.0-py312ha9124a0_1.conda @@ -549,7 +548,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pylint-3.3.7-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda @@ -569,7 +568,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.11.13-py312h1d08497_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.12.7-hf9daec2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.1-py312h4f0b9e3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.0-py312hf734454_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda @@ -579,12 +578,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.5-py312h8b63200_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-hceb3a55_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-hb60516a_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tidynamics-1.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-6.1.0-pyh29332c3_0.conda @@ -606,17 +605,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py312h66e93f0_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - pypi: git+https://github.com/scienting/atomea?branch=main#295c1346c6a4f3cc57d8b88b7e729c4d77fbe469 - - pypi: https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/79/13/13576941bf7cf95026abae43d8427c812c0054408212bf8ed490eda846b0/crc32c-2.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1b/f5/515f98d659ab0cbe3738da153eddae22186fd38f05a808511e10f04cf679/numcodecs-0.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b8/d9/5e2753784ea30d84b3e769a56f5e50ac5a89c129e87baa16ac0773eb4ef7/polars-1.31.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ec/14/ee34ebe3eb842c83ca1d2d3af6ee02b08377e056ffad156c9a2b15a6d05c/polars-1.32.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/36/71/610ac09997ae76138b326a7c89000d9c43da3382db320e3c81e7e9e2a9cc/pyrefly-0.16.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/0d/14/bb882645300ecaa43e93db1e39ce1e5071f1b65ef8a9de7e939039f32ec2/pyrefly-0.27.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ab/ac/8f96ba9b4cfe3e4ea201f23f4f97165862395e9331a424ed325ae37024a8/setuptools_scm-8.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ osx-64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda @@ -626,7 +625,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/astroid-3.3.11-py312hb401068_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.1-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/biopython-1.85-py312h01d7ebd_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/blosc-1.21.6-hd145fbb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-1.1.0-h6e16a3a_3.conda @@ -634,21 +633,21 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py312haafddd8_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.5-hf13058a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.17.1-py312hf857d28_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.4-py312h3a11e2b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cmarkgfm-2024.11.20-py312h01d7ebd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py312hedd4973_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.10.0-py312h3d55d04_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py312hedd4973_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.10.2-py312h3d55d04_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.11-py312hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dill-0.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fftw-3.3.10-nompi_h292e606_110.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda @@ -680,12 +679,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.4-ha6bc127_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-32_h7f60823_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-33_h7f60823_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libboost-1.86.0-hf0da243_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.1.0-h6e16a3a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-32_hff6cab4_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-33_hff6cab4_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.14.1-h5dec5d8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.8-h3d58e20_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.24-hcc1b750_0.conda @@ -699,26 +698,26 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h51e75f0_103.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h4b5e92a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-32_h236ab99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-33_h236ab99_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h924628f_117.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h6054f6d_118.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.64.0-hc7306c3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_hbf64a52_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h3c4a55f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.3-h875aaf5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h84aeda2_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.4-h39a8b3b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-h1167cee_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h4cb831e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-h93c44a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-he1bc88e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.11.2-h31df5bb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.2-py312h3520af0_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.3-py312h535dea3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.5-py312hb83d5b5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mdanalysis-2.9.0-py312hec45ffd_1.conda @@ -728,7 +727,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mrcfile-1.5.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.1-py312hc47a885_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.17.0-py312h2f459f6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.17.1-py312h2f459f6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf-fortran-4.6.2-nompi_hc6d3b56_100.conda @@ -736,10 +735,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nh3-0.3.0-py39ha61a9bf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nodejs-24.4.1-h2e7699b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.2-py312hda18a35_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.1-hc426f3f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h036ada5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.2-h6e31bce_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.1-py312hbf2c5ff_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/parmed-4.3.0-py312h9a1398e_1.conda @@ -757,7 +756,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pylint-3.3.7-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda @@ -777,7 +776,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.11.13-py312heade784_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.12.7-h6cc4cfe_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.7.1-py312hf34d0c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.16.0-py312hd0c0319_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda @@ -790,7 +789,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tidynamics-1.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-6.1.0-pyh29332c3_0.conda @@ -812,17 +811,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.23.0-py312h01d7ebd_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda - pypi: git+https://github.com/scienting/atomea?branch=main#295c1346c6a4f3cc57d8b88b7e729c4d77fbe469 - - pypi: https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9c/3e/e3656bfa76e50ef87b7136fef2dbf3c46e225629432fc9184fdd7fd187ff/crc32c-2.7.1-cp312-cp312-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ee/e2a903c88fed347dc74c70bbd7a8dab9aa22bb0dac68c5bc6393c2e9373b/numcodecs-0.16.1-cp312-cp312-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3d/6e/bdd0937653c1e7a564a09ae3bc7757ce83fedbf19da600c8b35d62c0182a/polars-1.31.0-cp39-abi3-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/61/b251ce6755d0d3c6f4c8cb245941b80901624fce7efeb95b37c170da2565/polars-1.32.2-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/13/1d/1bf1102c17f496d7ef6ae2debdd990505f56fc4ed521aec371b8bdf8b607/pyrefly-0.16.3-py3-none-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/56/5f/27eb8c57b5d6e58988f1e57a7d2e80a7a95f79d420ed89a9cbfe779170b7/pyrefly-0.27.1-py3-none-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ab/ac/8f96ba9b4cfe3e4ea201f23f4f97165862395e9331a424ed325ae37024a8/setuptools_scm-8.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda @@ -832,28 +831,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/astroid-3.3.11-py313h8f79df9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports-1.0-pyhd8ed1ab_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/backports.tarfile-1.2.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.0-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.1-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/blosc-1.21.6-h7dd00d9_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py313h928ef07_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.5-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.17.1-py313hc845a76_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.4-py313h93df234_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmarkgfm-2024.11.20-py313h90d716c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.10.0-py313ha0c97b7_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.10.2-py313ha0c97b7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.5-py313hd8ed1ab_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dill-0.4.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fftw-3.3.10-nompi_h6637ab6_110.conda - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda @@ -885,12 +884,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.4-h51d1e36_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-32_h10e41b3_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-33_h10e41b3_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libboost-1.86.0-hc9fb7c5_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.1.0-h5505292_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-32_hb3479ef_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-33_hb3479ef_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.14.1-h73640d1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-20.1.8-hf598326_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.24-h5773f1b_0.conda @@ -904,27 +903,27 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-14.2.0-h6c33f7e_103.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-hfe07756_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-32_hc9a63f6_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-33_hc9a63f6_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h3352478_117.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h2d3d5cf_118.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.64.0-h6d7220d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_hf332438_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h3783ad8_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.3-h4237e3c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h280e0eb_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h2f21f7c_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h5505292_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h52572c6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h4a9ca0c_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.11.2-h1336266_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.2-py313ha9b7d5b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.3-py313haaf02c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.5-py313h919948c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mdanalysis-2.9.0-py313h668b085_1.conda @@ -934,7 +933,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mrcfile-1.5.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.1-py313h0ebd0e5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.17.0-py313hcdf3177_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.17.1-py313hcdf3177_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf-fortran-4.6.2-nompi_hbeb164d_100.conda @@ -942,10 +941,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nh3-0.3.0-py39h24c5d98_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-24.4.1-hab9d20b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.2-py313h674b998_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h8a3d83b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.1-h81ee809_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.2-he92f556_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.1-py313hd1f53c0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/parmed-4.3.0-py313h70a7ac0_1.conda @@ -963,7 +962,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pylint-3.3.7-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.2.1-pyhd8ed1ab_0.conda @@ -983,7 +982,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.1.0-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.11.13-py313h19b3928_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.12.7-h575f11b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.7.1-py313h595da1d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.0-py313h9a24e0a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda @@ -996,7 +995,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tidynamics-1.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-6.1.0-pyh29332c3_0.conda @@ -1017,17 +1016,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.23.0-py313h90d716c_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda - pypi: git+https://github.com/scienting/atomea?branch=main#295c1346c6a4f3cc57d8b88b7e729c4d77fbe469 - - pypi: https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/47/02/2bd65fdef10139b6a802d83a7f966b7750fe5ffb1042f7cbe5dbb6403869/crc32c-2.7.1-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/42/72/5affb1ce92b7a6becee17921de7c6b521a48fa61fc3d36d9f1eea2cf83f5/numcodecs-0.16.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/77/fe/81aaca3540c1a5530b4bc4fd7f1b6f77100243d7bb9b7ad3478b770d8b3e/polars-1.31.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/22/74/ea073a88073cd6025b12850484f51d30dad695b51432a3f0a0439e2f8094/polars-1.32.2-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ed/8e/e5fa5c7cb327bb5ca086c9e1662b16ad9593e68bb41699e8d50299b7a514/pyrefly-0.16.3-py3-none-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5e/d1/20ddf3c3c90e3422f54267b4743f1fdb14e7cf0425a1614c9e732b9f68f3/pyrefly-0.27.1-py3-none-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/ab/ac/8f96ba9b4cfe3e4ea201f23f4f97165862395e9331a424ed325ae37024a8/setuptools_scm-8.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ docs: channels: @@ -1052,19 +1051,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py313h46c70d0_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py313hfab6e84_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py313ha014f3b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.15-py313h5d5ffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.16-py313h5d5ffb9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda @@ -1076,7 +1075,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/gitdb-4.0.12-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.45-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/griddataformats-1.0.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gsd-4.0.0-py313h536fd9c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/h5py-3.14.0-nompi_py313hfaf8fd4_100.conda @@ -1085,10 +1084,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/hjson-py-3.1.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.30.1-pyh82676e8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.4.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -1107,11 +1105,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.44-h1423503_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-32_h59b9bed_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-33_h59b9bed_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-32_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-33_he106b2a_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.14.1-h332b0f4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda @@ -1120,37 +1118,37 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-32_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-33_h7ac8fdf_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h0134ee8_117.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h21f7587_118.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h943b412_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h2cb61b6_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.11.2-h6991a6a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py313h8060acc_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.5-py313h683a580_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mdanalysis-2.9.0-py313ha87cce1_1.conda @@ -1160,7 +1158,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.4.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.5.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-git-revision-date-localized-plugin-1.2.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-glightbox-0.4.0-pyhd8ed1ab_1.conda @@ -1169,7 +1167,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-table-reader-plugin-3.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.28.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/mrcfile-1.5.4-pyhd8ed1ab_0.conda @@ -1185,8 +1183,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.7.2-nompi_py313h6d1955d_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.2-py313hf6604e3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.2-h26f9b46_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.1-py313h08cd8bf_0.conda @@ -1209,8 +1207,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.33.2-py313h4b2b08d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.5-hec9711d_102_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda @@ -1221,12 +1219,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py313h8060acc_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.0.0-py313h8e95178_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.0.1-py313hb9b051e_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.26.0-py313h4b2b08d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.27.0-py313h843e2db_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.1-py313h06d4379_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.0-py313h86fcf2b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda @@ -1246,7 +1244,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tidynamics-1.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda @@ -1271,14 +1269,14 @@ environments: - pypi: https://files.pythonhosted.org/packages/01/cf/32f019be5de9f6e180926a50ee5f08648e686c7d9a59f2c5d0806a77b1c7/crc32c-2.7.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/48/9d/797d595dc57bbcb6284584ca7e228ac54b421aa1e864cec15d0f78e02f4b/material_plausible_plugin-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/42/097a9eee92b2b96979823ae55b2b42fba590f79f979a0b24138db628fac4/material_plausible_plugin-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/23/2ae189f4bbb5d35bf6dbd202a534b3f7f929c404d056fb0b20e826b9b643/mkdocs_awesome_nav-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e1/46/db5d3235cfa6764e3b09ea82cb2c606b2a5bbe77547eb551ad30bc85d0cf/mkdocs_print_site_plugin-2.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/3e/7513f2f37c563da65d1b91781e047f4a1c0ceac8206d4f6042428428e4ad/mkdocs_print_site_plugin-2.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a8/e8/86e7741adb43261aff409b53c53c8bac2797bfca055d64dd65dc731d5141/numcodecs-0.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b8/d9/5e2753784ea30d84b3e769a56f5e50ac5a89c129e87baa16ac0773eb4ef7/polars-1.31.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ec/14/ee34ebe3eb842c83ca1d2d3af6ee02b08377e056ffad156c9a2b15a6d05c/polars-1.32.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/eb/d8/0d1d2e9d3fabcf5d6840362adcf05f8cf3cd06a73358140c3a97189238ae/wcmatch-10.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ osx-64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -1296,19 +1294,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py313h14b76d3_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.5-hf13058a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.17.1-py313h49682b3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.4-py313h8f4588c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313hc551f4f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313hc551f4f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.15-py313h03db916_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.16-py313h03db916_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda @@ -1320,7 +1318,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/gitdb-4.0.12-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.45-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/griddataformats-1.0.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gsd-4.0.0-py313h63b0ddb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/h5py-3.14.0-nompi_py313h003f59e_100.conda @@ -1332,7 +1330,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.30.1-pyh92f572d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.4.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -1349,11 +1347,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.4-ha6bc127_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-32_h7f60823_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-33_h7f60823_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.1.0-h6e16a3a_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.1.0-h6e16a3a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-32_hff6cab4_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-33_hff6cab4_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.14.1-h5dec5d8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.8-h3d58e20_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.24-hcc1b750_0.conda @@ -1367,28 +1365,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h51e75f0_103.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h4b5e92a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-32_h236ab99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-33_h236ab99_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h924628f_117.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h6054f6d_118.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.64.0-hc7306c3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.30-openmp_hbf64a52_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h3c4a55f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h84aeda2_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libsodium-1.0.20-hfdf4475_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.3-h875aaf5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.4-h39a8b3b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-h1167cee_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-h93c44a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-he1bc88e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.11.2-h31df5bb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.10.0-h240833e_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.2-py313h717bdf5_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.3-py313he981572_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.5-py313h5771d13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mdanalysis-2.9.0-py313h2e7108f_1.conda @@ -1398,7 +1396,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.4.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.5.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-git-revision-date-localized-plugin-1.2.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-glightbox-0.4.0-pyhd8ed1ab_1.conda @@ -1407,7 +1405,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-table-reader-plugin-3.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.28.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/mrcfile-1.5.4-pyhd8ed1ab_0.conda @@ -1423,8 +1421,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.7.2-nompi_py313h623cd79_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.2-py313hdb1a8e5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.1-hc426f3f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h036ada5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.2-h6e31bce_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.1-py313h366a99e_0.conda @@ -1447,8 +1445,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.33.2-py313hb35714d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.5-hc3a4c56_102_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda @@ -1459,12 +1457,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.2-py313h717bdf5_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.0.0-py313h2d45800_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.0.1-py313hc53fb4d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.26.0-py313hb35714d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.27.0-py313h66e1e84_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.7.1-py313hbe0a5c7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.16.0-py313h7e69c36_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda @@ -1484,7 +1482,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tidynamics-1.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.1-py313h63b0ddb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda @@ -1509,14 +1507,14 @@ environments: - pypi: https://files.pythonhosted.org/packages/4f/56/0dd652d4e950e6348bbf16b964b3325e4ad8220470774128fc0b0dd069cb/crc32c-2.7.1-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/48/9d/797d595dc57bbcb6284584ca7e228ac54b421aa1e864cec15d0f78e02f4b/material_plausible_plugin-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/42/097a9eee92b2b96979823ae55b2b42fba590f79f979a0b24138db628fac4/material_plausible_plugin-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/23/2ae189f4bbb5d35bf6dbd202a534b3f7f929c404d056fb0b20e826b9b643/mkdocs_awesome_nav-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e1/46/db5d3235cfa6764e3b09ea82cb2c606b2a5bbe77547eb551ad30bc85d0cf/mkdocs_print_site_plugin-2.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/3e/7513f2f37c563da65d1b91781e047f4a1c0ceac8206d4f6042428428e4ad/mkdocs_print_site_plugin-2.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/1e/73ffb1074f03d52cb1c4f4deaba26a2008ca45262f3622ed26dbec7a7362/numcodecs-0.16.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/3d/6e/bdd0937653c1e7a564a09ae3bc7757ce83fedbf19da600c8b35d62c0182a/polars-1.31.0-cp39-abi3-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/61/b251ce6755d0d3c6f4c8cb245941b80901624fce7efeb95b37c170da2565/polars-1.32.2-cp39-abi3-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/eb/d8/0d1d2e9d3fabcf5d6840362adcf05f8cf3cd06a73358140c3a97189238ae/wcmatch-10.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda @@ -1534,19 +1532,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py313h928ef07_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.5-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.17.1-py313hc845a76_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.4-py313h93df234_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.15-py313hab38a8b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.16-py313hab38a8b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda @@ -1558,7 +1556,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/gitdb-4.0.12-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/gitpython-3.1.45-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/griddataformats-1.0.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gsd-4.0.0-py313h90d716c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/h5py-3.14.0-nompi_py313h3a71123_100.conda @@ -1570,7 +1568,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.30.1-pyh92f572d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.4.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -1587,11 +1585,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.4-h51d1e36_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-32_h10e41b3_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-33_h10e41b3_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.1.0-h5505292_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.1.0-h5505292_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-32_hb3479ef_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-33_hb3479ef_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.14.1-h73640d1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-20.1.8-hf598326_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.24-h5773f1b_0.conda @@ -1605,28 +1603,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-14.2.0-h6c33f7e_103.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-hfe07756_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-32_hc9a63f6_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-33_hc9a63f6_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h3352478_117.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h2d3d5cf_118.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.64.0-h6d7220d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_hf332438_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h3783ad8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h280e0eb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.20-h99b78c6_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.3-h4237e3c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h2f21f7c_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h52572c6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h4a9ca0c_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.11.2-h1336266_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.8.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.2-py313ha9b7d5b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.3-py313haaf02c0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.5-py313h919948c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mda-xdrlib-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mdanalysis-2.9.0-py313h668b085_1.conda @@ -1636,7 +1634,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.3-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-1.6.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-autorefs-1.4.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.4.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.5.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-git-revision-date-localized-plugin-1.2.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-glightbox-0.4.0-pyhd8ed1ab_1.conda @@ -1645,7 +1643,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-9.6.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-material-extensions-1.3.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-table-reader-plugin-3.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.28.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/mrcfile-1.5.4-pyhd8ed1ab_0.conda @@ -1661,8 +1659,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.7.2-nompi_py313h2bc0fea_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.2-py313h674b998_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h8a3d83b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.1-h81ee809_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.2-he92f556_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/paginate-0.5.7-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.1-py313hd1f53c0_0.conda @@ -1685,8 +1683,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.33.2-py313hf3ab51e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyedr-0.8.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.5-hf3f3da0_102_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda @@ -1697,12 +1695,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.2-py313ha9b7d5b_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyyaml-env-tag-1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.0.0-py313he6960b1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.0.1-py313h330de61_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.36.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.26.0-py313hf3ab51e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.27.0-py313h80e0809_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.7.1-py313h595da1d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.0-py313h9a24e0a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda @@ -1722,7 +1720,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tidynamics-1.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.1-py313h90d716c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda @@ -1747,14 +1745,14 @@ environments: - pypi: https://files.pythonhosted.org/packages/47/02/2bd65fdef10139b6a802d83a7f966b7750fe5ffb1042f7cbe5dbb6403869/crc32c-2.7.1-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/48/9d/797d595dc57bbcb6284584ca7e228ac54b421aa1e864cec15d0f78e02f4b/material_plausible_plugin-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/42/097a9eee92b2b96979823ae55b2b42fba590f79f979a0b24138db628fac4/material_plausible_plugin-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/23/2ae189f4bbb5d35bf6dbd202a534b3f7f929c404d056fb0b20e826b9b643/mkdocs_awesome_nav-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e1/46/db5d3235cfa6764e3b09ea82cb2c606b2a5bbe77547eb551ad30bc85d0cf/mkdocs_print_site_plugin-2.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/3e/7513f2f37c563da65d1b91781e047f4a1c0ceac8206d4f6042428428e4ad/mkdocs_print_site_plugin-2.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/42/72/5affb1ce92b7a6becee17921de7c6b521a48fa61fc3d36d9f1eea2cf83f5/numcodecs-0.16.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/77/fe/81aaca3540c1a5530b4bc4fd7f1b6f77100243d7bb9b7ad3478b770d8b3e/polars-1.31.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/22/74/ea073a88073cd6025b12850484f51d30dad695b51432a3f0a0439e2f8094/polars-1.32.2-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/eb/d8/0d1d2e9d3fabcf5d6840362adcf05f8cf3cd06a73358140c3a97189238ae/wcmatch-10.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl - pypi: ./ packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -2134,9 +2132,9 @@ packages: - pkg:pypi/backrefs?source=hash-mapping size: 143810 timestamp: 1740887689966 -- conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.0-pyhe01879c_0.conda - sha256: cac9f946958cfb1ac67bc5e4cf96ec2e212132763b256699b16f37eb004698ae - md5: 37b50852c793b39b2b3ec44229e019b7 +- conda: https://conda.anaconda.org/conda-forge/noarch/basedpyright-1.31.1-pyhe01879c_0.conda + sha256: 6e7a64bf079315c86e357524fbb930f023f774a87672bee8207a901eba9b77cb + md5: a0febbff6d85df54173f6aa679ce52c1 depends: - python >=3.9 - nodejs-wheel >=20.13.1 @@ -2144,8 +2142,8 @@ packages: license: MIT AND Apache-2.0 purls: - pkg:pypi/basedpyright?source=hash-mapping - size: 8255872 - timestamp: 1752676975836 + size: 8256462 + timestamp: 1754233644528 - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.13.4-pyha770c72_0.conda sha256: ddb0df12fd30b2d36272f5daf6b6251c7625d6a99414d7ea930005bbaecad06d md5: 9f07c4fc992adb2d6c30da7fab3959a7 @@ -2421,41 +2419,21 @@ packages: - pkg:pypi/brotli?source=hash-mapping size: 338938 timestamp: 1749230456550 -- pypi: https://files.pythonhosted.org/packages/84/c2/80633736cd183ee4a62107413def345f7e6e3c01563dbca1417363cf957e/build-1.2.2.post1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl name: build - version: 1.2.2.post1 - sha256: 1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5 + version: 1.3.0 + sha256: 7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4 requires_dist: - packaging>=19.1 - pyproject-hooks - colorama ; os_name == 'nt' - importlib-metadata>=4.6 ; python_full_version < '3.10.2' - tomli>=1.1.0 ; python_full_version < '3.11' - - furo>=2023.8.17 ; extra == 'docs' - - sphinx~=7.0 ; extra == 'docs' - - sphinx-argparse-cli>=1.5 ; extra == 'docs' - - sphinx-autodoc-typehints>=1.10 ; extra == 'docs' - - sphinx-issues>=3.0.0 ; extra == 'docs' - - build[uv,virtualenv] ; extra == 'test' - - filelock>=3 ; extra == 'test' - - pytest>=6.2.4 ; extra == 'test' - - pytest-cov>=2.12 ; extra == 'test' - - pytest-mock>=2 ; extra == 'test' - - pytest-rerunfailures>=9.1 ; extra == 'test' - - pytest-xdist>=1.34 ; extra == 'test' - - wheel>=0.36.0 ; extra == 'test' - - setuptools>=42.0.0 ; python_full_version < '3.10' and extra == 'test' - - setuptools>=56.0.0 ; python_full_version == '3.10.*' and extra == 'test' - - setuptools>=56.0.0 ; python_full_version == '3.11.*' and extra == 'test' - - setuptools>=67.8.0 ; python_full_version >= '3.12' and extra == 'test' - - build[uv] ; extra == 'typing' - - importlib-metadata>=5.1 ; extra == 'typing' - - mypy~=1.9.0 ; extra == 'typing' - - tomli ; extra == 'typing' - - typing-extensions>=3.7.4.3 ; extra == 'typing' - uv>=0.1.18 ; extra == 'uv' - - virtualenv>=20.0.35 ; extra == 'virtualenv' - requires_python: '>=3.8' + - virtualenv>=20.11 ; python_full_version < '3.10' and extra == 'virtualenv' + - virtualenv>=20.17 ; python_full_version >= '3.10' and python_full_version < '3.14' and extra == 'virtualenv' + - virtualenv>=20.31 ; python_full_version >= '3.14' and extra == 'virtualenv' + requires_python: '>=3.9' - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d md5: 62ee74e96c5ebb0af99386de58cf9553 @@ -2518,15 +2496,15 @@ packages: purls: [] size: 179696 timestamp: 1744128058734 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.7.14-hbd8a1cb_0.conda - sha256: 29defbd83c7829788358678ec996adeee252fa4d4274b7cd386c1ed73d2b201e - md5: d16c90324aef024877d8713c0b7fea5b +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.8.3-hbd8a1cb_0.conda + sha256: 837b795a2bb39b75694ba910c13c15fa4998d4bb2a622c214a6a5174b2ae53d1 + md5: 74784ee3d225fc3dca89edb635b4e5cc depends: - __unix license: ISC purls: [] - size: 155658 - timestamp: 1752482350666 + size: 154402 + timestamp: 1754210968730 - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 noarch: python sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 @@ -2549,16 +2527,16 @@ packages: - pkg:pypi/cached-property?source=hash-mapping size: 11065 timestamp: 1615209567874 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.7.14-pyhd8ed1ab_0.conda - sha256: f68ee5038f37620a4fb4cdd8329c9897dce80331db8c94c3ab264a26a8c70a08 - md5: 4c07624f3faefd0bb6659fb7396cfa76 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.8.3-pyhd8ed1ab_0.conda + sha256: a1ad5b0a2a242f439608f22a538d2175cac4444b7b3f4e2b8c090ac337aaea40 + md5: 11f59985f49df4620890f3e746ed7102 depends: - python >=3.9 license: ISC purls: - pkg:pypi/certifi?source=compressed-mapping - size: 159755 - timestamp: 1752493370797 + size: 158692 + timestamp: 1754231530168 - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py312h06ac9bb_0.conda sha256: cba6ea83c4b0b4f5b5dc59cb19830519b28f95d7ebef7c9c5cf1c14843621457 md5: a861504bbea4161a9170b85d4d2be840 @@ -2795,86 +2773,92 @@ packages: - python >=3.9 - python license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/comm?source=compressed-mapping size: 14690 timestamp: 1753453984907 -- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py312hd9148b4_0.conda - sha256: 3ac7113709834ac1bbafe3d90bfbe26a943694a348f6947ffb26b87ab49d30e8 - md5: 12f9dea0fc4d1ec50741a0dbb5e5e3e8 +- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py312hd9148b4_1.conda + sha256: d9cb7f97a184a383bf0c72e1fa83b983a1caa68d7564f4449a4de7c97df9cb3f + md5: e25ed6c2e3b1effedfe9cd10a15ca8d8 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 - libstdcxx >=14 - - numpy >=1.23 + - numpy >=1.25 - python >=3.12,<3.13.0a0 - python_abi 3.12.* *_cp312 license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 292588 - timestamp: 1753561158900 -- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_0.conda - sha256: 597e0d6ca8b38aab1b6f47c3021bc94369541bf685ecb0e0f14b25c76f5587cb - md5: c142406f39c92e11dca2a440b6529ffd + - pkg:pypi/contourpy?source=compressed-mapping + size: 291827 + timestamp: 1754063770363 +- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_1.conda + sha256: a0ce615510eeaeace0e0e0c9301a1efef3e4bcbb554e4a25d819c3be864242b4 + md5: 7efd370a0349ce5722b7b23232bfe36b depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 - libstdcxx >=14 - - numpy >=1.23 + - numpy >=1.25 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/contourpy?source=hash-mapping - size: 294412 - timestamp: 1753561174517 -- conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py312hedd4973_0.conda - sha256: d123a3db17d9cac597a2d95a47c9648701fa7e85cc0997651d461dc54f402abe - md5: 34cee7aec16eff8398a270aedf529619 + size: 293513 + timestamp: 1754063719883 +- conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py312hedd4973_1.conda + sha256: e9bef101ef00dc48aef43d2470b2adede37e30f5f8594d90f28272d508b777c4 + md5: a5cfae27fe77321e49fc4268f78b4a38 depends: - __osx >=10.13 - libcxx >=19 - - numpy >=1.23 + - numpy >=1.25 - python >=3.12,<3.13.0a0 - python_abi 3.12.* *_cp312 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/contourpy?source=hash-mapping - size: 267964 - timestamp: 1753561390515 -- conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313hc551f4f_0.conda - sha256: 21a28adc80647b78d219fc90a2057666646d41cb88502a5e2d5f2332b6df2295 - md5: 0a11d16b8d6d48a93fe23b8897328af8 + size: 268369 + timestamp: 1754063947309 +- conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py313hc551f4f_1.conda + sha256: d7f81d9c84f07a3916473bc69cabaf2e42ce296b8f76727e24f15f636185a45f + md5: f944076ba621dfde21fc4f1cc283af2a depends: - __osx >=10.13 - libcxx >=19 - - numpy >=1.23 + - numpy >=1.25 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 269016 - timestamp: 1753561263202 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_0.conda - sha256: 16c877d2bc05e83dda3db41691d7f893aed11d4cc55086ccaad19176bc57de5a - md5: 3a6e65df9e2d0878142c131631dfaa0c + - pkg:pypi/contourpy?source=compressed-mapping + size: 268870 + timestamp: 1754064078937 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313hc50a443_1.conda + sha256: b444ecf07bdfaf05a875d517a598090bb2f574c33815b6248ececbc6b1e5a201 + md5: 84315902ea539576895726299478c0ec depends: - __osx >=11.0 - libcxx >=19 - - numpy >=1.23 + - numpy >=1.25 - python >=3.13,<3.14.0a0 - python >=3.13,<3.14.0a0 *_cp313 - python_abi 3.13.* *_cp313 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/contourpy?source=hash-mapping - size: 257807 - timestamp: 1753561488026 -- conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.10.0-py312h8a5da7c_0.conda - sha256: dd85469de0d62d65c456abfefd62939a28cb53704120b4f43f14f967b5123d53 - md5: 10c5a17b4546b4e236031ef8177cf9d1 + size: 258632 + timestamp: 1754064001338 +- conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.10.2-py312h8a5da7c_0.conda + sha256: 211754cf4be7ce64b11955509fcab60cd33090633c362d4aface4a5320adbf77 + md5: f8830a2249f4b8a5f9c33cb44ad5c31a depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -2882,26 +2866,28 @@ packages: - python_abi 3.12.* *_cp312 - tomli license: Apache-2.0 + license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 377204 - timestamp: 1753387756069 -- conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.10.0-py312h3d55d04_0.conda - sha256: 2fd77045f938584065d99433073652f1160c4147b2ae7e491b77011bc806730b - md5: 85bb94bf657c2ee1ca0b033208a3480e + size: 377963 + timestamp: 1754308562631 +- conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.10.2-py312h3d55d04_0.conda + sha256: f4edfe51e68f40ce8361ca74e13c5463c9f548b740355e4cdeaa8a2b9baa3b1b + md5: 78262f44dd6e921fb77db35a69a97ee8 depends: - __osx >=10.13 - python >=3.12,<3.13.0a0 - python_abi 3.12.* *_cp312 - tomli license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/coverage?source=hash-mapping - size: 375474 - timestamp: 1753387680033 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.10.0-py313ha0c97b7_0.conda - sha256: 5d003dce0739ed6ed989a2aeda2181e374946c9831b297e944ba7d0614f9ce3a - md5: 5933a12cf93ab2ee7f88120bfa5bc881 + - pkg:pypi/coverage?source=compressed-mapping + size: 375736 + timestamp: 1754308240153 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.10.2-py313ha0c97b7_0.conda + sha256: 6121a495249bd1687c6252f13b948673b6d6ecbd680523838ad1c1c43f1a0337 + md5: 927aeb1ff92c2c435bd9110704677bd4 depends: - __osx >=11.0 - python >=3.13,<3.14.0a0 @@ -2909,10 +2895,11 @@ packages: - python_abi 3.13.* *_cp313 - tomli license: Apache-2.0 + license_family: APACHE purls: - - pkg:pypi/coverage?source=compressed-mapping - size: 384441 - timestamp: 1753387708151 + - pkg:pypi/coverage?source=hash-mapping + size: 384709 + timestamp: 1754308344502 - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.12.11-py312hd8ed1ab_0.conda noarch: generic sha256: 7e7bc8e73a2f3736444a8564cbece7216464c00f0bc38e604b0c792ff60d621a @@ -2960,14 +2947,14 @@ packages: version: 2.7.1 sha256: 73361c79a6e4605204457f19fda18b042a94508a52e53d10a4239da5fb0f6a34 requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-45.0.5-py312hda17c39_0.conda - sha256: 4f0940ea061bc0194a447d1c571918e79ad834ef4d26fe4d17a4503bee71a49c - md5: b315b9ae992b31e65c59be8fac2e234a +- conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-45.0.6-py312hee9fe19_0.conda + sha256: 51921bbbbc02bcc30be016d5ce9d384d222c57d7e3bf4e9082fd6528bd19c9ec + md5: 8cabf722a579fb85f4dfe56146b20dab depends: - __glibc >=2.17,<3.0.a0 - cffi >=1.12 - - libgcc >=13 - - openssl >=3.5.1,<4.0a0 + - libgcc >=14 + - openssl >=3.5.2,<4.0a0 - python >=3.12,<3.13.0a0 - python_abi 3.12.* *_cp312 constrains: @@ -2975,9 +2962,9 @@ packages: license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT license_family: BSD purls: - - pkg:pypi/cryptography?source=hash-mapping - size: 1653383 - timestamp: 1751491514393 + - pkg:pypi/cryptography?source=compressed-mapping + size: 1653373 + timestamp: 1754473134017 - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda sha256: 9827efa891e507a91a8a2acf64e210d2aff394e1cde432ad08e1f8c66b12293c md5: 44600c4667a319d67dbe0681fc0bc833 @@ -3005,51 +2992,47 @@ packages: purls: [] size: 437860 timestamp: 1747855126005 -- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.15-py313h5d5ffb9_0.conda - sha256: d228ad299a09ce64935ad5352dc8122d81fd2040dc3a0ad4c621a72fe749928b - md5: 9befe517ce0a5bc50f747b33de3e7446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.16-py313h5d5ffb9_0.conda + sha256: 26c56e7f93cde8be5b1b3ec3404f95d2874946f6fe0182f6720e5c3232e006ed + md5: c6286f4df7bec3d3712d617a358149b4 depends: - python - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - libstdcxx >=14 - libgcc >=14 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2860206 - timestamp: 1752827112418 -- conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.15-py313h03db916_0.conda - sha256: ebd4192b8a3ff8f610b857e72540d1a30663917a640003a3be816f0eb087fa66 - md5: 62c19e12eca558c8758d7368df19dee8 + - pkg:pypi/debugpy?source=compressed-mapping + size: 2868365 + timestamp: 1754523414483 +- conda: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.16-py313h03db916_0.conda + sha256: 1c07630626879de9c4a63a767cc304d23373dc1c4fb92b1f1891534dcc316917 + md5: 3cd9930005c64df818f07d56c29bff1f depends: - python - - libcxx >=19 - __osx >=10.13 + - libcxx >=19 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2769164 - timestamp: 1752827121427 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.15-py313hab38a8b_0.conda - sha256: da57150d9f35eb9a82396577e32a0aaf4bd514d17ca1e852cb08157110d91fa5 - md5: ba1e48e8c0f20d5eff097583cd4a5fb4 + - pkg:pypi/debugpy?source=compressed-mapping + size: 2769397 + timestamp: 1754523432779 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.16-py313hab38a8b_0.conda + sha256: 214010d0ef5ec170cc24a28277c11893ecca0f78f0ba6ba6b90e8031ca8fff15 + md5: b8a25de90e021082a106f01be64c9c5b depends: - python - - libcxx >=19 - python 3.13.* *_cp313 - __osx >=11.0 + - libcxx >=19 - python_abi 3.13.* *_cp313 license: MIT - license_family: MIT purls: - pkg:pypi/debugpy?source=compressed-mapping - size: 2755984 - timestamp: 1752827124425 + size: 2755818 + timestamp: 1754523422224 - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 md5: 9ce473d1d1be1cc3810856a48b3fab32 @@ -3083,16 +3066,16 @@ packages: - pkg:pypi/dill?source=hash-mapping size: 90864 timestamp: 1744798629464 -- conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda - sha256: fa5966bb1718bbf6967a85075e30e4547901410cc7cb7b16daf68942e9a94823 - md5: 24c1ca34138ee57de72a943237cde4cc +- conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.22-pyhd8ed1ab_0.conda + sha256: dd585e49f231ec414e6550783f2aff85027fa829e5d66004ad702e1cfa6324aa + md5: 140faac6cff4382f5ea077ca618b2931 depends: - python >=3.9 license: CC-PDDC AND BSD-3-Clause AND BSD-2-Clause AND ZPL-2.1 purls: - pkg:pypi/docutils?source=hash-mapping - size: 402700 - timestamp: 1733217860944 + size: 436452 + timestamp: 1753875179563 - pypi: https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl name: donfig version: 0.8.1.post1 @@ -3342,17 +3325,17 @@ packages: - pkg:pypi/griddataformats?source=hash-mapping size: 2119109 timestamp: 1734293609160 -- conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.8.0-pyhd8ed1ab_0.conda - sha256: cfc2dd6154aa74a1887f1b631987148d277ef23380bff04399d0ebf1522ec6cd - md5: f4883564820f93d9ebe128bd52e4d2a9 +- conda: https://conda.anaconda.org/conda-forge/noarch/griffe-1.10.0-pyhd8ed1ab_0.conda + sha256: ff73e232a81a6a66d59a3306f0f5b07bf0578a97bc50690505b567ca012b5dec + md5: 076d9f17ed4f1cc0a5250e6d770ea5e6 depends: - colorama >=0.4 - python >=3.9 license: ISC purls: - pkg:pypi/griffe?source=hash-mapping - size: 102454 - timestamp: 1753274050872 + size: 105737 + timestamp: 1754501726635 - conda: https://conda.anaconda.org/conda-forge/linux-64/gsd-4.0.0-py312h66e93f0_0.conda sha256: 5939bc2c7c1cb035264158631346d583640480355005f40605ea3adc3ffad944 md5: eb0363b0fbb46dae9b3679e28f98940a @@ -3739,55 +3722,55 @@ packages: - pkg:pypi/iniconfig?source=hash-mapping size: 11474 timestamp: 1733223232820 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda - sha256: 33cfd339bb4efac56edf93474b37ddc049e08b1b4930cf036c893cc1f5a1f32a - md5: b40131ab6a36ac2c09b7c57d4d3fbf99 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.30.1-pyh82676e8_0.conda + sha256: cfc2c4e31dfedbb3d124d0055f55fda4694538fb790d52cd1b37af5312833e36 + md5: b0cc25825ce9212b8bee37829abad4d6 depends: - __linux - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 - - jupyter_client >=6.1.12 + - jupyter_client >=8.0.0 - jupyter_core >=4.12,!=5.0.* - matplotlib-inline >=0.1 - - nest-asyncio - - packaging - - psutil - - python >=3.8 - - pyzmq >=24 - - tornado >=6.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.9 + - pyzmq >=25 + - tornado >=6.2 - traitlets >=5.4.0 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/ipykernel?source=hash-mapping - size: 119084 - timestamp: 1719845605084 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda - sha256: 072534d4d379225b2c3a4e38bc7730b65ae171ac7f0c2d401141043336e97980 - md5: 9eb15d654daa0ef5a98802f586bb4ffc + - pkg:pypi/ipykernel?source=compressed-mapping + size: 121367 + timestamp: 1754352984703 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.30.1-pyh92f572d_0.conda + sha256: ec80ed5f68c96dd46ff1b533b28d2094b6f07e2ec8115c8c60803920fdd6eb13 + md5: f208c1a85786e617a91329fa5201168c depends: - __osx - appnope - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 - - jupyter_client >=6.1.12 + - jupyter_client >=8.0.0 - jupyter_core >=4.12,!=5.0.* - matplotlib-inline >=0.1 - - nest-asyncio - - packaging - - psutil - - python >=3.8 - - pyzmq >=24 - - tornado >=6.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.9 + - pyzmq >=25 + - tornado >=6.2 - traitlets >=5.4.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/ipykernel?source=hash-mapping - size: 119568 - timestamp: 1719845667420 + size: 121397 + timestamp: 1754353050327 - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.4.0-pyhfa0c392_0.conda sha256: ff5138bf6071ca01d84e1329f6baa96f0723df6fe183cfa1ab3ebc96240e6d8f md5: cb7706b10f35e7507917cefa0978a66d @@ -3931,7 +3914,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/jsonschema?source=compressed-mapping + - pkg:pypi/jsonschema?source=hash-mapping size: 81493 timestamp: 1752925388185 - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.4.1-pyh29332c3_0.conda @@ -4287,60 +4270,60 @@ packages: purls: [] size: 30173 timestamp: 1749993648288 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-32_h59b9bed_openblas.conda - build_number: 32 - sha256: 1540bf739feb446ff71163923e7f044e867d163c50b605c8b421c55ff39aa338 - md5: 2af9f3d5c2e39f417ce040f5a35c40c6 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-33_h59b9bed_openblas.conda + build_number: 33 + sha256: 18b165b45f3cea3892fee25a91b231abf29f521df76c8fcc0c92f6cf5071a911 + md5: b43d5de8fe73c2a5fb2b43f45301285b depends: - libopenblas >=0.3.30,<0.3.31.0a0 - libopenblas >=0.3.30,<1.0a0 constrains: - - libcblas 3.9.0 32*_openblas - mkl <2025 - - liblapacke 3.9.0 32*_openblas - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas + - liblapack 3.9.0 33*_openblas + - blas 2.133 openblas + - liblapacke 3.9.0 33*_openblas + - libcblas 3.9.0 33*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17330 - timestamp: 1750388798074 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-32_h7f60823_openblas.conda - build_number: 32 - sha256: e441fcc46858a9a073e4344c80e267aee3b95ec01b02e37205c36be79eec0694 - md5: 0f7197e3b4ecfa8aa24a371c3eaabb8a + size: 18778 + timestamp: 1754412356514 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-33_h7f60823_openblas.conda + build_number: 33 + sha256: 75a70ff09b7408e07a797bb7ebcc76156485c81e67cc82d56c13c0e1a5d13642 + md5: 574abce321840d4898b862d76469c476 depends: - libopenblas >=0.3.30,<0.3.31.0a0 - libopenblas >=0.3.30,<1.0a0 constrains: - - liblapack 3.9.0 32*_openblas - - blas 2.132 openblas - mkl <2025 - - liblapacke 3.9.0 32*_openblas - - libcblas 3.9.0 32*_openblas + - libcblas 3.9.0 33*_openblas + - liblapacke 3.9.0 33*_openblas + - liblapack 3.9.0 33*_openblas + - blas 2.133 openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17571 - timestamp: 1750389030403 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-32_h10e41b3_openblas.conda - build_number: 32 - sha256: 2775472dd81d43dc20804b484028560bfecd5ab4779e39f1fb95684da3ff2029 - md5: d4a1732d2b330c9d5d4be16438a0ac78 + size: 18982 + timestamp: 1754412431204 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-33_h10e41b3_openblas.conda + build_number: 33 + sha256: 8286b7743ed1d0927054c20a306685829545d4c2d83f470febe1f69d3b6f069e + md5: 3e997cfdad88c13d1562304d5281f540 depends: - libopenblas >=0.3.30,<0.3.31.0a0 - libopenblas >=0.3.30,<1.0a0 constrains: - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas + - libcblas 3.9.0 33*_openblas + - liblapacke 3.9.0 33*_openblas - mkl <2025 - - libcblas 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - blas 2.133 openblas + - liblapack 3.9.0 33*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17520 - timestamp: 1750388963178 + size: 18974 + timestamp: 1754412799592 - conda: https://conda.anaconda.org/conda-forge/linux-64/libboost-1.86.0-h6c02f8c_3.conda sha256: bad622863b3e4c8f0d107d8efd5b808e52d79cb502a20d700d05357b59a51e8f md5: eead4e74198698d1c74f06572af753bc @@ -4492,51 +4475,51 @@ packages: purls: [] size: 274404 timestamp: 1749230355483 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-32_he106b2a_openblas.conda - build_number: 32 - sha256: 92a001fc181e6abe4f4a672b81d9413ca2f22609f8a95327dfcc6eee593ffeb9 - md5: 3d3f9355e52f269cd8bc2c440d8a5263 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-33_he106b2a_openblas.conda + build_number: 33 + sha256: b34271bb9c3b2377ac23c3fb1ecf45c08f8d09675ff8aad860f4e3c547b126a7 + md5: 28052b5e6ea5bd283ac343c5c064b950 depends: - - libblas 3.9.0 32_h59b9bed_openblas + - libblas 3.9.0 33_h59b9bed_openblas constrains: - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - liblapack 3.9.0 33*_openblas + - liblapacke 3.9.0 33*_openblas + - blas 2.133 openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17308 - timestamp: 1750388809353 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-32_hff6cab4_openblas.conda - build_number: 32 - sha256: 745f6dd420389809c333734df6edc99d75caa3633e4778158c7549c6844af440 - md5: 2c1e774d4546cf542eaee5781eb8940b + size: 18748 + timestamp: 1754412369555 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-33_hff6cab4_openblas.conda + build_number: 33 + sha256: a035180aaf1462e654e22fd9665745eaec74835e4349df9ebf317c6e4d39122b + md5: 80af7294dcfe37b24bdb18dfaef4b373 depends: - - libblas 3.9.0 32_h7f60823_openblas + - libblas 3.9.0 33_h7f60823_openblas constrains: - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - liblapacke 3.9.0 33*_openblas + - liblapack 3.9.0 33*_openblas + - blas 2.133 openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17574 - timestamp: 1750389040732 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-32_hb3479ef_openblas.conda - build_number: 32 - sha256: 25d46ace14c3ac45d4aa18b5f7a0d3d30cec422297e900f8b97a66334232061c - md5: d8e8ba717ae863b13a7495221f2b5a71 + size: 18969 + timestamp: 1754412445799 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-33_hb3479ef_openblas.conda + build_number: 33 + sha256: b5fb4c18717e48071287a0b462fc3a4ca0223ec3bbfc2a87c2f19a3ab2b229ba + md5: b4e83e589589cc025b6742f09f712957 depends: - - libblas 3.9.0 32_h10e41b3_openblas + - libblas 3.9.0 33_h10e41b3_openblas constrains: - - blas 2.132 openblas - - liblapack 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - liblapacke 3.9.0 33*_openblas + - liblapack 3.9.0 33*_openblas + - blas 2.133 openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17485 - timestamp: 1750388970626 + size: 18976 + timestamp: 1754412811855 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.14.1-h332b0f4_0.conda sha256: b6c5cf340a4f80d70d64b3a29a7d9885a5918d16a5cb952022820e6d3e79dc8b md5: 45f6713cb00f124af300342512219182 @@ -4835,42 +4818,42 @@ packages: purls: [] size: 333529 timestamp: 1745370142848 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_3.conda - sha256: 59a87161212abe8acc57d318b0cc8636eb834cdfdfddcf1f588b5493644b39a3 - md5: 9e60c55e725c20d23125a5f0dd69af5d +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_4.conda + sha256: 144e35c1c2840f2dc202f6915fc41879c19eddbb8fa524e3ca4aa0d14018b26f + md5: f406dcbb2e7bef90d793e50e79a2882b depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgcc-ng ==15.1.0=*_3 - - libgomp 15.1.0 h767d61c_3 + - libgcc-ng ==15.1.0=*_4 + - libgomp 15.1.0 h767d61c_4 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 824921 - timestamp: 1750808216066 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_3.conda - sha256: b0b0a5ee6ce645a09578fc1cb70c180723346f8a45fdb6d23b3520591c6d6996 - md5: e66f2b8ad787e7beb0f846e4bd7e8493 + size: 824153 + timestamp: 1753903866511 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_4.conda + sha256: 76ceac93ed98f208363d6e9c75011b0ff7b97b20f003f06461a619557e726637 + md5: 28771437ffcd9f3417c66012dc49a3be depends: - - libgcc 15.1.0 h767d61c_3 + - libgcc 15.1.0 h767d61c_4 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 29033 - timestamp: 1750808224854 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_3.conda - sha256: 77dd1f1efd327e6991e87f09c7c97c4ae1cfbe59d9485c41d339d6391ac9c183 - md5: bfbca721fd33188ef923dfe9ba172f29 + size: 29249 + timestamp: 1753903872571 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_4.conda + sha256: 2fe41683928eb3c57066a60ec441e605a69ce703fc933d6d5167debfeba8a144 + md5: 53e876bc2d2648319e94c33c57b9ec74 depends: - - libgfortran5 15.1.0 hcea5267_3 + - libgfortran5 15.1.0 hcea5267_4 constrains: - - libgfortran-ng ==15.1.0=*_3 + - libgfortran-ng ==15.1.0=*_4 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 29057 - timestamp: 1750808257258 + size: 29246 + timestamp: 1753903898593 - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-5.0.0-14_2_0_h51e75f0_103.conda sha256: 124dcd89508bd16f562d9d3ce6a906336a7f18e963cd14f2877431adee14028e md5: 090b3c9ae1282c8f9b394ac9e4773b10 @@ -4891,19 +4874,19 @@ packages: purls: [] size: 156291 timestamp: 1743863532821 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_3.conda - sha256: 2d961f9748d994a4dc9891feae60e182ae9cdce4b0780caaa643e9e3757c7b43 - md5: 6e5d0574e57a38c36e674e9a18eee2b4 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_4.conda + sha256: a5713d8e5a92b4522de132b82368ba93a061e47bc15e6b638c745f28c67fec31 + md5: b1a97c0f2c4f1bb2b8872a21fc7e17a7 depends: - - libgfortran 15.1.0 h69a702a_3 + - libgfortran 15.1.0 h69a702a_4 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 29089 - timestamp: 1750808529101 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_3.conda - sha256: eea6c3cf22ad739c279b4d665e6cf20f8081f483b26a96ddd67d4df3c88dfa0a - md5: 530566b68c3b8ce7eec4cd047eae19fe + size: 29256 + timestamp: 1753904061220 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_4.conda + sha256: 3070e5e2681f7f2fb7af0a81b92213f9ab430838900da8b4f9b8cf998ddbdd84 + md5: 8a4ab7ff06e4db0be22485332666da0f depends: - __glibc >=2.17,<3.0.a0 - libgcc >=15.1.0 @@ -4912,8 +4895,8 @@ packages: license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 1565627 - timestamp: 1750808236464 + size: 1564595 + timestamp: 1753903882088 - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h51e75f0_103.conda sha256: d2ac5e09587e5b21b7bb5795d24f33257e44320749c125448611211088ef8795 md5: 6183f7e9cd1e7ba20118ff0ca20a05e5 @@ -4938,35 +4921,35 @@ packages: purls: [] size: 806566 timestamp: 1743863491726 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda - sha256: a6b5cf4d443044bc9a0293dd12ca2015f0ebe5edfdc9c4abdde0b9947f9eb7bd - md5: 072ab14a02164b7c0c089055368ff776 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.3-hf39c6af_0.conda + sha256: e1ad3d9ddaa18f95ff5d244587fd1a37aca6401707f85a37f7d9b5002fcf16d0 + md5: 467f23819b1ea2b89c3fc94d65082301 depends: - __glibc >=2.17,<3.0.a0 - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 + - libgcc >=14 - libiconv >=1.18,<2.0a0 - libzlib >=1.3.1,<2.0a0 - pcre2 >=10.45,<10.46.0a0 constrains: - - glib 2.84.2 *_0 + - glib 2.84.3 *_0 license: LGPL-2.1-or-later purls: [] - size: 3955066 - timestamp: 1747836671118 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_3.conda - sha256: 43710ab4de0cd7ff8467abff8d11e7bb0e36569df04ce1c099d48601818f11d1 - md5: 3cd1a7238a0dd3d0860fdefc496cc854 + size: 3961899 + timestamp: 1754315006443 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_4.conda + sha256: e0487a8fec78802ac04da0ac1139c3510992bc58a58cde66619dde3b363c2933 + md5: 3baf8976c96134738bba224e9ef6b1e5 depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 447068 - timestamp: 1750808138400 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.11.2-default_h3d81e11_1002.conda - sha256: 2823a704e1d08891db0f3a5ab415a2b7e391a18f1e16d27531ef6a69ec2d36b9 - md5: 56aacccb6356b6b6134a79cdf5688506 + size: 447289 + timestamp: 1753903801049 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h3d81e11_1000.conda + sha256: eecaf76fdfc085d8fed4583b533c10cb7f4a6304be56031c43a107e01a56b7e2 + md5: d821210ab60be56dd27b5525ed18366d depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -4975,8 +4958,8 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] - size: 2425708 - timestamp: 1752673860271 + size: 2450422 + timestamp: 1752761850672 - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda sha256: 18a4afe14f731bfb9cf388659994263904d20111e42f841e9eea1bb6f91f4ab4 md5: e796ff8ddc598affdf7c173d6145f087 @@ -5039,51 +5022,51 @@ packages: purls: [] size: 553624 timestamp: 1745268405713 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-32_h7ac8fdf_openblas.conda - build_number: 32 - sha256: 5b55a30ed1b3f8195dad9020fe1c6d0f514829bfaaf0cf5e393e93682af009f2 - md5: 6c3f04ccb6c578138e9f9899da0bd714 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-33_h7ac8fdf_openblas.conda + build_number: 33 + sha256: 60c2ccdfa181bc304b5162c73cdecb5b4c3972da71758472c71fefb33965cde3 + md5: e598bb54c4a4b45c3d83c72984f79dbb depends: - - libblas 3.9.0 32_h59b9bed_openblas + - libblas 3.9.0 33_h59b9bed_openblas constrains: - - libcblas 3.9.0 32*_openblas - - blas 2.132 openblas - - liblapacke 3.9.0 32*_openblas + - liblapacke 3.9.0 33*_openblas + - blas 2.133 openblas + - libcblas 3.9.0 33*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17316 - timestamp: 1750388820745 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-32_h236ab99_openblas.conda - build_number: 32 - sha256: 1e26450b80525b3f656e9c75fd26a10ebaa1d339fe4ca9c7affbebd9acbeac03 - md5: ccdca0c0730ad795e064d81dbe540723 + size: 18785 + timestamp: 1754412383434 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-33_h236ab99_openblas.conda + build_number: 33 + sha256: ef78af1de723e07a31b299bde6e3fa44e092f574e4bfb6e8d3166f18c0652ad3 + md5: 3b0d15df521c00d36af3fd18768c8b66 depends: - - libblas 3.9.0 32_h7f60823_openblas + - libblas 3.9.0 33_h7f60823_openblas constrains: - - blas 2.132 openblas - - liblapacke 3.9.0 32*_openblas - - libcblas 3.9.0 32*_openblas + - liblapacke 3.9.0 33*_openblas + - blas 2.133 openblas + - libcblas 3.9.0 33*_openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17553 - timestamp: 1750389051033 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-32_hc9a63f6_openblas.conda - build_number: 32 - sha256: 5e1cfa3581d1dec6b07a75084ff6cfa4b4465c646c6884a71c78a28543f83b61 - md5: bf9ead3fa92fd75ad473c6a1d255ffcb + size: 18975 + timestamp: 1754412457500 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-33_hc9a63f6_openblas.conda + build_number: 33 + sha256: 81efa7342a18c913b7a6278c6edd242156c34acc3db4c4a88b6c63eea19a6857 + md5: 95c3ac0d25d156fbe20046c2b542908a depends: - - libblas 3.9.0 32_h10e41b3_openblas + - libblas 3.9.0 33_h10e41b3_openblas constrains: - - blas 2.132 openblas - - libcblas 3.9.0 32*_openblas - - liblapacke 3.9.0 32*_openblas + - libcblas 3.9.0 33*_openblas + - liblapacke 3.9.0 33*_openblas + - blas 2.133 openblas license: BSD-3-Clause license_family: BSD purls: [] - size: 17507 - timestamp: 1750388977861 + size: 18979 + timestamp: 1754412823475 - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 md5: 1a580f7796c7bf6393fddb8bbbde58dc @@ -5149,76 +5132,76 @@ packages: purls: [] size: 71829 timestamp: 1748393749336 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h0134ee8_117.conda - sha256: bed629ab93148ea485009b06e2e4aa7709a66d19755713abff4f2c7193e65374 - md5: a979c07e8fc0e3f61c24a65d16cc6fbe +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h21f7587_118.conda + sha256: ad260036929255d8089f748db0dce193d0d588ad7f88c06027dd9d8662cc1cc6 + md5: 5f05af73150f62adab1492ab2d18d573 depends: - __glibc >=2.17,<3.0.a0 - blosc >=1.21.6,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.6,<1.14.7.0a0 - - libaec >=1.1.3,<2.0a0 - - libcurl >=8.13.0,<9.0a0 - - libgcc >=13 - - libstdcxx >=13 - - libxml2 >=2.13.7,<2.14.0a0 + - libaec >=1.1.4,<2.0a0 + - libcurl >=8.14.1,<9.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 >=2.13.8,<2.14.0a0 - libzip >=1.11.2,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.1,<4.0a0 - zlib - zstd >=1.5.7,<1.6.0a0 license: MIT license_family: MIT purls: [] - size: 835103 - timestamp: 1745509891236 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h924628f_117.conda - sha256: e17449a079ed0d4f689016d50737514c9aa2e307f64e7e9a30b3626503a3f550 - md5: a7a1495bcf5a556a84b15a77be6f37cf + size: 844115 + timestamp: 1754055003755 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h6054f6d_118.conda + sha256: 6145bccbc484d069938a9bad162f573c0421ccbf7a8ac9d34228d1706956af4d + md5: c92aa5e0a14b8381e7aaf78714a03ff6 depends: - __osx >=10.13 - blosc >=1.21.6,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.6,<1.14.7.0a0 - - libaec >=1.1.3,<2.0a0 - - libcurl >=8.13.0,<9.0a0 - - libcxx >=18 - - libxml2 >=2.13.7,<2.14.0a0 + - libaec >=1.1.4,<2.0a0 + - libcurl >=8.14.1,<9.0a0 + - libcxx >=19 + - libxml2 >=2.13.8,<2.14.0a0 - libzip >=1.11.2,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.1,<4.0a0 - zlib - zstd >=1.5.7,<1.6.0a0 license: MIT license_family: MIT purls: [] - size: 728865 - timestamp: 1745510284605 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h3352478_117.conda - sha256: 8c9079b246a1150a72bc2b76e3d41ea0c49ecd8e0d1e3e3ab69a082e142d1fd8 - md5: 8c08420c39e318bccf6d14634b6b5caa + size: 727390 + timestamp: 1754055079231 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h2d3d5cf_118.conda + sha256: e7ca7726e94ef56e96ef7e5a89b23971188b2b54e1b660ed1c200593cc0ae055 + md5: ed5b74ff627e6cb6d7ab1c3ef7e3baf8 depends: - __osx >=11.0 - blosc >=1.21.6,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.6,<1.14.7.0a0 - - libaec >=1.1.3,<2.0a0 - - libcurl >=8.13.0,<9.0a0 - - libcxx >=18 - - libxml2 >=2.13.7,<2.14.0a0 + - libaec >=1.1.4,<2.0a0 + - libcurl >=8.14.1,<9.0a0 + - libcxx >=19 + - libxml2 >=2.13.8,<2.14.0a0 - libzip >=1.11.2,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 + - openssl >=3.5.1,<4.0a0 - zlib - zstd >=1.5.7,<1.6.0a0 license: MIT license_family: MIT purls: [] - size: 685842 - timestamp: 1745510217553 + size: 683396 + timestamp: 1754055262589 - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda sha256: b0f2b3695b13a989f75d8fd7f4778e1c7aabe3b36db83f0fe80b2cd812c0e975 md5: 19e57602824042dfd0446292ef90488b @@ -5290,6 +5273,7 @@ packages: constrains: - openblas >=0.3.30,<0.3.31.0a0 license: BSD-3-Clause + license_family: BSD purls: [] size: 5918161 timestamp: 1753405234435 @@ -5323,37 +5307,37 @@ packages: purls: [] size: 4163399 timestamp: 1750378829050 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h943b412_0.conda - sha256: c7b212bdd3f9d5450c4bae565ccb9385222bf9bb92458c2a23be36ff1b981389 - md5: 51de14db340a848869e69c632b43cca7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda + sha256: e75a2723000ce3a4b9fd9b9b9ce77553556c93e475a4657db6ed01abc02ea347 + md5: 7af8e91b0deb5f8e25d1a595dea79614 depends: + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - libzlib >=1.3.1,<2.0a0 license: zlib-acknowledgement purls: [] - size: 289215 - timestamp: 1751559366724 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h3c4a55f_0.conda - sha256: a6b51f7056d3f5cf7e71f87314e7b3bb3b6ac5e38a4fb366cf500790e325ffd2 - md5: 0b750895b4a3cbd06e685f86c24c205d + size: 317390 + timestamp: 1753879899951 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.50-h84aeda2_1.conda + sha256: 8d92c82bcb09908008d8cf5fab75e20733810d40081261d57ef8cd6495fc08b4 + md5: 1fe32bb16991a24e112051cc0de89847 depends: - __osx >=10.13 - libzlib >=1.3.1,<2.0a0 license: zlib-acknowledgement purls: [] - size: 267202 - timestamp: 1751559565046 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h3783ad8_0.conda - sha256: 38d89e4ceae81f24a11129d2f5e8d10acfc12f057b7b4fd5af9043604a689941 - md5: f39e4bd5424259d8dfcbdbf0e068558e + size: 297609 + timestamp: 1753879919854 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.50-h280e0eb_1.conda + sha256: a2e0240fb0c79668047b528976872307ea80cb330baf8bf6624ac2c6443449df + md5: 4d0f5ce02033286551a32208a5519884 depends: - __osx >=11.0 - libzlib >=1.3.1,<2.0a0 license: zlib-acknowledgement purls: [] - size: 260895 - timestamp: 1751559636317 + size: 287056 + timestamp: 1753879907258 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda sha256: 0105bd108f19ea8e6a78d2d994a6d4a8db16d19a41212070d2d1d48a63c34161 md5: a587892d3c13b6621a6091be690dbca2 @@ -5381,40 +5365,38 @@ packages: purls: [] size: 164972 timestamp: 1716828607917 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.3-hee844dc_1.conda - sha256: 8c4faf560815a6d6b5edadc019f76d22a45171eaa707a1f1d1898ceda74b2e3f - md5: 18d2ac95b507ada9ca159a6bd73255f7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda + sha256: 6d9c32fc369af5a84875725f7ddfbfc2ace795c28f246dc70055a79f9b2003da + md5: 0b367fad34931cb79e0d6b7e5c06bb1c depends: - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 - libgcc >=14 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 936339 - timestamp: 1753262589168 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.3-h875aaf5_1.conda - sha256: 3a585d1ddf823a3d7b033196d4aa769971922a984b0735ba741f3cc756a2e576 - md5: 10de0664b3e6f560c7707890aca8174c + size: 932581 + timestamp: 1753948484112 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.50.4-h39a8b3b_0.conda + sha256: 466366b094c3eb4b1d77320530cbf5400e7a10ab33e4824c200147488eebf7a6 + md5: 156bfb239b6a67ab4a01110e6718cbc4 depends: - __osx >=10.13 - - icu >=75.1,<76.0a0 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 984580 - timestamp: 1753262751819 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.3-h4237e3c_1.conda - sha256: 248ba9622ee91c3ae1266f7b69143adf5031e1f2d94b6d02423e192e47531697 - md5: 6d034f4604ac104a1256204af7d1a534 + size: 980121 + timestamp: 1753948554003 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda + sha256: 802ebe62e6bc59fc26b26276b793e0542cfff2d03c086440aeaf72fb8bbcec44 + md5: 1dcb0468f5146e38fae99aef9656034b depends: - __osx >=11.0 - icu >=75.1,<76.0a0 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 902818 - timestamp: 1753262833682 + size: 902645 + timestamp: 1753948599139 - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 md5: eecce068c7e4eddeb169591baac20ac4 @@ -5451,27 +5433,27 @@ packages: purls: [] size: 279193 timestamp: 1745608793272 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_3.conda - sha256: 7650837344b7850b62fdba02155da0b159cf472b9ab59eb7b472f7bd01dff241 - md5: 6d11a5edae89fe413c0569f16d308f5a +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_4.conda + sha256: b5b239e5fca53ff90669af1686c86282c970dd8204ebf477cf679872eb6d48ac + md5: 3c376af8888c386b9d3d1c2701e2f3ab depends: - __glibc >=2.17,<3.0.a0 - - libgcc 15.1.0 h767d61c_3 + - libgcc 15.1.0 h767d61c_4 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 3896407 - timestamp: 1750808251302 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_3.conda - sha256: bbaea1ecf973a7836f92b8ebecc94d3c758414f4de39d2cc6818a3d10cb3216b - md5: 57541755b5a51691955012b8e197c06c + size: 3903453 + timestamp: 1753903894186 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_4.conda + sha256: 81c841c1cf4c0d06414aaa38a249f9fdd390554943065c3a0b18a9fb7e8cc495 + md5: 2d34729cbc1da0ec988e57b13b712067 depends: - - libstdcxx 15.1.0 h8f9b012_3 + - libstdcxx 15.1.0 h8f9b012_4 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 29093 - timestamp: 1750808292700 + size: 29317 + timestamp: 1753903924491 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda sha256: 7fa6ddac72e0d803bb08e55090a8f2e71769f1eb7adbd5711bdd7789561601b1 md5: e79a094918988bb1807462cd42c83962 @@ -5534,37 +5516,37 @@ packages: purls: [] size: 33601 timestamp: 1680112270483 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb9d3cd8_0.conda - sha256: 770ca175d64323976c9fe4303042126b2b01c1bd54c8c96cafeaba81bdb481b8 - md5: 1349c022c92c5efd3fd705a79a5804d8 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 890145 - timestamp: 1748304699136 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h4cb831e_0.conda - sha256: 2c820c8e26d680f74035f58c3d46593461bb8aeefa00faafa5ca39d8a51c87fa - md5: 8afd5432c2e6776d145d94f4ea4d4db5 + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + sha256: d90dd0eee6f195a5bd14edab4c5b33be3635b674b0b6c010fb942b956aa2254c + md5: fbfc6cf607ae1e1e498734e256561dc3 depends: - - __osx >=11.0 + - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 420355 - timestamp: 1748304826637 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h5505292_0.conda - sha256: 41c1230a3f4e0d265e5053c671f112a16be4405b9047d3da5581e03e9d53de65 - md5: 230a885fe67a3e945a4586b944b6020a + size: 422612 + timestamp: 1753948458902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 + md5: c0d87c3c8e075daf1daf6c31b53e8083 depends: - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 420654 - timestamp: 1748304893204 + size: 421195 + timestamp: 1753948426421 - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b md5: aea31d2e5b1091feca96fcfe945c3cf9 @@ -5651,24 +5633,40 @@ packages: purls: [] size: 100393 timestamp: 1702724383534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda - sha256: b0b3a96791fa8bb4ec030295e8c8bf2d3278f33c0f9ad540e73b5e538e6268e7 - md5: 14dbe05b929e329dbaa6f2d0aa19466d +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h04c0eec_1.conda + sha256: 03deb1ec6edfafc5aaeecadfc445ee436fecffcda11fcd97fde9b6632acb583f + md5: 10bcbd05e1c1c9d652fccb42b776a9fa depends: - __glibc >=2.17,<3.0.a0 - icu >=75.1,<76.0a0 - - libgcc >=13 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 698448 + timestamp: 1754315344761 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h2cb61b6_1.conda + sha256: 2c80ef042b47dfddb1f425d57d367e0657f8477d80111644c88b172ff2f99151 + md5: 42a8e4b54e322b4cd1dbfb30a8a7ce9e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - libiconv >=1.18,<2.0a0 - liblzma >=5.8.1,<6.0a0 - libzlib >=1.3.1,<2.0a0 + constrains: + - icu <0.0a0 license: MIT license_family: MIT purls: [] - size: 690864 - timestamp: 1746634244154 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-h93c44a6_0.conda - sha256: 4b29663164d7beb9a9066ddcb8578fc67fe0e9b40f7553ea6255cd6619d24205 - md5: e42a93a31cbc6826620144343d42f472 + size: 697020 + timestamp: 1754315347913 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.8-he1bc88e_1.conda + sha256: 248871154c6f86f0c6d456872457ad4f5799e23c09512a473041da3b9b9ee83c + md5: 1d31029d8d2685d56a812dec48083483 depends: - __osx >=10.13 - icu >=75.1,<76.0a0 @@ -5678,11 +5676,11 @@ packages: license: MIT license_family: MIT purls: [] - size: 609197 - timestamp: 1746634704204 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h52572c6_0.conda - sha256: 13eb825eddce93761d965da3edaf3a42d868c61ece7d9cf21f7e2a13087c2abe - md5: d7884c7af8af5a729353374c189aede8 + size: 611430 + timestamp: 1754315569848 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.8-h4a9ca0c_1.conda + sha256: 365ad1fa0b213e3712d882f187e6de7f601a0e883717f54fe69c344515cdba78 + md5: 05774cda4a601fc21830842648b3fe04 depends: - __osx >=11.0 - icu >=75.1,<76.0a0 @@ -5692,8 +5690,8 @@ packages: license: MIT license_family: MIT purls: [] - size: 583068 - timestamp: 1746634531197 + size: 582952 + timestamp: 1754315458016 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.11.2-h6991a6a_0.conda sha256: 991e7348b0f650d495fb6d8aa9f8c727bdf52dabf5853c0cc671439b160dce48 md5: a7b27c075c9b7f459f1c022090697cba @@ -5771,42 +5769,45 @@ packages: purls: [] size: 46438 timestamp: 1727963202283 -- conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.8-h4922eb0_0.conda - sha256: 209050b372cf2103ac6a8fcaaf7f1b0d4dbb425395733b2e84f8949fa66b6ca7 - md5: dda42855e1d9a0b59e071e28a820d0f5 +- conda: https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.8-h4922eb0_1.conda + sha256: 4539fd52a5f59039cd575caf222e22ebe57ab168cd102d182a970c1f1a72fe51 + md5: 5d5099916a3659a46cca8f974d0455b9 depends: - __glibc >=2.17,<3.0.a0 constrains: - openmp 20.1.8|20.1.8.* + - intel-openmp <0.0a0 license: Apache-2.0 WITH LLVM-exception license_family: APACHE purls: [] - size: 3214565 - timestamp: 1752565638114 -- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_0.conda - sha256: 9f4161cbb2d17c9622380ec0c59938bd1600324e30a48a770509fbe6d9eee8af - md5: ab3b31ebe0afdf903fa5ac7f13357e39 + size: 3207261 + timestamp: 1753978851330 +- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.8-hf4e0ed4_1.conda + sha256: 881975b8e13fb65d5e3d1cd7dd574581082af10c675c27c342e317c03ddfeaac + md5: 55ae491cc02d64a55b75ffae04d7369b depends: - __osx >=10.13 constrains: + - intel-openmp <0.0a0 - openmp 20.1.8|20.1.8.* license: Apache-2.0 WITH LLVM-exception license_family: APACHE purls: [] - size: 308578 - timestamp: 1752565939065 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_0.conda - sha256: d731910cd4d084574c6bba0638ac98906c1fd8104a2e844f69813e641cf72305 - md5: 6f5b4542c2dd772024d9f7e7b0d5e41a + size: 307933 + timestamp: 1753978812327 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-20.1.8-hbb9b287_1.conda + sha256: e56f46b253dd1a99cc01dde038daba7789fc6ed35b2a93e3fc44b8578a82b3ec + md5: a10bdc3e5d9e4c1ce554c83855dff6c4 depends: - __osx >=11.0 constrains: - openmp 20.1.8|20.1.8.* + - intel-openmp <0.0a0 license: Apache-2.0 WITH LLVM-exception license_family: APACHE purls: [] - size: 283218 - timestamp: 1752565794800 + size: 283300 + timestamp: 1753978829840 - pypi: https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl name: loguru version: 0.7.3 @@ -5976,17 +5977,17 @@ packages: - pkg:pypi/markupsafe?source=hash-mapping size: 24757 timestamp: 1733219916634 -- pypi: https://files.pythonhosted.org/packages/48/9d/797d595dc57bbcb6284584ca7e228ac54b421aa1e864cec15d0f78e02f4b/material_plausible_plugin-0.2.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/32/42/097a9eee92b2b96979823ae55b2b42fba590f79f979a0b24138db628fac4/material_plausible_plugin-0.3.0-py3-none-any.whl name: material-plausible-plugin - version: 0.2.0 - sha256: b7dc866b358475d940c5c61f56f86c400b9c1e73ffa2b06819207df38f34fcf4 + version: 0.3.0 + sha256: 4e1cbaf0eef86dbd34fafa2f25830960416c989f80e0b1d1fabceed6cf6b40aa requires_dist: - mkdocs - mkdocs-material - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py312hd3ec401_0.conda - sha256: 3b5be100ddfcd5697140dbb8d4126e3afd0147d4033defd6c6eeac78fe089bd2 - md5: 2d69618b52d70970c81cc598e4b51118 + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.5-py312he3d6523_0.conda + sha256: 66e94e6226fd3dd04bb89d04079e2d8e2c74d923c0bbf255e483f127aee621ff + md5: 9246288e5ef2a944f7c9c648f9f331c7 depends: - __glibc >=2.17,<3.0.a0 - contourpy >=1.0.1 @@ -5996,10 +5997,10 @@ packages: - kiwisolver >=1.3.1 - libfreetype >=2.13.3 - libfreetype6 >=2.13.3 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.19,<3 + - libgcc >=14 + - libstdcxx >=14 - numpy >=1.23 + - numpy >=1.23,<3 - packaging >=20.0 - pillow >=8 - pyparsing >=2.3.1 @@ -6011,12 +6012,12 @@ packages: license: PSF-2.0 license_family: PSF purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 8188885 - timestamp: 1746820680864 -- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda - sha256: eb23d6945d34836b62add0ca454f287cadb74b4b771cdd7196a1f51def425014 - md5: 4f8816d006b1c155ec416bcf7ff6cee2 + - pkg:pypi/matplotlib?source=compressed-mapping + size: 8071030 + timestamp: 1754005868258 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.5-py313h683a580_0.conda + sha256: 48c12e4682fdb92e2dfa4c4f885e252d0b14168dd4a672a6da376fea551b2e69 + md5: 9edc5badd11b451eb00eb8c492545fe2 depends: - __glibc >=2.17,<3.0.a0 - contourpy >=1.0.1 @@ -6026,10 +6027,10 @@ packages: - kiwisolver >=1.3.1 - libfreetype >=2.13.3 - libfreetype6 >=2.13.3 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.21,<3 + - libgcc >=14 + - libstdcxx >=14 - numpy >=1.23 + - numpy >=1.23,<3 - packaging >=20.0 - pillow >=8 - pyparsing >=2.3.1 @@ -6042,11 +6043,11 @@ packages: license_family: PSF purls: - pkg:pypi/matplotlib?source=hash-mapping - size: 8479847 - timestamp: 1746820689093 -- conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.3-py312h535dea3_0.conda - sha256: a5d1324658d173211db6c78ecbf0b3bd32c85477d293e347820adb528b1719a2 - md5: 8583ca3cb002ae887cbc747f8eb5ffdf + size: 8341150 + timestamp: 1754006124310 +- conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.5-py312hb83d5b5_0.conda + sha256: 2d9f3d2865209c3350e780bb788629e198fed71fb015e52cb162310a459453bc + md5: 4eba589e971291d9b64b96d4578110b8 depends: - __osx >=10.13 - contourpy >=1.0.1 @@ -6054,11 +6055,11 @@ packages: - fonttools >=4.22.0 - freetype - kiwisolver >=1.3.1 - - libcxx >=18 + - libcxx >=19 - libfreetype >=2.13.3 - libfreetype6 >=2.13.3 - - numpy >=1.19,<3 - numpy >=1.23 + - numpy >=1.23,<3 - packaging >=20.0 - pillow >=8 - pyparsing >=2.3.1 @@ -6069,12 +6070,12 @@ packages: license: PSF-2.0 license_family: PSF purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 8221825 - timestamp: 1746821002072 -- conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.3-py313he981572_0.conda - sha256: 4f904fe1bb1951d83bdcb66a19d02cf88fd2f330507221753e774adcd8f4a69f - md5: 91c22969c0974f2f23470d517774d457 + - pkg:pypi/matplotlib?source=compressed-mapping + size: 8193888 + timestamp: 1754005842129 +- conda: https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.5-py313h5771d13_0.conda + sha256: 37b206a2d000e555f0cf52589e79805f16cc4862eb3ca65fac2b15db582db03b + md5: c5210f966876b237ba35340b3b89d695 depends: - __osx >=10.13 - contourpy >=1.0.1 @@ -6082,11 +6083,11 @@ packages: - fonttools >=4.22.0 - freetype - kiwisolver >=1.3.1 - - libcxx >=18 + - libcxx >=19 - libfreetype >=2.13.3 - libfreetype6 >=2.13.3 - - numpy >=1.21,<3 - numpy >=1.23 + - numpy >=1.23,<3 - packaging >=20.0 - pillow >=8 - pyparsing >=2.3.1 @@ -6098,11 +6099,11 @@ packages: license_family: PSF purls: - pkg:pypi/matplotlib?source=hash-mapping - size: 8151792 - timestamp: 1746820926548 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.3-py313haaf02c0_0.conda - sha256: 26619ea7dacf7fa96b8c2e8de2a4fa7bc05bbfb902d8f2222e0de226b16e3274 - md5: 9d557ea5db71727347ad8779713e3f7c + size: 8249844 + timestamp: 1754005832823 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.5-py313h919948c_0.conda + sha256: 3942fd6b63ad0ea8a9109dd745e64091ba10bc3fa0504425c6e25633d8fcec9c + md5: 4029ee1e6d3448aac06fe33d6ceda272 depends: - __osx >=11.0 - contourpy >=1.0.1 @@ -6110,11 +6111,11 @@ packages: - fonttools >=4.22.0 - freetype - kiwisolver >=1.3.1 - - libcxx >=18 + - libcxx >=19 - libfreetype >=2.13.3 - libfreetype6 >=2.13.3 - - numpy >=1.21,<3 - numpy >=1.23 + - numpy >=1.23,<3 - packaging >=20.0 - pillow >=8 - pyparsing >=2.3.1 @@ -6126,9 +6127,9 @@ packages: license: PSF-2.0 license_family: PSF purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 8180005 - timestamp: 1746820965852 + - pkg:pypi/matplotlib?source=compressed-mapping + size: 8137095 + timestamp: 1754005898026 - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_1.conda sha256: 69b7dc7131703d3d60da9b0faa6dd8acbf6f6c396224cf6aef3e855b8c0c41c6 md5: af6ab708897df59bd6e7283ceab1b56b @@ -6442,18 +6443,19 @@ packages: - pydantic>=2.8.1 ; python_full_version >= '3.13' - wcmatch>=8.4 requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.4.0-pyhd8ed1ab_0.tar.bz2 - sha256: f158e2239b0b4549dc5e0d38c973135e19f8def084f0d096faf2c6161d12b1a9 - md5: ea350040131e9a179817f620a704411a +- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-gen-files-0.5.0-pyh29332c3_0.conda + sha256: 773e21929c07d44b3a4878b7381b45f06cc020d2cedbcc0b2569624113f91544 + md5: aeb821ec6ae5ef52d3ec7752098aa389 depends: - - mkdocs <2.0.0,>=1.0.3 - - python >=3.7 + - python >=3.9 + - mkdocs >=1.4.1 + - python license: MIT license_family: MIT purls: - pkg:pypi/mkdocs-gen-files?source=hash-mapping - size: 12043 - timestamp: 1661211107053 + size: 15937 + timestamp: 1745648543618 - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocs-get-deps-0.2.0-pyhd8ed1ab_1.conda sha256: e0b501b96f7e393757fb2a61d042015966f6c5e9ac825925e43f9a6eafa907b6 md5: 84382acddb26c27c70f2de8d4c830830 @@ -6566,10 +6568,10 @@ packages: - pkg:pypi/mkdocs-material-extensions?source=hash-mapping size: 16122 timestamp: 1734641109286 -- pypi: https://files.pythonhosted.org/packages/e1/46/db5d3235cfa6764e3b09ea82cb2c606b2a5bbe77547eb551ad30bc85d0cf/mkdocs_print_site_plugin-2.7.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/3f/3e/7513f2f37c563da65d1b91781e047f4a1c0ceac8206d4f6042428428e4ad/mkdocs_print_site_plugin-2.8-py3-none-any.whl name: mkdocs-print-site-plugin - version: 2.7.3 - sha256: 64de07350a93c1c5406e43186c41b29f1424b14264cbedf6da040adb018cdee9 + version: '2.8' + sha256: 838bd0a9b7141c11c0f1fdaa51ffe70c35740bec1f07c0806f8018e92f93f9da requires_dist: - mkdocs-material>=7.3.0 requires_python: '>=3.8' @@ -6588,26 +6590,25 @@ packages: - pkg:pypi/mkdocs-table-reader-plugin?source=hash-mapping size: 15076 timestamp: 1724961317361 -- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.28.3-pyhd8ed1ab_0.conda - sha256: 88e94cb9de7ad5b26db09ca9d8edb54a8b1bb412de404baa14b78b374f84199b - md5: 70de335a1b77f14e7f52be7ab127d7a8 +- conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-0.30.0-pyhd8ed1ab_0.conda + sha256: e5785a8e461444267d5b8e4fcc263e34184d004bb95ae425f925f4fd2585d9b0 + md5: 4107cd44ac3a0f2f12d345cbedcd6bed depends: - click >=7.0 - importlib-metadata >=4.6 - jinja2 >=2.11.1 - markdown >=3.6 - markupsafe >=1.1 - - mkdocs >=1.4 + - mkdocs >=1.6 - mkdocs-autorefs >=1.4 - - mkdocs-get-deps >=0.2 - pymdown-extensions >=6.3 - python >=3.9,<4.0 - typing-extensions >=4.1 license: ISC purls: - pkg:pypi/mkdocstrings?source=hash-mapping - size: 33908 - timestamp: 1741490316165 + size: 35364 + timestamp: 1753363420566 - conda: https://conda.anaconda.org/conda-forge/noarch/mkdocstrings-python-1.16.12-pyhff2d567_0.conda sha256: f07f4a42bb13378305f2702905d35099838de83a235880017d1ae3a0fd401772 md5: 6c3977dafc75737777349db98cd22d5e @@ -6622,9 +6623,9 @@ packages: - pkg:pypi/mkdocstrings-python?source=hash-mapping size: 58361 timestamp: 1748965218001 -- conda: https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_16.conda - sha256: 9be33c297dd53e4eafef7c6ec597f1b4dee99296a768816d9bf793e2432a027f - md5: 06fc17a281d2f71995f3bb58a7b7f4e5 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda + sha256: 1e59d0dc811f150d39c2ff2da930d69dcb91cb05966b7df5b7d85133006668ed + md5: e4ab075598123e783b788b995afbdad0 depends: - _openmp_mutex * *_llvm - _openmp_mutex >=4.5 @@ -6633,8 +6634,8 @@ packages: license: LicenseRef-IntelSimplifiedSoftwareOct2022 license_family: Proprietary purls: [] - size: 124933224 - timestamp: 1753395548401 + size: 124988693 + timestamp: 1753975818422 - conda: https://conda.anaconda.org/conda-forge/noarch/mmtf-python-1.1.3-pyhd8ed1ab_0.tar.bz2 sha256: be4a689665c1639eec71637dc4053d4c5d64a831de3120b4c77bf7f92ae05962 md5: 2e68d973b43ff50b76ffe35f227bdc73 @@ -6754,9 +6755,9 @@ packages: - pkg:pypi/munkres?source=hash-mapping size: 15851 timestamp: 1749895533014 -- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.17.0-py312h4c3975b_0.conda - sha256: f7a427cc6e94fc3c5be83ff0b48509a9a41e9ab48065a14101d0d13b2dd7c9bf - md5: ebf26f1cfb032d55a2f433ea7a3139f7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.17.1-py312h4c3975b_0.conda + sha256: 7d010066a2b0a699f0a3ad18242f2a1dcd277d7311fb74417b370f47eee5d08f + md5: 0a9db9dffdbd963f85ef4ac071a54d8c depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -6770,11 +6771,11 @@ packages: license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 18931157 - timestamp: 1752534887158 -- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.17.0-py312h2f459f6_0.conda - sha256: 90ddf6c2cfb92809ff12a59a4582bd407fec861392b788ae0ddbf74cb0730b02 - md5: 0e29f409ddc7bf728ecac96cb46a700f + size: 18951584 + timestamp: 1754001482966 +- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.17.1-py312h2f459f6_0.conda + sha256: d22d774f0aa5363205bf127fa19b2dfedf7630116ef5a506c795714dfb853cfa + md5: 7aa6026b32e0b4726b13b58cc58e1ad6 depends: - __osx >=10.13 - mypy_extensions >=1.0.0 @@ -6787,11 +6788,11 @@ packages: license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 12704250 - timestamp: 1752535007235 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.17.0-py313hcdf3177_0.conda - sha256: 286a3a00f735e6ef5e26344e8512c104d894951740e7b5344f764c1bcf598a41 - md5: 1c79a2ab3d0c2815c1ab94e8990cd696 + size: 12827570 + timestamp: 1754001914845 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.17.1-py313hcdf3177_0.conda + sha256: de86705b106363008fd1527174bc6a4e3d435e9e9c59bd0b577c98ad21dce670 + md5: dcbd013e9939fa4903e214344b560692 depends: - __osx >=11.0 - mypy_extensions >=1.0.0 @@ -6805,8 +6806,8 @@ packages: license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 10462183 - timestamp: 1752534911058 + size: 10482819 + timestamp: 1754001614290 - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 md5: e9c622e0d00fa24a6292279af3ab6d06 @@ -7209,9 +7210,9 @@ packages: purls: [] size: 17949155 timestamp: 1752839389217 -- conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.17.0-pyhd8ed1ab_0.conda - sha256: 459fe173ba9a087d42602cbd399b6074f9641dcb0053be8edebe618e9020bfed - md5: 6f863bd4d3bbdf6fcd741aa004529bb9 +- conda: https://conda.anaconda.org/conda-forge/noarch/nodejs-wheel-22.18.0-pyhd8ed1ab_0.conda + sha256: d3e3ce1945e1656959f2fb471a953b796783f2adc64d1f09aebddbc9d4171c25 + md5: dc6cbe92066444d24ebac0c4d2a1d755 depends: - nodejs - python >=3.9 @@ -7219,8 +7220,8 @@ packages: license_family: MIT purls: - pkg:pypi/nodejs-wheel-binaries?source=hash-mapping - size: 12351 - timestamp: 1751232576536 + size: 12388 + timestamp: 1754049967477 - pypi: https://files.pythonhosted.org/packages/1b/f5/515f98d659ab0cbe3738da153eddae22186fd38f05a808511e10f04cf679/numcodecs-0.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: numcodecs version: 0.16.1 @@ -7337,6 +7338,7 @@ packages: constrains: - numpy-base <0a0 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/numpy?source=compressed-mapping size: 8785045 @@ -7357,8 +7359,9 @@ packages: constrains: - numpy-base <0a0 license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/numpy?source=compressed-mapping + - pkg:pypi/numpy?source=hash-mapping size: 8889862 timestamp: 1753401532585 - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.2-py312hda18a35_0.conda @@ -7375,6 +7378,7 @@ packages: constrains: - numpy-base <0a0 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/numpy?source=hash-mapping size: 7944998 @@ -7393,8 +7397,9 @@ packages: constrains: - numpy-base <0a0 license: BSD-3-Clause + license_family: BSD purls: - - pkg:pypi/numpy?source=compressed-mapping + - pkg:pypi/numpy?source=hash-mapping size: 8031795 timestamp: 1753401536338 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.2-py313h674b998_0.conda @@ -7412,87 +7417,88 @@ packages: constrains: - numpy-base <0a0 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/numpy?source=compressed-mapping size: 6747854 timestamp: 1753401542639 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda - sha256: 5bee706ea5ba453ed7fd9da7da8380dd88b865c8d30b5aaec14d2b6dd32dbc39 - md5: 9e5816bc95d285c115a3ebc2f8563564 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda + sha256: 0b7396dacf988f0b859798711b26b6bc9c6161dca21bacfd778473da58730afa + md5: 01243c4aaf71bde0297966125aea4706 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libpng >=1.6.44,<1.7.0a0 - - libstdcxx >=13 + - libgcc >=14 + - libpng >=1.6.50,<1.7.0a0 + - libstdcxx >=14 - libtiff >=4.7.0,<4.8.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-2-Clause license_family: BSD purls: [] - size: 342988 - timestamp: 1733816638720 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda - sha256: faea03f36c9aa3524c911213b116da41695ff64b952d880551edee2843fe115b - md5: 025c711177fc3309228ca1a32374458d + size: 357828 + timestamp: 1754297886899 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h036ada5_1.conda + sha256: fea2a79edb123fda31d73857e96b6cd24404a31d41693d8ef41235caed74b28e + md5: 38f264b121a043cf379980c959fb2d75 depends: - __osx >=10.13 - - libcxx >=18 - - libpng >=1.6.44,<1.7.0a0 + - libcxx >=19 + - libpng >=1.6.50,<1.7.0a0 - libtiff >=4.7.0,<4.8.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-2-Clause license_family: BSD purls: [] - size: 332320 - timestamp: 1733816828284 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h8a3d83b_0.conda - sha256: 1d59bc72ca7faac06d349c1a280f5cfb8a57ee5896f1e24225a997189d7418c7 - md5: 4b71d78648dbcf68ce8bf22bb07ff838 + size: 336370 + timestamp: 1754297904811 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda + sha256: 6013916893fcd9bc97c479279cfe4616de7735ec566bad0ee41bc729e14d31b2 + md5: ab581998c77c512d455a13befcddaac3 depends: - __osx >=11.0 - - libcxx >=18 - - libpng >=1.6.44,<1.7.0a0 + - libcxx >=19 + - libpng >=1.6.50,<1.7.0a0 - libtiff >=4.7.0,<4.8.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-2-Clause license_family: BSD purls: [] - size: 319362 - timestamp: 1733816781741 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.1-h7b32b05_0.conda - sha256: 942347492164190559e995930adcdf84e2fea05307ec8012c02a505f5be87462 - md5: c87df2ab1448ba69169652ab9547082d + size: 320198 + timestamp: 1754297986425 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.2-h26f9b46_0.conda + sha256: c9f54d4e8212f313be7b02eb962d0cb13a8dae015683a403d3accd4add3e520e + md5: ffffb341206dd0dab0c36053c048d621 depends: - __glibc >=2.17,<3.0.a0 - ca-certificates - - libgcc >=13 + - libgcc >=14 license: Apache-2.0 license_family: Apache purls: [] - size: 3131002 - timestamp: 1751390382076 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.1-hc426f3f_0.conda - sha256: d5dc7da2ef7502a14f88443675c4894db336592ac7b9ae0517e1339ebb94f38a - md5: f1ac2dbc36ce2017bd8f471960b1261d + size: 3128847 + timestamp: 1754465526100 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.5.2-h6e31bce_0.conda + sha256: 8be57a11019666aa481122c54e29afd604405b481330f37f918e9fbcd145ef89 + md5: 22f5d63e672b7ba467969e9f8b740ecd depends: - __osx >=10.13 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2744123 - timestamp: 1751391059798 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.1-h81ee809_0.conda - sha256: f94fde0f096fa79794c8aa0a2665630bbf9026cc6438e8253f6555fc7281e5a8 - md5: a8ac77e7c7e58d43fa34d60bd4361062 + size: 2743708 + timestamp: 1754466962243 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.5.2-he92f556_0.conda + sha256: f6d1c87dbcf7b39fad24347570166dade1c533ae2d53c60a70fa4dc874ef0056 + md5: bcb0d87dfbc199d0a461d2c7ca30b3d8 depends: - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 3071649 - timestamp: 1751390309393 + size: 3074848 + timestamp: 1754465710470 - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda sha256: 289861ed0c13a15d7bbb408796af4de72c2fe67e2bcb0de98f4c3fce259d7991 md5: 58335b26c38bf4a20f399384c33cbcf9 @@ -8088,10 +8094,10 @@ packages: - pkg:pypi/pluggy?source=hash-mapping size: 24246 timestamp: 1747339794916 -- pypi: https://files.pythonhosted.org/packages/3d/6e/bdd0937653c1e7a564a09ae3bc7757ce83fedbf19da600c8b35d62c0182a/polars-1.31.0-cp39-abi3-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/22/74/ea073a88073cd6025b12850484f51d30dad695b51432a3f0a0439e2f8094/polars-1.32.2-cp39-abi3-macosx_11_0_arm64.whl name: polars - version: 1.31.0 - sha256: ccc68cd6877deecd46b13cbd2663ca89ab2a2cb1fe49d5cfc66a9cef166566d9 + version: 1.32.2 + sha256: d3f4e061312ef6c2a907378ce407a6132734fe1a13f261a1984a1a9ca2f6febc requires_dist: - polars-cloud>=0.0.1a1 ; extra == 'polars-cloud' - numpy>=1.16.0 ; extra == 'numpy' @@ -8122,10 +8128,10 @@ packages: - cudf-polars-cu12 ; extra == 'gpu' - polars[async,cloudpickle,database,deltalake,excel,fsspec,graph,iceberg,numpy,pandas,plot,pyarrow,pydantic,style,timezone] ; extra == 'all' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/77/fe/81aaca3540c1a5530b4bc4fd7f1b6f77100243d7bb9b7ad3478b770d8b3e/polars-1.31.0-cp39-abi3-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/ec/14/ee34ebe3eb842c83ca1d2d3af6ee02b08377e056ffad156c9a2b15a6d05c/polars-1.32.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: polars - version: 1.31.0 - sha256: a94c5550df397ad3c2d6adc212e59fd93d9b044ec974dd3653e121e6487a7d21 + version: 1.32.2 + sha256: a711a750cfc19f1f883d2b46895dd698abf4d446ca41c3bf510ced0ff1178057 requires_dist: - polars-cloud>=0.0.1a1 ; extra == 'polars-cloud' - numpy>=1.16.0 ; extra == 'numpy' @@ -8156,10 +8162,10 @@ packages: - cudf-polars-cu12 ; extra == 'gpu' - polars[async,cloudpickle,database,deltalake,excel,fsspec,graph,iceberg,numpy,pandas,plot,pyarrow,pydantic,style,timezone] ; extra == 'all' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b8/d9/5e2753784ea30d84b3e769a56f5e50ac5a89c129e87baa16ac0773eb4ef7/polars-1.31.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/f5/61/b251ce6755d0d3c6f4c8cb245941b80901624fce7efeb95b37c170da2565/polars-1.32.2-cp39-abi3-macosx_10_12_x86_64.whl name: polars - version: 1.31.0 - sha256: ada7940ed92bea65d5500ae7ac1f599798149df8faa5a6db150327c9ddbee4f1 + version: 1.32.2 + sha256: f21da6a5210898ec800b7e9e667fb53eb9161b7ceb812ee6555ff5661a00e517 requires_dist: - polars-cloud>=0.0.1a1 ; extra == 'polars-cloud' - numpy>=1.16.0 ; extra == 'numpy' @@ -8480,9 +8486,9 @@ packages: - pkg:pypi/pylint?source=hash-mapping size: 380752 timestamp: 1746387959153 -- conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16-pyhd8ed1ab_0.conda - sha256: 7465d67daa980999606138d74631563f5c233624cf5d65fc3f1f7210fce91b64 - md5: 79dbb1bfe734d8e8b36ca328a63fb4de +- conda: https://conda.anaconda.org/conda-forge/noarch/pymdown-extensions-10.16.1-pyhd8ed1ab_0.conda + sha256: 8f575f123694e5acd2829440da55828f2cea60b0af5d8fa5406d83251ba80f61 + md5: 26e013bc453e643991cfa9b76911fb79 depends: - markdown >=3.6 - python >=3.9 @@ -8491,38 +8497,39 @@ packages: license_family: MIT purls: - pkg:pypi/pymdown-extensions?source=hash-mapping - size: 171431 - timestamp: 1750571864207 -- conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda - sha256: b92afb79b52fcf395fd220b29e0dd3297610f2059afac45298d44e00fcbf23b6 - md5: 513d3c262ee49b54a8fec85c5bc99764 + size: 170121 + timestamp: 1753743741894 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhe01879c_2.conda + sha256: afe32182b1090911b64ac0f29eb47e03a015d142833d8a917defd65d91c99b74 + md5: aa0028616c0750c773698fdc254b2b8d depends: - python >=3.9 + - python license: MIT license_family: MIT purls: - - pkg:pypi/pyparsing?source=hash-mapping - size: 95988 - timestamp: 1743089832359 + - pkg:pypi/pyparsing?source=compressed-mapping + size: 102292 + timestamp: 1753873557076 - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl name: pyproject-hooks version: 1.2.0 sha256: 9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/13/1d/1bf1102c17f496d7ef6ae2debdd990505f56fc4ed521aec371b8bdf8b607/pyrefly-0.16.3-py3-none-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/0d/14/bb882645300ecaa43e93db1e39ce1e5071f1b65ef8a9de7e939039f32ec2/pyrefly-0.27.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: pyrefly - version: 0.16.3 - sha256: 65683af5c09469c392ff392904f409bd770e9201704047b7baa5fd6836c5fcf1 + version: 0.27.1 + sha256: 2f984a56b92752fb03d857638211937f09a7850d380d77c31321073a6758320e requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/36/71/610ac09997ae76138b326a7c89000d9c43da3382db320e3c81e7e9e2a9cc/pyrefly-0.16.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/56/5f/27eb8c57b5d6e58988f1e57a7d2e80a7a95f79d420ed89a9cbfe779170b7/pyrefly-0.27.1-py3-none-macosx_10_12_x86_64.whl name: pyrefly - version: 0.16.3 - sha256: 2dad4092abc456eb52f3bd0b54170a53ff3fef2e6b571e583af4fbd93039ad9f + version: 0.27.1 + sha256: cf5facff33505648fed542468184096cbe48540bfd4134f1060fc73091a55a28 requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ed/8e/e5fa5c7cb327bb5ca086c9e1662b16ad9593e68bb41699e8d50299b7a514/pyrefly-0.16.3-py3-none-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/5e/d1/20ddf3c3c90e3422f54267b4743f1fdb14e7cf0425a1614c9e732b9f68f3/pyrefly-0.27.1-py3-none-macosx_11_0_arm64.whl name: pyrefly - version: 0.16.3 - sha256: 8f1b13f168922a1dd669b3460a4d26018e3e23ad92ff099c2215fa5848fbde35 + version: 0.27.1 + sha256: d364e2aad188d37d3f8b4987007a58c6c0329a2b36dbbeb0125caa73e5dc196f requires_python: '>=3.8' - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 @@ -8967,14 +8974,14 @@ packages: - pkg:pypi/pyyaml-env-tag?source=hash-mapping size: 11137 timestamp: 1747237061448 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.0.0-py313h8e95178_0.conda - sha256: 6446721c43ba540c02ced4dde564f5a9a0131e40aa406e8af6313084c4a2024f - md5: c912a00e5cb59357ef55b7930a48cf48 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.0.1-py313hb9b051e_0.conda + sha256: c83a9fe52d0b08498492d00dc65f0f50fec614aa49914ab1269e7b23e8439a67 + md5: 3207e5aef7ef1d899d64bcf8aaeecb91 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - libsodium >=1.0.20,<1.0.21.0a0 - - libstdcxx >=13 + - libstdcxx >=14 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - zeromq >=4.3.5,<4.4.0a0 @@ -8982,14 +8989,14 @@ packages: license_family: BSD purls: - pkg:pypi/pyzmq?source=hash-mapping - size: 384549 - timestamp: 1749898593849 -- conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.0.0-py313h2d45800_0.conda - sha256: a97ec0b43ec20c6730dd4765d033eeef7370364467190899aa554db1be4cff02 - md5: 0dfe209a2803bf6c87f2bdbe92697c31 + size: 385743 + timestamp: 1754238229027 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-27.0.1-py313hc53fb4d_0.conda + sha256: de854171c6753fe21b9476de5f86851790630a2f12eea6071d33358b918c2ce8 + md5: fac17dc7e81d2847105a618eb3dd843b depends: - __osx >=10.13 - - libcxx >=18 + - libcxx >=19 - libsodium >=1.0.20,<1.0.21.0a0 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -8998,14 +9005,14 @@ packages: license_family: BSD purls: - pkg:pypi/pyzmq?source=hash-mapping - size: 369843 - timestamp: 1749898684229 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.0.0-py313he6960b1_0.conda - sha256: da722b8ee2785d764182c2d3b9007fb5ef8bc4096f5fc018fd3b3026719b1ee7 - md5: 2cacb246854e185506768b3f7ae23a69 + size: 369798 + timestamp: 1754238283947 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.0.1-py313h330de61_0.conda + sha256: 12b7537a76ad28b058801de98e76ee5c71085d91c4e13981727b95e61e2bfc5f + md5: c043e4ed1f91a638b39507f887f9f50c depends: - __osx >=11.0 - - libcxx >=18 + - libcxx >=19 - libsodium >=1.0.20,<1.0.21.0a0 - python >=3.13,<3.14.0a0 - python >=3.13,<3.14.0a0 *_cp313 @@ -9015,8 +9022,8 @@ packages: license_family: BSD purls: - pkg:pypi/pyzmq?source=hash-mapping - size: 363932 - timestamp: 1749899287142 + size: 365743 + timestamp: 1754238346375 - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda sha256: 776363493bad83308ba30bcb88c2552632581b143e8ee25b1982c8c743e73abc md5: 353823361b1d27eb3960efb076dfcaf6 @@ -9159,29 +9166,29 @@ packages: - typing_extensions >=4.0.0,<5.0.0 - python license: MIT + license_family: MIT purls: - pkg:pypi/rich?source=compressed-mapping size: 201098 timestamp: 1753436991345 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.26.0-py313h4b2b08d_0.conda - sha256: 1fcae82b7f316d2199113cae3f33664bf14c1244bbd7d33d57f81e8434886404 - md5: ef99c1212c7a66b10920105e8636d1e7 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.27.0-py313h843e2db_0.conda + sha256: e6ed8b8fa2a3280663ebf3c599cfff134ce8db1e77864f5f735c74e4e55601e7 + md5: 4126b8e1fcfaebfead4e059f64b16996 depends: - python - - libgcc >=13 - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python_abi 3.13.* *_cp313 constrains: - __glibc >=2.17 license: MIT - license_family: MIT purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 388125 - timestamp: 1751467685278 -- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.26.0-py313hb35714d_0.conda - sha256: f686fda2556c7c548f9ae9e342fab5d1c1973e198acf91ac28d24f3b721acb2e - md5: 1d9600ff9dfed62fc4e95b3e699dcea7 + - pkg:pypi/rpds-py?source=compressed-mapping + size: 388067 + timestamp: 1754570285552 +- conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.27.0-py313h66e1e84_0.conda + sha256: 9ddf04ae730fd4d3805f8fd22017cdb21e8eeb12aeda8f3ccfc513843cc6c2cb + md5: 0ea5ad38eb07898fae8325b5fbe31ec4 depends: - python - __osx >=10.13 @@ -9189,14 +9196,13 @@ packages: constrains: - __osx >=10.13 license: MIT - license_family: MIT purls: - pkg:pypi/rpds-py?source=hash-mapping - size: 368619 - timestamp: 1751467169263 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.26.0-py313hf3ab51e_0.conda - sha256: 661349c89b3dd7234cf9a470f9b00f9284d5bf26f053e80ea288e0174e8ec907 - md5: c911da8ab509760e4d30bc02c8d6935a + size: 368381 + timestamp: 1754570016076 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.27.0-py313h80e0809_0.conda + sha256: d05d4eb509beb6a8061793a5710f4f9dffad98284bb0ace9a3f21b63102c78a6 + md5: d7b4225434fffea78af14273a12dbcee depends: - python - python 3.13.* *_cp313 @@ -9205,61 +9211,56 @@ packages: constrains: - __osx >=11.0 license: MIT - license_family: MIT purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 356822 - timestamp: 1751467136573 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.11.13-py312h1d08497_0.conda - sha256: 25e99382bbe8431e25f086960ba34de8d975c903a4810fbf2009e95285e4d719 - md5: 8e7c909d4f48865c8c5241d83649fc66 + - pkg:pypi/rpds-py?source=compressed-mapping + size: 356744 + timestamp: 1754570030468 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.12.7-hf9daec2_0.conda + noarch: python + sha256: be3eb69d5f1bff60743289252dd37fc4369db01763cd0fb48e5cb0e340f665f9 + md5: e1775b6c7aae7ea99b3677b6bb8fcf1d depends: + - python - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 + - libgcc >=14 constrains: - __glibc >=2.17 license: MIT license_family: MIT purls: - - pkg:pypi/ruff?source=hash-mapping - size: 8254968 - timestamp: 1749215957598 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.11.13-py312heade784_0.conda - sha256: 9fbe59d5339e8c1d102591725a0d13c53c06c06c6788bc82b06782eca3e47119 - md5: 78236a42e7a04fba6484250ae90c5a85 + - pkg:pypi/ruff?source=compressed-mapping + size: 10481171 + timestamp: 1753906136472 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.12.7-h6cc4cfe_0.conda + noarch: python + sha256: 21c8ae33ee07e3f91cd515c90af5ae9df4337fa4ea38d94232418afbe3e1331a + md5: 2ba519ea2fc65b6a1091f3d1585215e0 depends: + - python - __osx >=10.13 - - libcxx >=18 - - python >=3.12,<3.13.0a0 - - python_abi 3.12.* *_cp312 constrains: - __osx >=10.13 license: MIT license_family: MIT purls: - - pkg:pypi/ruff?source=hash-mapping - size: 7893708 - timestamp: 1749216415517 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.11.13-py313h19b3928_0.conda - sha256: cc86ed15d30fe6039bf5c83d9157b44a2ad0133ce55209aff02330855455684b - md5: 8800290270f1d0d9d8482a153c92dc5e + - pkg:pypi/ruff?source=compressed-mapping + size: 10513239 + timestamp: 1753906187894 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.12.7-h575f11b_0.conda + noarch: python + sha256: 3217bde750750b135a9e1273ee776536de681ca24712e1b8c4c80e1999bbd253 + md5: db9a75ae51077e52982566919fb6bc16 depends: + - python - __osx >=11.0 - - libcxx >=18 - - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - - python_abi 3.13.* *_cp313 constrains: - __osx >=11.0 license: MIT license_family: MIT purls: - - pkg:pypi/ruff?source=hash-mapping - size: 7444761 - timestamp: 1749216159571 + - pkg:pypi/ruff?source=compressed-mapping + size: 9695306 + timestamp: 1753906196067 - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.1-py312h4f0b9e3_0.conda sha256: c87194d7a0659493aa8ca9007bba2a4a8965e60037c396cd2e08fc1b5c91548b md5: 7f96df096abbe0064f0ec5060c1d2af4 @@ -9560,7 +9561,7 @@ packages: requires_python: '>=3.8' - pypi: ./ name: simlify - version: 0.1.dev150+g9ba0306.d20250727125101 + version: 0.1.dev162+gdf4cba2.d20250807164543 sha256: eebf67b0a83abcab7ab7f34535f4171819aeb1862c0b30e68027dd5bb5a5129d requires_dist: - loguru>=0.7.2,<1.0 @@ -9580,7 +9581,7 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/six?source=compressed-mapping + - pkg:pypi/six?source=hash-mapping size: 18455 timestamp: 1753199211006 - conda: https://conda.anaconda.org/conda-forge/noarch/smmap-5.0.2-pyhd8ed1ab_0.conda @@ -9786,19 +9787,18 @@ packages: - pkg:pypi/tabulate?source=hash-mapping size: 37554 timestamp: 1733589854804 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-hceb3a55_1.conda - sha256: 65463732129899770d54b1fbf30e1bb82fdebda9d7553caf08d23db4590cd691 - md5: ba7726b8df7b9d34ea80e82b097a4893 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-hb60516a_2.conda + sha256: ad947bab8a4c6ac36be716afe0da2d81fc03b5af54c403f390103e9731e6e7e7 + md5: 761511f996d6e5e7b11ade8b25ecb68d depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libhwloc >=2.11.2,<2.11.3.0a0 - - libstdcxx >=13 + - libgcc >=14 + - libhwloc >=2.12.1,<2.12.2.0a0 + - libstdcxx >=14 license: Apache-2.0 - license_family: APACHE purls: [] - size: 175954 - timestamp: 1732982638805 + size: 177366 + timestamp: 1754499030769 - conda: https://conda.anaconda.org/conda-forge/noarch/termcolor-3.1.0-pyhd8ed1ab_0.conda sha256: 04c7b49fbe6a2421ca9126f3f880877e995c457aed8afeb5ad18f03990ca8738 md5: 951a99e94afe3d38bfdbd04902fe33b7 @@ -9890,17 +9890,18 @@ packages: - pkg:pypi/toml?source=hash-mapping size: 22132 timestamp: 1734091907682 -- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda - sha256: 18636339a79656962723077df9a56c0ac7b8a864329eb8f847ee3d38495b863e - md5: ac944244f1fed2eb49bae07193ae8215 +- conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhe01879c_2.conda + sha256: 040a5a05c487647c089ad5e05ad5aff5942830db2a4e656f1e300d73436436f1 + md5: 30a0a26c8abccf4b7991d590fe17c699 depends: - python >=3.9 + - python license: MIT license_family: MIT purls: - - pkg:pypi/tomli?source=hash-mapping - size: 19167 - timestamp: 1733256819729 + - pkg:pypi/tomli?source=compressed-mapping + size: 21238 + timestamp: 1753796677376 - conda: https://conda.anaconda.org/conda-forge/noarch/tomlkit-0.13.3-pyha770c72_0.conda sha256: f8d3b49c084831a20923f66826f30ecfc55a4cd951e544b7213c692887343222 md5: 146402bf0f11cbeb8f781fa4309a95d3 @@ -10394,6 +10395,7 @@ packages: - libgcc >=14 - __glibc >=2.17,<3.0.a0 license: MIT + license_family: MIT purls: [] size: 85189 timestamp: 1753484064210 @@ -10403,6 +10405,7 @@ packages: depends: - __osx >=10.13 license: MIT + license_family: MIT purls: [] size: 79419 timestamp: 1753484072608 @@ -10412,13 +10415,14 @@ packages: depends: - __osx >=11.0 license: MIT + license_family: MIT purls: [] size: 83386 timestamp: 1753484079473 -- pypi: https://files.pythonhosted.org/packages/94/72/c5fd70742126cab7403126a1719b4161a81b816d83a2fdb78b390d8ecc47/zarr-3.1.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/c8/48/bde2f58cfbc9fd6ab844e2f2fd79d5e54195c12a17aa9b47c0b0e701a421/zarr-3.1.1-py3-none-any.whl name: zarr - version: 3.1.0 - sha256: bd3d2f88d602d43f81df82e26dd115ea66635a2af5bf6da261d3c640bb4c1ce4 + version: 3.1.1 + sha256: 9a0b7e7c27bf62965b8eef6b8b8fdb9b47381f0738be35e40f37be6479b546be requires_dist: - donfig>=0.8 - numcodecs[crc32c]>=0.14 @@ -10451,7 +10455,7 @@ packages: - obstore>=0.5.1 ; extra == 'remote-tests' - requests ; extra == 'remote-tests' - s3fs>=2023.10.0 ; extra == 'remote-tests' - - coverage ; extra == 'test' + - coverage>=7.10 ; extra == 'test' - hypothesis ; extra == 'test' - mypy ; extra == 'test' - packaging ; extra == 'test' diff --git a/pixi.toml b/pixi.toml index ba72b3c..518e270 100644 --- a/pixi.toml +++ b/pixi.toml @@ -38,7 +38,7 @@ pytest-html = ">=4.0.1" colorama = ">=0.4.6" ambertools = ">=24.8,<25" basedpyright = ">=1.29.1,<2" -ruff = ">=0.11.8,<0.12" +ruff = ">=0.11.8,<1" twine = ">=6.1.0,<7" [feature.dev.tasks] @@ -65,24 +65,24 @@ publish = { cmd = ["twine", "upload", "dist/*"] } [feature.dev.pypi-dependencies] build = ">=1.2.2.post1,<2" mypy-extensions = ">=1.0.0" -pyrefly = ">=0.16.0, <0.17" +pyrefly = ">=0.16.0, <1" setuptools-scm = ">=8.0.0" [feature.docs.dependencies] mkdocs = ">=1.6.1,<2" mkdocs-material = ">=9.6.5,<10" -mkdocstrings = ">=0.28.2,<0.29" +mkdocstrings = ">=0.28.2,<1" mkdocstrings-python = ">=1.16.2,<2" pymdown-extensions = ">=10.14.3,<11" mkdocs-table-reader-plugin = ">=3.1.0,<4" -mkdocs-gen-files = ">=0.4.0,<0.5" +mkdocs-gen-files = ">=0.4.0,<1" mkdocs-macros-plugin = ">=1.3.7,<2" -mkdocs-jupyter = ">=0.25.1,<0.26" -mkdocs-glightbox = ">=0.4.0,<0.5" +mkdocs-jupyter = ">=0.25.1,<1" +mkdocs-glightbox = ">=0.4.0,<1" mkdocs-git-revision-date-localized-plugin = ">=1.2.9,<2" [feature.docs.pypi-dependencies] -material-plausible-plugin = ">=0.2.0,<0.3" +material-plausible-plugin = ">=0.2.0,<1" mkdocs-print-site-plugin = ">=2.6.0,<3" mkdocs-awesome-nav = ">=3.0.0,<4" diff --git a/simlify/__init__.py b/simlify/__init__.py index 105fd20..2e0ff3a 100644 --- a/simlify/__init__.py +++ b/simlify/__init__.py @@ -11,24 +11,24 @@ from typing import Any +from importlib.metadata import version, PackageNotFoundError import os import sys from ast import literal_eval from loguru import logger -from .config import SimlifyConfig - -__all__ = ["SimlifyConfig"] - -__version__ = "0.0.0" +try: + __version__ = version("simlify") +except PackageNotFoundError: + __version__ = "0.0.0" logger.disable("simlify") LOG_FORMAT = ( "{time:HH:mm:ss} | " "{level: <8} | " - "{name}:{function}:{line} - {message}" + "{message}" ) diff --git a/simlify/cli/pdb/filter.py b/simlify/cli/pdb/filter.py index 615ba4c..f6ae4b9 100644 --- a/simlify/cli/pdb/filter.py +++ b/simlify/cli/pdb/filter.py @@ -13,6 +13,8 @@ import argparse +from loguru import logger + from simlify.structure.pdb.utils import run_filter_pdb @@ -59,6 +61,7 @@ def add_pdb_filter_subparser(subparsers): help="Path to PDB file", ) parser.add_argument( + "-o", "--output", type=str, nargs="?", @@ -67,8 +70,7 @@ def add_pdb_filter_subparser(subparsers): parser.add_argument( "--records", type=str, - nargs="*", - help="Records to keep in the PDB file.", + help="PDB records to keep. For example: ATOM,HETATM,MODEL", ) parser.set_defaults(func=lambda args: cli_filter_pdb(args, parser)) return parser @@ -100,4 +102,9 @@ def cli_filter_pdb(args: argparse.Namespace, parser: argparse.ArgumentParser) -> It then directly calls the [`run_filter_pdb`][structure.pdb.utils.run_filter_pdb] function with these arguments to perform the filtering of the PDB file. """ - run_filter_pdb(args.pdb_path, args.output, args.records) + records = args.records + if records is not None: + records = tuple(r.strip() for r in args.records.split(",")) + pdb_filtered = run_filter_pdb(args.pdb_path, args.output, records) + if args.output is None: + print("".join(pdb_filtered)) diff --git a/simlify/cli/prep/slurm.py b/simlify/cli/prep/slurm.py index 2317bc2..ebf005a 100644 --- a/simlify/cli/prep/slurm.py +++ b/simlify/cli/prep/slurm.py @@ -13,7 +13,7 @@ import argparse -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig from simlify.simulation.slurm import run_slurm_prep diff --git a/simlify/cli/prep/topo.py b/simlify/cli/prep/topo.py index 65248fb..abb482e 100644 --- a/simlify/cli/prep/topo.py +++ b/simlify/cli/prep/topo.py @@ -13,7 +13,7 @@ import argparse -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig from simlify.simulation.topo import run_gen_topo @@ -64,7 +64,7 @@ def add_topo_subparser(subparsers): help="Path to a structure file.", ) parser.add_argument( - "import_string", + "--import-string", type=str, nargs="?", help="Import string to a topology generation class.", diff --git a/simlify/configs/__init__.py b/simlify/configs/__init__.py new file mode 100644 index 0000000..41eaff5 --- /dev/null +++ b/simlify/configs/__init__.py @@ -0,0 +1,15 @@ +from .ff import ForcefieldConfigBase +from .run import RunConfig +from .slurm import SlurmConfig +from .solution import SolutionConfig +from .topo import TopologyConfig +from .core import SimlifyConfig + +__all__: list[str] = [ + "ForcefieldConfigBase", + "SlurmConfig", + "TopologyConfig", + "SolutionConfig", + "RunConfig", + "SimlifyConfig", +] diff --git a/simlify/schemas/amber/__init__.py b/simlify/configs/amber/__init__.py similarity index 81% rename from simlify/schemas/amber/__init__.py rename to simlify/configs/amber/__init__.py index d6fbddd..a05018e 100644 --- a/simlify/schemas/amber/__init__.py +++ b/simlify/configs/amber/__init__.py @@ -9,25 +9,25 @@ from .cli import AmberCLIBase from .inputs import AmberInputsBase -from .schema import AmberSchemaBase -from .v18 import Amber18CLI, Amber18Forcefield, Amber18Inputs, Amber18Schema -from .v20 import Amber20CLI, Amber20Forcefield, Amber20Inputs, Amber20Schema -from .v22 import Amber22CLI, Amber22Forcefield, Amber22Inputs, Amber22Schema +from .core import AmberConfigBase +from .v18 import Amber18CLI, Amber18Forcefield, Amber18Inputs, Amber18Config +from .v20 import Amber20CLI, Amber20Forcefield, Amber20Inputs, Amber20Config +from .v22 import Amber22CLI, Amber22Forcefield, Amber22Inputs, Amber22Config -__all__ = [ +__all__: list[str] = [ "AmberCLIBase", "AmberInputsBase", - "AmberSchemaBase", + "AmberConfigBase", "Amber18Inputs", - "Amber18Schema", + "Amber18Config", "Amber18CLI", "Amber18Forcefield", "Amber20Inputs", - "Amber20Schema", + "Amber20Config", "Amber20CLI", "Amber20Forcefield", "Amber22Inputs", - "Amber22Schema", + "Amber22Config", "Amber22CLI", "Amber22Forcefield", ] diff --git a/simlify/schemas/amber/cli.py b/simlify/configs/amber/cli.py similarity index 97% rename from simlify/schemas/amber/cli.py rename to simlify/configs/amber/cli.py index b3aa077..9d4f1df 100644 --- a/simlify/schemas/amber/cli.py +++ b/simlify/configs/amber/cli.py @@ -9,10 +9,11 @@ from typing import Literal -from atomea.schemas import Render, YamlIO from loguru import logger from pydantic import BaseModel +from simlify.configs.utils import Render, YamlIO + AMBER_CLI_MAPPING = { "mdin": "i", "mdout": "o", @@ -72,7 +73,7 @@ def render(self, with_newlines: bool = False) -> list[str]: Path to input file for controlling AMBER calculations and operations. Options specified in [`AmberInputsBase`] - [schemas.workflow.amber.inputs.AmberInputsBase] should be in this file. + [configs.workflow.amber.inputs.AmberInputsBase] should be in this file. Below is a non-working example of what this file should look like. @@ -118,7 +119,7 @@ def render(self, with_newlines: bool = False) -> list[str]: Then it will provide any notes and information about the chosen methods and system. Afterwords, system information will be printed every - [`ntpr`][schemas.workflow.amber.inputs.AmberInputsBase.ntpr] steps. + [`ntpr`][configs.workflow.amber.inputs.AmberInputsBase.ntpr] steps. ```text NSTEP = 500 TIME(PS) = 1021.000 TEMP(K) = 300.64 PRESS = 0.0 @@ -173,7 +174,7 @@ def render(self, with_newlines: bool = False) -> list[str]: **Sander option:** `-inf` Path to store the latest - [`mdout`][schemas.workflow.amber.cli.AmberCLIBase.mdout] and other + [`mdout`][configs.workflow.amber.cli.AmberCLIBase.mdout] and other simulation progress information. An example is shown below. ```text diff --git a/simlify/schemas/amber/schema.py b/simlify/configs/amber/core.py similarity index 86% rename from simlify/schemas/amber/schema.py rename to simlify/configs/amber/core.py index 3b8b567..71680e6 100644 --- a/simlify/schemas/amber/schema.py +++ b/simlify/configs/amber/core.py @@ -9,11 +9,12 @@ from typing import Any -from atomea.schemas.io import YamlIO from pydantic import BaseModel +from simlify.configs.utils import YamlIO -class AmberSchemaBase(BaseModel, YamlIO): + +class AmberConfigBase(BaseModel, YamlIO): r"""Validate Amber contexts.""" inputs: Any = NotImplementedError diff --git a/simlify/schemas/amber/inputs.py b/simlify/configs/amber/inputs.py similarity index 86% rename from simlify/schemas/amber/inputs.py rename to simlify/configs/amber/inputs.py index b372285..94f7e30 100644 --- a/simlify/schemas/amber/inputs.py +++ b/simlify/configs/amber/inputs.py @@ -9,11 +9,11 @@ from typing import Literal -from atomea.schemas.io import YamlIO -from atomea.schemas.render import Render from loguru import logger from pydantic import BaseModel, Field +from simlify.configs.utils import Render, YamlIO + class AmberInputsBase(BaseModel, YamlIO, Render): def render(self, with_newlines: bool = False) -> list[str]: @@ -76,34 +76,34 @@ def render(self, with_newlines: bool = False) -> list[str]: Read in a trajectory for analysis using the minimization algorithms. Although sander will write energy information in the output files - (using [`ntpr`][schemas.workflow.amber.inputs.AmberInputsBase.ntpr]), + (using [`ntpr`][configs.workflow.amber.inputs.AmberInputsBase.ntpr]), it is often desirable to calculate the energies of a set of structures at a later point. In particular, one may wish to post-process a set of structures using a different energy function than was used to generate the structures. An example of this is MM-PBSA analysis, where the explicit water is removed and replaced with a continuum model. - If [`imin`][schemas.workflow.amber.inputs.AmberInputsBase.imin] is set to + If [`imin`][configs.workflow.amber.inputs.AmberInputsBase.imin] is set to `5`, sander will read a trajectory file (the `inptraj` argument, specified using `-y` on the command line), and will perform the functions described in the `mdin` file (e.g., an energy minimization) for each of the structures in this file. The final structure from each minimization will be written out to the normal `mdcrd` file. If you wish to read in a binary (i.e., NetCDF format) trajectory, - be sure to set [`ioutfm`][schemas.workflow.amber.inputs.AmberInputsBase.ioutfm] + be sure to set [`ioutfm`][configs.workflow.amber.inputs.AmberInputsBase.ioutfm] to `1`. Note that this will result in the output trajectory having NetCDF format as well. - For example, when [`imin`][schemas.workflow.amber.inputs.AmberInputsBase.imin] - is `5` and [`maxcyc`][schemas.workflow.amber.inputs.AmberInputsBase.maxcyc] is + For example, when [`imin`][configs.workflow.amber.inputs.AmberInputsBase.imin] + is `5` and [`maxcyc`][configs.workflow.amber.inputs.AmberInputsBase.maxcyc] is `1000`, sander will minimize each structure in the trajectory for 1000 steps and write a minimized coordinate set for each frame to the `mdcrd` file. - If [`maxcyc`][schemas.workflow.amber.inputs.AmberInputsBase.maxcyc] is `1`, the + If [`maxcyc`][configs.workflow.amber.inputs.AmberInputsBase.maxcyc] is `1`, the output file can be used to extract the energies of each of the coordinate sets in the `inptraj` file. Trajectories containing box coordinates can be post-processed. In order to read trajectories with box coordinates, - [`ntb`][schemas.workflow.amber.inputs.AmberInputsBase.ntb] should be greater + [`ntb`][configs.workflow.amber.inputs.AmberInputsBase.ntb] should be greater than `0`.
@@ -112,14 +112,14 @@ def render(self, with_newlines: bool = False) -> list[str]: Read in a trajectory for analysis using the molecular dynamics driver. - Like when [`imin`][schemas.workflow.amber.inputs.AmberInputsBase.imin] is `5`, + Like when [`imin`][configs.workflow.amber.inputs.AmberInputsBase.imin] is `5`, this option reads a trajectory file for analysis (the `inptraj` argument, specified using `-y` on the command line). Instead of minimizing the potential energy of each coordinate set, it instead initiates dynamics from each frame as if it were read as a restart file without initial velocities. That is, this option is equivalent to outputting each frame as a restart file and starting the - dynamics with [`irest`][schemas.workflow.amber.inputs.AmberInputsBase.irest] - is `0`. If [`nstlim`][schemas.workflow.amber.inputs.AmberInputsBase.nstlim] is + dynamics with [`irest`][configs.workflow.amber.inputs.AmberInputsBase.irest] + is `0`. If [`nstlim`][configs.workflow.amber.inputs.AmberInputsBase.nstlim] is `0`, then this effectively performs a single point energy for each frame.
@@ -159,7 +159,7 @@ def render(self, with_newlines: bool = False) -> list[str]: Do not restart the simulation; instead, run as a new simulation. Velocities in the input coordinate file, if any, will be ignored, and the time step count will be set to `0` (unless overridden by - [`t`][schemas.workflow.amber.inputs.AmberInputsBase.t]). + [`t`][configs.workflow.amber.inputs.AmberInputsBase.t]).
@@ -167,11 +167,11 @@ def render(self, with_newlines: bool = False) -> list[str]: Restart the simulation, reading coordinates and velocities from a previously saved restart file. The velocity information is necessary when restarting, so - [`ntx`][schemas.workflow.amber.inputs.AmberInputsBase.ntx] must be + [`ntx`][configs.workflow.amber.inputs.AmberInputsBase.ntx] must be `5` (for Amber versions much older than 20, - [`ntx`][schemas.workflow.amber.inputs.AmberInputsBase.ntx] must be greater than + [`ntx`][configs.workflow.amber.inputs.AmberInputsBase.ntx] must be greater than or equal to `4`), - if [`irest`][schemas.workflow.amber.inputs.AmberInputsBase.irest] is `1`. + if [`irest`][configs.workflow.amber.inputs.AmberInputsBase.irest] is `1`. """ ntx: Literal[1, 5] = Field(default=1) @@ -184,7 +184,7 @@ def render(self, with_newlines: bool = False) -> list[str]: File is read with no initial velocity information. Suitable for starting simulations with new systems where velocities are generated based - on [`tempi`][schemas.workflow.amber.inputs.AmberInputsBase.tempi] + on [`tempi`][configs.workflow.amber.inputs.AmberInputsBase.tempi] Option `1` must be used when one is starting from minimized or model-built coordinates. @@ -218,7 +218,7 @@ def render(self, with_newlines: bool = False) -> list[str]: **`1`** - For [`ncyc`][schemas.workflow.amber.inputs.AmberInputsBase.ncyc] cycles, the + For [`ncyc`][configs.workflow.amber.inputs.AmberInputsBase.ncyc] cycles, the steepest descent method is used, then the conjugate gradient is switched on. This option combines the robustness of steepest descent with the efficiency of conjugate gradient, making it a recommended choice for many scenarios. @@ -267,10 +267,10 @@ def render(self, with_newlines: bool = False) -> list[str]: ncyc: int = Field(default=10, ge=1) """ - If [`ntmin`][schemas.workflow.amber.inputs.AmberInputsBase.ntmin] is `1`, + If [`ntmin`][configs.workflow.amber.inputs.AmberInputsBase.ntmin] is `1`, then the minimization method will be switched from steepest descent to conjugate gradient after - [`ncyc`][schemas.workflow.amber.inputs.AmberInputsBase.ncyc] cycles. + [`ncyc`][configs.workflow.amber.inputs.AmberInputsBase.ncyc] cycles. Values typically range from `5` to `100`. Lower values will switch to conjugate gradient sooner, which can be more efficient @@ -295,7 +295,7 @@ def render(self, with_newlines: bool = False) -> list[str]: """ The seed for the pseudo-random number generator. This affects the starting velocities for MD simulations if - [`tempi`][schemas.workflow.amber.inputs.AmberInputsBase.tempi] is nonzero. + [`tempi`][configs.workflow.amber.inputs.AmberInputsBase.tempi] is nonzero. If this is `-1`, a random seed will be computed based on the current date and time. This should almost always be `-1` unless you are reproducing a run. @@ -304,7 +304,7 @@ def render(self, with_newlines: bool = False) -> list[str]: providing varied initial conditions for better sampling. - Use a specific integer value if you need to reproduce an exact simulation run for debugging or verification purposes. - - Ensure that [`tempi`][schemas.workflow.amber.inputs.AmberInputsBase.tempi] + - Ensure that [`tempi`][configs.workflow.amber.inputs.AmberInputsBase.tempi] is set appropriately when using this option to affect starting velocities. """ @@ -314,7 +314,7 @@ def render(self, with_newlines: bool = False) -> list[str]: each step in the simulation. - With SHAKE - ([`ntc`][schemas.workflow.amber.inputs.AmberInputsBase.ntc] is `2`): + ([`ntc`][configs.workflow.amber.inputs.AmberInputsBase.ntc] is `2`): The maximum value is `0.002` ps (2 fs). SHAKE constrains bond lengths involving hydrogen atoms, allowing for a larger time step. - Without SHAKE: The maximum value is `0.001` ps (1 fs). Without bond constraints, @@ -338,20 +338,20 @@ def render(self, with_newlines: bool = False) -> list[str]: nstlim: int = Field(default=1, ge=1) """ Number of MD steps to perform. Multiply - [`nstlim`][schemas.workflow.amber.inputs.AmberInputsBase.nstlim] and - [`dt`][schemas.workflow.amber.inputs.AmberInputsBase.dt] to get the duration + [`nstlim`][configs.workflow.amber.inputs.AmberInputsBase.nstlim] and + [`dt`][configs.workflow.amber.inputs.AmberInputsBase.dt] to get the duration of the MD simulation in picoseconds. tip: - For short equilibration runs or quick tests, use lower values of - [`nstlim`][schemas.workflow.amber.inputs.AmberInputsBase.nstlim], such as + [`nstlim`][configs.workflow.amber.inputs.AmberInputsBase.nstlim], such as `5000` to `50000`. - For production runs aimed at sampling equilibrium states or studying slower processes, higher values of - [`nstlim`][schemas.workflow.amber.inputs.AmberInputsBase.nstlim] are + [`nstlim`][configs.workflow.amber.inputs.AmberInputsBase.nstlim] are recommended, typically in the range of `1000000` to `50000000` (corresponding to 2 ns to 100 ns for `dt = 0.002`). - - Adjust [`nstlim`][schemas.workflow.amber.inputs.AmberInputsBase.nstlim] + - Adjust [`nstlim`][configs.workflow.amber.inputs.AmberInputsBase.nstlim] based on the specific requirements of your study, considering both the computational resources available and the timescale of the phenomena you are investigating. @@ -360,9 +360,9 @@ def render(self, with_newlines: bool = False) -> list[str]: nscm: int = Field(default=1000, ge=1) """ Flag for the removal of translational and rotational center-of-mass motion every - [`nscm`][schemas.workflow.amber.inputs.AmberInputsBase.nscm] steps. + [`nscm`][configs.workflow.amber.inputs.AmberInputsBase.nscm] steps. For periodic simulations - ([`ntb`][schemas.workflow.amber.inputs.AmberInputsBase.ntb] is `1` or `2`), + ([`ntb`][configs.workflow.amber.inputs.AmberInputsBase.ntb] is `1` or `2`), only the translational center-of-mass motion is removed. Reasonable values are between `100` and `2000`. Lower values ensure more frequent removal of center-of-mass motion, which can be beneficial @@ -382,7 +382,7 @@ def render(self, with_newlines: bool = False) -> list[str]: """ Flag for restraining positions of specified atoms using a harmonic potential. Ensure that - [`restraintmask`][schemas.workflow.amber.inputs.AmberInputsBase.restraintmask] + [`restraintmask`][configs.workflow.amber.inputs.AmberInputsBase.restraintmask] is properly defined to specify the atoms that require constraints.
@@ -398,9 +398,9 @@ def render(self, with_newlines: bool = False) -> list[str]: **`1`** Constrain atoms specified in - [`restraintmask`][schemas.workflow.amber.inputs.AmberInputsBase.restraintmask]. + [`restraintmask`][configs.workflow.amber.inputs.AmberInputsBase.restraintmask]. This applies a harmonic potential to the atoms defined in - [`restraintmask`][schemas.workflow.amber.inputs.AmberInputsBase.restraintmask], + [`restraintmask`][configs.workflow.amber.inputs.AmberInputsBase.restraintmask], effectively fixing their positions relative to the rest of the system. Use `1` when specific atoms need to be restrained, such as in cases where you want to focus on a particular region of the system while keeping another region fixed @@ -410,7 +410,7 @@ def render(self, with_newlines: bool = False) -> list[str]: restraint_wt: float = Field(default=4.0, ge=0.0) """ The weight (in kcal mol-1 Å-2) when - [`ntr`][schemas.workflow.amber.inputs.AmberInputsBase.ntr] is `1`. The form of + [`ntr`][configs.workflow.amber.inputs.AmberInputsBase.ntr] is `1`. The form of the restraint is $k (\Delta x)^2$ where $\Delta x$ is the deviation of the atom's coordinate from the reference position. @@ -427,7 +427,7 @@ def render(self, with_newlines: bool = False) -> list[str]: restraintmask: str = Field(default="") """ Strings that specify the restricted atoms when - [`ntr`][schemas.workflow.amber.inputs.AmberInputsBase.ntr] is `1`. To see what + [`ntr`][configs.workflow.amber.inputs.AmberInputsBase.ntr] is `1`. To see what atoms will be restrained, you can use `ambmask -p mol.prmtop -c mol.inpcrd -out pdb -find "RESTRAINT_STRING"` in `ambertools`. Here are some examples of `restraintmask`s and their descriptions. @@ -487,7 +487,7 @@ def render(self, with_newlines: bool = False) -> list[str]: **`2`** Ignore bond interactions involving hydrogens. This option is typically used when - [`ntc`][schemas.workflow.amber.inputs.AmberInputsBase.ntc] is `2`, meaning + [`ntc`][configs.workflow.amber.inputs.AmberInputsBase.ntc] is `2`, meaning constraints are applied to bonds involving hydrogens (e.g., SHAKE algorithm).
@@ -495,7 +495,7 @@ def render(self, with_newlines: bool = False) -> list[str]: **`3`** All bond interactions are omitted. This option is used when - [`ntc`][schemas.workflow.amber.inputs.AmberInputsBase.ntc] is `3`, which + [`ntc`][configs.workflow.amber.inputs.AmberInputsBase.ntc] is `3`, which implies constraints are applied to all bonds.
@@ -536,8 +536,8 @@ def render(self, with_newlines: bool = False) -> list[str]: fastest motions in the system. SHAKE removes the bond stretching freedom, which is the fastest motion, and consequently allows a larger timestep to be used. For water models, a special "three-point" algorithm is used. Consequently, to - employ TIP3P set [`ntf`][schemas.workflow.amber.inputs.AmberInputsBase.ntf] and - [`ntc`][schemas.workflow.amber.inputs.AmberInputsBase.ntc] to 2. + employ TIP3P set [`ntf`][configs.workflow.amber.inputs.AmberInputsBase.ntf] and + [`ntc`][configs.workflow.amber.inputs.AmberInputsBase.ntc] to 2. Since SHAKE is an algorithm based on dynamics, the minimizer is not aware of what SHAKE is doing; for this reason, minimizations generally should be carried @@ -620,11 +620,11 @@ def render(self, with_newlines: bool = False) -> list[str]: guaranteed, and there are many subtle problems that can arise with weak temperature coupling. - Using [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] of `1` is + Using [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] of `1` is especially dangerous for generalized Born simulations, where there are no collisions with solvent to aid in thermalization. Other temperature coupling options (especially - [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] of `3`) should be + [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] of `3`) should be used instead.
@@ -633,8 +633,8 @@ def render(self, with_newlines: bool = False) -> list[str]: Andersen-like temperature coupling scheme, in which imaginary "collisions" are performed with heat bath of temperature - [`temp0`][schemas.workflow.amber.inputs.AmberInputsBase.temp0] every - [`vrand`][schemas.workflow.amber.inputs.AmberInputsBase.vrand] steps. + [`temp0`][configs.workflow.amber.inputs.AmberInputsBase.temp0] every + [`vrand`][configs.workflow.amber.inputs.AmberInputsBase.vrand] steps. note: In between these "massive collisions", the dynamics is Newtonian. Hence, time correlation @@ -648,10 +648,10 @@ def render(self, with_newlines: bool = False) -> list[str]: **`3`** Use Langevin dynamics with the collision frequency - [`gamma_ln`][schemas.workflow.amber.inputs.AmberInputsBase.gamma_ln]. + [`gamma_ln`][configs.workflow.amber.inputs.AmberInputsBase.gamma_ln]. Since Langevin simulations are highly susceptible to "synchronization" artifacts, you should explicitly set - [`ig`][schemas.workflow.amber.inputs.AmberInputsBase.ig] to a different value + [`ig`][configs.workflow.amber.inputs.AmberInputsBase.ig] to a different value every restart (e.g., `-1`).
@@ -684,13 +684,13 @@ def render(self, with_newlines: bool = False) -> list[str]: Initialization temperature in Kelvin. This parameter sets the initial temperature for the system at the start of the simulation. - - If [`ntx`][schemas.workflow.amber.inputs.AmberInputsBase.ntx] is `1`, the + - If [`ntx`][configs.workflow.amber.inputs.AmberInputsBase.ntx] is `1`, the initial velocities of the atoms are assigned from a Maxwellian distribution corresponding to the temperature - [`tempi`][schemas.workflow.amber.inputs.AmberInputsBase.tempi]. This is + [`tempi`][configs.workflow.amber.inputs.AmberInputsBase.tempi]. This is typically used to start a new simulation where the initial conditions need to be defined. - - If [`ntx`][schemas.workflow.amber.inputs.AmberInputsBase.ntx] is `5`, this + - If [`ntx`][configs.workflow.amber.inputs.AmberInputsBase.ntx] is `5`, this parameter has no effect because the velocities are read from the input coordinates file, meaning the system continues from a previously equilibrated state. @@ -717,7 +717,7 @@ def render(self, with_newlines: bool = False) -> list[str]: gamma_ln: float = Field(default=2.0, gt=0.0) """ The collision frequency, $\gamma$, when - [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] is `3`. This parameter + [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] is `3`. This parameter is used in Langevin dynamics to control the rate of coupling between the system and a heat bath, thereby regulating the temperature. @@ -775,7 +775,7 @@ def render(self, with_newlines: bool = False) -> list[str]: for modifying the volume of the system, particularly useful for preparing replica-exchange molecular dynamics simulations where the shape of each replica needs to be the same. When - [`ntp`][schemas.workflow.amber.inputs.AmberInputsBase.ntp] is `4`, the following + [`ntp`][configs.workflow.amber.inputs.AmberInputsBase.ntp] is `4`, the following variables in the “ewald” namelist should be set: - `target_n`: Number of target volume iterations to reach the target volume @@ -825,7 +825,7 @@ def render(self, with_newlines: bool = False) -> list[str]: comp: float = Field(default=44.6, gt=0.0) """ Compressibility of the system when - [`ntp`][schemas.workflow.amber.inputs.AmberInputsBase.ntp] > `0` in units of + [`ntp`][configs.workflow.amber.inputs.AmberInputsBase.ntp] > `0` in units of 10-6 bar-1. 44.6` x 10-6 bar-1, appropriate for water. This value is used in pressure regulation to account for the compressibility of the solvent or system being simulated. @@ -834,7 +834,7 @@ def render(self, with_newlines: bool = False) -> list[str]: taup: float = Field(default=1.0, gt=0.0) """ Pressure relaxation time in picoseconds when - [`ntp`][schemas.workflow.amber.inputs.AmberInputsBase.ntp] > `0`. + [`ntp`][configs.workflow.amber.inputs.AmberInputsBase.ntp] > `0`. Recommended values are between `1.0` and `5.0` ps. This parameter controls how quickly the pressure adjusts to the target value. Start with `1.0` ps. If your simulations are unstable, consider increasing this value. @@ -860,16 +860,16 @@ def render(self, with_newlines: bool = False) -> list[str]: ntwr: int = Field(default=1000, ge=1) """ - Every [`ntwr`][schemas.workflow.amber.inputs.AmberInputsBase.ntwr] steps + Every [`ntwr`][configs.workflow.amber.inputs.AmberInputsBase.ntwr] steps during dynamics, the `restrt` file will be written, ensuring that recovery from a crash will not be so painful. No matter what the value of - [`ntwr`][schemas.workflow.amber.inputs.AmberInputsBase.ntwr], a `restrt` file + [`ntwr`][configs.workflow.amber.inputs.AmberInputsBase.ntwr], a `restrt` file will be written at the end of the run, i.e., after - [`nstlim`][schemas.workflow.amber.inputs.AmberInputsBase.nstlim] steps + [`nstlim`][configs.workflow.amber.inputs.AmberInputsBase.nstlim] steps (for dynamics) or - [`maxcyc`][schemas.workflow.amber.inputs.AmberInputsBase.maxcyc] steps + [`maxcyc`][configs.workflow.amber.inputs.AmberInputsBase.maxcyc] steps (for minimization). If - [`ntwr`][schemas.workflow.amber.inputs.AmberInputsBase.ntwr] < `0`, a unique + [`ntwr`][configs.workflow.amber.inputs.AmberInputsBase.ntwr] < `0`, a unique copy of the file, `restrt_`, is written every `abs(ntwr)` steps. This option is useful if for example one wants to run free energy perturbations from multiple starting points or save a series of `restrt` files for minimization. @@ -878,7 +878,7 @@ def render(self, with_newlines: bool = False) -> list[str]: ntpr: int = Field(default=1000, ge=1) """ Print energy information every - [`ntpr`][schemas.workflow.amber.inputs.AmberInputsBase.ntpr] steps in a + [`ntpr`][configs.workflow.amber.inputs.AmberInputsBase.ntpr] steps in a human-readable form to files `mdout` and `mdinfo`. `mdinfo` is closed and reopened each time, so it always contains the most recent energy and temperature. """ @@ -886,10 +886,10 @@ def render(self, with_newlines: bool = False) -> list[str]: ntwx: int = Field(default=0, ge=1) """ Coordinates are written every - [`ntwx`][schemas.workflow.amber.inputs.AmberInputsBase.ntwx] steps to the + [`ntwx`][configs.workflow.amber.inputs.AmberInputsBase.ntwx] steps to the `mdcrd` file. This parameter controls how often the coordinates are saved, which can be used for trajectory analysis. If - [`ntwx`][schemas.workflow.amber.inputs.AmberInputsBase.ntwx] is `0`, no coordinate + [`ntwx`][configs.workflow.amber.inputs.AmberInputsBase.ntwx] is `0`, no coordinate trajectory file will be written. """ @@ -934,11 +934,11 @@ def render(self, with_newlines: bool = False) -> list[str]: wrapping, however, can mess up diffusion and other calculations. For very long runs, setting - [`iwrap`][schemas.workflow.amber.inputs.AmberInputsBase.iwrap] is `1` may be + [`iwrap`][configs.workflow.amber.inputs.AmberInputsBase.iwrap] is `1` may be required to keep the coordinate output from overflowing the trajectory and restart file formats, especially if trajectories are written in ASCII format instead of NetCDF (see also the - [`ioutfm`][schemas.workflow.amber.inputs.AmberInputsBase.ioutfm] option). + [`ioutfm`][configs.workflow.amber.inputs.AmberInputsBase.ioutfm] option). """ nmropt: Literal[0, 1, 2] = Field(default=0) @@ -965,28 +965,28 @@ def render(self, with_newlines: bool = False) -> list[str]: """ ntave: int = Field(default=0, ge=0.0) - """Every [`ntave`][schemas.workflow.amber.inputs.AmberInputsBase.ntave] steps of + """Every [`ntave`][configs.workflow.amber.inputs.AmberInputsBase.ntave] steps of dynamics, running averages of average energies and fluctuations over the last - [`ntave`][schemas.workflow.amber.inputs.AmberInputsBase.ntave] steps will be + [`ntave`][configs.workflow.amber.inputs.AmberInputsBase.ntave] steps will be printed out. A value of `0` disables this printout. Setting - [`ntave`][schemas.workflow.amber.inputs.AmberInputsBase.ntave] to a value + [`ntave`][configs.workflow.amber.inputs.AmberInputsBase.ntave] to a value 1/2 or 1/4 of nstlim provides a simple way to look at convergence during the simulation. """ ntwv: int = Field(default=0, ge=0.0) """ - Every [`ntwv`][schemas.workflow.amber.inputs.AmberInputsBase.ntwv] steps, + Every [`ntwv`][configs.workflow.amber.inputs.AmberInputsBase.ntwv] steps, the velocities will be written to the `mdvel` file. If - [`ntwv`][schemas.workflow.amber.inputs.AmberInputsBase.ntwv] is `0`, no + [`ntwv`][configs.workflow.amber.inputs.AmberInputsBase.ntwv] is `0`, no velocity trajectory file will be written. If - [`ntwv`][schemas.workflow.amber.inputs.AmberInputsBase.ntwv] is `-1`, velocities + [`ntwv`][configs.workflow.amber.inputs.AmberInputsBase.ntwv] is `-1`, velocities will be written to mdcrd, which then becomes a combined coordinate/velocity trajectory file, at the interval defined by ntwx. This option is available only for binary NetCDF output - ([`ioutfm`][schemas.workflow.amber.inputs.AmberInputsBase.ioutfm] is `1`). + ([`ioutfm`][configs.workflow.amber.inputs.AmberInputsBase.ioutfm] is `1`). Most users will have no need for a velocity trajectory file and so can safely - leave [`ntwv`][schemas.workflow.amber.inputs.AmberInputsBase.ntwv] at the default. + leave [`ntwv`][configs.workflow.amber.inputs.AmberInputsBase.ntwv] at the default. Note that dumping velocities frequently, like forces or coordinates, will introduce potentially significant I/O and communication overhead, hurting both performance and parallel scaling. @@ -1001,18 +1001,18 @@ def render(self, with_newlines: bool = False) -> list[str]: ntwf: int = Field(default=0, ge=0) """ - Every [`ntwf`][schemas.workflow.amber.inputs.AmberInputsBase.ntwf] steps, the + Every [`ntwf`][configs.workflow.amber.inputs.AmberInputsBase.ntwf] steps, the forces will be written to the mdfrc file. If - [`ntwf`][schemas.workflow.amber.inputs.AmberInputsBase.ntwf] is `0`, no force + [`ntwf`][configs.workflow.amber.inputs.AmberInputsBase.ntwf] is `0`, no force trajectory file will be written. If - [`ntwf`][schemas.workflow.amber.inputs.AmberInputsBase.ntwf] is `-1`, forces + [`ntwf`][configs.workflow.amber.inputs.AmberInputsBase.ntwf] is `-1`, forces will be written to the mdcrd, which then becomes a combind coordinate/force trajectory file, at the interval defined by - [`ntwx`][schemas.workflow.amber.inputs.AmberInputsBase.ntwx]. + [`ntwx`][configs.workflow.amber.inputs.AmberInputsBase.ntwx]. This option is available only for binary NetCDF output - ([`ioutfm`][schemas.workflow.amber.inputs.AmberInputsBase.ioutfm] is `1`). + ([`ioutfm`][configs.workflow.amber.inputs.AmberInputsBase.ioutfm] is `1`). Most users will have no need for a force trajectory file and so can safely - leave [`ntwf`][schemas.workflow.amber.inputs.AmberInputsBase.ntwf] at the default. + leave [`ntwf`][configs.workflow.amber.inputs.AmberInputsBase.ntwf] at the default. Note that dumping forces frequently, like velocities or coordinates, will introduce potentially significant I/O and communication overhead, hurting both performance and parallel scaling. @@ -1020,13 +1020,13 @@ def render(self, with_newlines: bool = False) -> list[str]: ntwe: int = Field(default=0, ge=0) """ - Every [`ntwe`][schemas.workflow.amber.inputs.AmberInputsBase.ntwe] steps, + Every [`ntwe`][configs.workflow.amber.inputs.AmberInputsBase.ntwe] steps, the energies and temperatures will be written to file `mden` in a compact form. If - [`ntwe`][schemas.workflow.amber.inputs.AmberInputsBase.ntwe] is `0` then no + [`ntwe`][configs.workflow.amber.inputs.AmberInputsBase.ntwe] is `0` then no `mden` file will be written. Note that energies in the `mden` file are not synchronized with coordinates or velocities in the `mdcrd` or `mdvel` file(s). - Assuming identical [`ntwe`][schemas.workflow.amber.inputs.AmberInputsBase.ntwe] - and [`ntwx`][schemas.workflow.amber.inputs.AmberInputsBase.ntwx] values the + Assuming identical [`ntwe`][configs.workflow.amber.inputs.AmberInputsBase.ntwe] + and [`ntwx`][configs.workflow.amber.inputs.AmberInputsBase.ntwx] values the energies are one time step before the coordinates (as well as the velocities which are synchronized with the coordinates). Consequently, an `mden` file is rarely written. @@ -1050,7 +1050,7 @@ def render(self, with_newlines: bool = False) -> list[str]:
Include only atoms 1 to - [`ntwprt`][schemas.workflow.amber.inputs.AmberInputsBase.ntwprt] when writing + [`ntwprt`][configs.workflow.amber.inputs.AmberInputsBase.ntwprt] when writing trajectories. """ @@ -1091,7 +1091,7 @@ def render(self, with_newlines: bool = False) -> list[str]: **`3`** Decompose energies on a pairwise per-residue basis; otherwise equivalent to - [`idecomp`][schemas.workflow.amber.inputs.AmberInputsBase.idecomp] is `1`. + [`idecomp`][configs.workflow.amber.inputs.AmberInputsBase.idecomp] is `1`. Not available in TI simulations.
@@ -1099,7 +1099,7 @@ def render(self, with_newlines: bool = False) -> list[str]: **`4`** Decompose energies on a pairwise per-residue basis; otherwise equivalent to - [`idecomp`][schemas.workflow.amber.inputs.AmberInputsBase.idecomp] is `2`. + [`idecomp`][configs.workflow.amber.inputs.AmberInputsBase.idecomp] is `2`. Not available in TI simulations. """ @@ -1108,7 +1108,7 @@ def render(self, with_newlines: bool = False) -> list[str]: Flag for belly type dynamics. If set to `1`, a subset of the atoms in the system will be allowed to move, and the coordinates of the rest will be frozen. The moving atoms are specified with - [`bellymask`][schemas.workflow.amber.inputs.AmberInputsBase.bellymask]. + [`bellymask`][configs.workflow.amber.inputs.AmberInputsBase.bellymask]. This option is not available when `igb` > `0`. When belly type dynamics is in use, bonded energy terms, vdW interactions, and direct @@ -1116,13 +1116,13 @@ def render(self, with_newlines: bool = False) -> list[str]: Note that this does not provide any significant speed advantage. Freezing atoms can be useful for some applications but is maintained primarily for backwards compatibility with older versions of Amber. Most applications should - use the [`ntr`][schemas.workflow.amber.inputs.AmberInputsBase.ntr] variable + use the [`ntr`][configs.workflow.amber.inputs.AmberInputsBase.ntr] variable instead to restrain parts of the system to stay close to some initial configuration. """ bellymask: str = Field(default="") """String that specifies the moving atoms when - [`ibelly`][schemas.workflow.amber.inputs.AmberInputsBase.ibelly] is `1`. + [`ibelly`][configs.workflow.amber.inputs.AmberInputsBase.ibelly] is `1`. """ dx0: float = Field(default=0.01, ge=0.0) @@ -1141,7 +1141,7 @@ def render(self, with_newlines: bool = False) -> list[str]: t: float = Field(default=0.0, ge=0.0) """The time at the start (psec) this is for your own reference and is not critical. Start time is taken from the coordinate input file if - [`irest`][schemas.workflow.amber.inputs.AmberInputsBase.irest] is `1`. + [`irest`][configs.workflow.amber.inputs.AmberInputsBase.irest] is `1`. """ nrespa: int = Field(default=1, ge=1) @@ -1152,25 +1152,25 @@ def render(self, with_newlines: bool = False) -> list[str]: derivatives with respect to the effective radii, and pair interactions whose distances are greater than the "inner" cutoff, currently hard-wired at 8 Å. - If [`nrespa`][schemas.workflow.amber.inputs.AmberInputsBase.nrespa] > `1` + If [`nrespa`][configs.workflow.amber.inputs.AmberInputsBase.nrespa] > `1` these slowly-varying forces are evaluated every - [`nrespa`][schemas.workflow.amber.inputs.AmberInputsBase.nrespa] steps. + [`nrespa`][configs.workflow.amber.inputs.AmberInputsBase.nrespa] steps. The forces are adjusted appropriately, leading to an impulse at that step. - If [`nrespa`][schemas.workflow.amber.inputs.AmberInputsBase.nrespa] - $\times$ [`dt`][schemas.workflow.amber.inputs.AmberInputsBase.dt] + If [`nrespa`][configs.workflow.amber.inputs.AmberInputsBase.nrespa] + $\times$ [`dt`][configs.workflow.amber.inputs.AmberInputsBase.dt] is less than or equal to `4` fs then the energy conservation is not seriously compromised. However if - [`nrespa`][schemas.workflow.amber.inputs.AmberInputsBase.nrespa] $\times$ - [`dt`][schemas.workflow.amber.inputs.AmberInputsBase.dt] > `4` fs then the + [`nrespa`][configs.workflow.amber.inputs.AmberInputsBase.nrespa] $\times$ + [`dt`][configs.workflow.amber.inputs.AmberInputsBase.dt] > `4` fs then the simulation becomes less stable. Note that energies and related quantities are only accessible every - [`nrespa`][schemas.workflow.amber.inputs.AmberInputsBase.nrespa] steps, since + [`nrespa`][configs.workflow.amber.inputs.AmberInputsBase.nrespa] steps, since the values at other times are meaningless. """ temp0les: int = Field(default=-1, ge=-1) """This is the target temperature for all LES particles. If - [`temp0les`][schemas.workflow.amber.inputs.AmberInputsBase.temp0les] < `0`, + [`temp0les`][configs.workflow.amber.inputs.AmberInputsBase.temp0les] < `0`, a single temperature bath is used for all atoms, otherwise separate thermostats are used for LES and non-LES particles. Default is -1, corresponding to a single (weak-coupling) temperature bath. @@ -1179,12 +1179,12 @@ def render(self, with_newlines: bool = False) -> list[str]: tautp: float = Field(default=1.0, gt=0) """ Time constant, in ps, for heat bath coupling for the system, if - [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] is `1`. + [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] is `1`. Generally, values for - [`tautp`][schemas.workflow.amber.inputs.AmberInputsBase.tautp] should be in the + [`tautp`][configs.workflow.amber.inputs.AmberInputsBase.tautp] should be in the range of `0.5` to `5.0` ps, with a smaller value providing tighter coupling to the heat bath and, thus, faster heating and a less natural trajectory. Smaller values of - [`tautp`][schemas.workflow.amber.inputs.AmberInputsBase.tautp] result in + [`tautp`][configs.workflow.amber.inputs.AmberInputsBase.tautp] result in smaller fluctuations in kinetic energy, but larger fluctuations in the total energy. Values much larger than the length of the simulation result in a return to constant energy conditions. @@ -1192,11 +1192,11 @@ def render(self, with_newlines: bool = False) -> list[str]: vrand: int = Field(default=1000, ge=1) """ - If [`vrand`][schemas.workflow.amber.inputs.AmberInputsBase.vrand] > `0` - and [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] is `2`, the + If [`vrand`][configs.workflow.amber.inputs.AmberInputsBase.vrand] > `0` + and [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] is `2`, the velocities will be randomized to temperature - [`temp0`][schemas.workflow.amber.inputs.AmberInputsBase.temp0] every - [`vrand`][schemas.workflow.amber.inputs.AmberInputsBase.vrand] steps. + [`temp0`][configs.workflow.amber.inputs.AmberInputsBase.temp0] every + [`vrand`][configs.workflow.amber.inputs.AmberInputsBase.vrand] steps. """ vlimit: float = Field(default=20.0, ge=0.0) @@ -1212,11 +1212,11 @@ def render(self, with_newlines: bool = False) -> list[str]: nkija: int = Field(default=1, ge=1) r""" - For use with [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] if `9` or 10. - For [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] is `9`, this the - number of substeps of [`dt`][schemas.workflow.amber.inputs.AmberInputsBase.dt] + For use with [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] if `9` or 10. + For [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] is `9`, this the + number of substeps of [`dt`][configs.workflow.amber.inputs.AmberInputsBase.dt] when integrating the thermostat equations of motion, for greater accuracy. - For [`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] is `10`, this + For [`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] is `10`, this specifies the number of additional auxiliary velocity variables v1 and v2, which will total `nkija` $\times$ v1 + `nkija` $\times$ v2 """ @@ -1224,7 +1224,7 @@ def render(self, with_newlines: bool = False) -> list[str]: sinrtau: float = Field(default=1.0, gt=0.0) """ For the SINR (Stochastic Isokinetic Nose-Hoover RESPA) integrator - ([`ntt`][schemas.workflow.amber.inputs.AmberInputsBase.ntt] is `10`), this + ([`ntt`][configs.workflow.amber.inputs.AmberInputsBase.ntt] is `10`), this specifies the time scale for determining the masses associated with the two auxiliary velocity variables v1 and v2 (e.g. thermostat velocities) and hence the magnitude of the coupling of the physical velocities with the auxiliary @@ -1234,9 +1234,9 @@ def render(self, with_newlines: bool = False) -> list[str]: baroscalingdir: Literal[0, 1, 2, 3] = Field(default=0) """ Flag for pressure scaling direction control. Applicable when using Monte Carlo - barostat ([`barostat`][schemas.workflow.amber.inputs.AmberInputsBase.barostat] + barostat ([`barostat`][configs.workflow.amber.inputs.AmberInputsBase.barostat] is `2`) with anisotropic pressure scaling - ([`ntp`][schemas.workflow.amber.inputs.AmberInputsBase.ntp] is `2`). + ([`ntp`][configs.workflow.amber.inputs.AmberInputsBase.ntp] is `2`).
@@ -1339,9 +1339,9 @@ def render(self, with_newlines: bool = False) -> list[str]: noshakemask: str = Field(default="") """ String that specifies atoms that are not to be shaken - (assuming that [`ntc`][schemas.workflow.amber.inputs.AmberInputsBase.ntc]>1). + (assuming that [`ntc`][configs.workflow.amber.inputs.AmberInputsBase.ntc]>1). Any bond that would otherwise be shaken by virtue of the - [`ntc`][schemas.workflow.amber.inputs.AmberInputsBase.ntc] flag, but which + [`ntc`][configs.workflow.amber.inputs.AmberInputsBase.ntc] flag, but which involves an atom flagged here, will **not** be shaken. Default is an empty string, which matches nothing. A typical use would be to remove SHAKE constraints from all or part of a solute, while still shaking rigid water @@ -1350,14 +1350,14 @@ def render(self, with_newlines: bool = False) -> list[str]: which are the EVB or quantum regions of the system. If this option is invoked, then all parts of the potential must be evaluated, - that is, [`ntf`][schemas.workflow.amber.inputs.AmberInputsBase.ntf] must be `1`. + that is, [`ntf`][configs.workflow.amber.inputs.AmberInputsBase.ntf] must be `1`. The code enforces this by setting - [`ntf`][schemas.workflow.amber.inputs.AmberInputsBase.ntf] to `1` when a + [`ntf`][configs.workflow.amber.inputs.AmberInputsBase.ntf] to `1` when a noshakemask string is present in the input. If you want the noshakemask to apply to all or part of the water molecules, you must also set - [`jfastw`][schemas.workflow.amber.inputs.AmberInputsBase.jfastw] to `4`, to turn + [`jfastw`][configs.workflow.amber.inputs.AmberInputsBase.jfastw] to `4`, to turn off the special code for water SHAKE. (If you are not shaking waters, you presumably also want to issue the "set default FlexibleWater on" command in LEaP; see that chapter for more information.) diff --git a/simlify/schemas/amber/v18/__init__.py b/simlify/configs/amber/v18/__init__.py similarity index 91% rename from simlify/schemas/amber/v18/__init__.py rename to simlify/configs/amber/v18/__init__.py index 01e5d14..d8240d5 100644 --- a/simlify/schemas/amber/v18/__init__.py +++ b/simlify/configs/amber/v18/__init__.py @@ -10,6 +10,6 @@ from .cli import Amber18CLI from .ff import Amber18Forcefield from .inputs import Amber18Inputs -from .core import Amber18Schema +from .core import Amber18Config -__all__ = ["Amber18CLI", "Amber18Forcefield", "Amber18Inputs", "Amber18Schema"] +__all__ = ["Amber18CLI", "Amber18Forcefield", "Amber18Inputs", "Amber18Config"] diff --git a/simlify/configs/amber/v18/cli.py b/simlify/configs/amber/v18/cli.py new file mode 100644 index 0000000..4a13d8c --- /dev/null +++ b/simlify/configs/amber/v18/cli.py @@ -0,0 +1,5 @@ +from simlify.configs.amber import AmberCLIBase + + +class Amber18CLI(AmberCLIBase): + pass diff --git a/simlify/schemas/amber/v18/core.py b/simlify/configs/amber/v18/core.py similarity index 77% rename from simlify/schemas/amber/v18/core.py rename to simlify/configs/amber/v18/core.py index 69a1e27..d36f12b 100644 --- a/simlify/schemas/amber/v18/core.py +++ b/simlify/configs/amber/v18/core.py @@ -9,16 +9,16 @@ from pydantic import Field -from simlify.schemas.amber import AmberSchemaBase -from simlify.schemas.amber.v18 import ( +from simlify.configs.amber import AmberConfigBase +from simlify.configs.amber.v18 import ( Amber18CLI, Amber18Forcefield, Amber18Inputs, ) -class Amber18Schema(AmberSchemaBase): - r"""Amber 18 schema for simulation contexts.""" +class Amber18Config(AmberConfigBase): + r"""Amber 18 config for simulation contexts.""" inputs: Amber18Inputs = Field(default_factory=Amber18Inputs) diff --git a/simlify/schemas/amber/v18/ff.py b/simlify/configs/amber/v18/ff.py similarity index 92% rename from simlify/schemas/amber/v18/ff.py rename to simlify/configs/amber/v18/ff.py index 78ea235..c5a4f6c 100644 --- a/simlify/schemas/amber/v18/ff.py +++ b/simlify/configs/amber/v18/ff.py @@ -11,10 +11,10 @@ from pydantic import Field -from simlify.schemas import ForcefieldSchemaBase +from simlify.configs import ForcefieldConfigBase -class Amber18Forcefield(ForcefieldSchemaBase): +class Amber18Forcefield(ForcefieldConfigBase): protein: ( Literal[ "ff14SB", diff --git a/simlify/configs/amber/v18/inputs.py b/simlify/configs/amber/v18/inputs.py new file mode 100644 index 0000000..3536add --- /dev/null +++ b/simlify/configs/amber/v18/inputs.py @@ -0,0 +1,5 @@ +from simlify.configs.amber import AmberInputsBase + + +class Amber18Inputs(AmberInputsBase): + pass diff --git a/simlify/schemas/amber/v20/__init__.py b/simlify/configs/amber/v20/__init__.py similarity index 91% rename from simlify/schemas/amber/v20/__init__.py rename to simlify/configs/amber/v20/__init__.py index 8d5676d..fc670de 100644 --- a/simlify/schemas/amber/v20/__init__.py +++ b/simlify/configs/amber/v20/__init__.py @@ -10,6 +10,6 @@ from .cli import Amber20CLI from .ff import Amber20Forcefield from .inputs import Amber20Inputs -from .core import Amber20Schema +from .core import Amber20Config -__all__ = ["Amber20CLI", "Amber20Forcefield", "Amber20Inputs", "Amber20Schema"] +__all__ = ["Amber20CLI", "Amber20Forcefield", "Amber20Inputs", "Amber20Config"] diff --git a/simlify/configs/amber/v20/cli.py b/simlify/configs/amber/v20/cli.py new file mode 100644 index 0000000..e4d90b1 --- /dev/null +++ b/simlify/configs/amber/v20/cli.py @@ -0,0 +1,5 @@ +from simlify.configs.amber import AmberCLIBase + + +class Amber20CLI(AmberCLIBase): + pass diff --git a/simlify/schemas/amber/v20/core.py b/simlify/configs/amber/v20/core.py similarity index 77% rename from simlify/schemas/amber/v20/core.py rename to simlify/configs/amber/v20/core.py index 58114da..a23ce75 100644 --- a/simlify/schemas/amber/v20/core.py +++ b/simlify/configs/amber/v20/core.py @@ -9,16 +9,16 @@ from pydantic import Field -from simlify.schemas.amber import AmberSchemaBase -from simlify.schemas.amber.v20 import ( +from simlify.configs.amber import AmberConfigBase +from simlify.configs.amber.v20 import ( Amber20CLI, Amber20Forcefield, Amber20Inputs, ) -class Amber20Schema(AmberSchemaBase): - r"""Amber 20 schema for simulation contexts.""" +class Amber20Config(AmberConfigBase): + r"""Amber 20 config for simulation contexts.""" inputs: Amber20Inputs = Field(default_factory=Amber20Inputs) diff --git a/simlify/schemas/amber/v20/ff.py b/simlify/configs/amber/v20/ff.py similarity index 93% rename from simlify/schemas/amber/v20/ff.py rename to simlify/configs/amber/v20/ff.py index 35c5c92..5d8d049 100644 --- a/simlify/schemas/amber/v20/ff.py +++ b/simlify/configs/amber/v20/ff.py @@ -11,10 +11,10 @@ from pydantic import Field -from simlify.schemas import ForcefieldSchemaBase +from simlify.configs import ForcefieldConfigBase -class Amber20Forcefield(ForcefieldSchemaBase): +class Amber20Forcefield(ForcefieldConfigBase): protein: ( Literal[ "ff19SB", diff --git a/simlify/configs/amber/v20/inputs.py b/simlify/configs/amber/v20/inputs.py new file mode 100644 index 0000000..2973494 --- /dev/null +++ b/simlify/configs/amber/v20/inputs.py @@ -0,0 +1,5 @@ +from simlify.configs.amber import AmberInputsBase + + +class Amber20Inputs(AmberInputsBase): + pass diff --git a/simlify/schemas/amber/v22/__init__.py b/simlify/configs/amber/v22/__init__.py similarity index 91% rename from simlify/schemas/amber/v22/__init__.py rename to simlify/configs/amber/v22/__init__.py index cab2241..66edb39 100644 --- a/simlify/schemas/amber/v22/__init__.py +++ b/simlify/configs/amber/v22/__init__.py @@ -10,6 +10,6 @@ from .cli import Amber22CLI from .ff import Amber22Forcefield from .inputs import Amber22Inputs -from .core import Amber22Schema +from .core import Amber22Config -__all__ = ["Amber22CLI", "Amber22Forcefield", "Amber22Inputs", "Amber22Schema"] +__all__ = ["Amber22CLI", "Amber22Forcefield", "Amber22Inputs", "Amber22Config"] diff --git a/simlify/configs/amber/v22/cli.py b/simlify/configs/amber/v22/cli.py new file mode 100644 index 0000000..c4e9a21 --- /dev/null +++ b/simlify/configs/amber/v22/cli.py @@ -0,0 +1,5 @@ +from simlify.configs.amber import AmberCLIBase + + +class Amber22CLI(AmberCLIBase): + pass diff --git a/simlify/schemas/amber/v22/core.py b/simlify/configs/amber/v22/core.py similarity index 77% rename from simlify/schemas/amber/v22/core.py rename to simlify/configs/amber/v22/core.py index 59f65c6..da5c65b 100644 --- a/simlify/schemas/amber/v22/core.py +++ b/simlify/configs/amber/v22/core.py @@ -9,16 +9,16 @@ from pydantic import Field -from simlify.schemas.amber import AmberSchemaBase -from simlify.schemas.amber.v22 import ( +from simlify.configs.amber import AmberConfigBase +from simlify.configs.amber.v22 import ( Amber22CLI, Amber22Forcefield, Amber22Inputs, ) -class Amber22Schema(AmberSchemaBase): - r"""Amber 22 schema for simulation contexts.""" +class Amber22Config(AmberConfigBase): + r"""Amber 22 config for simulation contexts.""" inputs: Amber22Inputs = Field(default_factory=Amber22Inputs) diff --git a/simlify/schemas/amber/v22/ff.py b/simlify/configs/amber/v22/ff.py similarity index 93% rename from simlify/schemas/amber/v22/ff.py rename to simlify/configs/amber/v22/ff.py index caac3ac..9f4aca4 100644 --- a/simlify/schemas/amber/v22/ff.py +++ b/simlify/configs/amber/v22/ff.py @@ -11,10 +11,10 @@ from pydantic import Field -from simlify.schemas import ForcefieldSchemaBase +from simlify.configs import ForcefieldConfigBase -class Amber22Forcefield(ForcefieldSchemaBase): +class Amber22Forcefield(ForcefieldConfigBase): protein: ( Literal[ "ff19SB", diff --git a/simlify/configs/amber/v22/inputs.py b/simlify/configs/amber/v22/inputs.py new file mode 100644 index 0000000..afcae8d --- /dev/null +++ b/simlify/configs/amber/v22/inputs.py @@ -0,0 +1,5 @@ +from simlify.configs.amber import AmberInputsBase + + +class Amber22Inputs(AmberInputsBase): + pass diff --git a/simlify/config.py b/simlify/configs/core.py similarity index 76% rename from simlify/config.py rename to simlify/configs/core.py index 9622328..a6b2492 100644 --- a/simlify/config.py +++ b/simlify/configs/core.py @@ -9,43 +9,43 @@ from typing import Any -from atomea.schemas import Render, YamlIO from pydantic import BaseModel, Field -from simlify.schemas import ( +from simlify.configs import ( RunConfig, - SlurmSchema, + SlurmConfig, SolutionConfig, TopologyConfig, ) +from simlify.configs.utils import Render, YamlIO class SimlifyConfig(BaseModel, YamlIO, Render): """Contexts for setting up molecular simulations. - This class aggregates various configuration schemas required to define and + This class aggregates various configuration required to define and execute molecular simulations using the Simlify workflow. It includes settings for job submission (Slurm), solution conditions, topology generation, runtime parameters, and the specific simulation engine to be used. """ - slurm: SlurmSchema = Field(default_factory=SlurmSchema) + slurm: SlurmConfig = Field(default_factory=SlurmConfig) """ - Configuration schema for submitting jobs to a Slurm workload manager. + Configuration for submitting jobs to a Slurm workload manager. This includes parameters such as the number of nodes, tasks per node, partition, time limit, and other Slurm-specific settings. """ solution: SolutionConfig = Field(default_factory=SolutionConfig) """ - Configuration schema for defining the solution environment of the + Configuration for defining the solution environment of the molecular system. This includes parameters related to solvent, ions, and charge neutralization. """ topology: TopologyConfig = Field(default_factory=TopologyConfig) """ - Configuration schema for generating the topology and parameter files + Configuration for generating the topology and parameter files required for the molecular simulation. This can include options for appending extra lines to the topology file. """ @@ -58,15 +58,15 @@ class SimlifyConfig(BaseModel, YamlIO, Render): run: RunConfig = Field(default_factory=RunConfig) """ - Configuration schema for specifying parameters related to the simulation + Configuration for specifying parameters related to the simulation runtime environment. This includes working directories, input/output paths, and options for splitting the simulation into chunks. """ engine: Any = None """ - Workflow schema for the molecular simulation engine (e.g., - [`Amber22Schema`][simlify.schemas.amber.v22.Amber22Schema]). + Workflow for the molecular simulation engine (e.g., + [`Amber22Config`][simlify.configs.amber.v22.Amber22Config]). This attribute holds the specific engine configuration, allowing Simlify to interact with different simulation packages. """ diff --git a/simlify/schemas/ff.py b/simlify/configs/ff.py similarity index 92% rename from simlify/schemas/ff.py rename to simlify/configs/ff.py index 4b13541..fcfac53 100644 --- a/simlify/schemas/ff.py +++ b/simlify/configs/ff.py @@ -7,11 +7,13 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas import YamlIO + from pydantic import BaseModel +from simlify.configs.utils import YamlIO + -class ForcefieldSchemaBase(BaseModel, YamlIO): +class ForcefieldConfigBase(BaseModel, YamlIO): dna: str | None = None """Molecular mechanics force fields for DNA.""" diff --git a/simlify/configs/gnina/__init__.py b/simlify/configs/gnina/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/configs/gnina/core.py b/simlify/configs/gnina/core.py new file mode 100644 index 0000000..6de6231 --- /dev/null +++ b/simlify/configs/gnina/core.py @@ -0,0 +1,9 @@ +from typing import Any + +from pydantic import BaseModel + +from simlify.configs.utils import YamlIO + + +class GninaConfigBase(BaseModel, YamlIO): + r"""Gnina config.""" diff --git a/simlify/schemas/run.py b/simlify/configs/run.py similarity index 81% rename from simlify/schemas/run.py rename to simlify/configs/run.py index becb7ab..8d9ed48 100644 --- a/simlify/schemas/run.py +++ b/simlify/configs/run.py @@ -7,9 +7,10 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas.io import YamlIO from pydantic import BaseModel +from simlify.configs.utils import YamlIO + class RunConfig(BaseModel, YamlIO): """Configuration options during the simulation runtime.""" @@ -23,21 +24,21 @@ class RunConfig(BaseModel, YamlIO): dir_run: str = "." """ Directory that calculations are performed in. This can be the same as - [`dir_work`][schemas.RunConfig.dir_work] + [`dir_work`][configs.RunConfig.dir_work] or some scratch space like `$SLURM_SCRATCH`. """ dir_input: str = "." """ Path to a directory relative to - [`dir_work`][schemas.RunConfig.dir_work] that will contain + [`dir_work`][configs.RunConfig.dir_work] that will contain input files. """ dir_output: str = "." """ Path to a directory relative to - [`dir_work`][schemas.RunConfig.dir_work] that the simulation will + [`dir_work`][configs.RunConfig.dir_work] that the simulation will store output files. """ @@ -46,7 +47,7 @@ class RunConfig(BaseModel, YamlIO): use_scratch: bool = False """ - Treat [`dir_run`][schemas.RunConfig.dir_run] as a scratch directory + Treat [`dir_run`][configs.RunConfig.dir_run] as a scratch directory by copying input files to that location, running the simulation there, and then copying output files back. """ diff --git a/simlify/schemas/slurm.py b/simlify/configs/slurm.py similarity index 97% rename from simlify/schemas/slurm.py rename to simlify/configs/slurm.py index df6533a..7bfa01f 100644 --- a/simlify/schemas/slurm.py +++ b/simlify/configs/slurm.py @@ -7,11 +7,12 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas import Render, YamlIO from pydantic import BaseModel +from simlify.configs.utils import Render, YamlIO -class SlurmSchema(BaseModel, YamlIO, Render): + +class SlurmConfig(BaseModel, YamlIO, Render): """Context manager for Slurm job submission scripts. This class provides a structured way to define and manage the configuration for @@ -20,7 +21,7 @@ class SlurmSchema(BaseModel, YamlIO, Render): """ def render(self, with_newlines: bool = False) -> list[str]: - lines = ["#!/bin/bash", ""] + lines: list[str] = ["#!/bin/bash", ""] for key, value in self.model_dump(exclude_none=True).items(): # Skip keys that we have to manually handle @@ -182,7 +183,7 @@ def render(self, with_newlines: bool = False) -> list[str]: cpus_per_gpu: int | None = None """Request that ncpus processors be allocated per allocated GPU. Steps inheriting this value will imply `--exact`. Not compatible with the - [`--cpus-per-task`][schemas.workflow.slurm.SlurmSchema.cpus_per_task] option. + [`--cpus-per-task`][configs.workflow.slurm.SlurmConfig.cpus_per_task] option. [More information](https://slurm.schedmd.com/sbatch.html#OPT_cpus-per-gpu) """ diff --git a/simlify/schemas/solution.py b/simlify/configs/solution.py similarity index 80% rename from simlify/schemas/solution.py rename to simlify/configs/solution.py index c78004c..830b956 100644 --- a/simlify/schemas/solution.py +++ b/simlify/configs/solution.py @@ -7,16 +7,17 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas.io import YamlIO from pydantic import BaseModel +from simlify.configs.utils import YamlIO + class SolutionConfig(BaseModel, YamlIO): charge_anion_extra: int = 0 """Number of extra anions of type [`charge_anion_identity`] - [schemas.SolutionConfig.charge_anion_identity] to add to + [configs.SolutionConfig.charge_anion_identity] to add to the system. This does not include any ions added if [`charge_neutralize`] - [schemas.SolutionConfig.charge_neutralize] is `True`. + [configs.SolutionConfig.charge_neutralize] is `True`. """ charge_anion_identity: str = "Cl-" @@ -27,9 +28,9 @@ class SolutionConfig(BaseModel, YamlIO): charge_cation_extra: int = 0 """Number of extra cations of type [`charge_cation_identity`] - [schemas.SolutionConfig.charge_cation_identity] to add to the + [configs.SolutionConfig.charge_cation_identity] to add to the system. This does not include any ions added if [`charge_neutralize`] - [schemas.SolutionConfig.charge_neutralize] is `True`. + [configs.SolutionConfig.charge_neutralize] is `True`. """ charge_cation_identity: str = "Na+" @@ -44,11 +45,11 @@ class SolutionConfig(BaseModel, YamlIO): charge_neutralize: bool = True """Flag to determine if system charge should be neutralized by placing additional ions of type [`charge_cation_identity`] - [schemas.SolutionConfig.charge_cation_identity] + [configs.SolutionConfig.charge_cation_identity] or [`charge_anion_identity`] - [schemas.SolutionConfig.charge_anion_identity] based on + [configs.SolutionConfig.charge_anion_identity] based on the value of [`charge_net`] - [schemas.SolutionConfig.charge_net]. + [configs.SolutionConfig.charge_net]. """ solvent_ionic_strength: float = 0.150 diff --git a/simlify/schemas/topo.py b/simlify/configs/topo.py similarity index 92% rename from simlify/schemas/topo.py rename to simlify/configs/topo.py index 1c4c7b0..4235f10 100644 --- a/simlify/schemas/topo.py +++ b/simlify/configs/topo.py @@ -7,9 +7,10 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas.io import YamlIO from pydantic import BaseModel +from simlify.configs.utils import YamlIO + class TopologyConfig(BaseModel, YamlIO): """Topology configuration.""" diff --git a/simlify/configs/utils/__init__.py b/simlify/configs/utils/__init__.py new file mode 100644 index 0000000..d078a2c --- /dev/null +++ b/simlify/configs/utils/__init__.py @@ -0,0 +1,4 @@ +from .io import YamlIO +from .render import Render + +__all__ = ["YamlIO", "Render"] diff --git a/simlify/configs/utils/io.py b/simlify/configs/utils/io.py new file mode 100644 index 0000000..e9ed3ab --- /dev/null +++ b/simlify/configs/utils/io.py @@ -0,0 +1,77 @@ +from typing import Any + +from abc import ABC + +import yaml + +from simlify.utils import get_obj_from_string + + +class YamlIO(ABC): + """Handles YAML inputs and outputs.""" + + def update(self, data: dict[str, Any]) -> None: + """Iteratively update pydantic model. + + Args: + data: Key-value mapping to update attributes with. + + Notes: + Many of our pydantic models have fields that need to specified by + instantiating other objects or models. In order to instantiate these + objects, you can use the `import` root key to specify which class to use. + For example, if you need to specify the + [`AmberTopoGen`][simulation.amber.topo.AmberTopoGen] as the + simlify configuration `engine`, you can add this to your YAML file. + + ```yaml + import: + engine: simlify.simulation.amber.topo.AmberTopoGen + ``` + + This will call [`get_obj_from_string`][utils.get_obj_from_string] and + set the [`engine`][config.SimlifyConfig.engine] attribute to + [`AmberTopoGen`][simulation.amber.topo.AmberTopoGen]. + We handle these imports before any other field is handled. + """ + # Handle the imports first + if "import" in data.keys(): + import_info = data.pop("import") + for key, import_str in import_info.items(): + obj = get_obj_from_string(import_str) + setattr(self, key, obj) + + for key, value in data.items(): + if key in self.model_fields: # type: ignore # pylint: disable=no-member + setattr(self, key, value) + + def from_yaml(self, yaml_paths: str | list[str]) -> None: + """Update the instance's attributes from one or more YAML files. + + Args: + yaml_paths: A sequence of YAML file paths or a single YAML file path. + + Raises: + FileNotFoundError: If any of the YAML files cannot be found. + """ + if isinstance(yaml_paths, str): + yaml_paths = [yaml_paths] + for yaml_path in yaml_paths: + with open(yaml_path, "r", encoding="utf-8") as f: + yaml_data = yaml.safe_load(f) + self.update(yaml_data) + + def to_yaml(self, file_path: str) -> None: + """Serialize a Pydantic BaseModel instance to a YAML file. + + TODO: Need to fix with new Pydantic framework. + + Args: + file_path: Path to the YAML file to write the serialized data to. + + Raises: + YamlIOError: If the file cannot be written to. + """ + config_dict = self.model_dump() # type: ignore # pylint: disable=no-member + with open(file_path, "w", encoding="utf-8") as f: + yaml.dump(config_dict, f, default_flow_style=False) diff --git a/simlify/configs/utils/render.py b/simlify/configs/utils/render.py new file mode 100644 index 0000000..b278ac8 --- /dev/null +++ b/simlify/configs/utils/render.py @@ -0,0 +1,40 @@ +from abc import ABC + +from pydantic import Field + + +class Render(ABC): + """Handles rendering files.""" + + dir_work: str = Field(default=".", exclude=True) + """ + Working directory to write files. + """ + + dir_input: str = Field(default=".", exclude=True) + """ + Path to a directory relative to + [`dir_work`][configs.render.Render.dir_work] that will contain + input files. + """ + + dir_output: str = Field(default=".", exclude=True) + """ + Path to a directory relative to + [`dir_work`][configs.render.Render.dir_work] that the simulation will + store output files. + """ + + def render(self, with_newlines: bool = False) -> list[str]: + """Prepare input lines by rendering templates or combining input configuration.""" + raise NotImplementedError + + def write_render(self, file_path: str) -> None: + """Thin wrapper to write lines from the `render` function. + + Args: + file_path: Path to write file. + """ + lines = self.render() + with open(file_path, "w", encoding="utf-8") as f: + f.write("\n".join(lines)) diff --git a/simlify/schemas/westpa/__init__.py b/simlify/configs/westpa/__init__.py similarity index 100% rename from simlify/schemas/westpa/__init__.py rename to simlify/configs/westpa/__init__.py diff --git a/simlify/schemas/westpa/cfg/__init__.py b/simlify/configs/westpa/cfg/__init__.py similarity index 100% rename from simlify/schemas/westpa/cfg/__init__.py rename to simlify/configs/westpa/cfg/__init__.py diff --git a/simlify/schemas/westpa/cfg/core.py b/simlify/configs/westpa/cfg/core.py similarity index 94% rename from simlify/schemas/westpa/cfg/core.py rename to simlify/configs/westpa/cfg/core.py index e4096e6..26b940c 100644 --- a/simlify/schemas/westpa/cfg/core.py +++ b/simlify/configs/westpa/cfg/core.py @@ -7,10 +7,10 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas import Render from pydantic import BaseModel, Field -from simlify.schemas.westpa.cfg import ( +from simlify.configs.utils import Render +from simlify.configs.westpa.cfg import ( DataConfig, ExecutableConfig, PropagationConfig, diff --git a/simlify/schemas/westpa/cfg/data.py b/simlify/configs/westpa/cfg/data.py similarity index 100% rename from simlify/schemas/westpa/cfg/data.py rename to simlify/configs/westpa/cfg/data.py diff --git a/simlify/schemas/westpa/cfg/executable.py b/simlify/configs/westpa/cfg/executable.py similarity index 100% rename from simlify/schemas/westpa/cfg/executable.py rename to simlify/configs/westpa/cfg/executable.py diff --git a/simlify/schemas/westpa/cfg/propagation.py b/simlify/configs/westpa/cfg/propagation.py similarity index 100% rename from simlify/schemas/westpa/cfg/propagation.py rename to simlify/configs/westpa/cfg/propagation.py diff --git a/simlify/schemas/westpa/cfg/system.py b/simlify/configs/westpa/cfg/system.py similarity index 100% rename from simlify/schemas/westpa/cfg/system.py rename to simlify/configs/westpa/cfg/system.py diff --git a/simlify/schemas/westpa/cli.py b/simlify/configs/westpa/cli.py similarity index 98% rename from simlify/schemas/westpa/cli.py rename to simlify/configs/westpa/cli.py index 9073fde..45fd6ce 100644 --- a/simlify/schemas/westpa/cli.py +++ b/simlify/configs/westpa/cli.py @@ -12,7 +12,7 @@ from loguru import logger -from simlify.schemas.westpa import WestpaConfig +from simlify.configs.westpa import WestpaConfig def run_westpa_config( diff --git a/simlify/schemas/westpa/core.py b/simlify/configs/westpa/core.py similarity index 79% rename from simlify/schemas/westpa/core.py rename to simlify/configs/westpa/core.py index 0d4a5b5..524c430 100644 --- a/simlify/schemas/westpa/core.py +++ b/simlify/configs/westpa/core.py @@ -7,11 +7,11 @@ # # See the LICENSE.md file for full license terms. -from atomea.schemas.io import YamlIO from pydantic import BaseModel, Field -from simlify.schemas.westpa import WestpaEnv -from simlify.schemas.westpa.cfg.core import WestpaConfigConfig +from simlify.configs.utils import YamlIO +from simlify.configs.westpa import WestpaEnv +from simlify.configs.westpa.cfg.core import WestpaConfigConfig class WestpaConfig(BaseModel, YamlIO): diff --git a/simlify/schemas/westpa/environment.py b/simlify/configs/westpa/environment.py similarity index 100% rename from simlify/schemas/westpa/environment.py rename to simlify/configs/westpa/environment.py diff --git a/simlify/schemas/__init__.py b/simlify/schemas/__init__.py deleted file mode 100644 index 812365a..0000000 --- a/simlify/schemas/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from .ff import ForcefieldSchemaBase -from .run import RunConfig -from .slurm import SlurmSchema -from .solution import SolutionConfig -from .topo import TopologyConfig - -__all__ = [ - "ForcefieldSchemaBase", - "SlurmSchema", - "TopologyConfig", - "SolutionConfig", - "RunConfig", -] diff --git a/simlify/schemas/amber/v18/cli.py b/simlify/schemas/amber/v18/cli.py deleted file mode 100644 index 913b793..0000000 --- a/simlify/schemas/amber/v18/cli.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.schemas.amber import AmberCLIBase - - -class Amber18CLI(AmberCLIBase): - pass diff --git a/simlify/schemas/amber/v18/inputs.py b/simlify/schemas/amber/v18/inputs.py deleted file mode 100644 index d52791f..0000000 --- a/simlify/schemas/amber/v18/inputs.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.schemas.amber import AmberInputsBase - - -class Amber18Inputs(AmberInputsBase): - pass diff --git a/simlify/schemas/amber/v20/cli.py b/simlify/schemas/amber/v20/cli.py deleted file mode 100644 index 2cfe314..0000000 --- a/simlify/schemas/amber/v20/cli.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.schemas.amber import AmberCLIBase - - -class Amber20CLI(AmberCLIBase): - pass diff --git a/simlify/schemas/amber/v20/inputs.py b/simlify/schemas/amber/v20/inputs.py deleted file mode 100644 index b36b0fb..0000000 --- a/simlify/schemas/amber/v20/inputs.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.schemas.amber import AmberInputsBase - - -class Amber20Inputs(AmberInputsBase): - pass diff --git a/simlify/schemas/amber/v22/cli.py b/simlify/schemas/amber/v22/cli.py deleted file mode 100644 index b4ba7ca..0000000 --- a/simlify/schemas/amber/v22/cli.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.schemas.amber import AmberCLIBase - - -class Amber22CLI(AmberCLIBase): - pass diff --git a/simlify/schemas/amber/v22/inputs.py b/simlify/schemas/amber/v22/inputs.py deleted file mode 100644 index caa3b2d..0000000 --- a/simlify/schemas/amber/v22/inputs.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.schemas.amber import AmberInputsBase - - -class Amber22Inputs(AmberInputsBase): - pass diff --git a/simlify/simulation/__init__.py b/simlify/simulation/__init__.py deleted file mode 100644 index bea42ea..0000000 --- a/simlify/simulation/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. diff --git a/simlify/simulation/amber/__init__.py b/simlify/simulation/amber/__init__.py deleted file mode 100644 index bea42ea..0000000 --- a/simlify/simulation/amber/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. diff --git a/simlify/structure/__init__.py b/simlify/structure/__init__.py deleted file mode 100644 index 3a55713..0000000 --- a/simlify/structure/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -from simlify.structure.extract import extract_atoms - -__all__ = ["extract_atoms"] diff --git a/simlify/structure/dims.py b/simlify/structure/dims.py deleted file mode 100644 index cd3efdb..0000000 --- a/simlify/structure/dims.py +++ /dev/null @@ -1,123 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -""" -Dimensions of systems. - -This module provides utility functions to calculate geometric properties -of a molecular system such as the bounding box lengths, box vectors, -and the volume of the box required to enclose the atoms. -""" - -import numpy as np -import numpy.typing as npt -from loguru import logger - - -def get_box_lengths(positions: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: - r"""Compute lengths of box edges. - - This function calculates the lengths of the edges of a box that - encompasses a set of atomic positions by finding the difference - between the maximum and minimum coordinates in each dimension. - - Args: - positions: A 2D NumPy array of shape (N, 3), where N is the - number of atoms and each row represents the Cartesian coordinates - [x, y, z] of an atom. - - Returns: - A 1D NumPy array of shape (3,) containing the lengths of the - box in the x, y, and z directions. - - Example: - ```python - >>> import numpy as np - >>> from box_utils import get_box_lengths - >>> positions = np.array([[0, 0, 0], [1, 2, 3]]) - >>> get_box_lengths(positions) - array([1., 2., 3.]) - ``` - """ - logger.trace("Computing box lengths") - box_lengths: npt.NDArray[np.float64] = np.max(positions, axis=0) - np.min( - positions, axis=0 - ) - logger.trace("Box lengths: {}", box_lengths) - return box_lengths - - -def get_box_vectors(positions: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: - r"""Construct orthogonal box vectors. - - This function calculates the vectors of the edges of a box that - encompasses a set of atomic positions. The vectors are represented - as a diagonal matrix where the diagonal elements correspond to the - lengths of the box edges. - - Args: - positions: A 2D NumPy array of shape (N, 3), where N is the - number of atoms and each row represents the Cartesian coordinates - [x, y, z] of an atom. - - Returns: - A 3x3 NumPy array representing the box vectors in matrix form. - The matrix is diagonal since the box is assumed to be orthorhombic. - - Example: - ```python - >>> import numpy as np - >>> from box_utils import get_box_vectors - >>> positions = np.array([[0, 0, 0], [1, 2, 3]]) - >>> get_box_vectors(positions) - array([[1., 0., 0.], - [0., 2., 0.], - [0., 0., 3.]]) - ``` - """ - box_lengths = get_box_lengths(positions) - - logger.trace("Computing box vectors") - box_vectors = np.zeros((3, 3), dtype=np.float64) - np.fill_diagonal(box_vectors, box_lengths) - logger.trace("Box vector:\n{}", box_vectors) - - return box_vectors - - -def get_box_volume( - positions: npt.NDArray[np.float64], -) -> float: - r"""Calculate volume of the enclosing orthorhombic box. - - Computes the volume of the orthorhombic box that encapsulates all atoms. - The box vectors are assumed to form an orthogonal basis. - - Args: - positions: A 2D NumPy array of shape (N, 3), where N is the - number of atoms and each row represents the Cartesian coordinates - [x, y, z] of an atom. - - Returns: - Volume of the enclosing box. - - Example: - ```python - >>> import numpy as np - >>> from box_utils import get_box_volume - >>> positions = np.array([[0, 0, 0], [1, 2, 3]]) - >>> get_box_volume(positions) - 6.0 - ``` - """ - box_vectors = get_box_vectors(positions) - logger.trace("Computing box volume") - volume = float(np.linalg.det(box_vectors)) - logger.trace("Box volume: {}", volume) - return volume diff --git a/simlify/structure/pdb/__init__.py b/simlify/structure/pdb/__init__.py deleted file mode 100644 index bea42ea..0000000 --- a/simlify/structure/pdb/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. diff --git a/simlify/structure/pdb/names.py b/simlify/structure/pdb/names.py deleted file mode 100644 index 8b6cc77..0000000 --- a/simlify/structure/pdb/names.py +++ /dev/null @@ -1,435 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -"""Module for modifying lines within PDB files, including functionalities for replacing -atom and residue names. - -This module provides a set of utility functions to manipulate the content of Protein -Data Bank (PDB) files. It includes functions to perform general line modifications -based on filtering criteria, as well as specific functions for replacing atom names -and residue names within the ATOM and HETATM records of a PDB file. Additionally, it -offers a function to standardize the atom names of water molecules. -""" - -from typing import Any - -import os -from collections.abc import Callable, Iterable - -from loguru import logger - -from simlify.structure.pdb.utils import ( - parse_atomname, - parse_resid, - parse_resname, - replace_in_pdb_line, -) - - -def modify_lines( - pdb_lines: Iterable[str], - fn_process: Callable[[str, str, str, int | None, int], str], - fn_args: Iterable[Any], - fn_filter: Callable[[str], str] | None = None, - include: list[str] | None = None, - exclude: list[str] | None = None, -) -> list[str]: - r"""General function to modify specific lines in a PDB file based on filtering. - - This function iterates through a list of PDB lines and applies a processing function - (`fn_process`) to lines that meet certain criteria defined by an optional filter - function (`fn_filter`) and inclusion/exclusion lists. - - Args: - pdb_lines: An iterable of strings, where each string represents a line - from a PDB file. - fn_process: A callable function that takes a PDB line as its first argument, - followed by the elements of `fn_args`, and returns a modified PDB line. - This function is responsible for the actual modification of the line. - fn_args: An iterable containing additional arguments to be passed to the - `fn_process` function after the PDB line itself. - fn_filter: An optional callable function that takes - a PDB line as input and returns a string. This string is then used to - check against the `include` and `exclude` lists. If `None`, all ATOM and - HETATM lines are processed. - include: An optional list of strings. If `fn_filter` is provided, - only lines for which the result of `fn_filter` is present in this list - will be processed by `fn_process`. - exclude: An optional list of strings. If `fn_filter` is provided, - lines for which the result of `fn_filter` is present in this list - will *not* be processed by `fn_process`. Defaults to `None`. - - Returns: - A list of modified PDB lines. Lines that did not meet the filtering criteria - or were not ATOM or HETATM records are returned unchanged. - - Notes: - - The `fn_filter` function should be designed to extract a specific piece of information - from the PDB line (e.g., residue name, atom name) that can be used for inclusion or - exclusion. - - If both `include` and `exclude` are provided and a filtered value is present in both, - the line will be processed if it's in `include`. Exclusion takes precedence if only - `exclude` is provided. - - Examples: - To replace "CA" atom names with "CB" only in residues named "GLY": - - >>> pdb_lines = [ - ... "ATOM 1 CA GLY A 1 ...", - ... "ATOM 2 CB ALA A 2 ...", - ... ] - >>> def get_resname(line): - ... return parse_resname(line).strip() - >>> modified = modify_lines( - ... pdb_lines, - ... replace_in_pdb_line, - ... ("CA ", "CB ", 13, 17), - ... fn_filter=get_resname, - ... include=["GLY"], - ... ) - >>> for line in modified: - ... print(line) - ATOM 1 CB GLY A 1 ... - ATOM 2 CB ALA A 2 ... - """ - modified_lines = [] - if callable(fn_filter): - logger.debug("Filter function is provided.") - for line in pdb_lines: - if "ATOM" in line or "HETATM" in line: - if callable(fn_filter): - filter_return = fn_filter(line).strip() - logger.trace("Filter function provided: {}", filter_return) - # Line is in included and should be processed. - if (include is not None) and (filter_return in include): - line = fn_process(line, *fn_args) - # Line is not in excluded and should be processed. - if (exclude is not None) and (filter_return not in exclude): - line = fn_process(line, *fn_args) - else: - line = fn_process(line, *fn_args) - modified_lines.append(line) - - return modified_lines - - -def replace_atom_names( - pdb_lines: Iterable[str], orig_atom_name: str, new_atom_name: str -) -> list[str]: - r"""Replaces all occurrences of a specified original atom name with a new atom - name in a list of PDB lines. - - This function iterates through the provided PDB lines and, for each ATOM or - HETATM record, it checks if the atom name matches the `orig_atom_name`. - If it does, the atom name is replaced with the `new_atom_name`. The atom names are - stripped of leading/trailing whitespace and left-justified - to a length of 4 characters to ensure proper formatting in the PDB file. - - Args: - pdb_lines: An iterable of strings, where each string represents a line - from a PDB file. - orig_atom_name: The original atom name to be replaced. - new_atom_name: The new atom name to replace the original one. - - Returns: - list[str]: A list of PDB lines with the specified atom names replaced. - - Examples: - >>> pdb_lines = [ - ... "ATOM 1 CA ALA A 1 ...", - ... "ATOM 2 CB ALA A 1 ...", - ... ] - >>> modified_lines = replace_atom_names(pdb_lines, "CA", "CB") - >>> for line in modified_lines: - ... print(line) - ATOM 1 CB ALA A 1 ... - ATOM 2 CB ALA A 1 ... - """ - orig_atom_name = orig_atom_name.strip().ljust(4) - new_atom_name = new_atom_name.strip().ljust(4) - return modify_lines( - pdb_lines, replace_in_pdb_line, (orig_atom_name, new_atom_name, 13, 17) - ) - - -def replace_residue_names( - pdb_lines: Iterable[str], - orig_resname: str, - new_resname: str, - fn_filter: Callable[[str], str] | None = None, - include: list[str] | None = None, - exclude: list[str] | None = None, -) -> list[str]: - r"""Replaces all occurrences of a specified original residue name with a new - residue name in a list of PDB lines. - - This function iterates through the provided PDB lines and, for each ATOM or - HETATM record, it checks if the residue name matches the `orig_resname`. - If it does, the residue name is replaced with the `new_resname`. The residue names - are stripped of leading/trailing whitespace and left-justified to a length of 4 - characters to ensure proper formatting in the PDB file. Optionally, a filter - function and inclusion/exclusion lists can be used to control which lines - are processed. - - Args: - pdb_lines: An iterable of strings, where each string represents a line - from a PDB file. - orig_resname: The original residue name to be replaced. - new_resname: The new residue name to replace the original one. - fn_filter: An optional callable function that takes a PDB line as input and - returns a string (e.g., residue ID) for filtering. - include: An optional list of strings. Only lines where the result of - `fn_filter` is in this list will have their residue names replaced. - exclude: An optional list of strings. Lines where the result of `fn_filter` - is in this list will *not* have their residue names replaced. - - Returns: - A list of PDB lines with the specified residue names replaced, subject to any - provided filtering. - - Examples: - To replace all "MET" residues with "ALA": - - >>> pdb_lines = [ - ... "ATOM 1 N MET A 1 ...", - ... "ATOM 2 CA MET A 1 ...", - ... ] - >>> modified_lines = replace_residue_names(pdb_lines, "MET", "ALA") - >>> for line in modified_lines: - ... print(line) - ATOM 1 N ALA A 1 ... - ATOM 2 CA ALA A 1 ... - - To replace "MET" with "ALA" only in residue ID "1": - - >>> pdb_lines = [ - ... "ATOM 1 N MET A 1 ...", - ... "ATOM 2 CA MET A 1 ...", - ... "ATOM 3 C MET A 2 ...", - ... ] - >>> def get_resid(line): - ... return parse_resid(line).strip() - >>> modified_lines = replace_residue_names( - ... pdb_lines, "MET", "ALA", fn_filter=get_resid, include=["1"] - ... ) - >>> for line in modified_lines: - ... print(line) - ATOM 1 N ALA A 1 ... - ATOM 2 CA ALA A 1 ... - ATOM 3 C MET A 2 ... - """ - orig_resname = orig_resname.strip().ljust(4) - new_resname = new_resname.strip().ljust(4) - logger.info("Renaming '{}' to '{}'", orig_resname, new_resname) - return modify_lines( - pdb_lines, - replace_in_pdb_line, - (orig_resname, new_resname, 17, 21), - fn_filter, - include, - exclude, - ) - - -def run_replace_resnames( - pdb_path: str, - resname_map: dict[str, str], - output_path: str | None = None, - fn_filter: Callable[[str], str] | None = None, - include: list[str] | None = None, - exclude: list[str] | None = None, -) -> list[str]: - r"""Replaces multiple residue names in a PDB file based on a provided mapping. - - This function reads a PDB file, iterates through a dictionary that maps original - residue names to new residue names, and applies the replacement using the - `replace_residue_names` function for each mapping. The modified PDB lines are - then either returned or written to a new file. Optional filtering based on a - function and inclusion/exclusion lists can be applied during the replacement - process for each residue name in the map. - - Args: - pdb_path: The path to the input PDB file. - resname_map: A dictionary where the keys are the original residue names - to be replaced, and the values are the corresponding new residue names. - output_path: The path to save the new PDB file with the replaced residue names. - If `None`, no file is written, and the modified PDB lines are returned. - fn_filter: An optional callable function that takes a PDB line as input and - returns a string for filtering during each residue name replacement. - include: An optional list of strings. Only lines where the result of - `fn_filter` is in this list will have their residue names replaced for each - mapping in `resname_map`. Defaults to `None`. - exclude: An optional list of strings. Lines where the result of `fn_filter` - is in this list will *not* have their residue names replaced for each - mapping in `resname_map`. - - Returns: - A list of PDB lines with the residue names replaced according to the - `resname_map`, subject to any provided filtering. - - Raises: - FileNotFoundError: If the specified `pdb_path` does not exist. - IOError: If there is an error reading the PDB file or writing to the output - file. - - Examples: - To replace all "MET" residues with "ALA" and all "GLU" residues with "ASP" in - "input.pdb" and save the result to "output.pdb": - - >>> resname_mapping = {"MET": "ALA", "GLU": "ASP"} - >>> modified_lines = run_replace_resnames( - ... "input.pdb", resname_mapping, output_path="output.pdb" - ... ) - - To perform the same replacement but only for residues with ID "1": - - >>> def get_resid(line): - ... return parse_resid(line).strip() - >>> resname_mapping = {"MET": "ALA", "GLU": "ASP"} - >>> modified_lines = run_replace_resnames( - ... "input.pdb", - ... resname_mapping, - ... output_path="filtered_output.pdb", - ... fn_filter=get_resid, - ... include=["1"], - ... ) - """ - logger.info("Renaming residue names {}", os.path.abspath(pdb_path)) - with open(pdb_path, "r", encoding="utf-8") as f: - pdb_lines: list[str] = f.readlines() - - for orig_resname, new_resname in resname_map.items(): - pdb_lines = replace_residue_names( - pdb_lines, orig_resname, new_resname, fn_filter, include, exclude - ) - - if output_path is not None: - logger.info("Writing PDB file to {}", os.path.abspath(output_path)) - with open(output_path, "w+", encoding="utf-8") as f: - f.writelines(pdb_lines) - - return pdb_lines - - -def run_unify_water_labels( - pdb_path: str, - atom_map: dict[str, str] | None = None, - water_resname: str = "WAT", - water_atomnames: dict[str, Iterable[str]] | None = None, - output_path: str | None = None, -) -> Iterable[str]: - r"""Ensures that water molecule atom names are consistently labeled as 'O', 'H1', - and 'H2'. - - This function processes a PDB file to standardize the atom names of water - molecules. It identifies water residues based on the `water_resname` and then - renames their atoms to 'O' for oxygen and 'H1' and 'H2' for the two hydrogen atoms. - The hydrogen atoms are assigned 'H1' and 'H2' based on their sequential appearance - within each water residue in the PDB file. - - Args: - pdb_path: The path to the input PDB file. - atom_map: A dictionary mapping the standard water atom names ('O', 'H1', 'H2') - to the desired names. If `None`, it defaults to - `{'O': 'O', 'H1': 'H1', 'H2': 'H2'}`. This allows for customization of the - output atom names if needed. Defaults to `None`. - water_resname: The residue name used to identify water molecules in the PDB - file. - water_atomnames: A dictionary specifying the original atom names that should - be considered as oxygen and hydrogen atoms of water. The keys should be - 'O' and 'H', and the values should be iterables of possible atom names. - If `None`, it defaults to `{'O': ['OW'], 'H': ['HW']}`. - output_path: The path to save the new PDB file with the unified water atom - labels. If `None`, no file is written, and the modified PDB lines are - returned. - - Returns: - An iterable of PDB lines with the unified water atom labels. - - Raises: - FileNotFoundError: If the specified `pdb_path` does not exist. - IOError: If there is an error reading the PDB file or writing to the output - file. - - Warning: - This function has not been thoroughly tested and might not handle all edge - cases correctly. Use with caution. - - Examples: - To unify water atom labels in "input.pdb" using the default settings and save - to "unified_water.pdb": - - >>> modified_lines = run_unify_water_labels( - ... "input.pdb", output_path="unified_water.pdb" - ... ) - - To specify a different water residue name and atom name mapping: - - >>> atom_mapping = {"O": "OXT", "H1": "HT1", "H2": "HT2"} - >>> original_water_names = {"O": ["SOL"], "H": ["HY"]} - >>> modified_lines = run_unify_water_labels( - ... "input.pdb", - ... atom_map=atom_mapping, - ... water_resname="SOL", - ... water_atomnames=original_water_names, - ... output_path="custom_water.pdb", - ... ) - """ - logger.info("Renaming water atom names in {}", os.path.abspath(pdb_path)) - - logger.debug("Water residue name: {}", water_resname) - if atom_map is None: - atom_map = {"O": "O", "H1": "H1", "H2": "H2"} - logger.debug("O atom name: {}", atom_map["O"]) - logger.debug("H1 atom name: {}", atom_map["H1"]) - logger.debug("H2 atom name: {}", atom_map["H2"]) - if water_atomnames is None: - water_atomnames = {"O": ["OW"], "H": ["HW"]} - - with open(pdb_path, "r", encoding="utf-8") as f: - pdb_lines: list[str] = f.readlines() - - water_h_resids = [] - - with open(pdb_path, "r", encoding="utf-8") as f: - pdb_lines = f.readlines() - - for i, line in enumerate(pdb_lines): - logger.trace("Working on: {}", line.strip()) - if parse_resname(line).strip() == water_resname: - logger.trace("Line is water residue") - original_atom_name = parse_atomname(line).strip() - - if original_atom_name in water_atomnames["O"]: - logger.trace( - "Atom name, {}, matches an oxygen type", original_atom_name - ) - pdb_lines[i] = replace_atom_names( - [line], original_atom_name, atom_map["O"] - )[0] - elif original_atom_name.startswith("H"): - # Use the original hydrogen atom name as the key in the dictionary - resid = parse_resid(line).strip() - if resid not in water_h_resids: - water_h_resids.append(resid) - atom_map_name = atom_map["H1"] - else: - atom_map_name = atom_map["H2"] - pdb_lines[i] = replace_atom_names( - [line], - original_atom_name, - atom_map_name, - )[0] - - if output_path is not None: - logger.info("Writing PDB file to {}", os.path.abspath(output_path)) - with open(output_path, "w+", encoding="utf-8") as f: - f.writelines(pdb_lines) - - return pdb_lines diff --git a/simlify/structure/pdb/numbering/__init__.py b/simlify/structure/pdb/numbering/__init__.py deleted file mode 100644 index bea42ea..0000000 --- a/simlify/structure/pdb/numbering/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. diff --git a/simlify/structure/pdb/numbering/atoms.py b/simlify/structure/pdb/numbering/atoms.py deleted file mode 100644 index c207b2e..0000000 --- a/simlify/structure/pdb/numbering/atoms.py +++ /dev/null @@ -1,43 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -"""Module for writing or modifying atom identifiers within PDB file lines.""" - -from simlify.structure.pdb.utils import write_in_pdb_line - - -def write_atom_id(line: str, atom_id: int) -> str: - r"""Writes a new atom ID into a specific PDB line. - - This function takes a PDB line and an integer representing the new atom ID. - It formats the atom ID to fit within the standard atom serial number columns - (columns 7-11, inclusive) of a PDB file line and then uses the `write_in_pdb_line` - utility function to insert this new ID into the line. - - Args: - line: The PDB line to be modified. This should be a standard PDB - format line, typically starting with "ATOM" or "HETATM". - atom_id: The new atom ID (serial number) to be written into the PDB line. - - Returns: - The modified PDB line with the new atom ID written into the appropriate columns. - - Examples: - >>> line = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> new_line = write_atom_id(line, 100) - >>> print(new_line) - ATOM 100 N MET A 1 10.000 20.000 30.000 1.00 20.00 N - """ - line_start = 6 # zero-based index - line_stop = 11 - field_width = line_stop - line_start # 6 characters total - # Format as right-justified in field_width, which includes the trailing space - atom_line = str(atom_id).rjust(field_width) - new_line = write_in_pdb_line(line, atom_line, line_start, line_stop) - return new_line diff --git a/simlify/structure/pdb/numbering/main.py b/simlify/structure/pdb/numbering/main.py deleted file mode 100644 index 60d84ed..0000000 --- a/simlify/structure/pdb/numbering/main.py +++ /dev/null @@ -1,172 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -"""Standardizes residue ID numbering in PDB files.""" - -import os -from collections.abc import Iterable - -from loguru import logger - -from simlify.structure.pdb.numbering.atoms import write_atom_id -from simlify.structure.pdb.numbering.residues import unify_resid -from simlify.structure.pdb.utils import parse_resid - - -def run_unify_numbering( - pdb_path: str, output_path: str | None = None, reset_initial_resid: bool = True -) -> Iterable[str]: - r"""Unifies the atom and residue numbering within a PDB file, ensuring sequential - and consistent IDs. - - This function reads a PDB file and renumbers the atom serial numbers and residue IDs - to be sequential, starting from 1 for the first atom and the first residue encountered. - It also handles chain identifiers, incrementing them upon encountering a "TER" record - if `reset_initial_resid` is True. Duplicate "TER" statements are removed, and "ENDMDL" - records trigger a reset of atom and residue numbering, as well as the chain identifier. - - Args: - pdb_path: The path to the input PDB file. - output_path: The path to save the new PDB file with unified - numbering. If `None`, no file is written, and the modified PDB lines are returned. - Defaults to `None`. - reset_initial_resid: If `True` (default), the residue numbering will - start from 1 for the first residue in each chain. If `False`, the initial - residue ID will be based on the original numbering in the PDB file for the - first chain, and subsequent chains will continue sequentially. - - Returns: - An iterable of strings, where each string is a line from the PDB file - with the unified atom and residue numbering. - - Raises: - FileNotFoundError: If the specified `pdb_path` does not exist. - IOError: If there is an error reading the PDB file or writing to the output file. - - Notes: - - The function iterates through the PDB lines, tracking the current residue - and chain IDs. - - When a "TER" record is encountered, it signifies the end of a chain, and - the chain ID is incremented if `reset_initial_resid` is True. - - "ENDMDL" records indicate the start of a new model, and all numbering is - reset. - - Atom serial numbers are simply incremented sequentially. - - Residue IDs are unified within each chain, potentially resetting to 1 at - the start of a new chain. - - Examples: - To unify the numbering in "input.pdb" and save it to "output.pdb": - - >>> unified_lines = run_unify_numbering("input.pdb", output_path="output.pdb") - - To unify the numbering but keep the initial residue ID of the first chain: - - >>> unified_lines = run_unify_numbering( - ... "input.pdb", output_path="output.pdb", reset_initial_resid=False - ... ) - - To unify the numbering and only get the lines without saving to a file: - - >>> unified_lines = run_unify_numbering("input.pdb") - >>> for line in unified_lines: - ... print(line.strip()) - """ - logger.info("Unify residue IDs from {}", os.path.abspath(pdb_path)) - with open(pdb_path, "r", encoding="utf-8") as f: - pdb_lines: list[str] = f.readlines() - - # current_resid keeps track of our residue ID while parsing. - # If this becomes None, then we restart our numbering at 1 - # (determined in assign_resid function). - current_resid: str | None = None - # current_chain is essentially the same thing as current_resid, but for the chain - # ID. - current_chain: str | None = None - # parse_structure is used to turn parsing on or off depending on if the current - # line contains any atomic information. - parse_structure = False - - # atom_id keeps track of the atom serial number. - atom_id: int = 1 - for i, line in enumerate(pdb_lines): - logger.trace("Processing line number: {}", i) - - # When we hit a TER statement, we need to keep track/handle our IDs for the next - # section. - if line.startswith("TER"): - # Catches and fixes duplicate TER statements - if pdb_lines[i - 1].strip() == "TER": - logger.debug("Fixing duplicate `TER` statements.") - pdb_lines[i] = "" - continue - - logger.debug("Encountered `TER`, storing ID information.") - - parse_structure = False - logger.trace("Set parse_structure to False") - - current_resid = str(parse_resid(pdb_lines[i - 1])) - logger.trace(f"Setting current_resid to {current_resid} (from last one)") - - if reset_initial_resid and current_chain is not None: - current_chain = chr(ord(current_chain) + 1) - logger.trace(f"Increasing current_chain to {current_chain}") - - pdb_lines[i] = "TER\n" - continue - - # If we hit an ENDMDL statement, we are essentially providing another unique - # PDB structure. So we reset everything. - if line.startswith("ENDMDL"): - logger.debug("Encountered `ENDMDL`; resetting all ID information") - parse_structure = False - current_resid = None - current_chain = None - atom_id = 1 - - if line.startswith(("ATOM", "HETATM")): - # Handle initializing the chain information - chain_id = line[21] - if current_chain is None: - current_chain = chain_id - - # Activate coordinate parsing on first instance of ATOM or HETATM - if not parse_structure: - parse_structure = True - - # When we turn on parsing, this line contains the first atom - # information. This is where we can reset our - if not reset_initial_resid: - current_original_resid = str(parse_resid(line)).strip() - else: - current_original_resid = "1" - - # Write atom index. - line = write_atom_id(line, atom_id) - atom_id += 1 - - # Write residue index. - line, current_resid, current_original_resid = unify_resid( - line, current_resid, current_original_resid - ) - - # Write chain. - s_list = list(line) - s_list[21] = current_chain - line = "".join(s_list) - - # Update line - pdb_lines[i] = line - - if output_path is not None: - logger.info("Writing PDB file to {}", os.path.abspath(output_path)) - with open(output_path, "w+", encoding="utf-8") as f: - f.writelines(pdb_lines) - - return pdb_lines diff --git a/simlify/structure/pdb/numbering/residues.py b/simlify/structure/pdb/numbering/residues.py deleted file mode 100644 index f4855ff..0000000 --- a/simlify/structure/pdb/numbering/residues.py +++ /dev/null @@ -1,135 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -""" -Module for assigning and unifying residue identifiers in PDB file lines to ensure -consistent numbering. -""" - -from loguru import logger - -from simlify.structure.pdb.utils import parse_resid, replace_in_pdb_line - - -def assign_resid( - line: str, current_resid: str | None, prev_original_resid: str -) -> tuple[str, str]: - r"""Assigns a consistent residue ID based on the sequence of residues encountered. - - This function takes a PDB line, the currently assigned residue ID, and the original - residue ID from the previous line. It determines the residue ID for the current line - based on whether the original residue ID has changed. If it's the first residue - encountered (`current_resid` is None), it assigns the `prev_original_resid`. If the - current line's original residue ID is the same as the previous one, it retains the - `current_resid`. If the original residue ID has changed, it increments the - `current_resid`. - - Args: - line: The PDB line for which the residue ID is to be determined. - current_resid: The residue ID that has been assigned to the previous - residues. If this is the first residue, it will be `None`. - prev_original_resid : The original residue ID as parsed from the previous - PDB line. This is used to detect changes in the residue sequence. - - Returns: - A tuple containing: - - - The assigned residue ID for the current line, based on the consistent - numbering scheme. - - The original residue ID parsed from the current `line`, which will serve - as the `prev_original_resid` for the next line. - - Examples: - >>> line1 = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> line2 = "ATOM 2 CA MET A 1 11.000 21.000 31.000 1.00 20.00 C" - >>> line3 = "ATOM 3 C ALA A 2 12.000 22.000 32.000 1.00 20.00 C" - >>> assigned_id1, next_orig1 = assign_resid(line1, None, " 1") - >>> print(f"{assigned_id1=}, {next_orig1=}") - assigned_id1=' 1', next_orig1=' 1' - >>> assigned_id2, next_orig2 = assign_resid(line2, assigned_id1, next_orig1) - >>> print(f"{assigned_id2=}, {next_orig2=}") - assigned_id2=' 1', next_orig2=' 1' - >>> assigned_id3, next_orig3 = assign_resid(line3, assigned_id2, next_orig2) - >>> print(f"{assigned_id3=}, {next_orig3=}") - assigned_id3='2', next_orig3=' 2' - """ - next_original_resid = parse_resid(line).strip() - logger.trace("Parsed residue ID from line: {}", next_original_resid) - - # We have our first residue. - if current_resid is None: - logger.debug("Current residue ID is None; must be our first atom.") - assigned_resid = prev_original_resid - else: - # If the line's residue id is the same as the current original, then we should - # group this atom with the previous one. - assigned_resid = current_resid - if next_original_resid != prev_original_resid: - logger.trace("Parsed residue ID is not the same as previous.") - logger.trace("Previous residue ID: {}", assigned_resid) - assigned_resid = str(int(assigned_resid) + 1) - logger.trace("Assigning residue ID: {}", assign_resid) - return assigned_resid, next_original_resid - - -def unify_resid( - line: str, current_resid: str | None, prev_original_resid: str -) -> tuple[str, str, str]: - r"""Unifies the residue ID in a PDB line based on a consistent numbering scheme. - - This function takes a PDB line, the currently assigned residue ID, and the original - residue ID from the previous line. It calls the `assign_resid` function to determine - the unified residue ID for the current line and then replaces the original residue ID - in the PDB line with this new, unified ID. - - Args: - line: The PDB line to be modified. - current_resid: The residue ID that has been assigned to the previous - residues. If this is the first residue, it will be `None`. - prev_original_resid: The original residue ID as parsed from the previous - PDB line. - - Returns: - A tuple containing: - - The modified PDB line with the unified residue ID. - - The residue ID that was assigned to this atom. - - The original residue ID parsed from the input `line`, which should - be used as `prev_original_resid` for the next line. - - Examples: - >>> line1 = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> line2 = "ATOM 2 CA MET A 1 11.000 21.000 31.000 1.00 20.00 C" - >>> line3 = "ATOM 3 C ALA A 2 12.000 22.000 32.000 1.00 20.00 C" - >>> unified_line1, assigned_id1, next_orig1 = unify_resid(line1, None, " 1") - >>> print(unified_line1.strip()) - ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N - >>> unified_line2, assigned_id2, next_orig2 = unify_resid( - ... line2, assigned_id1, next_orig1 - ... ) - >>> print(unified_line2.strip()) - ATOM 2 CA MET A 1 11.000 21.000 31.000 1.00 20.00 C - >>> unified_line3, assigned_id3, next_orig3 = unify_resid( - ... line3, assigned_id2, next_orig2 - ... ) - >>> print(unified_line3.strip()) - ATOM 3 C ALA A 2 12.000 22.000 32.000 1.00 20.00 C - """ - assigned_resid, next_original_resid = assign_resid( - line, current_resid, prev_original_resid - ) - line_start = 21 - line_stop = 26 - new_line = replace_in_pdb_line( - line, - next_original_resid, - assigned_resid.rjust(line_stop - line_start), - line_start, - line_stop, - ) - return new_line, assigned_resid, next_original_resid diff --git a/simlify/structure/pdb/utils.py b/simlify/structure/pdb/utils.py deleted file mode 100644 index 42a4cf5..0000000 --- a/simlify/structure/pdb/utils.py +++ /dev/null @@ -1,595 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -import argparse -import os -from collections.abc import Iterable - -import MDAnalysis as mda -import numpy as np -from loguru import logger -from MDAnalysis import transformations as trans - - -def write_in_pdb_line(line: str, new: str, start: int | None, stop: int | None) -> str: - r"""General function to write a new string into a specific portion of a PDB line. - - This function takes a PDB line and replaces a segment of it with a provided new string. - It offers precise control over which part of the line is modified using start and stop indices. - - Args: - line: The original PDB line to be modified. - new: The new string to be inserted into the PDB line. This string should be - formatted to match the expected width of the replaced segment, including - any necessary spaces. For example, to represent the number 42 in a field - that typically occupies 5 characters, the `new` string should be `" 42"`. - start: The starting index (inclusive) of the slice in the `line` to be - replaced. If `None`, the replacement starts from the beginning of the line. - stop: The stopping index (exclusive) of the slice in the `line` to be - replaced. If `None`, the replacement continues to the end of the line. - - Returns: - The modified PDB line with the specified segment replaced by the `new` string. - - Examples: - >>> line = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> new_line = write_in_pdb_line(line, " 42", 6, 11) - >>> print(new_line) - ATOM 42 N MET A 1 10.000 20.000 30.000 1.00 20.00 N - """ - line = line[:start] + new + line[stop:] - return line - - -def replace_in_pdb_line( - line: str, orig: str, new: str, start: int | None, stop: int | None -) -> str: - r"""General function to replace an original string with a new string within a - specific portion of a PDB line. - - This function searches for a specific `orig` string within a defined slice of a - PDB line. If the `orig` string is found, it is replaced with the provided `new` - string. The replacement is constrained to the segment of the line specified by - the `start` and `stop` indices. - - Args: - line: The original PDB line to be examined and potentially modified. - orig: The original string to search for within the specified slice of the - `line`. - new: The new string to replace the `orig` string if it is found. This string - should be formatted to match the expected width of the replaced segment, - including any necessary spaces. For example, to represent the residue - number 42, the `new` string should be `" 42"` if the residue number - field occupies 5 characters. - start: The starting index (inclusive) of the slice in the `line` to be - searched and where the replacement will occur. If `None`, the search - and replacement start from the beginning of the line. - stop: The stopping index (exclusive) of the slice in the `line` to be - searched and where the replacement will occur. If `None`, the search - and replacement continue to the end of the line. - - Returns: - The modified PDB line where the `orig` string has been replaced by the - `new` string within the specified slice, or the original line if `orig` - was not found. - - Examples: - >>> line = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> new_line = replace_in_pdb_line(line, "MET", "ALA", 17, 20) - >>> print(new_line) - ATOM 1 N ALA A 1 10.000 20.000 30.000 1.00 20.00 N - """ - line_slice = line[start:stop] - logger.trace("Slice gives us: '{}'", line_slice) - if orig in line_slice: - line_slice = new - return line[:start] + line_slice + line[stop:] - - -def parse_resid(line: str) -> str: - r"""Extracts the residue ID from a standard PDB file line. - - This function assumes the input `line` adheres to the standard PDB format for ATOM - or HETATM records, where the residue ID is typically located in columns - 23-30 (inclusive). - - Args: - line: A line from a PDB file that starts with either "ATOM" or "HETATM". - - Returns: - The residue ID extracted from the line. This will typically include the residue - sequence number and optionally an insertion code. - - Raises: - IndexError: If the input `line` is shorter than 30 characters, accessing the - residue ID slice will result in an `IndexError`. - - Examples: - >>> line = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> resid = parse_resid(line) - >>> print(resid) - ' 1' - """ - return line[22:30] - - -def parse_resname(line: str) -> str: - r"""Extracts the residue name from a standard PDB file line. - - This function assumes the input `line` adheres to the standard PDB format for ATOM - or HETATM records, where the residue name is typically located in columns - 18-21 (inclusive). - - Args: - line: A line from a PDB file that starts with either "ATOM" or "HETATM". - - Returns: - The residue name (e.g., "MET", "ALA", "HOH") extracted from the line. - - Raises: - IndexError: If the input `line` is shorter than 21 characters, accessing the - residue name slice will result in an `IndexError`. - - Examples: - >>> line = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> resname = parse_resname(line) - >>> print(resname) - 'MET' - """ - return line[17:21] - - -def parse_atomname(line: str) -> str: - r"""Extracts the atom name from a standard PDB file line. - - This function assumes the input `line` adheres to the standard PDB format for ATOM - or HETATM records, where the atom name is typically located in columns 14-17 (inclusive). - - Args: - line: A line from a PDB file that starts with either "ATOM" or "HETATM". - - Returns: - The atom name (e.g., "N", "CA", "O") extracted from the line. - - Raises: - IndexError: If the input `line` is shorter than 17 characters, accessing the - atom name slice will result in an `IndexError`. - - Examples: - >>> line = "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N" - >>> atomname = parse_atomname(line) - >>> print(atomname) - 'N' - """ - return line[13:17] - - -def keep_lines( - lines: Iterable[str], - record_types: tuple[str, ...] = ("ATOM", "HETATM", "TER", "END", "MODEL", "ENDMDL"), -) -> list[str]: - r"""Filters a list of PDB file lines, retaining only those that start with specified - record types. - - This function iterates through a given iterable of strings, which are assumed to be - lines from a PDB file. It checks if each line begins with any of the record types - provided in the `record_types` tuple. Only the lines that match one of these record - types are included in the returned list. - - Args: - lines: An iterable (e.g., a list) of strings, where each string represents - a line from a PDB file. - record_types: A tuple of strings representing the PDB record types to be kept. - The default value is `("ATOM", "HETATM", "TER", "END", "MODEL", "ENDMDL")`, - which includes the most common record types. - - Returns: - A new list containing only the lines from the input `lines` that start with - one of the specified `record_types`. The order of the lines in the output - list will be the same as in the input. - - Examples: - >>> pdb_lines = [ - ... "HEADER TITLE 04-APR-25 NONE", - ... "ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N", - ... "HELIX 1 1 MET A 1 THR A 4 1 4", - ... "HETATM 999 O HOH 1 15.000 25.000 35.000 1.00 20.00 O", - ... "TER 1 MET A 1", - ... "END", - ... ] - >>> kept_lines = keep_lines( - ... pdb_lines, record_types=("ATOM", "HETATM", "TER", "END") - ... ) - >>> for line in kept_lines: - ... print(line.strip()) - ATOM 1 N MET A 1 10.000 20.000 30.000 1.00 20.00 N - HETATM 999 O HOH 1 15.000 25.000 35.000 1.00 20.00 O - TER 1 MET A 1 - END - """ - logger.info("Keeping the following record types: {}", ", ".join(record_types)) - return [line for line in lines if line.startswith(record_types)] - - -def run_filter_pdb( - pdb_path: str, - output_path: str | None = None, - record_types: tuple[str, ...] | None = None, -) -> list[str]: - r"""Reads a PDB file and keeps only the lines that contain specified record types. - - This function takes the path to a PDB file, reads its contents, filters the lines - to retain only those that start with the record types specified in the - `record_types` argument, and optionally writes the filtered lines to a new PDB file. - - Args: - pdb_path: The path to the input PDB file. - output_path: The path to the output PDB file where the filtered lines will be - written. If `None`, no new file is created, and the filtered lines are - only returned. - record_types: A tuple of strings representing the PDB record types to be kept. - If `None`, the default record types - `("ATOM", "HETATM", "TER", "END", "MODEL", "ENDMDL")` are used. - - Returns: - A list of strings, where each string is a line from the PDB file that starts - with one of the specified `record_types`. - - Raises: - FileNotFoundError: If the `pdb_path` does not exist. - IOError: If there is an error reading or writing the PDB files. - - Examples: - To filter a PDB file named "input.pdb" and save the result to "output.pdb", - keeping only ATOM and TER records: - - >>> run_filter_pdb("input.pdb", "output.pdb", record_types=("ATOM", "TER")) - - To filter a PDB file and only get the lines without writing to a new file: - - >>> filtered_lines = run_filter_pdb( - ... "input.pdb", record_types=("ATOM", "HETATM") - ... ) - >>> for line in filtered_lines: - ... print(line.strip()) - """ - logger.info("Filtering PDB lines of {}", os.path.abspath(pdb_path)) - with open(pdb_path, "r", encoding="utf-8") as f: - pdb_lines: list[str] = f.readlines() - - if record_types is None: - record_types = ("ATOM", "HETATM", "TER", "END", "MODEL", "ENDMDL") - out_lines = keep_lines(pdb_lines, record_types) - - if output_path is not None: - logger.info("Writing PDB file to {}", os.path.abspath(output_path)) - with open(output_path, "w+", encoding="utf-8") as f: - f.writelines(out_lines) - - return out_lines - - -def run_merge_pdbs(*pdb_paths: str, output_path: str | None = None) -> mda.Universe: - r"""Merges multiple PDB files into a single MDAnalysis Universe object. - - This function takes a variable number of PDB file paths as input. It loads the - first PDB file into an MDAnalysis Universe object and then iteratively adds the - atoms from the subsequent PDB files. It assumes that the residue indices are - consistent across all input PDB files. The merging process attempts to add missing - atom types to existing residues based on the information in the later PDB files. - Duplicate atoms (based on their coordinates) are removed, and the atoms within each - residue are sorted by their type. Finally, some topology attributes - that might interfere with other programs are removed. - - Args: - *pdb_paths: A variable number of strings, where each string is the path to a PDB - file. The order of the paths is important, as the first PDB file sets the - initial structure, and subsequent files are used to add missing atoms. - output_path: The path to save the merged PDB structure to a new - file. If `None`, no file is written. - - Returns: - An MDAnalysis Universe object containing all the atoms from the input PDB - files, with duplicate atoms removed and atoms within each residue sorted. - - Raises: - FileNotFoundError: If any of the provided `pdb_paths` do not exist. - IOError: If there is an error reading any of the PDB files. - - Notes: - - This function prioritizes the atom information from the PDB files provided - later in the argument list when resolving missing atom types within a - residue. - - The function removes the "segids" topology attribute from the merged - Universe, as it can sometimes cause issues with programs like pdb4amber. - - Examples: - To merge two PDB files, "file1.pdb" and "file2.pdb", and save the result to - "merged.pdb": - - >>> merged_universe = run_merge_pdbs( - ... "file1.pdb", "file2.pdb", output_path="merged.pdb" - ... ) - - To merge multiple PDB files without saving to a new file: - - >>> merged_universe = run_merge_pdbs("file1.pdb", "file2.pdb", "file3.pdb") - """ - logger.info("Merging PDB files") - u = mda.Universe(pdb_paths[0]) - atoms_to_add = [mda.Universe(pdb_path).atoms for pdb_path in pdb_paths[1:]] - u_to_add = mda.core.universe.Merge(*atoms_to_add) - - for residue in u_to_add.residues: - logger.debug("Processing residue ID of {}", residue.resid) - available_types = {atom.name for atom in residue.atoms} - logger.trace("Available atom types: {}", available_types) - present_types = {atom.name for atom in u.select_atoms(f"resid {residue.resid}")} - logger.trace("Current atom types: {}", present_types) - missing_types = { - atype for atype in available_types if atype not in present_types - } - if len(missing_types) > 0: - logger.trace("Missing atom types: {}", missing_types) - add_atoms = [atom for atom in residue.atoms if atom.name in missing_types] - u = mda.core.universe.Merge(u.atoms, mda.AtomGroup(add_atoms)) - - # Get the indices of duplicate atoms - coordinates = u.atoms.positions - _, unique_indices = np.unique(coordinates, axis=0, return_index=True) - if len(unique_indices) < len(coordinates): - logger.info("Cleaning up duplicate atoms") - duplicate_indices = np.setdiff1d(np.arange(len(coordinates)), unique_indices) - u.atoms = u.atoms[ - np.isin(np.arange(len(coordinates)), duplicate_indices, invert=True) - ] - - # Group atoms by residue - residue_groups = u.atoms.groupby("resids") - u = mda.core.universe.Merge( - *[atoms.sort("types") for _, atoms in residue_groups.items()] - ) - - # Remove some Merge artifacts that messes with pdb4amber - u.del_TopologyAttr("segids") - - if output_path is not None: - logger.info("Writing merged PDB at {}", output_path) - u.atoms.write(output_path) - return u.atoms - - -def run_write_pdb( - file_paths: Iterable[str], - output_path: str, - selection_str: str | None = None, - stride: int = 1, -) -> None: - r"""Writes a PDB file from a set of topology and coordinate files, - potentially applying a selection and stride. - - This function takes a list of file paths that can be read by MDAnalysis to create - a Universe object. It then iterates through the trajectory of this Universe, - and at each time step (optionally with a specified stride), it writes the - coordinates of the selected atoms to a PDB file. - - Args: - file_paths: An iterable of strings, where each string is the path to a - topology or coordinate file that can be loaded by MDAnalysis - (e.g., a topology file like a PRMTOP or a coordinate file like a TRR, DCD, - or PDB). If multiple files are provided, the first is typically the - topology, and the rest are coordinate files. - output_path: The path to the output PDB file that will be created or - overwritten. - selection_str: An MDAnalysis selection string that specifies which atoms to - write to the PDB file. If `None`, all atoms in the current frame are - written. - stride: An integer specifying the stride for writing frames from the - trajectory. Only frames where the frame number modulo `stride` is 0 will - be written. A stride of 1 means every frame is written. Defaults to 1. - - Raises: - FileNotFoundError: If any of the files specified in `file_paths` do not exist. - IOError: If there is an error reading the input files or writing the output PDB file. - ValueError: If the `file_paths` iterable is empty. - - Examples: - To write all atoms from a TRR trajectory file "traj.trr" and topology file - "top.pdb" to a PDB file "output.pdb": - - >>> run_write_pdb(["top.pdb", "traj.trr"], "output.pdb") - - To write only the protein atoms with a stride of 10: - - >>> run_write_pdb( - ... ["top.pdb", "traj.dcd"], - ... "protein.pdb", - ... selection_str="protein", - ... stride=10, - ... ) - - To write all atoms from a single PDB file to another PDB file (effectively copying it): - - >>> run_write_pdb(["input.pdb"], "output.pdb") - """ - u = mda.Universe(*file_paths) - with mda.Writer(output_path, multiframe=True) as W: - for ts in u.trajectory: - if ts.frame % stride == 0: - if isinstance(selection_str, str): - atoms = u.select_atoms(selection_str) - else: - atoms = u.atoms - W.write(atoms) - - -def cli_write_pdb() -> None: - r"""Command-line interface for writing a PDB file from topology and coordinate - files. - - This function sets up an argument parser to allow users to write PDB files from - the command line. It takes arguments for the output path, input files, an optional - MDAnalysis selection string, and an optional stride for writing frames. - - The command-line usage is as follows: - - ```bash - python your_script_name.py output.pdb --files top.pdb traj.dcd --select "protein and name CA" --stride 10 - ``` - - This would write a PDB file named "output.pdb" containing only the alpha carbon - atoms of the protein from the trajectory "traj.dcd" (with topology in "top.pdb"), - taking every 10th frame. - - Raises: - SystemExit: If the command-line arguments are invalid or if help is requested. - - See Also: - `run_write_pdb`: The underlying function that performs the PDB writing. - """ - parser = argparse.ArgumentParser( - description="Write PDB from topology and coordinate files." - ) - parser.add_argument( - "output_path", - type=str, - nargs="?", - help="PDB file to write", - ) - parser.add_argument( - "--files", - type=str, - nargs="+", - help="Files to load into MDAnalysis universe.", - ) - parser.add_argument( - "--select", - type=str, - nargs="*", - help="Selection string for MDAnalysis universe.", - ) - parser.add_argument( - "--stride", - type=int, - nargs="?", - help="Stride of trajectory when writing.", - default=1, - ) - args = parser.parse_args() - if args.select is not None: - args.select = " ".join(args.select) - run_write_pdb(args.files, args.output_path, args.select, args.stride) - - -def run_align_pdb( - pdb_path: str, - out_path: str, - selection_str: str | None = None, -) -> None: - r"""Aligns the structure within a PDB file to a reference configuration based on a - selection of atoms. - - This function loads a PDB file into an MDAnalysis Universe, selects a subset of - atoms based on the `selection_str`, and then performs a rigid-body fit of these - atoms to their initial positions in the first frame of the trajectory. - The transformation (rotation and translation) that achieves this fit - is then applied to all atoms in all frames of the trajectory. The aligned - trajectory is then written to a new PDB file. - - Args: - pdb_path: The path to the input PDB file containing the structure to be aligned. - out_path: The path to the output PDB file where the aligned structure will be - written. - selection_str: An MDAnalysis selection string that specifies the group - of atoms to be used for the alignment. If `None`, all atoms in the - structure are used for alignment. - - Raises: - FileNotFoundError: If the input `pdb_path` does not exist. - IOError: If there is an error reading the input PDB file or writing the output - PDB file. - ValueError: If the `selection_str` does not select any atoms. - - Notes: - - The alignment is performed against the conformation in the first frame of - the input PDB file. - - This function is useful for removing overall translation and rotation from - a structural ensemble. - - Examples: - To align a PDB file "input.pdb" to its first frame using all atoms and save the - result to "aligned.pdb": - - >>> run_align_pdb("input.pdb", "aligned.pdb") - - To align only the backbone atoms (N, CA, C) of the protein: - - >>> run_align_pdb( - ... "input.pdb", - ... "aligned_backbone.pdb", - ... selection_str="protein and backbone", - ... ) - """ - u = mda.Universe(pdb_path) - ag = u.select_atoms(selection_str) - u_ref = u.copy() - ag_ref = u_ref.select_atoms(selection_str) - workflow = (trans.fit_rot_trans(ag, ag_ref),) - u.trajectory.add_transformations(*workflow) - with mda.Writer(out_path, multiframe=True) as W: - for ts in u.trajectory: - W.write(u.atoms) - - -def cli_align_pdb() -> None: - r"""Command-line interface for aligning a PDB file. - - This function sets up an argument parser to allow users to align PDB files from - the command line. It takes arguments for the input PDB path, the output PDB path, - and an optional MDAnalysis selection string to specify which atoms should be used - for the alignment. - - The command-line usage is as follows: - - ```bash - python your_script_name.py input.pdb aligned.pdb --selection "protein and name CA" - ``` - - This would align the PDB file "input.pdb" to its first frame based on the alpha - carbon atoms of the protein and save the aligned structure to "aligned.pdb". - - Raises: - SystemExit: If the command-line arguments are invalid or if help is requested. - - See Also: - `run_align_pdb`: The underlying function that performs the PDB alignment. - """ - parser = argparse.ArgumentParser(description="Align PDB file to some selection.") - parser.add_argument( - "pdb_path", - type=str, - nargs="?", - help="PDB file to load", - ) - parser.add_argument( - "out_path", - type=str, - nargs="?", - help="PDB file to write", - ) - parser.add_argument( - "--selection", - type=str, - nargs="*", - help="Selection string for MDAnalysis universe.", - ) - args = parser.parse_args() - if args.selection is not None: - args.selection = " ".join(args.selection) - run_align_pdb(args.pdb_path, args.out_path, args.selection) diff --git a/simlify/structure/pos.py b/simlify/structure/pos.py deleted file mode 100644 index 29cd1d1..0000000 --- a/simlify/structure/pos.py +++ /dev/null @@ -1,87 +0,0 @@ -# This file is licensed under the Prosperity Public License 3.0.0. -# You may use, copy, and share it for noncommercial purposes. -# Commercial use is allowed for a 30-day trial only. -# -# Contributor: Scientific Computing Studio -# Source Code: https://github.com/scienting/simlify -# -# See the LICENSE.md file for full license terms. - -""" -Provides functions for interacting with the positions of atoms in molecular structures. - -This module offers utilities for analyzing and manipulating the spatial coordinates -of atoms within an MDAnalysis Universe. Currently, it includes functionality to -calculate the center of mass of a selected group of atoms. -""" - -import MDAnalysis as mda -import numpy as np -import numpy.typing as npt -from loguru import logger - - -def get_com(atoms: mda.AtomGroup) -> npt.NDArray[np.float64]: - r"""Compute the center of mass for a group of atoms. - - The center of mass (COM) is the average position of all the parts of the - system, weighted by their masses. For a collection of atoms, it is calculated - as the weighted average of their coordinates, where the weights are the masses - of the atoms. This function leverages the built-in center of mass calculation - provided by MDAnalysis for an `AtomGroup`. - - Args: - atoms: An MDAnalysis `AtomGroup` object representing the selection of - atoms for which the center of mass needs to be computed. This object - contains information about the atoms, including their positions and - masses (if available in the topology). - - Returns: - A NumPy array of shape (3,) containing the x, y, and z coordinates of - the center of mass of the provided `AtomGroup`. The units of these - coordinates will be the same as the units of the atomic coordinates - within the MDAnalysis Universe (typically Angstroms). - - Examples: - Calculating the center of mass of all atoms in a loaded structure: - - ```python - import MDAnalysis as mda - from simlify.structure.io import load_mda - from simlify.structure.pos import get_com - - # Load a molecular structure - try: - universe = load_mda("protein.pdb") - all_atoms = universe.atoms - - # Calculate the center of mass of all atoms - center_of_mass = get_com(all_atoms) - print(f"Center of mass of all atoms: {center_of_mass}") - except FileNotFoundError as e: - print(f"Error: {e}") - ``` - - Calculating the center of mass of a specific selection of atoms (e.g., protein): - - ```python - import MDAnalysis as mda - from simlify.structure.io import load_mda - from simlify.structure.pos import get_com - - # Load a molecular structure - try: - universe = load_mda("complex.gro", "traj.xtc") - protein = universe.select_atoms("protein") - - # Calculate the center of mass of the protein atoms - protein_com = get_com(protein) - print(f"Center of mass of the protein: {protein_com}") - except FileNotFoundError as e: - print(f"Error: {e}") - ``` - """ - logger.info("Computing center of mass (com)") - com: npt.NDArray[np.float64] = atoms.center_of_mass() - logger.debug("center of mass: {}", com) - return com diff --git a/simlify/tasks/__init__.py b/simlify/tasks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/tasks/align/__init__.py b/simlify/tasks/align/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/tasks/align/mda.py b/simlify/tasks/align/mda.py new file mode 100644 index 0000000..bf06c8d --- /dev/null +++ b/simlify/tasks/align/mda.py @@ -0,0 +1,112 @@ +import argparse + +import MDAnalysis as mda +from MDAnalysis import transformations as trans + + +def run_align_pdb( + pdb_path: str, + out_path: str, + selection_str: str | None = None, +) -> None: + r"""Aligns the structure within a PDB file to a reference configuration based on a + selection of atoms. + + This function loads a PDB file into an MDAnalysis Universe, selects a subset of + atoms based on the `selection_str`, and then performs a rigid-body fit of these + atoms to their initial positions in the first frame of the trajectory. + The transformation (rotation and translation) that achieves this fit + is then applied to all atoms in all frames of the trajectory. The aligned + trajectory is then written to a new PDB file. + + Args: + pdb_path: The path to the input PDB file containing the structure to be aligned. + out_path: The path to the output PDB file where the aligned structure will be + written. + selection_str: An MDAnalysis selection string that specifies the group + of atoms to be used for the alignment. If `None`, all atoms in the + structure are used for alignment. + + Raises: + FileNotFoundError: If the input `pdb_path` does not exist. + IOError: If there is an error reading the input PDB file or writing the output + PDB file. + ValueError: If the `selection_str` does not select any atoms. + + Notes: + - The alignment is performed against the conformation in the first frame of + the input PDB file. + - This function is useful for removing overall translation and rotation from + a structural ensemble. + + Examples: + To align a PDB file "input.pdb" to its first frame using all atoms and save the + result to "aligned.pdb": + + >>> run_align_pdb("input.pdb", "aligned.pdb") + + To align only the backbone atoms (N, CA, C) of the protein: + + >>> run_align_pdb( + ... "input.pdb", + ... "aligned_backbone.pdb", + ... selection_str="protein and backbone", + ... ) + """ + u = mda.Universe(pdb_path) + ag = u.select_atoms(selection_str) + u_ref = u.copy() + ag_ref = u_ref.select_atoms(selection_str) + workflow = (trans.fit_rot_trans(ag, ag_ref),) + u.trajectory.add_transformations(*workflow) + with mda.Writer(out_path, multiframe=True) as W: + for ts in u.trajectory: + W.write(u.atoms) + + +def cli_align_pdb() -> None: + r"""Command-line interface for aligning a PDB file. + + This function sets up an argument parser to allow users to align PDB files from + the command line. It takes arguments for the input PDB path, the output PDB path, + and an optional MDAnalysis selection string to specify which atoms should be used + for the alignment. + + The command-line usage is as follows: + + ```bash + python your_script_name.py input.pdb aligned.pdb --selection "protein and name CA" + ``` + + This would align the PDB file "input.pdb" to its first frame based on the alpha + carbon atoms of the protein and save the aligned structure to "aligned.pdb". + + Raises: + SystemExit: If the command-line arguments are invalid or if help is requested. + + See Also: + `run_align_pdb`: The underlying function that performs the PDB alignment. + """ + parser = argparse.ArgumentParser(description="Align PDB file to some selection.") + parser.add_argument( + "pdb_path", + type=str, + nargs="?", + help="PDB file to load", + ) + parser.add_argument( + "out_path", + type=str, + nargs="?", + help="PDB file to write", + ) + parser.add_argument( + "--selection", + type=str, + nargs="*", + help="Selection string for MDAnalysis universe.", + ) + args = parser.parse_args() + if args.selection is not None: + args.selection = " ".join(args.selection) + run_align_pdb(args.pdb_path, args.out_path, args.selection) diff --git a/simlify/tasks/conformer/__init__.py b/simlify/tasks/conformer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/tasks/io/__init__.py b/simlify/tasks/io/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/structure/io.py b/simlify/tasks/io/mda.py similarity index 100% rename from simlify/structure/io.py rename to simlify/tasks/io/mda.py diff --git a/simlify/tasks/ionize/__init__.py b/simlify/tasks/ionize/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/tasks/rendering/__init__.py b/simlify/tasks/rendering/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/simulation/slurm.py b/simlify/tasks/rendering/slurm.py similarity index 85% rename from simlify/simulation/slurm.py rename to simlify/tasks/rendering/slurm.py index 612617a..4896ba2 100644 --- a/simlify/simulation/slurm.py +++ b/simlify/tasks/rendering/slurm.py @@ -11,7 +11,7 @@ import os -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig def run_slurm_prep( @@ -45,16 +45,19 @@ def run_slurm_prep( SLURM submission script. Examples: - To prepare SLURM files for a simulation in the directory "my_simulation" and - write the submission script to "submit.sh": + To prepare SLURM files for a simulation in the directory `my_simulation` and + write the submission script to `submit.sh`: - >>> from simlify import SimlifyConfig - >>> config = SimlifyConfig() - >>> run_slurm_prep( - ... dir_work="my_simulation", - ... path_slurm_write="submit.sh", - ... simlify_config=config, - ... ) + ```python + from simlify.configs import SimlifyConfig + + config = SimlifyConfig() + run_slurm_prep( + dir_work="my_simulation", + path_slurm_write="submit.sh", + simlify_config=config, + ) + ``` """ os.makedirs(dir_work, exist_ok=True) diff --git a/simlify/tasks/rotate/__init__.py b/simlify/tasks/rotate/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/structure/pdb/orientation.py b/simlify/tasks/rotate/orientation.py similarity index 100% rename from simlify/structure/pdb/orientation.py rename to simlify/tasks/rotate/orientation.py diff --git a/simlify/tasks/slice/__init__.py b/simlify/tasks/slice/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/structure/extract.py b/simlify/tasks/slice/extract.py similarity index 97% rename from simlify/structure/extract.py rename to simlify/tasks/slice/extract.py index 5956475..eb41707 100644 --- a/simlify/structure/extract.py +++ b/simlify/tasks/slice/extract.py @@ -64,7 +64,7 @@ def extract_atoms( "Both selection and frames are None. No changes to the structure(s) will be made." ) - u = load_mda(path_topo, path_coords, **kwargs_universe) + u: mda.Universe = load_mda(path_topo, path_coords, **kwargs_universe) if select: logger.info(f"Making selection: {select}") diff --git a/simlify/tasks/solvent/__init__.py b/simlify/tasks/solvent/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/structure/solvent.py b/simlify/tasks/solvent/ions.py similarity index 95% rename from simlify/structure/solvent.py rename to simlify/tasks/solvent/ions.py index 8cbda17..74031b7 100644 --- a/simlify/structure/solvent.py +++ b/simlify/tasks/solvent/ions.py @@ -13,7 +13,7 @@ from loguru import logger -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig def get_ion_counts( @@ -74,7 +74,7 @@ def get_ion_counts( ionic strength: ```python - from simlify import SimlifyConfig + from simlify.configs import SimlifyConfig from simlify.solvate.ions import get_ion_counts # Create a SimlifyConfig instance @@ -99,7 +99,7 @@ def get_ion_counts( neutralization: ```python - from simlify import SimlifyConfig + from simlify.configs import SimlifyConfig from simlify.solvate.ions import get_ion_counts # Create a SimlifyConfig instance with charge neutralization disabled @@ -123,7 +123,7 @@ def get_ion_counts( Calculating ion counts for a neutral system with a specific ionic strength: ```python - from simlify import SimlifyConfig + from simlify.configs import SimlifyConfig from simlify.solvate.ions import get_ion_counts # Create a SimlifyConfig instance for a neutral system @@ -150,12 +150,12 @@ def get_ion_counts( water_box_volume /= 1e27 # L n_ions = simlify_config.solution.solvent_ionic_strength * water_box_volume # moles n_ions *= 6.0221409e23 # atoms - extra_ions = int(round(n_ions, 0)) - ions = { + extra_ions: int = int(round(n_ions, 0)) + ions: dict[str, int] = { "charge_cation_num": simlify_config.solution.charge_cation_extra, "charge_anion_num": simlify_config.solution.charge_anion_extra, } - ions = {k: v + extra_ions for k, v in ions.items()} + ions: dict[str, int] = {k: v + extra_ions for k, v in ions.items()} if simlify_config.solution.charge_neutralize: if charge_net < 0: ions["charge_cation_num"] += abs(int(charge_net)) diff --git a/simlify/tasks/topology/__init__.py b/simlify/tasks/topology/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/tasks/topology/amber/__init__.py b/simlify/tasks/topology/amber/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/simulation/amber/topo.py b/simlify/tasks/topology/amber/core.py similarity index 99% rename from simlify/simulation/amber/topo.py rename to simlify/tasks/topology/amber/core.py index 3e7be67..02bf880 100644 --- a/simlify/simulation/amber/topo.py +++ b/simlify/tasks/topology/amber/core.py @@ -26,7 +26,7 @@ from loguru import logger -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig from simlify.simulation.topo import TopoGen from simlify.structure.solvent import get_ion_counts from simlify.utils import simple_generator @@ -81,7 +81,7 @@ def ff_lines(cls, simlify_config: SimlifyConfig) -> Iterable[str]: command to load a specific force field. Examples: - >>> from simlify import SimlifyConfig + >>> from simlify.configs import SimlifyConfig >>> config = SimlifyConfig( ... engine={ ... "ff": { diff --git a/simlify/simulation/topo.py b/simlify/tasks/topology/core.py similarity index 88% rename from simlify/simulation/topo.py rename to simlify/tasks/topology/core.py index dfb26ed..fc787aa 100644 --- a/simlify/simulation/topo.py +++ b/simlify/tasks/topology/core.py @@ -13,8 +13,7 @@ from abc import ABC, abstractmethod -from simlify import SimlifyConfig -from simlify.utils import get_obj_from_string +from simlify.configs import SimlifyConfig class TopoGen(ABC): @@ -105,7 +104,6 @@ def run( def run_gen_topo( path_structure: str, - import_string: str, simlify_config: SimlifyConfig, ) -> dict[str, Any]: """Driver function to instantiate and run a topology generator. @@ -118,11 +116,6 @@ def run_gen_topo( Args: path_structure: The file path to the molecular structure file for which the topology will be generated. - import_string: A string representing the import path to the topology - generator class. This string should be in the format that can be used by - `simlify.utils.get_obj_from_string` (e.g., `"module.submodule.ClassName"`). - For example, to use the Amber topology generator, the import string might be - `"simlify.simulation.amber.topo.AmberTopoGen"`. simlify_config: An instance of the Simlify configuration object. Returns: @@ -142,24 +135,20 @@ def run_gen_topo( To generate an Amber topology for the structure file "input.pdb" using the `AmberTopoGen` class: - >>> from simlify import SimlifyConfig + >>> from simlify.configs import SimlifyConfig >>> config = SimlifyConfig() >>> topo_info = run_gen_topo( ... path_structure="input.pdb", - ... import_string="simlify.simulation.amber.topo.AmberTopoGen", ... simlify_config=config, ... ) >>> print(topo_info) {'topology_file': '/path/to/input.prmtop', 'coordinate_file': '/path/to/input.inpcrd'} """ - - cls_topo = get_obj_from_string(import_string) - - topo_info_dry_run: dict[str, Any] = cls_topo.dry_run( # type: ignore + topo_info_dry_run: dict[str, Any] = simlify_config.engine.dry_run( # type: ignore path_structure, simlify_config, ) - topo_info: dict[str, Any] = cls_topo.run( # type: ignore + topo_info: dict[str, Any] = simlify_config.engine.run( # type: ignore path_structure, simlify_config, **topo_info_dry_run, diff --git a/simlify/tasks/translate/__init__.py b/simlify/tasks/translate/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/structure/center.py b/simlify/tasks/translate/center.py similarity index 100% rename from simlify/structure/center.py rename to simlify/tasks/translate/center.py diff --git a/simlify/workflows/__init__.py b/simlify/workflows/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/workflows/amber/__init__.py b/simlify/workflows/amber/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simlify/simulation/amber/prep.py b/simlify/workflows/amber/prep.py similarity index 99% rename from simlify/simulation/amber/prep.py rename to simlify/workflows/amber/prep.py index 6dd3eab..f8d9b9a 100644 --- a/simlify/simulation/amber/prep.py +++ b/simlify/workflows/amber/prep.py @@ -11,7 +11,7 @@ from loguru import logger -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig from simlify.simulation.prep import SimPrep @@ -235,7 +235,7 @@ def prepare_stage( method. """ if run_commands is None or len(run_commands) == 0: - run_commands = ["#!/usr/bin/env bash"] + run_commands: list[str] = ["#!/usr/bin/env bash"] # We do not want to change source context in prepare_sim_config, so we do this # here. diff --git a/simlify/simulation/prep.py b/simlify/workflows/prep.py similarity index 98% rename from simlify/simulation/prep.py rename to simlify/workflows/prep.py index de13e1b..7317745 100644 --- a/simlify/simulation/prep.py +++ b/simlify/workflows/prep.py @@ -19,7 +19,7 @@ from loguru import logger -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig class SimPrep(ABC): @@ -72,7 +72,6 @@ def prepare_sim_config( NotImplementedError: If this abstract method is called directly. Subclasses must provide their own implementation. """ - raise NotImplementedError @classmethod @abstractmethod @@ -102,7 +101,6 @@ def get_stage_input_lines( NotImplementedError: If this abstract method is called directly. Subclasses must provide their own implementation. """ - raise NotImplementedError @classmethod def prepare_slurm( @@ -186,7 +184,6 @@ def get_stage_run_command( has been called prior to this method to ensure that the `simlify_config` object is properly prepared. """ - raise NotImplementedError @classmethod @abstractmethod @@ -226,7 +223,6 @@ def prepare_stage( NotImplementedError: If this abstract method is called directly. Subclasses must provide their own implementation. """ - raise NotImplementedError @classmethod @abstractmethod @@ -246,4 +242,3 @@ def prepare(cls, simlify_config: SimlifyConfig, **kwargs: Any) -> None: If this abstract method is called directly. Subclasses must provide their own implementation. """ - raise NotImplementedError diff --git a/tests/conftest.py b/tests/conftest.py index 3f542af..eee1885 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,13 +13,14 @@ import pytest -from simlify import SimlifyConfig, enable_logging -from simlify.schemas.amber import Amber22Schema +from simlify import enable_logging +from simlify.configs import SimlifyConfig +from simlify.configs.amber import Amber22Config from simlify.structure.io import load_mda -TEST_DIR = os.path.dirname(__file__) -TMP_DIR = os.path.join(TEST_DIR, "tmp") -FILE_DIR = os.path.join(TEST_DIR, "files") +TEST_DIR: str = os.path.dirname(__file__) +TMP_DIR: str = os.path.join(TEST_DIR, "tmp") +FILE_DIR: str = os.path.join(TEST_DIR, "files") @pytest.fixture @@ -64,7 +65,7 @@ def path_cro_lib(): @pytest.fixture def amber_sim_standard_config(): simlify_config = SimlifyConfig() - simlify_config.engine = Amber22Schema() + simlify_config.engine = Amber22Config() simlify_config.label = "01_min" simlify_config.run.dir_work = os.path.join(TEST_DIR, "tmp") simlify_config.engine.cli.compute_platform = "pmemd.MPI" diff --git a/tests/simulation/test_amber_prep.py b/tests/simulation/test_amber_prep.py index ff5f57e..401bf70 100644 --- a/tests/simulation/test_amber_prep.py +++ b/tests/simulation/test_amber_prep.py @@ -58,9 +58,12 @@ def test_1jc0_with_cro( f"loadOff {path_cro_lib}", ] + amber_sim_standard_config.update( + {"import": {"engine": "simlify.simulation.amber.topo.AmberTopoGen"}} + ) + run_gen_topo( path_1jc0_prepped, - "simlify.simulation.amber.topo.AmberTopoGen", amber_sim_standard_config, ) diff --git a/tests/simulation/test_render_amber.py b/tests/simulation/test_render_amber.py index 103af40..a3daaf0 100644 --- a/tests/simulation/test_render_amber.py +++ b/tests/simulation/test_render_amber.py @@ -11,19 +11,19 @@ from conftest import TMP_DIR -from simlify.schemas.amber import Amber22CLI, Amber22Schema +from simlify.configs.amber import Amber22CLI, Amber22Config def test_render_amber_to_yaml(): - schema_amber = Amber22Schema() + config_amber = Amber22Config() yaml_path = os.path.join(TMP_DIR, "amber22.yml") - schema_amber.to_yaml(yaml_path) + config_amber.to_yaml(yaml_path) def test_render_amber_write_input(): - schema_amber = Amber22Schema() + config_amber = Amber22Config() input_path = os.path.join(TMP_DIR, "amber22.in") - schema_amber.inputs.write_render(input_path) + config_amber.inputs.write_render(input_path) def test_render_amber_cli(): diff --git a/tests/simulation/test_render_slurm.py b/tests/simulation/test_render_slurm.py index 68c84c9..248c53a 100644 --- a/tests/simulation/test_render_slurm.py +++ b/tests/simulation/test_render_slurm.py @@ -11,10 +11,10 @@ from conftest import TMP_DIR -from simlify.schemas.slurm import SlurmSchema +from simlify.configs.slurm import SlurmConfig def test_render_slurm(): - slurm_schema = SlurmSchema() + slurm_config = SlurmConfig() write_path = os.path.join(TMP_DIR, "job.slurm") - slurm_schema.write_render(write_path) + slurm_config.write_render(write_path) diff --git a/tests/simulation/test_slurm.py b/tests/simulation/test_slurm.py index e37bf82..7ef4ede 100644 --- a/tests/simulation/test_slurm.py +++ b/tests/simulation/test_slurm.py @@ -9,7 +9,7 @@ import os -from simlify import SimlifyConfig +from simlify.configs import SimlifyConfig from simlify.simulation.slurm import run_slurm_prep