makepst 0.3.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- makepst-0.5.0/CHANGELOG.md +143 -0
- {makepst-0.3.0 → makepst-0.5.0}/CITATION.cff +2 -2
- {makepst-0.3.0 → makepst-0.5.0}/MANIFEST.in +1 -0
- {makepst-0.3.0 → makepst-0.5.0}/PKG-INFO +196 -51
- {makepst-0.3.0 → makepst-0.5.0}/README.md +195 -50
- {makepst-0.3.0 → makepst-0.5.0}/makepst/__init__.py +6 -4
- {makepst-0.3.0 → makepst-0.5.0}/makepst/checks.py +8 -5
- {makepst-0.3.0 → makepst-0.5.0}/makepst/cli.py +334 -32
- {makepst-0.3.0 → makepst-0.5.0}/makepst/diff.py +49 -2
- {makepst-0.3.0 → makepst-0.5.0}/makepst/excel.py +5 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/hpstart.py +4 -2
- makepst-0.5.0/makepst/pestpp.py +244 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/provenance.py +9 -0
- makepst-0.5.0/makepst/pst.py +944 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/reader.py +65 -21
- makepst-0.5.0/makepst/reweight.py +344 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/rules.py +102 -4
- {makepst-0.3.0 → makepst-0.5.0}/makepst/sections.py +77 -19
- {makepst-0.3.0 → makepst-0.5.0}/makepst/starter.py +9 -0
- makepst-0.5.0/makepst/writer.py +291 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst.egg-info/PKG-INFO +196 -51
- {makepst-0.3.0 → makepst-0.5.0}/makepst.egg-info/SOURCES.txt +14 -1
- {makepst-0.3.0 → makepst-0.5.0}/pyproject.toml +1 -1
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.par +1 -1
- {makepst-0.3.0 → makepst-0.5.0}/tests/make_fixture.py +2 -1
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_checks.py +10 -2
- makepst-0.5.0/tests/test_convenience.py +113 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_diff.py +22 -3
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_examples.py +31 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_fixture.py +50 -2
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_makepst.py +46 -10
- makepst-0.5.0/tests/test_optional_positions.py +93 -0
- makepst-0.5.0/tests/test_optional_positions_variations.py +19 -0
- makepst-0.5.0/tests/test_pest_hp.py +172 -0
- makepst-0.5.0/tests/test_pestpp.py +141 -0
- makepst-0.5.0/tests/test_rescale.py +193 -0
- makepst-0.5.0/tests/test_reweight.py +240 -0
- makepst-0.5.0/tests/test_rule_sources.py +152 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_rules.py +18 -0
- makepst-0.5.0/tests/test_set_par.py +166 -0
- makepst-0.5.0/tools/rule_sources.py +353 -0
- makepst-0.5.0/tools/snapshots/pestchek.json +719 -0
- makepst-0.5.0/tools/snapshots/pestpp.json +322 -0
- makepst-0.3.0/CHANGELOG.md +0 -73
- makepst-0.3.0/makepst/pst.py +0 -449
- makepst-0.3.0/makepst/writer.py +0 -164
- makepst-0.3.0/tests/test_convenience.py +0 -60
- {makepst-0.3.0 → makepst-0.5.0}/LICENSE +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/control.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/flow.ins +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/flow.out +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/heads.ins +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/heads.out +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/io.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/model.in +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/model.par +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/model.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/model.res +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/model.tpl +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/obs.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/par.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/examples/minimal/pargp.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/__main__.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/model_files.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/phi.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst/pyemu_bridge.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst.egg-info/dependency_links.txt +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst.egg-info/entry_points.txt +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst.egg-info/requires.txt +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/makepst.egg-info/top_level.txt +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/setup.cfg +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.3.obs.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.3.par.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.phi.actual.csv +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.pst +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.res +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/data/demo.xlsx +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_hpstart.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_log_bundle.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_model_files.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_phi.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_provenance.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_pyemu.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_starter.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_v2.py +0 -0
- {makepst-0.3.0 → makepst-0.5.0}/tests/test_version.py +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.5.0 (2026-09-29)
|
|
4
|
+
|
|
5
|
+
- `tools/rule_sources.py`: are `validate`'s rules still current? `pestpp` re-reads PEST++'s option
|
|
6
|
+
parser from GitHub (names, aliases, types, choices, deprecations); `pestchek --source DIR` reads a
|
|
7
|
+
PEST download's `pestchek.F` / `cheksub.F` (control-data keywords and every message). Each is
|
|
8
|
+
compared with the reviewed snapshot in `tools/snapshots/` and with makePst's own tables; exit 1 on
|
|
9
|
+
a change, 2 when the source cannot be read; `--write` records a reviewed source. Tests hold
|
|
10
|
+
`makepst/pestpp.py` and the control-data schema to the snapshots, and a weekly GitHub workflow
|
|
11
|
+
(`.github/workflows/rule-sources.yml`) opens an issue when PEST++'s parser changes. The PEST++
|
|
12
|
+
registry is unchanged; its provenance now names commit 02e1455 (5.2.29) - the commit named before,
|
|
13
|
+
ad8428d, has identical option parsing but is labelled 5.2.28 in the source.
|
|
14
|
+
|
|
15
|
+
- `build --dry_run`: the `validate` report on the control file a build would write, from a workbook's
|
|
16
|
+
BUILD sheet or from tables named on the command line; nothing is written, no manifest; exit 1 on
|
|
17
|
+
errors. A workbook with no BUILD sheet now says how to name its tables and check them this way.
|
|
18
|
+
- `validate` on a workbook judges it as `build` would write it, after the same normalization
|
|
19
|
+
(regularisation equations from `PRIOR`/`WEIGHT`, unused groups removed, ties to fixed parameters
|
|
20
|
+
fixed), listing those as notes. It used to judge the tables before that and report errors building
|
|
21
|
+
removes: a regularisation file with no "regul" group, prior information not generated.
|
|
22
|
+
|
|
23
|
+
- PEST_HP control variables are treated as `++` options are: a control-data token makePst does not
|
|
24
|
+
know (`newhpvar=7`, a new flag) is kept with the line it came from and written back there, instead
|
|
25
|
+
of being dropped, and `validate` warns about it with the closest known name. `dump` writes it to
|
|
26
|
+
the CONTROL sheet with its line (`control data line 4`), so `build` puts it back.
|
|
27
|
+
- Every PEST_HP variable PEST 17.2's pestchek reads is now known: `run_slow_fac`, `run_abandon_fac`,
|
|
28
|
+
`jcowarnthresh`, `jcozerothresh`, `zerosenval`, `hardstophours`, `softstophours`, `reg2measrat`,
|
|
29
|
+
`orr_not_first`, and `obsreref_N`; `name = value` with spaces around `=` is read, as PEST_HP does.
|
|
30
|
+
- `validate` checks that PEST can read each control value: an integer or a number where one is
|
|
31
|
+
expected (Fortran `1d-3` included), a known word for `precis`, `dpoint` and the other flags,
|
|
32
|
+
`absparmax(n)=value` with n 1-10; and the PEST_HP ranges and combinations (`RUN_ABANDON_FAC` 0 or
|
|
33
|
+
at least 1.2, not both stop-hours variables, `JCOZEROTHRESH` above `JCOWARNTHRESH`, `REG2MEASRAT`
|
|
34
|
+
below 1, `orr_not_first` and `ZEROSENVAL` only with what they need).
|
|
35
|
+
- The rule sources are pinned and reported: `PESTCHEK_SOURCE_VERSION` (17.2) beside
|
|
36
|
+
`PESTPP_REGISTRY_VERSION` (5.2.29); `validate` prints both and every manifest records them under
|
|
37
|
+
`checked_against`.
|
|
38
|
+
|
|
39
|
+
## 0.4.0 (2026-09-27)
|
|
40
|
+
|
|
41
|
+
- `rescale` / `Pst.rescale_par()`: move parameter values into `SCALE` so each selected parameter
|
|
42
|
+
starts at 1 (bounds divided by the value), or back with `--undo`; the model sees the same values.
|
|
43
|
+
Selection by `--par` globs and `--pargp` (fixed parameters included unless `--exclude_fixed`;
|
|
44
|
+
tied children follow their parent). Prior-information equations are rewritten exactly (every
|
|
45
|
+
residual is unchanged), and settings in parameter units that cannot be converted (absolute
|
|
46
|
+
derivative increments, `absolute(n)` limits, `++parcov` / `++base_jacobian` / `++ies_par_en`)
|
|
47
|
+
are reported.
|
|
48
|
+
- `fill_parval` (`build --fill_parval`, `parrep`), `tempchek --par` and `hpstart --par` convert a
|
|
49
|
+
`.par` value written under a different `SCALE` / `OFFSET` than the control file's through the
|
|
50
|
+
model value, instead of copying `PARVAL1` across. The test fixture's `demo.par` now records the
|
|
51
|
+
parameters' own offsets, as PEST writes them.
|
|
52
|
+
- Writing a control file no longer fails on an adjustable `PARVAL1` outside its bounds (a `parrep`
|
|
53
|
+
from an IES realization, say): it is a warning, as documented, and the file is written.
|
|
54
|
+
`makepst validate` still reports it as an error. `diff` normalizes a workbook side, as `build`
|
|
55
|
+
would, so a workbook compares equal to the control file built from it.
|
|
56
|
+
|
|
57
|
+
- `reweight`: balance observation-group contributions equally or to relative target shares,
|
|
58
|
+
multiply selected group weights directly, match weights to the current misfit with
|
|
59
|
+
`--discrepancy group|obs` (group phi = weighted-observation count, or `w = min(w, 1/|r|)`), consume `.res`/IES observation results, enforce
|
|
60
|
+
optional weight bounds with `--clip`, and write an auditable before/after report.
|
|
61
|
+
|
|
62
|
+
- `++` options are checked against PEST++ 5.2.29's option list (`makepst/pestpp.py`): a known option
|
|
63
|
+
with a value PEST++ would not accept, or the same option twice (also through an alias), is an error;
|
|
64
|
+
an unknown option is a warning with the closest known name (`did you mean "ies_num_reals"?`) and is
|
|
65
|
+
kept as written. Findings name the workbook cell, csv line or control-file line the option came from
|
|
66
|
+
(`PP!A17`). `validate` reports them; `build`, `parrep` and `set` print them but still write.
|
|
67
|
+
|
|
68
|
+
- Unknown control-file sections are retained verbatim, including their original header,
|
|
69
|
+
body lines and position, instead of being dropped during a read/write round trip.
|
|
70
|
+
- `Pst.validate()` now returns a read-only report; `apply_fixes(report)` and `normalize()` make
|
|
71
|
+
the previous tied-parameter, unused-group and prior-information cleanups explicit.
|
|
72
|
+
|
|
73
|
+
## 0.3.0 (2026-09-21)
|
|
74
|
+
|
|
75
|
+
- `log`: ledger of every manifest under a folder — when, which command, which output from
|
|
76
|
+
which sources, dimensions, version; `--file` filters by file name, path or sha256 prefix
|
|
77
|
+
("which runs used that version of the workbook?"), `--command`, `--last`, `--check`
|
|
78
|
+
verifies every recorded hash
|
|
79
|
+
- `bundle`: zip a run for reproduction or review — control file, manifest, templates,
|
|
80
|
+
instruction files, model inputs, command-line files; `--sources`, `--outputs`, `--extra`,
|
|
81
|
+
`--list`, `--strict`; the zip gets its own manifest
|
|
82
|
+
- `provenance`: compare the hashes recorded in a manifest with the files on disk
|
|
83
|
+
(`unchanged` / `changed` / `missing`; exit 1 unless all unchanged)
|
|
84
|
+
- `update --dry_run`: preview matched names, target columns and skipped cells without writing
|
|
85
|
+
- `build` warns when a referenced sheet has formulas without cached values (a workbook saved
|
|
86
|
+
by openpyxl and not yet recalculated in Excel)
|
|
87
|
+
- `hpstart`: a PEST_HP `.hp` file with observation values from residuals or an IES realization
|
|
88
|
+
|
|
89
|
+
## 0.2.0 (2026-09-19)
|
|
90
|
+
|
|
91
|
+
- `update`: the xlwings backend reads only headers, name and target columns, writes contiguous
|
|
92
|
+
cells in one call per run, suspends events and calculation while writing and recalculates
|
|
93
|
+
once before saving (1,068 parameters over eight sheets of a 27-sheet workbook: ~9 s, was
|
|
94
|
+
minutes); `--par` with `--pst` no longer rewrites the observation sheets
|
|
95
|
+
- `tempchek`: check a template file or write model input files from parameter values, with
|
|
96
|
+
PEST's number writer (maximum precision in the space, `PRECIS` / `DPOINT`, one word per
|
|
97
|
+
parameter, right-justified; checked against `tempchek.exe`); for a template + `.par` file
|
|
98
|
+
or for a whole case
|
|
99
|
+
- `inschek`: check an instruction file or read a model output file with it into an `.obf`
|
|
100
|
+
file, for one file or a whole case
|
|
101
|
+
- `validate`: values that cannot be written into their template space are errors; a line
|
|
102
|
+
advance not at the start of an instruction line and `t` / fixed instructions moving left
|
|
103
|
+
are errors (INSCHEK's rules); three more pestchek warnings (empty observation group,
|
|
104
|
+
`ICOV`/`ICOR`/`IEIG` with more than 300 adjustable parameters, PEST_HP-only variables —
|
|
105
|
+
the last as a note); an all-zero-weight observation group is now a note, not a warning
|
|
106
|
+
- `update`: cells inside array formulas or dynamic-array spill ranges are left alone (Excel
|
|
107
|
+
refuses them; xlwings no longer shows a dialog); names present on only one side are reported
|
|
108
|
+
with counts and examples
|
|
109
|
+
- `validate`: pestchek's rules added (parameter data, groups, observations, prior information,
|
|
110
|
+
~60 control-variable ranges and consistency rules, template and instruction syntax), derived
|
|
111
|
+
from PEST 17's `pestchek.F` / `cheksub.F`; file paths resolved from the directory PEST runs
|
|
112
|
+
in, not only the control file's folder
|
|
113
|
+
|
|
114
|
+
## 0.1.0 (2026-09-19)
|
|
115
|
+
|
|
116
|
+
First packaged release; replaces the single-file `makePst.py` script.
|
|
117
|
+
|
|
118
|
+
- `init`: starter workbook with headers, defaults, descriptions, drop-down lists, comments and
|
|
119
|
+
a `BUILD` sheet
|
|
120
|
+
- `build`: Excel/CSV tables -> control file; sheet globs (`book,PAR_*`); a workbook with a
|
|
121
|
+
`BUILD` sheet as the only argument; counts computed; PEST_HP keyed tokens and
|
|
122
|
+
`++` options; regularisation equations from `PRIOR`/`WEIGHT` columns; validation of tied
|
|
123
|
+
targets, groups, prior references and bounds
|
|
124
|
+
- `dump`: control file -> workbook with a `BUILD` sheet that rebuilds it
|
|
125
|
+
- `update`: `.par` / `.res` / `.rei` / PESTPP-IES ensembles into an existing workbook, matched
|
|
126
|
+
by name across sheets; formula cells protected; `--sheet` / `--group` filters; `--real`;
|
|
127
|
+
`PHI` sheet (objective function by observation group) and `PHI_IES` (realization phis)
|
|
128
|
+
whenever residuals are available
|
|
129
|
+
- `validate`: pestchek-style report on a control file or workbook: table checks, missing
|
|
130
|
+
files, parameter / observation names against template and instruction files, optional run
|
|
131
|
+
of instruction files against model outputs; exit 1 on errors
|
|
132
|
+
- PEST++ version-2 control files (`pcf version=2`, keyword control data, external csv
|
|
133
|
+
tables) are read and written (`--v2`); observation covariance files are kept
|
|
134
|
+
- `diff`: semantic comparison of two control files / workbooks (tables, effective control
|
|
135
|
+
values, options, io, comments), text report or workbook; exit 1 on differences
|
|
136
|
+
- pyEMU bridge: `to_pyemu()` / `from_pyemu()` via a temporary control file (`pyemu` extra)
|
|
137
|
+
- provenance: every producing command writes `<output>.manifest.json` (version, command
|
|
138
|
+
line, source hashes and sheets, output hash and counts)
|
|
139
|
+
- `parrep`: `.par` or IES realization into a control file (or a workbook with a `BUILD` sheet),
|
|
140
|
+
with `--set NAME=VALUE`
|
|
141
|
+
- Fixes over the old script: `jacupdate` was never written; values were truncated to 6
|
|
142
|
+
significant digits; `phistopthresh` could not be set; SVD / regularisation values in the
|
|
143
|
+
CONTROL sheet were ignored; prior information in estimation mode produced an invalid file
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
include LICENSE README.md CHANGELOG.md CITATION.cff
|
|
2
2
|
recursive-include tests *.py *.xlsx *.pst *.par *.res *.csv
|
|
3
|
+
recursive-include tools *.py *.json
|
|
3
4
|
recursive-include examples/minimal *.csv *.py *.tpl *.ins *.in *.out *.par *.res
|
|
4
5
|
prune examples/mnnrd
|
|
5
6
|
global-exclude __pycache__ *.py[cod] *.manifest.json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: makepst
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Build PEST / PEST++ / PEST_HP control files from spreadsheet tables, read them back, and push results into the workbook
|
|
5
5
|
Author-email: Michael Ou <ougengxin@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -45,8 +45,10 @@ reads control files back into editable workbooks, and returns calibration result
|
|
|
45
45
|
Excel / CSV tables -> .pst makepst build
|
|
46
46
|
.pst -> editable workbook makepst dump
|
|
47
47
|
.par / .res / .rei / IES ensemble -> existing workbook makepst update
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
.par or IES realization (+ tweaks) -> new .pst makepst parrep
|
|
49
|
+
.pst -> values moved to SCALE makepst rescale
|
|
50
|
+
.res/.rei or IES obs + group targets -> reweighted .pst makepst reweight
|
|
51
|
+
.res/.rei or IES obs + existing .hp -> new .hp makepst hpstart
|
|
50
52
|
two .pst / workbooks -> what changed makepst diff
|
|
51
53
|
manifests in a folder -> run ledger makepst log
|
|
52
54
|
.pst + everything it references -> zip for review makepst bundle
|
|
@@ -158,7 +160,7 @@ without `--force`.
|
|
|
158
160
|
|
|
159
161
|
```
|
|
160
162
|
makepst validate model.pst --outputs
|
|
161
|
-
makepst validate book.
|
|
163
|
+
makepst validate book.xlsx --strict
|
|
162
164
|
```
|
|
163
165
|
|
|
164
166
|
See [Validation](#validation). Template and instruction paths are resolved the way PEST
|
|
@@ -167,27 +169,43 @@ the current directory and the control file's parent, uses the one where the file
|
|
|
167
169
|
says which; `--base_dir` overrides that. `--strict` also fails on warnings,
|
|
168
170
|
`--quiet` hides the informational lines.
|
|
169
171
|
|
|
172
|
+
A workbook is accepted in place of a control file when it carries a `BUILD` sheet (one that
|
|
173
|
+
`dump` or `init` wrote), which is built first and then checked. For tables that have no
|
|
174
|
+
`BUILD` sheet — a hand-made workbook, or a set of CSV files — name them on a
|
|
175
|
+
[`build`](#build--tables--pst) command line and add `--dry_run`, which runs this same report
|
|
176
|
+
and writes nothing.
|
|
177
|
+
|
|
170
178
|
### build — tables → .pst
|
|
171
179
|
|
|
172
180
|
```
|
|
173
181
|
makepst build out.pst [estimation|regularisation|prediction|pareto]
|
|
174
|
-
--set_ctl_xls book.
|
|
175
|
-
--add_pargp_xls book.
|
|
176
|
-
--add_par_xls book.
|
|
177
|
-
--add_obs_xls book.
|
|
178
|
-
--add_io_xls book.
|
|
182
|
+
--set_ctl_xls book.xlsx,CONTROL (or --set_ctl_csv file.csv)
|
|
183
|
+
--add_pargp_xls book.xlsx,PARGP
|
|
184
|
+
--add_par_xls book.xlsx,PAR_* (repeatable; sheet names may be globs)
|
|
185
|
+
--add_obs_xls book.xlsx,OBS_*
|
|
186
|
+
--add_io_xls book.xlsx,IO --add_pp_xls book.xlsx,PPcntl
|
|
179
187
|
[--add_tied_xls ...] [--add_prior_xls ...] [--add_comment "text"] [--add_comment_xls ...]
|
|
180
188
|
[--fill_parval run.par [--real NAME]] [--ss] [--no_dump_tpl] [--v2]
|
|
181
189
|
```
|
|
182
190
|
|
|
183
191
|
Each `--add_*` takes `book,SHEET` (`_xls`) or a csv path (`_csv`) and may be repeated;
|
|
184
192
|
tables split across sheets are concatenated. The sheet name may be a glob:
|
|
185
|
-
`--add_par_xls tr13.
|
|
186
|
-
case-insensitive. `makepst build book.
|
|
193
|
+
`--add_par_xls tr13.xlsx,PAR_*` adds every `PAR_…` sheet in workbook order. Headers are
|
|
194
|
+
case-insensitive. `makepst build book.xlsx [--out x.pst]` runs the command stored in the
|
|
187
195
|
workbook's `BUILD` sheet instead. The mode argument
|
|
188
196
|
overrides `pestmode` in the CONTROL sheet; adding prior information switches to regularisation.
|
|
189
197
|
`--ss` drops `ss*`/`sy*` parameters and groups (steady-state runs of a transient setup).
|
|
190
198
|
|
|
199
|
+
`--dry_run` builds the control file in memory, runs the full [validation](#validation) report
|
|
200
|
+
on it — including the template, instruction and model files it references — and writes
|
|
201
|
+
nothing (no `.pst`, no `dump.tpl`, no manifest), exiting 1 when there are errors. This is how
|
|
202
|
+
to check a workbook or a set of CSV tables that has no `BUILD` sheet; for one that has a
|
|
203
|
+
`BUILD` sheet, `makepst validate book.xlsx` does the same in one argument.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
makepst build case.pst --add_par_xls book.xlsx,PAR_* --add_obs_xls book.xlsx,OBS_* ... --dry_run
|
|
207
|
+
```
|
|
208
|
+
|
|
191
209
|
| table | columns |
|
|
192
210
|
|---------|---------|
|
|
193
211
|
| CONTROL | `NAME`, `VALUE` in the first four columns (`LINE`, `NAME`, `DEFAULT`, `VALUE`); blank values use the built-in default. Any variable of the control data, SVD, LSQR, AUI, SVD-assist or regularisation sections: `noptmax`, `jacupdate`, `lamforgive`, `win_mrun_hours`, `absparmax(1)=0.1 absparmax(2)=20`, `svdmode`, `phimlim`, … Counts are ignored (computed). |
|
|
@@ -200,6 +218,15 @@ overrides `pestmode` in the CONTROL sheet; adding prior information switches to
|
|
|
200
218
|
| IO | `TYPE` (`cmd` / `tpl` / `ins`), `IN`, `OUT` |
|
|
201
219
|
| PP | first two columns: PEST++ option name, value → `++name(value)` |
|
|
202
220
|
|
|
221
|
+
Classic PEST numeric control settings are positional. If a later setting is supplied,
|
|
222
|
+
all earlier numeric settings on that line must have values after built-in defaults
|
|
223
|
+
are applied. For example, `upvecbend` requires `iboundstick`, and `regsingthresh`
|
|
224
|
+
requires both `noptregadj` and `regweightrat`. Export raises an error naming any
|
|
225
|
+
missing predecessors instead of shifting settings into the wrong slots. Supply
|
|
226
|
+
those values explicitly; trailing optional fields may remain blank. Text flags
|
|
227
|
+
and named tokens such as `absparmax(1)=0.1` do not require numeric fillers. This
|
|
228
|
+
positional requirement does not apply to the version-2 keyword format (`--v2`).
|
|
229
|
+
|
|
203
230
|
**Regularisation from the parameter table.** In regularisation mode each adjustable
|
|
204
231
|
parameter with a `PRIOR` and a positive `WEIGHT` gets an equation: a numeric `PRIOR` gives
|
|
205
232
|
`1.0 * log(p) = log10(v)` (or `1.0 * p = v` for untransformed parameters); a `PRIOR` naming
|
|
@@ -221,13 +248,13 @@ to recover a workbook that was lost.
|
|
|
221
248
|
### update — results → existing workbook
|
|
222
249
|
|
|
223
250
|
```
|
|
224
|
-
makepst update book.
|
|
225
|
-
makepst update book.
|
|
226
|
-
makepst update book.
|
|
227
|
-
makepst update book.
|
|
228
|
-
makepst update book.
|
|
229
|
-
makepst update book.
|
|
230
|
-
[--sheet "PAR_*"] [--group hk,sy] [--overwrite_formulas] [--out copy.
|
|
251
|
+
makepst update book.xlsx --par run.par # PARVAL1
|
|
252
|
+
makepst update book.xlsx --res run.res # adds MODELLED / RESIDUAL
|
|
253
|
+
makepst update book.xlsx --pst run.pst --par_cols PARVAL1,PARTRANS,PARLBND,PARUBND
|
|
254
|
+
makepst update book.xlsx --par run.3.par.csv --real best # PESTPP-IES ensemble
|
|
255
|
+
makepst update book.xlsx --obs_csv run.3.obs.csv --pst run.pst # IES simulated values
|
|
256
|
+
makepst update book.xlsx --par run.par --dry_run # preview; write nothing
|
|
257
|
+
[--sheet "PAR_*"] [--group hk,sy] [--overwrite_formulas] [--out copy.xlsx] [--backend openpyxl|xlwings]
|
|
231
258
|
```
|
|
232
259
|
|
|
233
260
|
> **`update` saves in place unless `--out` is given.** Use `--out` the first time, and keep
|
|
@@ -244,6 +271,8 @@ refuse), only counted. `--sheet` (glob, case-insensitive) restricts the workshee
|
|
|
244
271
|
add `--pst` to supply them). `--pst` on its own writes the control file's parameter and
|
|
245
272
|
observation columns; next to `--par`, `--res` or `--obs_csv` it only supplies groups and
|
|
246
273
|
measured values, and the observation sheets are not touched by a parameter update.
|
|
274
|
+
Likewise, `--res` or `--obs_csv` with `--pst` leaves parameter cells unchanged unless
|
|
275
|
+
`--par` is also supplied.
|
|
247
276
|
|
|
248
277
|
The xlwings backend reads only each sheet's header, name column and target columns, writes
|
|
249
278
|
contiguous runs of cells in one call each and recalculates once before saving: the
|
|
@@ -272,18 +301,67 @@ unmatched names without saving a workbook or manifest. It does not test whether
|
|
|
272
301
|
refuse individual writes. During `build`, missing cached formula results in referenced
|
|
273
302
|
tables produce a warning; existing cached values may still be stale and cannot be verified.
|
|
274
303
|
|
|
304
|
+
### reweight — balance observation-group weights
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
makepst reweight run.pst balanced.pst --res run.res --equal
|
|
308
|
+
makepst reweight run.pst balanced.pst --res run.res --targets group_shares.csv
|
|
309
|
+
makepst reweight run.pst scaled.pst --factor heads=0.5 --factor flow=2
|
|
310
|
+
makepst reweight run.pst balanced.pst --obs_csv run.3.obs.csv --real base --equal
|
|
311
|
+
makepst reweight run.pst adjusted.pst --res run.res --discrepancy group
|
|
312
|
+
makepst reweight run.pst adjusted.pst --obs_csv run.0.obs.csv --discrepancy obs
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
`reweight` writes a new control file; it never overwrites the input. `--equal` gives each
|
|
316
|
+
eligible measurement group the same initial objective-function contribution; a group whose
|
|
317
|
+
current phi is zero cannot be scaled to a share, so it is skipped with an INFO line and its
|
|
318
|
+
weights are left unchanged. `--targets`
|
|
319
|
+
reads a CSV or `BOOK,SHEET` table with `OBGNME,TARGET_SHARE` columns. Shares are relative, so
|
|
320
|
+
`4,3,2` means 44.44%, 33.33% and 22.22%; the selected groups' total phi is preserved. Direct
|
|
321
|
+
`--factor GROUP=NUMBER` specifications multiply the existing positive weights in named groups.
|
|
322
|
+
|
|
323
|
+
`--discrepancy` makes weights consistent with the current misfit, so that each weighted
|
|
324
|
+
observation contributes about 1 to phi. `--discrepancy group` scales each measurement group by
|
|
325
|
+
one factor so its phi equals its number of weighted observations (as PEST's PWTADJ2); relative
|
|
326
|
+
weights inside a group are kept and zero-phi groups are skipped. It raises the weights of groups
|
|
327
|
+
that already fit better than that, so pair it with `--clip` when some groups fit very closely.
|
|
328
|
+
`--discrepancy obs` sets `w = min(w, 1/|residual|)` for each observation (pyEMU's
|
|
329
|
+
`adjust_weights_discrepancy` with its original ceiling): observations the model cannot fit are
|
|
330
|
+
lowered to a contribution of 1, weights are never raised, and zero residuals keep their weight.
|
|
331
|
+
It is commonly applied to the prior mean or base realization before a PESTPP-IES run so that
|
|
332
|
+
observation noise is not smaller than the misfit the prior can reach. Total phi is not preserved
|
|
333
|
+
in either variant.
|
|
334
|
+
|
|
335
|
+
For equal, target and discrepancy modes, residuals are joined by observation name while weights and group
|
|
336
|
+
membership come from the input control file. Groups backed by covariance matrices, `predict`,
|
|
337
|
+
and `regul*` groups are not measurement groups and are rejected or skipped as appropriate.
|
|
338
|
+
|
|
339
|
+
Use `--clip MIN MAX` to constrain final positive weights, for example `--clip 0 10`. Original
|
|
340
|
+
zero weights remain zero. Clipping is included in the balancing calculation; if a requested
|
|
341
|
+
target cannot be reached under the bounds, the command fails instead of reporting a misleading
|
|
342
|
+
result. `--report FILE` writes the before/after group table, including phi, percentages,
|
|
343
|
+
factors, clipping counts and the number of weights lowered (`N_REDUCED`). `--dry_run` prints that table without writing a control file,
|
|
344
|
+
report or manifest.
|
|
345
|
+
|
|
346
|
+
The workbook remains the source of truth. If the control file is rebuilt from a workbook later,
|
|
347
|
+
formula-generated workbook weights will replace weights changed by `reweight` unless the change
|
|
348
|
+
is deliberately transferred back to the workbook.
|
|
349
|
+
|
|
275
350
|
### parrep — .par values → new .pst
|
|
276
351
|
|
|
277
352
|
```
|
|
278
353
|
makepst parrep run.pst run.par next.pst [--set noptmax=0] [--set NAME=VALUE ...] [--v1|--v2]
|
|
279
354
|
makepst parrep run.pst run.3.par.csv next.pst --real best
|
|
280
|
-
makepst parrep book.
|
|
355
|
+
makepst parrep book.xlsx run.par next.pst # base is the workbook
|
|
281
356
|
```
|
|
282
357
|
|
|
283
358
|
Like PEST's PARREP: `PARVAL1` is replaced from a `.par` file or an IES realization and a new
|
|
284
359
|
control file is written; `--set` changes control values on the way. All supported content of
|
|
285
360
|
the input control file is preserved semantically (see below); adjustable parameters that end
|
|
286
|
-
up outside their bounds are reported.
|
|
361
|
+
up outside their bounds are reported. A `.par` file records the `SCALE` and `OFFSET` each value
|
|
362
|
+
was written with; where those differ from the control file's (a run from before a
|
|
363
|
+
[`rescale`](#rescale--parameter-values--scale)), the value is converted so the model sees the
|
|
364
|
+
same number (`PARVAL1 × SCALE + OFFSET`). An IES ensemble carries no scales and is copied as is.
|
|
287
365
|
|
|
288
366
|
With a **workbook** as the base, the control file is first built from the command in the
|
|
289
367
|
workbook's `BUILD` sheet (`dump` writes one; for a hand-made workbook paste the build command
|
|
@@ -292,6 +370,37 @@ to that workbook; other relative names resolve against the workbook's folder. No
|
|
|
292
370
|
route rebuilds from the workbook's *current* state, so any edits made since the original
|
|
293
371
|
control file was written are picked up too.
|
|
294
372
|
|
|
373
|
+
### rescale — parameter values → SCALE
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
makepst rescale run.pst run_unit.pst # every parameter starts at 1
|
|
377
|
+
makepst rescale run.pst run_unit.pst --par "hk*,sy*" --exclude_fixed
|
|
378
|
+
makepst rescale run.pst run_unit.pst --pargp kh --pargp kv
|
|
379
|
+
makepst rescale run_unit.pst run_back.pst --undo # SCALE folded back into PARVAL1
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
PEST applies `SCALE` and `OFFSET` only when it writes a model input file, so a parameter at
|
|
383
|
+
value *v* can start at 1 without the model seeing any difference: `PARVAL1 = 1`,
|
|
384
|
+
`SCALE = SCALE × v`, bounds divided by *v* (swapped when *v* < 0), `OFFSET` unchanged. `--undo`
|
|
385
|
+
does the reverse (`PARVAL1 × SCALE`, bounds likewise, `SCALE = 1`).
|
|
386
|
+
|
|
387
|
+
- **Selection:** all parameters by default, fixed ones included; `--par` (names or globs) and
|
|
388
|
+
`--pargp` narrow it, and both must match when both are given; `--exclude_fixed` leaves fixed
|
|
389
|
+
parameters alone. Tied children follow a selected parent. Parameters at zero are skipped and
|
|
390
|
+
listed.
|
|
391
|
+
- **Prior information** is written in PEST's own units, so every equation naming a rescaled
|
|
392
|
+
parameter is rewritten exactly: a linear term takes *v* into its coefficient, a log term
|
|
393
|
+
moves `log10(v)` to the right-hand side. Each equation's residual is the same number as
|
|
394
|
+
before, so its weight is unchanged.
|
|
395
|
+
- **Warned, not converted:** settings in parameter units that one factor per parameter can't
|
|
396
|
+
convert — `INCTYP absolute` and `DERINCLB` of groups holding rescaled parameters, `absolute(n)`
|
|
397
|
+
change limits — and files named in the control file that were written for the old values
|
|
398
|
+
(`++parcov`, `++base_jacobian`, `++ies_par_en`, SVD-assist `basepestfile` / `basejacfile`).
|
|
399
|
+
A Jacobian given to PEST another way (a restart, a command-line switch) can't be seen from
|
|
400
|
+
the control file; don't reuse one across a rescale.
|
|
401
|
+
|
|
402
|
+
`--set`, `--eol`, `--v1|--v2` and `--no_manifest` work as for `parrep`.
|
|
403
|
+
|
|
295
404
|
### hpstart — modeled observations → new PEST_HP .hp file
|
|
296
405
|
|
|
297
406
|
```
|
|
@@ -350,8 +459,8 @@ read and observations the control file lists but no file produced are reported.
|
|
|
350
459
|
### diff — what changed
|
|
351
460
|
|
|
352
461
|
```
|
|
353
|
-
makepst diff tr12.pst tr13.pst [--xlsx changes.xlsx] [--rtol 1e-9] [--max_rows 50]
|
|
354
|
-
makepst diff tr13.
|
|
462
|
+
makepst diff tr12.pst tr13.pst [--xlsx changes.xlsx] [--file changes.txt] [--rtol 1e-9] [--max_rows 50]
|
|
463
|
+
makepst diff tr13.xlsx tr13.pst # is the control file still what the workbook says?
|
|
355
464
|
```
|
|
356
465
|
|
|
357
466
|
Compares the tables, not the text: parameters and observations added, removed or changed
|
|
@@ -361,11 +470,12 @@ instruction pairs, command lines and header comments. Numbers are compared with
|
|
|
361
470
|
tolerance, so `49.7377` vs `49.73775` shows up at the default `1e-9` and disappears at
|
|
362
471
|
`--rtol 1e-5`. Prints a table per section and a one-line summary; `--xlsx` writes the same
|
|
363
472
|
tables to a workbook for review. Exits 1 when there are differences, like `diff`.
|
|
473
|
+
`--file` writes the complete text report, including rows beyond the console's `--max_rows` limit.
|
|
364
474
|
|
|
365
475
|
### log — the run ledger
|
|
366
476
|
|
|
367
477
|
```
|
|
368
|
-
makepst log [FOLDER ...] [--file tr13.
|
|
478
|
+
makepst log [FOLDER ...] [--file tr13.xlsx] [--command build] [--last 10] [--check] [--no_recursive]
|
|
369
479
|
```
|
|
370
480
|
|
|
371
481
|
Every manifest under the folders (default: the current one, recursively), oldest first, one
|
|
@@ -376,8 +486,8 @@ the workbook?" even after the file was renamed or overwritten. `--check` adds a
|
|
|
376
486
|
`provenance`: `unchanged` / `changed` / `missing`.
|
|
377
487
|
|
|
378
488
|
```
|
|
379
|
-
2026-09-19 21:14 build pest/tr13.pst <- tr13.
|
|
380
|
-
2026-09-21 08:10 update tr13-xlwings.
|
|
489
|
+
2026-09-19 21:14 build pest/tr13.pst <- tr13.xlsx [1068 par 41747 obs 159 prior] makepst 0.5.0
|
|
490
|
+
2026-09-21 08:10 update tr13-xlwings.xlsx <- tr13.xlsx, tr13.par [1068 rows in 8 sheets] makepst 0.5.0
|
|
381
491
|
```
|
|
382
492
|
|
|
383
493
|
### bundle — a run, zipped for review
|
|
@@ -405,11 +515,13 @@ Preserved: every parameter, group, observation, prior-information equation, tied
|
|
|
405
515
|
template/instruction pair, command line, `++` option, header comment, control-data value
|
|
406
516
|
(including PEST_HP keyed tokens), SVD / LSQR / AUI / SVD-assist / regularisation values, and
|
|
407
517
|
the verbatim text of `* sensitivity reuse`, `* derivatives command line`, `* predictive
|
|
408
|
-
analysis` and `* pareto`.
|
|
518
|
+
analysis` and `* pareto`. Any section unknown to this version of makePst is also retained
|
|
519
|
+
verbatim at its original position, so newer or site-specific PEST content survives a round trip.
|
|
409
520
|
|
|
410
521
|
Normalised: parameter, observation and group names are lower-cased (PEST is
|
|
411
522
|
case-insensitive); numbers are written with 11 significant digits; whitespace and column
|
|
412
|
-
alignment
|
|
523
|
+
alignment in understood sections is makePst's own; comments *inside understood sections* are
|
|
524
|
+
dropped; observation groups are
|
|
413
525
|
listed in first-use order (or the order of the source file when reading a `.pst`).
|
|
414
526
|
|
|
415
527
|
Also preserved: covariance-file references in `* observation groups` (an `OBSGP` sheet on
|
|
@@ -419,27 +531,27 @@ written back as version 2 unless `--v1` is given; `--v2` writes any control file
|
|
|
419
531
|
format, with `case.par_data.csv` / `obs_data` / `pargp_data` / `prior_data` beside it. Both
|
|
420
532
|
versions of the same content are identical after reading (`makepst diff` says so).
|
|
421
533
|
|
|
422
|
-
Not preserved: any unrecognised section (dropped with a warning naming it).
|
|
423
|
-
|
|
424
534
|
## Compatibility
|
|
425
535
|
|
|
426
536
|
| | |
|
|
427
537
|
|---|---|
|
|
428
538
|
| PEST dialects | PEST, PEST_HP (`win_mrun_hours=`, `uptestmin=`, `uptestlim=`, `absparmax(n)=`), PEST++ (`++name(value)` options) |
|
|
429
|
-
| Control-file sections | control data, singular value decomposition, lsqr, automatic user intervention, svd assist, parameter groups, parameter data (incl. tied pairs), observation groups, observation data, model command line, model input/output, prior information (with `&` continuation lines), regularisation. Kept verbatim: sensitivity reuse, derivatives command line, predictive analysis, pareto. |
|
|
539
|
+
| Control-file sections | control data, singular value decomposition, lsqr, automatic user intervention, svd assist, parameter groups, parameter data (incl. tied pairs), observation groups, observation data, model command line, model input/output, prior information (with `&` continuation lines), regularisation. Kept verbatim: sensitivity reuse, derivatives command line, predictive analysis, pareto, and all unknown sections. |
|
|
430
540
|
| File formats | classic (version 1) and PEST++ version 2 (`pcf version=2`, `* control data keyword` with control variables and `++` options, `* … external` csv tables with `sep=` / `missing_values=`, `partied` column); observation covariance files in `* observation groups` |
|
|
431
|
-
| Not supported | unknown sections — dropped with a warning |
|
|
432
541
|
| Result files | `.par`, `.res` / `.rei`, PESTPP-IES `case.N.par.csv` / `case.N.obs.csv` / `case.phi.actual.csv` |
|
|
433
|
-
| Table inputs | `.xlsx` / `.
|
|
542
|
+
| Table inputs | `.xlsx` / `.xlsx` sheets (openpyxl), `.csv` |
|
|
434
543
|
| Workbook update | openpyxl backend on any platform (macros kept, charts/images dropped, no recalculation); xlwings backend on Windows/macOS with Excel (everything kept, recalculated) |
|
|
435
544
|
| Platforms | CI runs the suite on Ubuntu 24.04 and Windows Server 2022 for Python 3.9, 3.11 and 3.13. macOS is expected to work but is not exercised in CI. |
|
|
436
545
|
| Python | ≥ 3.9; pandas ≥ 2.0 (tested with 2.3 and 3.0), numpy, openpyxl ≥ 3.1; optional xlwings, pyemu, pytest |
|
|
437
546
|
|
|
438
547
|
## Validation
|
|
439
548
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
549
|
+
`Pst.validate()` is a read-only audit of the in-memory tables. It returns a report with
|
|
550
|
+
`errors`, `warnings`, and `fixes_available`; inspecting it never changes the `Pst`. Apply
|
|
551
|
+
reviewed fixes explicitly with `pst.apply_fixes(report)`, or use `pst.normalize()` to apply
|
|
552
|
+
all currently available normalizations. Writers refuse validation errors and serialize the
|
|
553
|
+
current tables without modifying them. The CLI's file-building commands call `normalize()`
|
|
554
|
+
explicitly before writing.
|
|
443
555
|
|
|
444
556
|
| check | outcome |
|
|
445
557
|
|---|---|
|
|
@@ -447,19 +559,20 @@ cannot:
|
|
|
447
559
|
| duplicate parameter, observation or prior-information names | error |
|
|
448
560
|
| parameter group used but not defined | error |
|
|
449
561
|
| tied parameter whose target is missing, or tied to a tied parameter | error |
|
|
450
|
-
| tied to a fixed parameter |
|
|
451
|
-
| parameter group defined but unused |
|
|
452
|
-
| prior equation referencing a fixed, tied or missing parameter |
|
|
562
|
+
| tied to a fixed parameter | error and fix available: convert it to fixed |
|
|
563
|
+
| parameter group defined but unused | fix available: remove the group |
|
|
564
|
+
| prior equation referencing a fixed, tied or missing parameter | error and fix available: rebuild prior information, dropping those equations |
|
|
453
565
|
| adjustable `PARVAL1` outside `[PARLBND, PARUBND]` | warning |
|
|
454
|
-
| control value that is computed (`npar` …)
|
|
566
|
+
| control value that is computed (`npar` …) | ignored (warning) |
|
|
567
|
+
| control variable makePst does not know (a newer PEST_HP keyword): kept on the line it came from; a CONTROL-sheet row gives that line in `LINE` (`control data line 4`) or is ignored | warning |
|
|
455
568
|
|
|
456
|
-
`makepst validate`
|
|
457
|
-
tables at the files the control file points to, and exits 1
|
|
458
|
-
stop:
|
|
569
|
+
`makepst validate` uses the same table checks and adds the **pestchek-style report**: it
|
|
570
|
+
changes nothing, looks beyond the tables at the files the control file points to, and exits 1
|
|
571
|
+
on errors so a batch file can stop:
|
|
459
572
|
|
|
460
573
|
```
|
|
461
574
|
makepst validate model.pst [--outputs] [--strict] [--quiet] [--base_dir DIR]
|
|
462
|
-
makepst validate tr13.
|
|
575
|
+
makepst validate tr13.xlsx # a workbook with a BUILD sheet is built first, in memory
|
|
463
576
|
```
|
|
464
577
|
|
|
465
578
|
| check | severity |
|
|
@@ -470,19 +583,47 @@ makepst validate tr13.xlsm # a workbook with a BUILD sheet is built f
|
|
|
470
583
|
| malformed prior equation; non-numeric right-hand side; `log()` used on a non-log parameter or vice versa | error |
|
|
471
584
|
| `DERCOM` beyond the number of model command lines | error |
|
|
472
585
|
| name longer than PEST's limit (12 parameter / 20 observation / 12 group; PEST++ allows 200) | warning |
|
|
473
|
-
| **pestchek's rules** (from PEST 17's `pestchek.F` / `cheksub.F`): `PARCHGLIM` vocabulary and `absolute(n)` needing `absparmax(n)=`; log parameters factor-limited with positive values; factor-limited bounds of one sign and non-zero; `SCALE ≠ 0`; tied to itself, tied or parent with initial value 0; group `none` reserved; all parameters fixed/tied; `INCTYP` / `FORCEN` / `DERMTHD` vocabularies and their compatibility; split-column ranges; duplicate groups; `dum` as an observation name; prior weights, labels (≤ 20, not an observation name), duplicated parameters, all-zero factors, group `predict`; regularisation needs a `regul*` group, prediction exactly one `predict` observation; ~60 control-variable range and consistency rules (`RLAMFAC`, `PHIRATSUF`, `FACPARMAX`, `NPHISTP`, `RELPARSTP < RELPARMAX`, `EIGTHRESH`, `PHIMLIM < PHIMACCEPT < 1.2·PHIMLIM`, `WFMIN ≤ WFINIT ≤ WFMAX`, `UPTESTMIN`/`UPTESTLIM`, SVD vs AUI vs LSQR exclusivity, …) | error |
|
|
586
|
+
| **pestchek's rules** (from PEST 17.2's `pestchek.F` / `cheksub.F`): `PARCHGLIM` vocabulary and `absolute(n)` needing `absparmax(n)=`; log parameters factor-limited with positive values; factor-limited bounds of one sign and non-zero; `SCALE ≠ 0`; tied to itself, tied or parent with initial value 0; group `none` reserved; all parameters fixed/tied; `INCTYP` / `FORCEN` / `DERMTHD` vocabularies and their compatibility; split-column ranges; duplicate groups; `dum` as an observation name; prior weights, labels (≤ 20, not an observation name), duplicated parameters, all-zero factors, group `predict`; regularisation needs a `regul*` group, prediction exactly one `predict` observation; ~60 control-variable range and consistency rules (`RLAMFAC`, `PHIRATSUF`, `FACPARMAX`, `NPHISTP`, `RELPARSTP < RELPARMAX`, `EIGTHRESH`, `PHIMLIM < PHIMACCEPT < 1.2·PHIMLIM`, `WFMIN ≤ WFINIT ≤ WFMAX`, `UPTESTMIN`/`UPTESTLIM`, SVD vs AUI vs LSQR exclusivity, …) | error |
|
|
587
|
+
| control value PEST cannot read: not an integer or a number where one is expected (Fortran `1d-3` is fine), a word outside its field's vocabulary (`precis`, `dpoint`, `obsreref`, …), `absparmax(n)=` malformed or n outside 1-10; the PEST_HP limits and combinations (`RUN_SLOW_FAC`, `RUN_ABANDON_FAC`, `HARDSTOPHOURS` / `SOFTSTOPHOURS` not both, `JCOZEROTHRESH` above `JCOWARNTHRESH`, `ZEROSENVAL`, `REG2MEASRAT` below 1, `orr_not_first` only with `obsreref`) | error |
|
|
588
|
+
| control-data token not in PEST 17.2's pestchek — kept as written, with the closest known name (`"win_mrun_hour=2" … did you mean "win_mrun_hours"?`) | warning |
|
|
474
589
|
| pestchek's warnings: derivative increment larger than a third of the range; initial value 0 with a relative increment; group with only fixed/tied parameters; log parameters with a non-relative increment; observation group listed but empty (dropped on write); `MAXSING` above the adjustable-parameter count; more than 300 adjustable parameters with `ICOV`/`ICOR`/`IEIG` on; `NOPTMAX 0` | warning |
|
|
475
590
|
| PEST_HP-only control variables present (`WIN_MRUN_HOURS`, `UPTESTMIN`, `RRFSAVE`, …; plain PEST needs `/hpstart`); observation group whose weights are all zero | note |
|
|
476
591
|
| template: parameter space narrower than 3 characters or containing a tab | error |
|
|
477
592
|
| template: a value that cannot be written into its space as PEST writes numbers (`PRECIS` / `DPOINT` honoured), e.g. `1e-10` in five characters | error |
|
|
478
593
|
| instruction file syntax: `l` / `t` integers, marker delimiters, `!` balance, `[name]n1:n2` order, `dum` in a fixed field, continuation `&` placement, `l` only at the start of a line, `t` and fixed columns moving left to right, unknown instructions — checked statically, without model output | error |
|
|
479
|
-
|
|
|
594
|
+
| `++` option with a value PEST++ does not accept (integer given `2.5`, boolean given `t` or `yes`, number list with a non-number, `svd_pack` / `glm_normal_form` / `ies_subset_how` outside their choices, `ies_num_reals` < 1, …); the same option twice, directly or through an alias (`ies_par_en` and `ies_parameter_ensemble`) | error |
|
|
595
|
+
| `++` option not in PEST++'s option list — kept, with the closest known name (`unknown PEST++ option "ies_num_real"; did you mean "ies_num_reals"?`); a control variable such as `noptmax` given as a `++` option | warning (note with `++forgive_unknown_args(true)`) |
|
|
596
|
+
| deprecated `++` option that PEST++ ignores (`mat_inv`, `upgrade_augment`, `svd_pack(propack)`, …) | note |
|
|
597
|
+
| unknown section in the `.pst` that makePst preserves verbatim | note |
|
|
480
598
|
| template or instruction file missing; bad `ptf` / `pif` line | error |
|
|
481
599
|
| parameter cited in no template; template citing an unknown parameter | error |
|
|
482
600
|
| observation read by no instruction file, by two files, or twice in one; unknown observation in an instruction file | error |
|
|
483
601
|
| model command / model-input folder not found next to the control file | warning |
|
|
484
602
|
| `--outputs`: each instruction file run against its model output file when present | note (success) / warning (failure) |
|
|
485
603
|
|
|
604
|
+
The `++` checks use the option list in `makepst/pestpp.py`, read off PEST++ 5.2.29's option parser
|
|
605
|
+
(250 options and 34 aliases, with their types). They point at where each option came from —
|
|
606
|
+
`PP!A17` for a workbook cell, `pp.csv:17`, `line 42` of a control file — and `build` prints them
|
|
607
|
+
too, without refusing to write: plain PEST ignores `++` lines, and a newer PEST++ may know an
|
|
608
|
+
option this list does not. PEST++ itself stops on an option it does not accept, so fix or remove
|
|
609
|
+
what is flagged before a run.
|
|
610
|
+
|
|
611
|
+
`validate` prints the two releases its rules were read from, and every manifest records them
|
|
612
|
+
(`checked_against`). Whether they are still current is checked by `tools/rule_sources.py`, which
|
|
613
|
+
re-reads the upstream source and compares it with the snapshot the rules were written against
|
|
614
|
+
(`tools/snapshots/`), exiting 1 on any change:
|
|
615
|
+
|
|
616
|
+
```
|
|
617
|
+
python tools/rule_sources.py pestpp # usgs/pestpp develop, from GitHub
|
|
618
|
+
python tools/rule_sources.py pestchek --source pest_source # the source folder of a PEST download
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
It reports added and removed `++` options, aliases, value types and choices; for PEST, the
|
|
622
|
+
control-data keywords pestchek reads and its messages (each message is a rule); and anything
|
|
623
|
+
makePst's own tables no longer agree with. It edits nothing: port what changed, then run it
|
|
624
|
+
again with `--write` to record the new source as reviewed, and the tests hold the code to that
|
|
625
|
+
snapshot. The PEST++ check runs weekly on GitHub and opens an issue when the parser changes.
|
|
626
|
+
|
|
486
627
|
The `--outputs` interpreter follows the PEST manual (primary and secondary markers, `l`, `w`,
|
|
487
628
|
`t`, `!name!`, `[name]c1:c2`, `(name)c1:c2`, `dum`, `&` continuation) and catches the classic
|
|
488
629
|
mistakes — a `w` too few so a label is read instead of a number, a marker that never appears
|
|
@@ -501,14 +642,15 @@ from?" after the fact:
|
|
|
501
642
|
|
|
502
643
|
```json
|
|
503
644
|
{
|
|
504
|
-
"makepst": "0.
|
|
645
|
+
"makepst": "0.5.0",
|
|
505
646
|
"command": "build",
|
|
506
|
-
"argv": ["build", "tr13.pst", "regul", "--set_ctl_xls", "tr13.
|
|
647
|
+
"argv": ["build", "tr13.pst", "regul", "--set_ctl_xls", "tr13.xlsx,CONTROL", "..."],
|
|
507
648
|
"created": "2026-09-19T13:51:39-04:00",
|
|
508
649
|
"user": "hydro", "host": "OU13700", "cwd": "D:\\...\\0023-makePst",
|
|
509
650
|
"python": "3.12.12", "pandas": "3.0.5", "platform": "Windows-11-10.0.26200-SP0",
|
|
651
|
+
"checked_against": {"pestchek": "17.2", "pestpp": "5.2.29"},
|
|
510
652
|
"sources": [
|
|
511
|
-
{"path": "D:\\...\\tr13.
|
|
653
|
+
{"path": "D:\\...\\tr13.xlsx", "sha256": "9d641a2f...", "size": 3089317,
|
|
512
654
|
"modified": "2026-07-12T03:32:10-04:00", "role": "control",
|
|
513
655
|
"sheets": ["CONTROL", "PARGP", "PAR_HK", "PAR_VK", "...", "PPglm"]}
|
|
514
656
|
],
|
|
@@ -568,10 +710,11 @@ from makepst import Pst, read_pst, write_pst, to_workbook, update_workbook, load
|
|
|
568
710
|
pst = read_pst('run.pst') # Pst: .par/.obs/.pargp/.prior DataFrames, .control dict, ...
|
|
569
711
|
pst.fill_parval('run.3.par.csv', real='best')
|
|
570
712
|
pst.set_control({'noptmax': 0})
|
|
713
|
+
pst.rescale_par(patterns=['hk*'], include_fixed=False) # values -> SCALE; returns a report dict
|
|
571
714
|
write_pst(pst, 'run_final.pst', dump_tpl=False)
|
|
572
715
|
|
|
573
716
|
to_workbook(pst, 'run.xlsx', split=True)
|
|
574
|
-
update_workbook('book.
|
|
717
|
+
update_workbook('book.xlsx', par='run.par', res='run.res', out='book_results.xlsx',
|
|
575
718
|
sheets=['PAR_*'], groups=['hk'])
|
|
576
719
|
```
|
|
577
720
|
|
|
@@ -603,9 +746,10 @@ makepst/
|
|
|
603
746
|
writer.py Pst -> .pst text (+ dump.tpl)
|
|
604
747
|
reader.py .pst text -> Pst
|
|
605
748
|
excel.py sheets -> Pst; Pst -> workbook; results -> existing workbook
|
|
606
|
-
cli.py init / validate / build / dump / update / parrep / diff / tempchek / inschek / log / bundle
|
|
749
|
+
cli.py init / validate / build / dump / update / parrep / set / rescale / reweight / diff / tempchek / inschek / log / bundle
|
|
607
750
|
diff.py semantic comparison of two Pst objects
|
|
608
751
|
phi.py objective function by group from residuals; IES realization phis
|
|
752
|
+
reweight.py observation-group balancing, scaling and bounded weight adjustment
|
|
609
753
|
pyemu_bridge.py to_pyemu / from_pyemu
|
|
610
754
|
checks.py the validate report: table checks, template / instruction cross-checks, instruction interpreter
|
|
611
755
|
rules.py pestchek's rules (parameters, groups, observations, prior information, control variables)
|
|
@@ -614,6 +758,7 @@ makepst/
|
|
|
614
758
|
starter.py the `init` workbook: control-variable descriptions, example rows, drop-downs
|
|
615
759
|
examples/minimal/ the tutorial inputs
|
|
616
760
|
tests/ suite + fixture generator
|
|
761
|
+
tools/ rule_sources.py (are the rules current with PEST / PEST++?) and its snapshots
|
|
617
762
|
```
|
|
618
763
|
|
|
619
764
|
## Releasing
|
|
@@ -623,7 +768,7 @@ stored anywhere. To release: bump the version in `pyproject.toml` and the fallba
|
|
|
623
768
|
`makepst/__init__.py` (a test keeps them equal), add a `CHANGELOG.md` entry, commit, then
|
|
624
769
|
|
|
625
770
|
```
|
|
626
|
-
git tag v0.
|
|
771
|
+
git tag v0.5.0 && git push origin main v0.5.0
|
|
627
772
|
```
|
|
628
773
|
|
|
629
774
|
The `publish` workflow checks that the tag matches the package version, runs the tests, builds
|