Skip to main content

Read, validate, and build Program MARK encounter-history (.inp) files.

Project description

markinp

CI PyPI Python versions License: MIT

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:

  1. validate an existing .inp file and report precise, actionable errors;
  2. inspect an .inp file and summarize its structure;
  3. build a valid .inp file from a tidy capture table (CSV).

Disclaimer. markinp is 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. markinp never 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 name markio was 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

markinp-0.1.0.tar.gz (38.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markinp-0.1.0-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

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

Hashes for markinp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9a0fc05c99a9f68d998e280b0ab92a9495ecd7ec2cceb146139ef624e96d8e3a
MD5 b2db2dced8db26d5e11dfb19e54a5074
BLAKE2b-256 ae723eab5decc84d96e9b46f6cada721493761d4605f5cf5c2abbdc6fd500da7

See more details on using hashes here.

Provenance

The following attestation bundles were made for markinp-0.1.0.tar.gz:

Publisher: release.yml on leonbzt/markinp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for markinp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eff9e1831e3bcbcb25e6ff5c2e245f96349f2879a2600e14c56139fec0308de8
MD5 e11481f9c9f02d782b8150093a13f0d0
BLAKE2b-256 9d45d76e604ecb3b38235fb16266511cc454bc2015d8b4ae028d22a0f2edc4e2

See more details on using hashes here.

Provenance

The following attestation bundles were made for markinp-0.1.0-py3-none-any.whl:

Publisher: release.yml on leonbzt/markinp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page