Metadata-Version: 2.4
Name: onsight-trend
Version: 0.1.0
Summary: Time-series trend analysis for any parameter (pressure, rate, temperature, etc.)
Author: Onsight Trend
License: MIT
Project-URL: Homepage, https://github.com/onsight-trend/onsight-trend
Project-URL: Documentation, https://github.com/onsight-trend/onsight-trend#readme
Project-URL: Repository, https://github.com/onsight-trend/onsight-trend
Keywords: trend,time-series,analysis,pressure,rate,well,industrial
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=1.5.0
Requires-Dist: numpy>=1.21.0
Requires-Dist: scipy>=1.9.0
Provides-Extra: viz
Requires-Dist: matplotlib>=3.5.0; extra == "viz"
Dynamic: license-file

# onsight_trend

**Time-series trend analysis for the oil & gas industry—and beyond.**

Analyze pressure, rate, temperature, or any parameter with rolling segmentation, dual-method voting (subtraction + linear regression), and configurable magnitude categories. Built for well performance, process monitoring, and industrial analytics.

## Installation

```bash
pip install onsight-trend
```

## Quick Start

```python
from onsight_trend import analyze_trend

import pandas as pd
df = pd.read_csv("data.csv")
result = analyze_trend(df)

print(result.direction)    # 'increase', 'decrease', or 'steady'
print(result.magnitude)    # net change in parameter units
print(result.confidence)   # 0-100%
```

## Input Formats

**DataFrame** with columns:
- **Time:** `datetime`, `time`, `date`, or `timestamp`
- **Parameter:** `value`, `parameter`, `thp`, `pressure`, `rate`, `oil_rate`, `temperature`, `flow_rate`, etc.—or any numeric column

**Series** with `DatetimeIndex`:
```python
series = df.set_index("datetime")["pressure"]
result = analyze_trend(series)
```

## Parameters

```python
analyze_trend(
    data,
    duration_days=7.0,           # analysis window (most recent data)
    magnitude_categories=None,   # custom thresholds (see below)
)
```

## Custom Magnitude Categories

Magnitude categories classify the size of change in your parameter’s units (e.g. psi, bar, stb/d, °C).

### Default Categories

| Category    | Range (units) |
|------------|---------------|
| negligible | 0 - 10        |
| small      | 10 - 50       |
| moderate   | 50 - 150      |
| large      | 150 - 300     |
| very_large | 300+          |

### How to Change Magnitude Categories

**1. Python API—pass a dict**

```python
my_categories = {
    "negligible": (0, 15),
    "small": (15, 60),
    "moderate": (60, 200),
    "large": (200, 400),
    "very_large": (400, float("inf")),
}
result = analyze_trend(df, magnitude_categories=my_categories)
print(result.magnitude_category)  # uses your categories
```

**2. Modify defaults and reuse**

```python
from onsight_trend import analyze_trend
from onsight_trend.config import DEFAULT_MAGNITUDE_CATEGORIES

# Copy and adjust
my_cats = DEFAULT_MAGNITUDE_CATEGORIES.copy()
my_cats["small"] = (10, 75)
my_cats["moderate"] = (75, 200)

result = analyze_trend(df, magnitude_categories=my_cats)
```

**3. Different units (e.g. oil rate in stb/d)**

```python
# For oil rate: 0-100 stb/d = low, 100-500 = medium, 500+ = high
rate_categories = {
    "low": (0, 100),
    "medium": (100, 500),
    "high": (500, float("inf")),
}
result = analyze_trend(rate_df, magnitude_categories=rate_categories)
```

**4. CLI**

```bash
python -m onsight_trend data.csv -d 7 -m "low:0,25 medium:25,100 high:100,inf"
```

Format: `"name1:min1,max1 name2:min2,max2 ..."`. Use `inf` for no upper limit.

### Category Rules

- Categories are checked in order; the first matching range is used.
- Ranges are `[min, max)` (inclusive min, exclusive max).
- Use `float("inf")` for unbounded upper limits.

## Result Attributes

| Attribute           | Type   | Description                          |
|--------------------|--------|--------------------------------------|
| `direction`        | str    | `'increase'`, `'decrease'`, `'steady'` |
| `magnitude`        | float  | Net change in parameter units        |
| `confidence`       | float  | Vote confidence 0-100%               |
| `magnitude_pct`    | float  | Percentage change                    |
| `magnitude_category` | str  | Category from your thresholds        |
| `start_value`      | float  | Parameter at start of window         |
| `end_value`        | float  | Parameter at end of window           |
| `duration_days`    | float  | Analysis window length               |
| `n_segments`       | int    | Number of rolling segments (10)      |

## How It Works

1. **Rolling segments:** Splits the duration into 10 overlapping segments (60% overlap).
2. **Two methods per segment:** Simple subtraction and linear regression.
3. **Voting:** Each segment contributes 2 votes; majority direction wins.
4. **Confidence:** Percentage of votes for the winning direction.
5. **Magnitude:** Net change from first to last point in the window.

## License

MIT
