zntrack

Create, visualize, run & benchmark DVC pipelines in Python & Jupyter notebooks.

https://github.com/zincware/zntrack

Science Score: 54.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
    Links to: arxiv.org
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (14.9%) to scientific vocabulary

Keywords

data-science data-version-control developer-tools dvc git machine-learning python reproducibility

Keywords from Contributors

energy-system-model particles molecular-dynamics-simulation mesh optimizer parallel yolov5s interpretability pipeline-testing datacleaner
Last synced: 4 months ago · JSON representation ·

Repository

Create, visualize, run & benchmark DVC pipelines in Python & Jupyter notebooks.

Basic Info
Statistics
  • Stars: 53
  • Watchers: 4
  • Forks: 4
  • Open Issues: 127
  • Releases: 44
Topics
data-science data-version-control developer-tools dvc git machine-learning python reproducibility
Created over 4 years ago · Last pushed 4 months ago
Metadata Files
Readme Contributing Funding License Citation

README.md

codecov PyTest PyPI version code-style Documentation Binder DOI ZnTrack zincware Discord

Logo

ZnTrack: Make Your Python Code Reproducible!

ZnTrack (zɪŋk træk) is a lightweight and easy-to-use Python package for converting your existing Python code into reproducible workflows. By structuring your code as a directed graph with well-defined inputs and outputs, ZnTrack ensures reproducibility, scalability, and ease of collaboration.

Key Features

  • Reproducible Workflows: Convert Python scripts into reproducible workflows with minimal effort.
  • Parameter, Output, and Metric Tracking: Easily track parameters, outputs, and metrics in your Python code.
  • Shareable and Collaborative: Collaborate with your team by working together through GIT. Share your workflows and use parts in other projects or package them as Python packages.
  • DVC Integration: ZnTrack is built on top of DVC for version control and experiment management and seamlessly integrates into the DVC ecosystem.

Example: Molecular Dynamics Workflow

Let’s take a workflow that constructs a periodic, atomistic system of Ethanol and runs a geometry optimization using MACE-MP-0.

Original Workflow

```python from ase.optimize import LBFGS from mace.calculators import mace_mp from rdkit2ase import pack, smiles2conformers

model = mace_mp()

frames = smiles2conformers(smiles="CCO", numConfs=32) box = pack(data=[frames], counts=[32], density=789)

box.calc = model

dyn = LBFGS(box, trajectory="optim.traj") dyn.run(fmax=0.5) ```

Dependencies For this example to work, you will need:
  • https://github.com/ACEsuit/mace
  • https://github.com/m3g/packmol
  • https://github.com/zincware/rdkit2ase

Converted Workflow with ZnTrack

To make this workflow reproducible, we convert it into a directed graph structure where each step is represented as a Node. Nodes define their inputs, outputs, and the computational logic to execute. Here's the graph structure for our example:

```mermaid flowchart LR

Smiles2Conformers --> Pack --> StructureOptimization MACE_MP --> StructureOptimization ```

Node Definitions

In ZnTrack, each Node is defined as a Python class. The class attributes define the inputs (parameters and dependencies) and outputs, while the run method contains the computational logic to be executed.

[!NOTE] ZnTrack uses Python dataclasses under the hood, providing an automatic __init__ method. Starting from Python 3.11, most IDEs should reliably provide type hints for ZnTrack Nodes.

[!TIP] For files produced during the run method, ZnTrack provides a unique Node Working Directory (zntrack.nwd). Always use this directory to store files to ensure reproducibility and avoid conflicts.

