Read, validate, and build Program MARK encounter-history (.inp) files.
Project description
markinp
Read, validate, and build Program MARK encounter-history (.inp) files —
with error messages that actually tell you what to fix.
markinp removes the most common friction in the capture–recapture workflow:
hand-building .inp files in a text editor or Excel, and only discovering
formatting mistakes when MARK rejects the file with an unhelpful message.
It does three things and nothing more:
- validate an existing
.inpfile and report precise, actionable errors; - inspect an
.inpfile and summarize its structure; - build a valid
.inpfile from a tidy capture table (CSV).
Disclaimer.
markinpis an independent, unofficial utility. It is not affiliated with, endorsed by, or maintained by the authors of Program MARK or RMark. "MARK" is referenced only to describe the file format it interoperates with.markinpnever fits models or computes statistics — it does file I/O and validation only.
Note on the name. The command and PyPI package are
markinp(the namemarkiowas already taken on PyPI).
Install
pip install markinp
60-second quickstart
Validate a file you already have:
markinp validate captures.inp
markinp validate captures.inp
Structure: 4 occasions, 2 groups, 1 covariate, live_recapture
Records: 3 Individuals: 7
Summary: 0 errors, 0 warnings, 0 infos -> PASS
When something is wrong, you get the line and the fix — not a traceback:
MK001 ERROR line 12: record is not terminated by a semicolon
hint: Add a ';' at the end of this line to close the record ...
Inspect the inferred structure:
markinp inspect captures.inp
Build an .inp from a tidy CSV:
# long format: one row per (individual x occasion)
markinp build captures.csv -o out.inp \
--id-col id --occasion-col occasion --detect-col detected \
--group-col sex --covariate-cols weight
Validate many files at once (exits non-zero if any fail):
markinp validate data/*.inp --strict
Every command accepts --json for machine-readable output and exits non-zero
when errors are found, so markinp validate drops straight into CI.
Guard a pipeline (CI & pre-commit)
GitHub Action — fail a build when any .inp file is malformed:
# .github/workflows/validate-inp.yml
name: Validate .inp
on: [push, pull_request]
jobs:
markinp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: leonbzt/markinp@v0
with:
files: "data/**/*.inp"
args: "--strict"
pre-commit hook — validate .inp files before every commit:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/leonbzt/markinp
rev: v0.1.0
hooks:
- id: markinp-validate
Use it as a library
The CLI is a thin wrapper; everything is importable:
from markinp import parse_text, validate
result = parse_text("1001 1;\n0101 2;\n")
for diag in validate(result.dataset):
print(diag.code, diag.message)
The .inp format in one minute
Each record is one line ending in ;. Whitespace separates the fields:
[/* comment */] HISTORY FREQ_1 [FREQ_2 ...] [COV_1 ...] ; [/* comment */]
- HISTORY — one character per sampling occasion (
1= detected,0= not). - FREQ — one integer count per group; may be negative for losses on capture.
- COV — optional numeric individual covariates (no missing values allowed).
/* ind 001 */ 1001 1 0 10.2;
/* ind 002 */ 1101 0 2 9.5;
0101 3 1 8.1;
The number of occasions, groups, and covariates is usually not stored in the
file, so markinp infers it. Tighten the checks by asserting what you expect:
markinp validate captures.inp --occasions 4 --groups 2 --covariates 1
Error codes
Every problem is reported as a stable, documented diagnostic code (MK001 …).
See docs/error-codes.md for the full reference.
Highlights:
| Code | Meaning |
|---|---|
| MK001 | Record not terminated by ; |
| MK002 | History length differs between records |
| MK004 | Wrong number of frequency columns for the group count |
| MK007 | Missing / non-numeric covariate |
| MK011 | All-zero history (warning) |
| MK012 | Negative frequency — loss on capture (warning) |
| MK900 | Specialized format detected; only partially validated (info) |
--strict promotes warnings to errors. Exit code is 0 when there are no
errors and 1 otherwise.
Scope
v0 fully supports the standard 0/1 encounter-history format (live recapture /
CJS / Jolly-Seber / closed captures). Known-fate, dead-recovery (Brownie), and
multistrata formats are detected and structurally checked only (see MK900);
full support is a later milestone. markinp will always tell you honestly when
it can only partially validate a file.
Development
pip install -e ".[dev]"
ruff check .
mypy markinp
pytest
Testing
The suite includes a fixture that triggers every diagnostic code, round-trip
(parse → write → parse) stability checks, and build → validate round-trips.
To try it on real data, point markinp at a folder of .inp files:
markinp validate path/to/*.inp # batch validate; exits 1 if any fail
markinp inspect path/to/one.inp # summarize inferred structure
A local sample_data/ folder of third-party MARK example files is not part
of this repository (licensing), but is handy as a regression corpus — running
markinp validate sample_data/*.inp over it is a quick way to smoke-test a
change against a wide variety of real files. Note that occupancy, false-positive,
robust-design, and multistrata files are outside v0's standard-format scope and
will be flagged accordingly (see docs/error-codes.md).
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file markinp-0.1.0.tar.gz.
File metadata
- Download URL: markinp-0.1.0.tar.gz
- Upload date:
- Size: 38.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a0fc05c99a9f68d998e280b0ab92a9495ecd7ec2cceb146139ef624e96d8e3a
|
|
| MD5 |
b2db2dced8db26d5e11dfb19e54a5074
|
|
| BLAKE2b-256 |
ae723eab5decc84d96e9b46f6cada721493761d4605f5cf5c2abbdc6fd500da7
|
Provenance
The following attestation bundles were made for markinp-0.1.0.tar.gz:
Publisher:
release.yml on leonbzt/markinp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
markinp-0.1.0.tar.gz -
Subject digest:
9a0fc05c99a9f68d998e280b0ab92a9495ecd7ec2cceb146139ef624e96d8e3a - Sigstore transparency entry: 2047862046
- Sigstore integration time:
-
Permalink:
leonbzt/markinp@d9a9aaffde5e14dad2325341d442f4ceff69a74d -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/leonbzt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d9a9aaffde5e14dad2325341d442f4ceff69a74d -
Trigger Event:
release
-
Statement type:
File details
Details for the file markinp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: markinp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eff9e1831e3bcbcb25e6ff5c2e245f96349f2879a2600e14c56139fec0308de8
|
|
| MD5 |
e11481f9c9f02d782b8150093a13f0d0
|
|
| BLAKE2b-256 |
9d45d76e604ecb3b38235fb16266511cc454bc2015d8b4ae028d22a0f2edc4e2
|
Provenance
The following attestation bundles were made for markinp-0.1.0-py3-none-any.whl:
Publisher:
release.yml on leonbzt/markinp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
markinp-0.1.0-py3-none-any.whl -
Subject digest:
eff9e1831e3bcbcb25e6ff5c2e245f96349f2879a2600e14c56139fec0308de8 - Sigstore transparency entry: 2047862049
- Sigstore integration time:
-
Permalink:
leonbzt/markinp@d9a9aaffde5e14dad2325341d442f4ceff69a74d -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/leonbzt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d9a9aaffde5e14dad2325341d442f4ceff69a74d -
Trigger Event:
release
-
Statement type: