Metadata-Version: 2.4
Name: pyskby
Version: 0.2.2
Summary: SKBY（时空变源混合产流）水文模型的 Python 版 —— 由 Java 版 SKBY 完整移植
Author: wly
License: MIT
Keywords: hydrology,rainfall-runoff,watershed,runoff,source-area,infiltration,channel-routing,STVSRM,SKBY
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Hydrology
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: numpy

# pyskby

SKBY（时空变源混合产流）水文模型的 Python 版 —— 由 Java 版完整移植，
与 Java 参考模型**逐位对齐**（对拍通过），支持物理-守恒双模式、多外部水源接入。

- **发布名**：`pyskby`
- **导入名**：`pyskby`
- **版本**：`0.2.0`
- **Python**：≥ 3.10，依赖 `numpy`

---

## 1. 安装指令

### 方式一：从 PyPI 安装（发布后）

```bash
pip install pyskby
```

### 方式二：从源码安装（开发模式）

```bash
cd skby_py
pip install -e .
```

### 验证安装

```bash
python -c "import pyskby; print(pyskby.__version__)"
# 输出: 0.2.0
```

---

## 2. 调用指令

### 2.1 Python API

```python
from pyskby.model import SKBYModel

# Faithful 模式（默认，与 Java 逐位对齐）
m = SKBYModel(
    "data/liulan_fupan/params-testnew.csv",   # 参数文件
    "data/liulan_fupan/data-test.csv",        # 驱动/时序数据
    conservative=False,
)
m.run()
m.write_outlet_csv("outlet.csv")   # 流域出口流量
m.write_qj_csv("QJ.csv")           # 逐河道出流明细

# Conservative 守恒模式（修复运动波质量损失，≠ Java 基线）
m2 = SKBYModel("params.csv", "data.csv", conservative=True)
m2.run()
```

### 2.2 命令行

pyskby 提供两种命令行入口，底层都调用同一套逻辑（`pyskby.cli:main`）。

**方式 A：安装后的 console script（推荐给使用者）**

```bash
pip install pyskby          # 安装后自动注册 skby-run 命令
skby-run liulan_fupan                          # faithful 模式（Java 参考/不守恒）
skby-run liulan_fupan --conservative           # 守恒修复版
```

`skby-run` 默认从**当前工作目录**查找 `sim/<sim>.groovy` 与 `data/`，因此使用者
在自己的算例目录（含 `sim/`、`data/`）下运行即可；也可用 `--root PATH` 指定根目录：

```bash
cd my_case_study && skby-run liulan_fupan --root .
```

输出写到 `<root>/output/<sim>/out/outlet_py.csv` 与 `QJ_py.csv`。

**打包内置示例（安装后直接跑通）**

pyskby 在 wheel 中内置了示例算例 `liulan_fupan`。安装后用 `skby-example` 把示例
解包到当前目录，再用 `skby-run` 运行：

```bash
pip install pyskby
skby-example liulan_fupan          # 复制 ./examples/{sim,data}/liulan_fupan
skby-run liulan_fupan --root examples          # faithful 模式
skby-run liulan_fupan --root examples --conservative   # 守恒模式
# 结果: ./examples/output/liulan_fupan/out/outlet_py.csv 与 QJ_py.csv
```

`skby-example` 不带参数则复制全部示例；已存在时跳过（加 `--force` 覆盖）。

> **关于 `--root` 与 `site-packages`**
> 安装后示例其实就在 `site-packages/pyskby/examples/`。`--root` 直接指向它
> （如 `--root $(python -c "import pyskby,os;print(os.path.dirname(pyskby.__file__))")/examples`）
> **也能算**，但输出会写到该安装目录下的 `.../examples/output/<sim>/out/`。不推荐：
> 会污染 pip 管理的安装目录（重装/升级会被清掉），且在无写权限环境下会报 `PermissionError`。
> 标准做法仍是 `skby-example` 把示例导出到你自己的工作目录再跑。

**方式 B：仓库内调试（`run.py`，加载本地源码）**

```bash
cd skby_py
python run.py liulan_fupan                  # 等价于 --root 指向仓库根
python run.py liulan_fupan --conservative
```

`run.py` 会把自身所在目录（`skby_py`）插入 `sys.path` 最前，**强制优先加载本地
`pyskby` 源码**（而非已安装的 PyPI 副本）。因此调试时改动 `pyskby/` 下的代码，
`python run.py` 立即生效，不会误加载已 `pip install` 的版本。

也可以用模块方式调用（等价于安装后的 console script）：

```bash
python -m pyskby.cli liulan_fupan --conservative --root /path/to/case
```

### 2.3 可选水量平衡诊断

```python
m.run(diag="diag.csv")   # 落盘逐时步水量平衡
```

> 详细参数说明见仓库内 `skby_py/使用手册.md`（产汇流参数、水源/分洪/水库出流等）。

---

## 3. 打包发布指令

### 3.1 一次性安装发布工具

```bash
pip install --upgrade build twine
```

### 3.2 构建分发包

```bash
cd skby_py
python -m build
```

会生成 `dist/pyskby-0.2.0-py3-none-any.whl`（wheel）和
`dist/pyskby-0.2.0.tar.gz`（sdist）。

### 3.3 发布到 PyPI

```bash
# 方式一：只发布 wheel（不含 sdist 源码包，推荐）
twine upload dist/*.whl

# 方式二：同时发布 wheel + sdist
twine upload dist/*

# 先上传到测试服务器验证
twine upload --repository testpypi dist/*
```

> `twine upload` 会提示输入 PyPI 账号的 API Token（用户名填 `__token__`，密码填 token）。

### 3.4 发布后验证

```bash
pip install pyskby
python -c "import pyskby; print(pyskby.__version__)"
```

---

## 4. 升级发布版本

改版本号后需同步两处：

1. `skby_py/pyproject.toml` → `version = "x.y.z"`
2. `skby_py/pyskby/__init__.py` → `__version__ = "x.y.z"`

然后重新执行 §3.2 构建、§3.3 上传。

---

## 5. 常见问题

- **发布名 vs 导入名**：PyPI 包名和 Python 导入名均为 `pyskby`（`import pyskby`）。

- **调试时改了 `pyskby/` 源码，`run.py` 用的还是旧代码？**
  不会。`run.py` 在导入前把自身目录（`skby_py`）插到 `sys.path` 最前，因此
  `python run.py ...` 永远加载**本地** `pyskby` 源码，即使系统里已 `pip install`
  过正式版也优先本地。发布后的使用者用 `skby-run` 命令则加载其安装的副本。

- **`skby-run` 与 `python run.py` 的区别？**
  二者调用同一套逻辑（`pyskby.cli:main`）。`skby-run` 是给**安装者**用的
  console script（从 cwd 找算例）；`run.py` 是给**开发者**调试用的入口
  （默认把仓库根作为算例根，并强制加载本地源码）。