```python from dataclasses import dataclass from pathlib import Path

import ase.io from ase.optimize import LBFGS from mace.calculators import mace_mp from rdkit2ase import pack, smiles2conformers

import zntrack

class Smiles2Conformers(zntrack.Node): smiles: str = zntrack.params() # A required parameter numConfs: int = zntrack.params(32) # A parameter with a default value

frames_path: Path = zntrack.outs_path(zntrack.nwd / "frames.xyz")  # Output file path

def run(self) -> None:
    frames = smiles2conformers(smiles=self.smiles, numConfs=self.numConfs)
    ase.io.write(self.frames_path, frames)

@property
def frames(self) -> list[ase.Atoms]:
    # Load the frames from the output file using the node's filesystem
    with self.state.fs.open(self.frames_path, "r") as f:
        return list(ase.io.iread(f, ":", format="extxyz"))

class Pack(zntrack.Node): data: list[list[ase.Atoms]] = zntrack.deps() # Input dependency (list of ASE Atoms) counts: list[int] = zntrack.params() # Parameter (list of counts) density: float = zntrack.params() # Parameter (density value)

frames_path: Path = zntrack.outs_path(zntrack.nwd / "frames.xyz")  # Output file path

def run(self) -> None:
    box = pack(data=self.data, counts=self.counts, density=self.density)
    ase.io.write(self.frames_path, box)

@property
def frames(self) -> list[ase.Atoms]:
    # Load the packed structure from the output file
    with self.state.fs.open(self.frames_path, "r") as f:
        return list(ase.io.iread(f, ":", format="extxyz"))

We could hardcode the MACE_MP model into the StructureOptimization Node, but we

can also define it as a dependency. Since the model doesn't require a run method,

we define it as a @dataclass.

@dataclass class MACE_MP: model: str = "medium" # Default model type

def get_calculator(self, **kwargs):
    return mace_mp(model=self.model)

class StructureOptimization(zntrack.Node): model: MACEMP = zntrack.deps() # Dependency (MACEMP model) data: list[ase.Atoms] = zntrack.deps() # Dependency (list of ASE Atoms) data_id: int = zntrack.params() # Parameter (index of the structure to optimize) fmax: float = zntrack.params(0.05) # Parameter (force convergence threshold)

frames_path: Path = zntrack.outs_path(zntrack.nwd / "frames.traj")  # Output file path

def run(self):
    atoms = self.data[self.data_id]
    atoms.calc = self.model.get_calculator()
    dyn = LBFGS(atoms, trajectory=self.frames_path.as_posix())
    dyn.run(fmax=0.5)

@property
def frames(self) -> list[ase.Atoms]:
    # Load the optimization trajectory from the output file
    with self.state.fs.open(self.frames_path, "rb") as f:
        return list(ase.io.iread(f, ":", format="traj"))

```

Building and Running the Workflow

Now that we’ve defined all the necessary Nodes, we can build and execute the workflow. Follow these steps:

  1. Initialize a new directory for your project:

bash git init dvc init

  1. Create a Python module for the Node definitions:
  • Create a file src/__init__.py and place the Node definitions inside it.
  1. Define and execute the workflow in a main.py file:

```python from src import MACE_MP, Pack, Smiles2Conformers, StructureOptimization

import zntrack

# Initialize the ZnTrack project
project = zntrack.Project()

# Define the MACE-MP model
model = MACE_MP()

# Build the workflow graph
with project:
    etoh = Smiles2Conformers(smiles="CCO", numConfs=32)
    box = Pack(data=[etoh.frames], counts=[32], density=789)
    optm = StructureOptimization(model=model, data=box.frames, data_id=-1, fmax=0.5)

# Execute the workflow
project.repro()

```

[!TIP] If you don’t want to execute the graph immediately, use project.build() instead. You can run the graph later using dvc repro or the paraffin package.

Accessing Results

Once the workflow has been executed, the results are stored in the respective files. For example, the optimized trajectory is saved in nodes/StructureOptimization/frames.traj.

You can load the results directly using ZnTrack, without worrying about file paths or formats:

```python import zntrack

Load the StructureOptimization Node

optm = zntrack.from_rev(name="StructureOptimization")

you can pass remote: str and rev: str to access data from

a different commit or a remote repository.

Access the optimization trajectory

print(optm.frames) ```


More Examples

For additional examples and advanced use cases, check out these packages built on top of ZnTrack:

  • mlipx - Machine Learned Interatomic Potential eXploration.
  • IPSuite - Machine Learned Interatomic Potential Tools.

References

If you use ZnTrack in your research, please cite us:

