Metadata-Version: 2.2
Name: pyairtree
Version: 1.3.0
Summary: High-performance Python bindings for the AirMettle AirTree C++ library
Keywords: histogram,compression,numpy,statistics,airtree
Author-Email: AirMettle <support@airmettle.com>
License: AirMettle Noncommercial License
         ===============================
         
         This license is derived from the PolyForm Noncommercial License 1.0.0
         (https://polyformproject.org/licenses/noncommercial/1.0.0) with the sole
         modification that government institutions are excluded from noncommercial
         use.
         
         
         Acceptance
         ----------
         
         In order to get any license under these terms, you must agree to them as
         both strict obligations and conditions to all your licenses.
         
         
         Copyright License
         -----------------
         
         The licensor grants you a copyright license for the software to do
         everything you might do with the software that would otherwise infringe
         the licensor's copyright in it for any permitted purpose. However, you
         may only distribute the software according to the Distribution License
         section and make changes or new works based on the software according to
         the Changes and New Works License section.
         
         
         Distribution License
         --------------------
         
         The licensor grants you an additional copyright license to distribute
         copies of the software. Your license to distribute covers distributing
         the software with changes and new works permitted by the Changes and New
         Works License section.
         
         
         Notices
         -------
         
         You must ensure that anyone who gets a copy of any part of the software
         from you also gets a copy of these terms, as well as copies of any
         plain-text lines beginning with "Required Notice:" that the licensor
         provided with the software. For example:
         
             Required Notice: Copyright AirMettle, Inc. (https://airmettle.com)
         
         
         Changes and New Works License
         -----------------------------
         
         The licensor grants you an additional copyright license to make changes
         and new works based on the software for any permitted purpose.
         
         
         Patent License
         --------------
         
         The licensor grants you a patent license for the software that covers
         patent claims the licensor can license, or becomes able to license, that
         you would infringe by using the software.
         
         
         Noncommercial Purposes
         ----------------------
         
         Any noncommercial purpose is a permitted purpose.
         
         
         Personal Uses
         -------------
         
         Personal use for research, experiment, and testing for the benefit of
         public knowledge, personal study, private entertainment, hobby projects,
         amateur pursuits, or religious observance, without any anticipated
         commercial application, is use for a permitted purpose.
         
         
         Noncommercial Organizations
         ---------------------------
         
         Use by any charitable organization, educational institution, public
         research organization, public safety or health organization, or
         environmental protection organization is use for a permitted purpose
         regardless of the source of funding or obligations resulting from the
         funding.
         
         Use by any government institution, including national laboratories, is
         deemed commercial use and requires a separate license.
         
         
         Fair Use
         --------
         
         You may have "fair use" rights for the software under the law. These
         terms do not limit them.
         
         
         No Other Rights
         ---------------
         
         These terms do not allow you to sublicense or transfer any of your
         licenses to anyone else, or prevent the licensor from granting licenses
         to anyone else. These terms do not imply any other licenses.
         
         
         Patent Defense
         --------------
         
         If you make any written claim that the software infringes or contributes
         to infringement of any patent, your patent license for the software
         granted under these terms ends immediately. If your company makes such a
         claim, your patent license ends immediately for work on behalf of your
         company.
         
         
         Violations
         ----------
         
         The first time you are notified in writing that you have violated any of
         these terms, or done anything with the software not covered by your
         licenses, your licenses can nonetheless continue if you come into full
         compliance with these terms, and take practical steps to correct past
         violations, within 32 days of receiving notice. Otherwise, all your
         licenses end immediately.
         
         
         No Liability
         ------------
         
         AS FAR AS THE LAW ALLOWS, THE SOFTWARE COMES AS IS, WITHOUT ANY WARRANTY
         OR CONDITION, AND THE LICENSOR WILL NOT BE LIABLE TO YOU FOR ANY DAMAGES
         ARISING OUT OF THESE TERMS OR THE USE OR NATURE OF THE SOFTWARE, UNDER
         ANY KIND OF LEGAL CLAIM.
         
         
         Definitions
         -----------
         
         The "licensor" is the individual or entity offering these terms, and the
         "software" is the software the licensor makes available under these
         terms.
         
         "You" refers to the individual or entity agreeing to these terms.
         
         "Your company" is any legal entity, sole proprietorship, or other kind
         of organization that you work for, plus all organizations that have
         control over, are under the control of, or are under common control with
         that organization. "Control" means ownership of substantially all the
         assets of an entity, or the power to direct its management and policies
         by vote, contract, or otherwise. Control can be direct or indirect.
         
         "Your licenses" are all the licenses granted to you for the software
         under these terms.
         
         "Use" means anything you do with the software requiring one of your
         licenses.
         
         
         Patent & Licensing
         ------------------
         
         Patent Pending — U.S. Patent Application Publication No. 2025/0217930 A1
         (https://patents.google.com/patent/US20250217930A1).
         
         This software is provided for non-commercial use only, per the terms
         above.
         
         For commercial licensing, support, or enterprise usage, please contact
         support@airmettle.com.
         
         Cloud services powered by this technology are launching in June 2026,
         starting with Azure.
         
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: C++
Classifier: Topic :: Scientific/Engineering
Classifier: License :: Other/Proprietary License
Project-URL: Homepage, https://airmettle.com
Project-URL: Documentation, https://github.com/AirMettle/AirTree
Project-URL: Repository, https://github.com/AirMettle/AirTree
Requires-Python: >=3.8
Requires-Dist: numpy>=1.21.0
Description-Content-Type: text/markdown

# pyairtree

Python bindings for [AirTree](https://airmettle.com) — a high-performance library for building, compressing, and querying multi-dimensional histograms over floating-point data.

Turn large numeric datasets into compact `.airtree` histograms and run fast statistical queries without keeping the full raw data in memory.

**Required Notice:** Copyright AirMettle, Inc. (https://airmettle.com)

---

## Installation

```bash
pip install pyairtree
```

### Supported platforms

| Platform | Architecture | Python    |
|----------|--------------|------------|
| Linux    | x86_64, ARM  | 3.8 – 3.12 |
| Windows  | amd64        | 3.8 – 3.12 |


NumPy is installed automatically as a dependency.

### Verify the install

```python
import pyairtree
print(pyairtree.__version__)
```

---

## Quick start

Build a 1D histogram from a NumPy array, save it, and query percentiles:

```python
import numpy as np
import pyairtree

# Sample data
data = np.random.randn(100_000)

# Build a compressed histogram (1D, high precision)
buffer = pyairtree.generate(data)

# Save to disk
pyairtree.write(buffer, "histogram.airtree")

# Query percentiles
p = pyairtree.Percentile(buffer)
print(f"Median: {p.get_percentile(50):.4f}")
print(f"95th percentile: {p.get_percentile(95):.4f}")
```

#### Load data directly from .npy or single-array .npz files
```python
buffer = pyairtree.generate("samples/data.npy")
```

---

## Core workflow

A typical workflow has three steps:

1. Generate — compress numeric arrays into an in-memory histogram buffer
2. Store — write the buffer to a .airtree file
3. Query — run statistics or spatial queries on the buffer or file

```python
import pyairtree

# 1. Generate
buffer = pyairtree.generate(x, y, options)

# 2. Store
pyairtree.write(buffer, "output.airtree")

# 3. Query
reader = pyairtree.read("output.airtree")
p = pyairtree.Percentile(buffer)
```

---

## Generating histograms

### Unified generate() API (recommended)

Pass one NumPy array per dimension. Use AirTreeOptions to control dimensionality and precision:

```python
import numpy as np
import pyairtree

x = np.random.randn(50_000)
y = np.random.randn(50_000)

options = pyairtree.AirTreeOptions()
options.dimensions = 2
options.type = pyairtree.ConfigType.XP   # highest precision (default for most use cases)

buffer = pyairtree.generate(x, y, options)
```

#### Configuration types

| Type          | Precision                  | Best for                       |
|---------------|----------------------------|--------------------------------|
| ConfigType.XT | 13-bit                     | Large datasets, fastest builds |
| ConfigType.XF | 16-bit                     | General-purpose balance        |
| ConfigType.XP | 20-bit (1D) / 10-bit (2D+) | Highest accuracy               |

#### Dimensionality

```python
# 1D
buf_1d = pyairtree.generate(a, options)

# 2D
buf_2d = pyairtree.generate(a, b, options)

# 3D
buf_3d = pyairtree.generate(a, b, c, options)

# 4D
buf_4d = pyairtree.generate(a, b, c, d, options)
```

Set options.dimensions to match the number of arrays you pass.

### Named generation functions

Convenience functions are also available for explicit configs:

```python
arr = pyairtree.buildFPHArray(data)

# 1D
pyairtree.generate_1DxT(arr)   # 13-bit
pyairtree.generate_1DxF(arr)   # 16-bit
pyairtree.generate_1DxP(arr)   # 20-bit

# 2D / 3D / 4D
pyairtree.generate_2DxP(arr_x, arr_y)
pyairtree.generate_3DxP(arr_x, arr_y, arr_z)
pyairtree.generate_4DxP(arr_x, arr_y, arr_z, arr_w)
```

#### Supported array types

NumPy arrays with dtype float64, float32, int64, or int32.

---

## File I/O

### Write a histogram

```python
pyairtree.write(buffer, "histogram.airtree")
```

### Read a histogram

```python
reader = pyairtree.read("histogram.airtree")

print(reader.dims)        # number of dimensions
print(reader.bit_length)  # encoding precision
print(reader.type)        # configuration type

header = reader.header
print(header.version)
print(header.nan_count)
```

---

### Query operations

#### Percentile (1D)

```python
p = pyairtree.Percentile(buffer)

median = p.get_percentile(50.0)
p95    = p.get_percentile(95.0)
```

#### Min / Max (1D)

```python
mm = pyairtree.MinMax(buffer)
print(mm.get_min(), mm.get_max())
```

#### Top-K (1D)

Return the bins with the highest counts:

```python
topk = pyairtree.TopK(buffer)
results = topk.top_k(10.0)   # top 10% of bins by count

for r in results:
    print(r.lower_bound, r.upper_bound, r.count)
```

#### CDF (1D)

```python
cdf = pyairtree.CDF(buffer)
values = cdf.get_cdf()
```

#### Bounding box (2D)

Count values inside a rectangular region:

```python
bbox_query = pyairtree.BoundingBox(buffer_2d)

region = pyairtree.BoundingBoxCoordinate2D(
    min_x=0.0, max_x=1.0,
    min_y=0.0, max_y=1.0,
)

safe, edge = bbox_query.get_counts(region)
(safe_coords, safe_count) = safe
(edge_coords, edge_count) = edge
```

#### Grid query (1D)

Evaluate the histogram over a regular grid:

```python
gq = pyairtree.GridQuery(buffer)
result = gq.get_grid(spec)   # pass a GridSpec with min, max, steps
rows = result.materialize_rows()
```

---

#### Export

Export histogram data to common interchange formats:

```python
pyairtree.export_tree(buffer, "output.arrow", pyairtree.ExportFormat.ARROW)
pyairtree.export_tree(buffer, "output.parquet", pyairtree.ExportFormat.PARQUET)
pyairtree.export_tree(buffer, "output.csv", pyairtree.ExportFormat.CSV)
```

---

#### Choosing a configuration

| Use case                                  | Suggested config               |
|-------------------------------------------|--------------------------------|
| Exploratory analysis on large 1D datasets | ConfigType.XT or generate_1DxT |
| Production 1D analytics                   | ConfigType.XF or generate_1DxF |
| High-precision 1D requirements            | ConfigType.XP or generate_1DxP |
| 2D spatial / correlation data             | generate_2DxP                  |
| 3D / 4D multi-variate data                | generate_3DxP / generate_4DxP  |

---

#### Error handling

```python
import pyairtree
import numpy as np

try:
    pyairtree.generate(np.array(["not", "numeric"]))
except (TypeError, RuntimeError) as e:
    print(f"Generation failed: {e}")

try:
    pyairtree.Percentile(two_d_buffer)   # Percentile is 1D only
except RuntimeError as e:
    print(f"Query failed: {e}")
```

---

## License

AirMettle Noncommercial License

This software is provided for noncommercial use only. Government use requires a separate commercial license.

• Personal, research, educational, and qualifying nonprofit use is permitted
• Commercial or government use requires a license from AirMettle

For commercial licensing, support, or enterprise usage:

support@airmettle.com

Patent Pending — U.S. Patent Application Publication No. 2025/0217930 A1 (https://patents.google.com/patent/US20250217930A1)

See the bundled LICENSE file for full terms.

---

Links

- Homepage: https://airmettle.com
- Support: support@airmettle.com