Metadata-Version: 2.4
Name: formulate
Version: 1.0.1
Summary:  Easy conversions between different styles of expressions
Project-URL: Homepage, https://github.com/Scikit-HEP/formulate
Project-URL: Bug Tracker, https://github.com/Scikit-HEP/formulate/issues
Project-URL: Discussions, https://github.com/Scikit-HEP/formulate/discussions
Project-URL: Changelog, https://github.com/Scikit-HEP/formulate/releases
Author-email: Chris Burr <c.b@cern.ch>, Aryan Roy <aryanroy5678@gmail.com>, Jonas Eschle <jonas.eschle@gmail.com>
Maintainer-email: The Scikit-HEP admins <scikit-hep-admins@googlegroups.com>
License-File: LICENSE
Classifier: Development Status :: 1 - Planning
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: hepunits
Requires-Dist: lark>=1.3
Requires-Dist: ordered-set
Provides-Extra: all
Requires-Dist: hypothesis; extra == 'all'
Requires-Dist: jupyter-sphinx>=0.3.2; extra == 'all'
Requires-Dist: myst-parser>=0.13; extra == 'all'
Requires-Dist: numexpr; extra == 'all'
Requires-Dist: numpy; extra == 'all'
Requires-Dist: pre-commit; extra == 'all'
Requires-Dist: pytest-cov>=3; extra == 'all'
Requires-Dist: pytest>=6; extra == 'all'
Requires-Dist: sphinx-autodoc-typehints; extra == 'all'
Requires-Dist: sphinx-book-theme>=0.1.0; extra == 'all'
Requires-Dist: sphinx-copybutton; extra == 'all'
Requires-Dist: sphinx-rtd-theme; extra == 'all'
Requires-Dist: sphinx>=4.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: hypothesis; extra == 'dev'
Requires-Dist: jupyter-sphinx>=0.3.2; extra == 'dev'
Requires-Dist: myst-parser>=0.13; extra == 'dev'
Requires-Dist: numexpr; extra == 'dev'
Requires-Dist: numpy; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pytest-cov>=3; extra == 'dev'
Requires-Dist: pytest>=6; extra == 'dev'
Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
Requires-Dist: sphinx-book-theme>=0.1.0; extra == 'dev'
Requires-Dist: sphinx-copybutton; extra == 'dev'
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
Requires-Dist: sphinx>=4.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: jupyter-sphinx>=0.3.2; extra == 'docs'
Requires-Dist: myst-parser>=0.13; extra == 'docs'
Requires-Dist: numexpr; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
Requires-Dist: sphinx-book-theme>=0.1.0; extra == 'docs'
Requires-Dist: sphinx-copybutton; extra == 'docs'
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
Requires-Dist: sphinx>=4.0; extra == 'docs'
Provides-Extra: test
Requires-Dist: hypothesis; extra == 'test'
Requires-Dist: numpy; extra == 'test'
Requires-Dist: pytest-cov>=3; extra == 'test'
Requires-Dist: pytest>=6; extra == 'test'
Description-Content-Type: text/markdown

# formulate

[![Actions Status][actions-badge]][actions-link]
[![Documentation Status][rtd-badge]][rtd-link]

[![PyPI version][pypi-version]][pypi-link]
[![Conda-Forge][conda-badge]][conda-link]
[![PyPI platforms][pypi-platforms]][pypi-link]

[![GitHub Discussion][github-discussions-badge]][github-discussions-link]
[![Scikit-HEP][sk-badge]](https://scikit-hep.org/)

<!-- prettier-ignore-start -->
[actions-badge]:            https://github.com/scikit-hep/formulate/workflows/unittests/badge.svg
[actions-link]:             https://github.com/Scikit-HEP/formulate/actions
[conda-badge]:              https://img.shields.io/conda/vn/conda-forge/formulate
[conda-link]:               https://github.com/conda-forge/formulate-feedstock
[github-discussions-badge]: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
[github-discussions-link]:  https://github.com/Scikit-HEP/formulate/discussions
[pypi-link]:                https://pypi.org/project/formulate/
[pypi-platforms]:           https://img.shields.io/pypi/pyversions/formulate
[pypi-version]:             https://img.shields.io/pypi/v/formulate
[rtd-badge]:                https://readthedocs.org/projects/formulate/badge/?version=latest
[rtd-link]:                 https://formulate.readthedocs.io/en/latest/?badge=latest
[sk-badge]:                 https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg

<!-- prettier-ignore-end -->

# Formulate

Easy conversions between different styles of expressions. Formulate
currently supports converting between
[ROOT](https://root.cern.ch/doc/master/classTFormula.html) and
[numexpr](https://numexpr.readthedocs.io/en/latest/user_guide.html)
style expressions.

## Installation

Install formulate like any other Python package, ideally inside a virtual environment:

```bash
pip install formulate
```

or using conda:

```bash
conda install -c conda-forge formulate
```

(`-c conda-forge` is only needed if you don't have the `conda-forge` channel already configured)

## Roadmap and releases

For the roadmap, planned features, breaking changes and versioning please see the [roadmap](https://github.com/scikit-hep/formulate/discussions/61).

## Usage

### API

The most basic usage involves calling `from_$BACKEND` and then `to_$BACKEND`, for example when starting with a ROOT style expression:

```pycon
>>> import formulate
>>> momentum = formulate.from_root("TMath::Sqrt(X_PX**2 + X_PY**2 + X_PZ**2)")
>>> momentum
Call(function='sqrt', arguments=[BinaryOperator(operator='add', left=BinaryOperator(operator='add', left=BinaryOperator(operator='pow', left=Symbol(name='X_PX'), right=Literal(value=2)), right=BinaryOperator(operator='pow', left=Symbol(name='X_PY'), right=Literal(value=2))), right=BinaryOperator(operator='pow', left=Symbol(name='X_PZ'), right=Literal(value=2)))])
>>> momentum.to_numexpr()
'sqrt((((X_PX ** 2) + (X_PY ** 2)) + (X_PZ ** 2)))'
>>> momentum.to_root()
'TMath::Sqrt((((X_PX ** 2) + (X_PY ** 2)) + (X_PZ ** 2)))'
```

Similarly, when starting with a `numexpr` style expression:

```pycon
>>> my_selection = formulate.from_numexpr("(X_PT > 5) & ((Mu_NHits > 3) | (Mu_PT > 10))")
>>> my_selection.to_root()
'((X_PT > 5) && ((Mu_NHits > 3) || (Mu_PT > 10)))'
>>> my_selection.to_numexpr()
'((X_PT > 5) & ((Mu_NHits > 3) | (Mu_PT > 10)))'
```

### CLI

The package also provides a command-line interface for converting expressions between different styles. To use it, simply run the `formulate` command followed by the input expression and the desired output.

```bash
$ formulate --from-root '(A && B) || TMath::Sqrt(A)' --to-numexpr
((A & B) | sqrt(A))

$ formulate --from-numexpr '(A & B) | sqrt(A)' --to-root
((A && B) || TMath::Sqrt(A))

$ formulate --from-root '(A && B) || TMath::Sqrt(1.23) * e_num**1.2 + 5*pi' --variables
A
B

$ formulate --from-root '(A && B) || TMath::Sqrt(1.23) * e_num**1.2 + 5*pi' --named-constants
exp1
pi

$ formulate --from-root '(A && B) || TMath::Sqrt(1.23) * e_num**1.2 + 5*pi' --unnamed-constants
1.23
1.2
5
```