bibtex @misc{zillsZnTrackDataCode2024, title = {{{ZnTrack}} -- {{Data}} as {{Code}}}, author = {Zills, Fabian and Sch{\"a}fer, Moritz and Tovey, Samuel and K{\"a}stner, Johannes and Holm, Christian}, year = {2024}, eprint={2401.10603}, archivePrefix={arXiv}, }


Copyright

This project is distributed under the Apache License Version 2.0.


Similar Tools

Here’s a list of other projects that either work together with ZnTrack or achieve similar results with slightly different goals or programming languages:

  • DVC - Main dependency of ZnTrack for Data Version Control.
  • dvthis - Introduce DVC to R.
  • DAGsHub Client - Logging parameters from within Python.
  • MLFlow - A Machine Learning Lifecycle Platform.
  • Metaflow - A framework for real-life data science.
  • Hydra - A framework for elegantly configuring complex applications.
  • Snakemake - Workflow management system for reproducible and scalable data analyses.

Owner

  • Name: Zincware
  • Login: zincware
  • Kind: organization
  • Email: zincwarecode@gmail.com
  • Location: Germany

Open source software organisation hosting software built for computational physics and chemistry.

Citation (CITATION.cff)

# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!

cff-version: 1.2.0
title: ZnTrack
message: >-
  If you use this software, please cite it using the
  metadata from this file.
type: software
authors:
  - given-names: Fabian
    family-names: Zills
    affiliation: >-
      Institute for Computational Physics, University of
      Stuttgart
    orcid: 'https://orcid.org/0000-0002-6936-4692'
  - given-names: Moritz
    family-names: Schaefer
    orcid: 'https://orcid.org/0000-0001-8474-5808'
  - given-names: Samuel
    family-names: Tovey
    affiliation: >-
      Institute for Computational Physics, University of
      Stuttgart
    orcid: 'https://orcid.org/0000-0001-9537-8361'
identifiers:
  - type: url
    value: 'https://arxiv.org/abs/2401.10603'
    description: ZnTrack - Data as Code
  - type: doi
    value: 10.5281/zenodo.6472850.
repository-code: 'https://github.com/zincware/ZnTrack'
license: Apache-2.0

GitHub Events

Total
  • Create event: 62
  • Release event: 8
  • Issues event: 77
  • Watch event: 7
  • Delete event: 71
  • Issue comment event: 91
  • Push event: 439
  • Pull request review comment event: 19
  • Pull request review event: 34
  • Pull request event: 116
Last Year
  • Create event: 62
  • Release event: 8
  • Issues event: 77
  • Watch event: 7
  • Delete event: 71
  • Issue comment event: 91
  • Push event: 439
  • Pull request review comment event: 19
  • Pull request review event: 34
  • Pull request event: 116

Committers

Last synced: 5 months ago

All Time
  • Total Commits: 695
  • Total Committers: 5
  • Avg Commits per committer: 139.0
  • Development Distribution Score (DDS): 0.129
Past Year
  • Commits: 48
  • Committers: 3
  • Avg Commits per committer: 16.0
  • Development Distribution Score (DDS): 0.104
Top Committers
Name Email Commits
Fabian Zills 4****Z 605
SamTov t****l@g****m 44
dependabot[bot] 4****] 23
pre-commit-ci[bot] 6****] 19
MrJulEnergy j****s@g****t 4
Committer Domains (Top 20 + Academic)
gmx.net: 1

Issues and Pull Requests

Last synced: 4 months ago

All Time
  • Total issues: 119
  • Total pull requests: 236
  • Average time to close issues: 6 months
  • Average time to close pull requests: 6 months
  • Total issue authors: 3
  • Total pull request authors: 6
  • Average comments per issue: 0.16
  • Average comments per pull request: 1.05
  • Merged pull requests: 137
  • Bot issues: 1
  • Bot pull requests: 42
Past Year
  • Issues: 37
  • Pull requests: 111
  • Average time to close issues: about 1 month
  • Average time to close pull requests: 5 days
  • Issue authors: 1
  • Pull request authors: 4
  • Average comments per issue: 0.11
  • Average comments per pull request: 0.93
  • Merged pull requests: 84
  • Bot issues: 0
  • Bot pull requests: 8
Top Authors
Issue Authors
  • PythonFZ (118)
  • M-R-Schaefer (1)
  • pre-commit-ci[bot] (1)
Pull Request Authors
  • PythonFZ (194)
  • dependabot[bot] (22)
  • pre-commit-ci[bot] (20)
  • M-R-Schaefer (6)
  • MrJulEnergy (3)
  • NiklasKappel (2)
Top Labels
Issue Labels
bug (12) p1-important (10) enhancement (5) needs-tests (3) p3-nice-to-have (3) p0-critical (3) discussion (2) p2-medium (2) good first issue (1)
Pull Request Labels
dependencies (22) bug (2) p1-important (2) wontfix (2)

Packages

  • Total packages: 2
  • Total downloads:
    • pypi 1,213 last-month
  • Total dependent packages: 4
    (may contain duplicates)
  • Total dependent repositories: 4
    (may contain duplicates)
  • Total versions: 60
  • Total maintainers: 2
pypi.org: zntrack

Create, Run and Benchmark DVC Pipelines in Python

  • Versions: 53
  • Dependent Packages: 4
  • Dependent Repositories: 4
  • Downloads: 849 Last month
Rankings
Dependent packages count: 3.2%
Average: 6.0%
Downloads: 7.3%
Dependent repos count: 7.5%
Maintainers (1)
Last synced: 5 months ago
pypi.org: laufband

Parallel Iteration with File-Based Coordination

  • Versions: 7
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 364 Last month
Rankings
Dependent packages count: 9.2%
Average: 30.6%
Dependent repos count: 52.0%
Maintainers (1)
Last synced: 5 months ago

Dependencies

.github/workflows/codeql-analysis.yml actions
  • actions/checkout v2 composite
  • github/codeql-action/analyze v1 composite
  • github/codeql-action/autobuild v1 composite
  • github/codeql-action/init v1 composite
poetry.lock pypi
  • 225 dependencies
pyproject.toml pypi
  • dot4dict ^0.1.1
  • dvc ^2.12.0
  • pandas ^1.4.3
  • python >=3.8,<4.0.0
  • pyyaml ^6.0
  • tqdm ^4.64.0
  • typer ^0.7.0
  • zninit >=0.1.6
  • znjson ^0.2.1
.github/workflows/test.yaml actions
  • actions/checkout v2 composite
  • actions/setup-python v3 composite
  • codecov/codecov-action v2 composite
  • coverallsapp/github-action master composite