gp3sequencespy 0.1.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.
Files changed (104) hide show
  1. gp3sequencespy-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +38 -0
  2. gp3sequencespy-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. gp3sequencespy-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +32 -0
  4. gp3sequencespy-0.1.0/.github/pull_request_template.md +17 -0
  5. gp3sequencespy-0.1.0/.github/workflows/ci.yml +83 -0
  6. gp3sequencespy-0.1.0/.github/workflows/docs.yml +41 -0
  7. gp3sequencespy-0.1.0/.github/workflows/release-check.yml +57 -0
  8. gp3sequencespy-0.1.0/.gitignore +30 -0
  9. gp3sequencespy-0.1.0/CHANGELOG.md +81 -0
  10. gp3sequencespy-0.1.0/CITATION.cff +20 -0
  11. gp3sequencespy-0.1.0/CODE_OF_CONDUCT.md +25 -0
  12. gp3sequencespy-0.1.0/CONTRIBUTING.md +38 -0
  13. gp3sequencespy-0.1.0/LICENSE +21 -0
  14. gp3sequencespy-0.1.0/PARITY_EXCEPTIONS.md +67 -0
  15. gp3sequencespy-0.1.0/PARITY_TEST_MATRIX.md +181 -0
  16. gp3sequencespy-0.1.0/PKG-INFO +103 -0
  17. gp3sequencespy-0.1.0/README.md +48 -0
  18. gp3sequencespy-0.1.0/RELEASE_CHECKLIST.md +41 -0
  19. gp3sequencespy-0.1.0/REPRODUCIBILITY.md +98 -0
  20. gp3sequencespy-0.1.0/SECURITY.md +25 -0
  21. gp3sequencespy-0.1.0/SIGNATURE_PARITY.md +40 -0
  22. gp3sequencespy-0.1.0/docs/articles/choosing-a-sequence-analysis-method.md +132 -0
  23. gp3sequencespy-0.1.0/docs/articles/consensus-and-group-comparisons.md +52 -0
  24. gp3sequencespy-0.1.0/docs/articles/contiguous-motif-workflow.md +118 -0
  25. gp3sequencespy-0.1.0/docs/articles/distances-clustering-and-stability.md +75 -0
  26. gp3sequencespy-0.1.0/docs/articles/extended-sequence-visualisations.md +60 -0
  27. gp3sequencespy-0.1.0/docs/articles/getting-started-with-gp3sequences.md +160 -0
  28. gp3sequencespy-0.1.0/docs/articles/index.md +23 -0
  29. gp3sequencespy-0.1.0/docs/articles/latent-models-and-optional-adapters.md +67 -0
  30. gp3sequencespy-0.1.0/docs/articles/longitudinal-panel-sequences.md +69 -0
  31. gp3sequencespy-0.1.0/docs/articles/multichannel-and-covariate-hmms.md +59 -0
  32. gp3sequencespy-0.1.0/docs/articles/noncontiguous-subsequence-mining.md +64 -0
  33. gp3sequencespy-0.1.0/docs/articles/reproducible-sequence-analysis-case-study.md +128 -0
  34. gp3sequencespy-0.1.0/docs/articles/sequence-data-validation-and-preparation.md +113 -0
  35. gp3sequencespy-0.1.0/docs/articles/sequence-inference-and-randomization.md +62 -0
  36. gp3sequencespy-0.1.0/docs/articles/time-varying-condition-models.md +68 -0
  37. gp3sequencespy-0.1.0/docs/articles/transition-networks-and-higher-order-models.md +48 -0
  38. gp3sequencespy-0.1.0/docs/index.md +29 -0
  39. gp3sequencespy-0.1.0/docs/parity.md +12 -0
  40. gp3sequencespy-0.1.0/docs/reference/api.md +571 -0
  41. gp3sequencespy-0.1.0/docs/reference/index.md +6 -0
  42. gp3sequencespy-0.1.0/docs/release-readiness.md +28 -0
  43. gp3sequencespy-0.1.0/docs/stylesheets/extra.css +2 -0
  44. gp3sequencespy-0.1.0/mkdocs.yml +65 -0
  45. gp3sequencespy-0.1.0/parity/README.md +13 -0
  46. gp3sequencespy-0.1.0/parity/__init__.py +1 -0
  47. gp3sequencespy-0.1.0/parity/actual/.gitkeep +0 -0
  48. gp3sequencespy-0.1.0/parity/canonicalizers/__init__.py +1 -0
  49. gp3sequencespy-0.1.0/parity/canonicalizers/csv_contracts.py +54 -0
  50. gp3sequencespy-0.1.0/parity/compare_oracle.py +47 -0
  51. gp3sequencespy-0.1.0/parity/expected/README.md +15 -0
  52. gp3sequencespy-0.1.0/parity/fixtures/minimal.csv +17 -0
  53. gp3sequencespy-0.1.0/parity/generate_python_outputs.py +70 -0
  54. gp3sequencespy-0.1.0/parity/r_scripts/generate_reference_outputs.R +82 -0
  55. gp3sequencespy-0.1.0/parity/signature_audit.py +456 -0
  56. gp3sequencespy-0.1.0/pyproject.toml +74 -0
  57. gp3sequencespy-0.1.0/reference/R_REFERENCE.md +18 -0
  58. gp3sequencespy-0.1.0/reference/api_manifest.json +488 -0
  59. gp3sequencespy-0.1.0/reference/article_manifest.json +77 -0
  60. gp3sequencespy-0.1.0/reference/oracle_validation.json +71 -0
  61. gp3sequencespy-0.1.0/reference/release_candidate_contract_0.1.0.json +17 -0
  62. gp3sequencespy-0.1.0/reference/signature_parity_matrix.json +3564 -0
  63. gp3sequencespy-0.1.0/reference/signatures.json +83 -0
  64. gp3sequencespy-0.1.0/reference/source_manifest.json +117 -0
  65. gp3sequencespy-0.1.0/reference/test_manifest.json +112 -0
  66. gp3sequencespy-0.1.0/reference/test_parity_matrix.json +912 -0
  67. gp3sequencespy-0.1.0/src/gp3sequencespy/__init__.py +220 -0
  68. gp3sequencespy-0.1.0/src/gp3sequencespy/_advanced.py +441 -0
  69. gp3sequencespy-0.1.0/src/gp3sequencespy/_exceptions.py +14 -0
  70. gp3sequencespy-0.1.0/src/gp3sequencespy/_types.py +189 -0
  71. gp3sequencespy-0.1.0/src/gp3sequencespy/adapters.py +256 -0
  72. gp3sequencespy-0.1.0/src/gp3sequencespy/analysis_audit.py +462 -0
  73. gp3sequencespy-0.1.0/src/gp3sequencespy/capabilities.py +102 -0
  74. gp3sequencespy-0.1.0/src/gp3sequencespy/consensus.py +394 -0
  75. gp3sequencespy-0.1.0/src/gp3sequencespy/covariate_hmm.py +576 -0
  76. gp3sequencespy-0.1.0/src/gp3sequencespy/data.py +979 -0
  77. gp3sequencespy-0.1.0/src/gp3sequencespy/distances.py +878 -0
  78. gp3sequencespy-0.1.0/src/gp3sequencespy/hmm.py +644 -0
  79. gp3sequencespy-0.1.0/src/gp3sequencespy/inference.py +342 -0
  80. gp3sequencespy-0.1.0/src/gp3sequencespy/motif_visualisation.py +550 -0
  81. gp3sequencespy-0.1.0/src/gp3sequencespy/motifs.py +517 -0
  82. gp3sequencespy-0.1.0/src/gp3sequencespy/multichannel_hmm.py +425 -0
  83. gp3sequencespy-0.1.0/src/gp3sequencespy/networks.py +514 -0
  84. gp3sequencespy-0.1.0/src/gp3sequencespy/panel.py +282 -0
  85. gp3sequencespy-0.1.0/src/gp3sequencespy/py.typed +0 -0
  86. gp3sequencespy-0.1.0/src/gp3sequencespy/subsequences.py +347 -0
  87. gp3sequencespy-0.1.0/src/gp3sequencespy/summaries.py +441 -0
  88. gp3sequencespy-0.1.0/src/gp3sequencespy/time_models.py +450 -0
  89. gp3sequencespy-0.1.0/src/gp3sequencespy/visualisations.py +420 -0
  90. gp3sequencespy-0.1.0/tests/test_core_port.py +492 -0
  91. gp3sequencespy-0.1.0/tests/test_docs_contract.py +48 -0
  92. gp3sequencespy-0.1.0/tests/test_numpy_pandas_compat.py +19 -0
  93. gp3sequencespy-0.1.0/tests/test_parity_harness.py +57 -0
  94. gp3sequencespy-0.1.0/tests/test_public_api.py +79 -0
  95. gp3sequencespy-0.1.0/tests/test_r_advanced_deterministic_contracts.py +473 -0
  96. gp3sequencespy-0.1.0/tests/test_r_block_completion.py +296 -0
  97. gp3sequencespy-0.1.0/tests/test_r_deterministic_contracts.py +680 -0
  98. gp3sequencespy-0.1.0/tests/test_r_hclust_oracle_regressions.py +128 -0
  99. gp3sequencespy-0.1.0/tests/test_r_remaining_contracts.py +620 -0
  100. gp3sequencespy-0.1.0/tests/test_release_contract.py +73 -0
  101. gp3sequencespy-0.1.0/tests/test_remaining_r_api.py +184 -0
  102. gp3sequencespy-0.1.0/tests/test_signature_parity.py +108 -0
  103. gp3sequencespy-0.1.0/tests/test_time_mssm_backend.py +131 -0
  104. gp3sequencespy-0.1.0/uv.lock +2872 -0
@@ -0,0 +1,38 @@
1
+ name: Bug report
2
+ description: Report a reproducible defect or parity regression
3
+ title: "[Bug]: "
4
+ labels: ["bug"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: Thanks for reporting a reproducible problem.
9
+ - type: input
10
+ id: version
11
+ attributes:
12
+ label: gp3sequencespy version or commit
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: reproduce
17
+ attributes:
18
+ label: Minimal reproducible example
19
+ render: python
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: expected
24
+ attributes:
25
+ label: Expected behavior
26
+ validations:
27
+ required: true
28
+ - type: textarea
29
+ id: observed
30
+ attributes:
31
+ label: Observed behavior
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: environment
36
+ attributes:
37
+ label: Environment
38
+ description: OS, Python, pandas/numpy/scipy versions, and optional extras.
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Documentation
4
+ url: https://stefanosbalaskas.github.io/gp3sequencespy/
5
+ about: Check the documentation and parity notes before filing an issue.
@@ -0,0 +1,32 @@
1
+ name: Feature request
2
+ description: Propose a parity-preserving or Python-native extension
3
+ title: "[Feature]: "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: textarea
7
+ id: problem
8
+ attributes:
9
+ label: Scientific or software problem
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed API or behavior
16
+ validations:
17
+ required: true
18
+ - type: dropdown
19
+ id: relationship
20
+ attributes:
21
+ label: Relationship to frozen R 0.3.0
22
+ options:
23
+ - Direct parity counterpart
24
+ - Parity clarification or bug fix
25
+ - Python-native extension after frozen parity
26
+ - Unsure
27
+ validations:
28
+ required: true
29
+ - type: textarea
30
+ id: evidence
31
+ attributes:
32
+ label: Methodological references or examples
@@ -0,0 +1,17 @@
1
+ ## Summary
2
+
3
+ Describe the change and the scientific/software contract it affects.
4
+
5
+ ## Parity impact
6
+
7
+ - [ ] No frozen R contract is changed.
8
+ - [ ] Frozen parity behavior is intentionally changed/clarified and tests were updated.
9
+ - [ ] `PARITY_EXCEPTIONS.md` was updated if an R → Python translation is involved.
10
+
11
+ ## Validation
12
+
13
+ - [ ] Ruff lint and format checks pass.
14
+ - [ ] mypy passes.
15
+ - [ ] Full pytest suite passes.
16
+ - [ ] Documentation builds with `mkdocs build --strict` when applicable.
17
+ - [ ] Built-artifact behavior was checked when packaging metadata changed.
@@ -0,0 +1,83 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ quality:
14
+ name: Static quality / Python 3.11
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: astral-sh/setup-uv@v6
19
+ with:
20
+ python-version: "3.11"
21
+ enable-cache: true
22
+ - name: Sync environment
23
+ run: uv sync --extra dev --extra time
24
+ - name: Ruff lint
25
+ run: uv run ruff check src tests parity
26
+ - name: Ruff format
27
+ run: uv run ruff format --check src tests parity
28
+ - name: mypy
29
+ run: uv run mypy src/gp3sequencespy
30
+ - name: Frozen API contract
31
+ run: >-
32
+ uv run python -c "import json,pathlib,gp3sequencespy as g;
33
+ names=[x['name'] for x in json.loads(pathlib.Path('reference/api_manifest.json').read_text())];
34
+ missing=[x for x in names if not hasattr(g,x)];
35
+ hidden=[x for x in names if x not in g.__all__];
36
+ print('reference:',len(names),'present:',len(names)-len(missing),'missing:',missing,'not_in___all__:',hidden);
37
+ assert len(names)==81 and not missing and not hidden"
38
+ - name: Frozen R block ledger
39
+ run: >-
40
+ uv run python -c "import json,pathlib;
41
+ m=json.loads(pathlib.Path('reference/test_parity_matrix.json').read_text());
42
+ pairs={(r['r_test_file'],r['r_block_index']) for r in m};
43
+ py={r['python_test'] for r in m};
44
+ print('mapped blocks:',len(m),'unique R blocks:',len(pairs),'unique Python translations:',len(py));
45
+ assert len(m)==130 and len(pairs)==130 and len(py)==130"
46
+
47
+ - name: Frozen signature parity
48
+ run: uv run python parity/signature_audit.py --check reference/signature_parity_matrix.json
49
+
50
+ test:
51
+ name: Python ${{ matrix.python-version }} / ${{ matrix.os }}
52
+ runs-on: ${{ matrix.os }}
53
+ strategy:
54
+ fail-fast: false
55
+ matrix:
56
+ os: [ubuntu-latest, windows-latest, macos-latest]
57
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
58
+ steps:
59
+ - uses: actions/checkout@v4
60
+ - uses: astral-sh/setup-uv@v6
61
+ with:
62
+ python-version: ${{ matrix.python-version }}
63
+ enable-cache: true
64
+ - name: Sync environment
65
+ run: uv sync --extra dev --extra time
66
+ - name: Run tests
67
+ run: uv run pytest -q
68
+
69
+ build:
70
+ runs-on: ubuntu-latest
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ - uses: astral-sh/setup-uv@v6
74
+ with:
75
+ python-version: "3.13"
76
+ - name: Build distributions
77
+ run: uv build
78
+ - name: Fresh wheel smoke test
79
+ shell: bash
80
+ run: |
81
+ python -m venv /tmp/gp3seq-wheel-test
82
+ /tmp/gp3seq-wheel-test/bin/pip install dist/*.whl
83
+ /tmp/gp3seq-wheel-test/bin/python -c "import gp3sequencespy; print(gp3sequencespy.__version__)"
@@ -0,0 +1,41 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "docs/**"
8
+ - "mkdocs.yml"
9
+ - "src/**"
10
+ - "pyproject.toml"
11
+ - ".github/workflows/docs.yml"
12
+ pull_request:
13
+ paths:
14
+ - "docs/**"
15
+ - "mkdocs.yml"
16
+ - "src/**"
17
+ - "pyproject.toml"
18
+ - ".github/workflows/docs.yml"
19
+ workflow_dispatch:
20
+
21
+ permissions:
22
+ contents: write
23
+
24
+ jobs:
25
+ build:
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: astral-sh/setup-uv@v6
30
+ with:
31
+ python-version: "3.13"
32
+ enable-cache: true
33
+ - name: Sync docs environment
34
+ run: uv sync --extra docs --extra dev --extra time
35
+ - name: Validate documentation contracts
36
+ run: uv run pytest -q tests/test_docs_contract.py
37
+ - name: Build documentation
38
+ run: uv run mkdocs build --strict
39
+ - name: Deploy gh-pages
40
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
41
+ run: uv run mkdocs gh-deploy --force
@@ -0,0 +1,57 @@
1
+ name: Release checks
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ release-check:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: astral-sh/setup-uv@v6
18
+ with:
19
+ python-version: "3.13"
20
+ enable-cache: true
21
+ - name: Sync release environment
22
+ run: uv sync --extra dev --extra time --extra docs --extra release
23
+ - name: Validate project metadata
24
+ run: uv run validate-pyproject pyproject.toml
25
+ - name: Static quality
26
+ run: |
27
+ uv run ruff check src tests parity
28
+ uv run ruff format --check src tests parity
29
+ uv run mypy src/gp3sequencespy
30
+ - name: Tests and frozen contracts
31
+ run: |
32
+ uv run pytest -q
33
+ uv run python -c "import json,pathlib,gp3sequencespy as g; assert g.__version__ == '0.1.0'; n=[x['name'] for x in json.loads(pathlib.Path('reference/api_manifest.json').read_text())]; assert len(n)==81 and all(hasattr(g,x) and x in g.__all__ for x in n)"
34
+ uv run python -c "import json,pathlib; m=json.loads(pathlib.Path('reference/test_parity_matrix.json').read_text()); assert len(m)==130 and len({(r['r_test_file'],r['r_block_index']) for r in m})==130"
35
+ - name: Verify frozen signature matrix
36
+ run: uv run python parity/signature_audit.py --check reference/signature_parity_matrix.json
37
+ - name: Strict documentation build
38
+ run: uv run mkdocs build --strict
39
+ - name: Build distributions
40
+ run: uv build
41
+ - name: Validate distributions
42
+ run: uv run twine check --strict dist/*
43
+ - name: Verify wheel contents and metadata
44
+ run: >-
45
+ uv run python -c "import glob,zipfile; w=glob.glob('dist/*.whl'); assert len(w)==1; z=zipfile.ZipFile(w[0]); n=z.namelist(); assert any(x.endswith('.dist-info/licenses/LICENSE') for x in n); assert any(x=='gp3sequencespy/__init__.py' for x in n); print(w[0]); print('wheel files:',len(n))"
46
+ - name: Fresh wheel smoke test
47
+ shell: bash
48
+ run: |
49
+ python -m venv /tmp/gp3seq-release-wheel
50
+ wheel="$(echo dist/*.whl)"
51
+ /tmp/gp3seq-release-wheel/bin/pip install "${wheel}[time]"
52
+ /tmp/gp3seq-release-wheel/bin/python -c "import gp3sequencespy as g; assert g.__version__ == '0.1.0'; print(g.__version__); print(len(g.__all__))"
53
+ - uses: actions/upload-artifact@v4
54
+ with:
55
+ name: gp3sequencespy-release-candidate
56
+ path: dist/*
57
+ if-no-files-found: error
@@ -0,0 +1,30 @@
1
+ # Python environments and caches
2
+ .venv/
3
+ venv/
4
+ __pycache__/
5
+ *.py[cod]
6
+ .pytest_cache/
7
+ .mypy_cache/
8
+ .ruff_cache/
9
+ .coverage
10
+ htmlcov/
11
+
12
+ # Build artifacts
13
+ build/
14
+ dist/
15
+ *.egg-info/
16
+
17
+ # IDE / OS
18
+ .vscode/
19
+ .idea/
20
+ .DS_Store
21
+ Thumbs.db
22
+
23
+ # Local secrets
24
+ .env
25
+ .env.*
26
+
27
+ # Generated parity outputs
28
+ parity/actual/*
29
+ !parity/actual/.gitkeep
30
+ parity/reports/*.txt
@@ -0,0 +1,81 @@
1
+ # Changelog
2
+
3
+ All notable changes to `gp3sequencespy` are documented here. The project is
4
+ currently alpha software and follows parity-first development against the frozen
5
+ R package `gp3sequences` 0.3.0.
6
+
7
+ ## [Unreleased]
8
+
9
+ No changes yet.
10
+
11
+ ## [0.1.0] - 2026-08-30
12
+
13
+ ### Added
14
+
15
+ - First non-prerelease Python release preserving all **81 / 81** frozen
16
+ `gp3sequences 0.3.0` public function counterparts.
17
+ - **130 / 130** dedicated translations of the frozen R `test_that()` blocks.
18
+ - Fifteen Python-native article/vignette counterparts, MkDocs documentation,
19
+ release governance, and multi-platform CI across Python 3.11–3.14.
20
+ - Machine-readable frozen API, test-block, signature, and oracle records.
21
+
22
+ ### Changed
23
+
24
+ - Replaced the early statsmodels/Patsy time-model approximation with a validated
25
+ `mssm` binomial GAMM backend using penalized by-group smooths and genuine
26
+ participant random intercepts.
27
+ - Restored frozen plotting defaults and retained Matplotlib `ax=` only as a
28
+ keyword-only Python extension.
29
+ - Aligned hierarchical clustering and medoid semantics with R `hclust()`/PAM,
30
+ including `members=` behavior and tie-sensitive medoid scoring.
31
+
32
+ ### Validation
33
+
34
+ - **182** Python tests pass locally before the release-candidate artifact freeze.
35
+ - Frozen API: **81 / 81**.
36
+ - Frozen R block ledger: **130 / 130**.
37
+ - Frozen public signatures: **81 / 81**, with **0 unexplained drift**.
38
+ - Deterministic six-contract R↔Python oracle: **PASS**.
39
+ - Extended clustering oracle: **3915 / 3915** partition rows and **108 / 108**
40
+ medoid rows matched, plus fresh `members=` oracle **PASS**.
41
+ - Time-model calibration: **12 / 12** `k=3/4/5 × state/transition × random-effect`
42
+ scenarios fit successfully within the validated R-error envelope; frozen-R
43
+ transition extrapolation matched to an absolute difference of approximately
44
+ `8.29e-06`.
45
+ - Exact final-version wheel and sdist must pass clean-environment artifact tests
46
+ before this commit can be pushed by the RC transaction.
47
+
48
+ ### Deliberate parity boundaries
49
+
50
+ The stable release retains the explicitly reviewed boundaries in
51
+ `PARITY_EXCEPTIONS.md`: ecosystem-specific R object identity, plotting-engine
52
+ identity, cross-language RNG stream identity, and bit-for-bit `mgcv` identity /
53
+ non-default smoothing criteria are not claimed.
54
+
55
+ ## [0.1.0a1] - 2026-08-29
56
+
57
+ ### Added
58
+
59
+ - 81 / 81 frozen R 0.3.0 public API counterparts.
60
+ - 130 / 130 frozen R `test_that()` block translations.
61
+ - Data validation, preparation, summaries, sequence distances, clustering,
62
+ consensus, motifs, transition networks, higher-order models, HMM families,
63
+ panel workflows, subsequence mining, inference, time-varying models, adapters,
64
+ audits, and visualisations.
65
+ - Cross-language parity harness with deterministic oracle fixtures.
66
+ - Ruff and mypy release-quality gates.
67
+ - Linux, macOS, and Windows CI on Python 3.11–3.14.
68
+ - Fifteen Python-native ports of the frozen R vignette set.
69
+ - MkDocs documentation and GitHub Pages deployment.
70
+
71
+ ### Validation
72
+
73
+ - 162 tests passing before the release-readiness tranche.
74
+ - 81 / 81 public API contract.
75
+ - 130 / 130 frozen R test-block ledger.
76
+ - Wheel and source distribution build smoke tests.
77
+
78
+ ### Known parity boundaries
79
+
80
+ See `PARITY_EXCEPTIONS.md`. API and behavioral-contract coverage do not by
81
+ themselves establish exact numerical parity for R RNG streams, cross-language RNG streams, ecosystem-specific adapter objects, or explicitly documented backend boundaries.
@@ -0,0 +1,20 @@
1
+ cff-version: 1.2.0
2
+ message: >-
3
+ If you use gp3sequencespy in research, please cite the software and record
4
+ the exact version used.
5
+ title: gp3sequencespy
6
+ type: software
7
+ authors:
8
+ - family-names: Balaskas
9
+ given-names: Stefanos
10
+ version: 0.1.0
11
+ date-released: 2026-08-30
12
+ license: MIT
13
+ repository-code: https://github.com/stefanosbalaskas/gp3sequencespy
14
+ url: https://stefanosbalaskas.github.io/gp3sequencespy/
15
+ keywords:
16
+ - sequence analysis
17
+ - scanpaths
18
+ - eye tracking
19
+ - categorical sequences
20
+ - reproducible research
@@ -0,0 +1,25 @@
1
+ # Code of Conduct
2
+
3
+ ## Our standard
4
+
5
+ Participation in the `gp3sequencespy` community should be professional,
6
+ respectful, constructive, and focused on improving scientific software.
7
+ Harassment, discriminatory conduct, personal attacks, intimidation, deliberate
8
+ disruption, and disclosure of private information are not acceptable.
9
+
10
+ ## Scientific disagreement
11
+
12
+ Technical and methodological disagreement is welcome. Critique ideas, evidence,
13
+ implementations, and assumptions rather than people. When a parity or statistical
14
+ claim is disputed, prefer a reproducible example, test, benchmark, or primary
15
+ source over rhetoric.
16
+
17
+ ## Enforcement
18
+
19
+ Maintainers may edit, reject, lock, or remove contributions that violate these
20
+ standards and may restrict participation for repeated or severe violations.
21
+
22
+ ## Scope
23
+
24
+ This policy applies to project repositories, issue trackers, pull requests,
25
+ documentation spaces, and other project-managed communication channels.
@@ -0,0 +1,38 @@
1
+ # Contributing to gp3sequencespy
2
+
3
+ `gp3sequencespy` is developed parity-first against the frozen R package
4
+ `gp3sequences` 0.3.0. Contributions are welcome when they preserve the frozen
5
+ scientific contracts and make deviations explicit.
6
+
7
+ ## Development setup
8
+
9
+ ```bash
10
+ uv sync --extra dev --extra time --extra docs --extra release
11
+ ```
12
+
13
+ Run the local quality gates before opening a pull request:
14
+
15
+ ```bash
16
+ uv run ruff check src tests parity
17
+ uv run ruff format --check src tests parity
18
+ uv run mypy src/gp3sequencespy
19
+ uv run pytest -q
20
+ uv run mkdocs build --strict
21
+ uv build
22
+ uv run twine check dist/*
23
+ ```
24
+
25
+ ## Parity rules
26
+
27
+ 1. Do not change an R-corresponding public contract silently.
28
+ 2. Add or update a parity test whenever a frozen behavior changes or is clarified.
29
+ 3. Record deliberate R → Python ecosystem translations in `PARITY_EXCEPTIONS.md`.
30
+ 4. Keep stochastic behavior reproducible without mutating the caller's global RNG.
31
+ 5. Do not infer psychological, medical, biometric, or causal meaning from sequence
32
+ structure unless the study design and method explicitly support that inference.
33
+
34
+ ## Pull requests
35
+
36
+ Keep changes focused. Describe the scientific contract affected, tests added,
37
+ backward-compatibility implications, and whether exact R numerical parity is
38
+ expected, translated, or still oracle-pending.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stefanos Balaskas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,67 @@
1
+ # Parity exceptions and validation status
2
+
3
+ The frozen behavioral reference is **gp3sequences 0.3.0**. Python functions retain the frozen R public names, but R-specific runtime objects cannot always be represented identically in Python.
4
+
5
+ ## Validated deterministic cross-language parity
6
+
7
+ The deterministic oracle was executed on Windows with **R 4.6.1** against a locally rebuilt final `gp3sequences 0.3.0` tarball from release commit `4ebf0bebea2955c5f98f8ddf0fe03e81d0b7ac3a`.
8
+
9
+ The local final tarball has archive SHA-256:
10
+
11
+ ```text
12
+ 4024a6657d4567e44615cdf87419654bd097822016c8b84bd929aa3db4dcd3a8
13
+ ```
14
+
15
+ It was proven source-equivalent to the canonical frozen artifact after normalizing build-only `DESCRIPTION` fields and excluding generated build artifacts. The normalized 199-file source manifest has SHA-256:
16
+
17
+ ```text
18
+ 4dd1566e38cb20da1115fc466cc6db3b99f98413aa93876402f59221fc954e56
19
+ ```
20
+
21
+ The core deterministic oracle matched all six canonical CSV contracts: state summaries, transition summaries, formatted paths, motif summaries, consensus sequences, and Levenshtein distances.
22
+
23
+ The extended clustering oracle also validates R-compatible hierarchical partitions and medoids for `single`, `complete`, `average`, `mcquitty`, `median`, `centroid`, `ward.D`, and `ward.D2` across four tie-resistant fixtures and multiple `k` values, plus deterministic PAM behavior. Regression tests preserve the discovered R `hclust()` semantics.
24
+
25
+ ## Explicit backend-object translations
26
+
27
+ - `as_traminer_sequences()` returns a structured wide-sequence Python adapter rather than a TraMineR `stslist` S3 object.
28
+ - `as_seqhmm_sequences()` returns the same structured observations tagged for the seqHMM handoff rather than an R `stslist`.
29
+ - `as_arules_sequences()` returns itemsets plus cSPADE-compatible `sequenceID`/`eventID` metadata rather than an R `transactions` S4 object.
30
+ - `as_igraph_transition_network()` returns a NetworkX graph with the corresponding edge attributes rather than an R igraph object.
31
+
32
+ These are deliberate semantic translations. Their data contracts are tested; object identity with the R backend is not claimed.
33
+
34
+ ## Remaining deliberate/non-exact numerical boundaries
35
+
36
+ - **Plotting backend:** frozen plotting formals/default labels are preserved, while Python uses Matplotlib rather than base R graphics. Plot functions expose a keyword-only `ax=` target as a Python-native extension. R palette labels are mapped to Matplotlib renderers (`Viridis` → `viridis`, `Dark 3` → `tab10`). Plot-data contracts are tested; pixel-identical R graphics are not claimed.
37
+ - **Randomised algorithms:** NumPy and R use different random-number generators and streams. The parity target is deterministic behavior for a declared Python seed, global-RNG isolation, and equivalent statistical/algorithmic contracts—not bit-for-bit identity of cross-language random draws.
38
+ - **Time-varying sequence models:** the statsmodels/Patsy approximation has been replaced by `mssm` 1.2.5, using a binomial GAMM with a group main effect, separate penalized time smooths by group, and a genuine participant random intercept when requested. The documented `mgcv k -> mssm nk=k-1` mapping is used, with an adaptive spline degree at the frozen public minimum `k=3`. Population prediction excludes the participant random effect, as frozen R `predict.gam(..., exclude='s(.participant)')` does. Cross-language calibration covered state/transition outcomes, random effect on/off, `k=3/4/5`, and out-of-support transition prediction. This is a validated close semantic translation, not a claim of bit-for-bit `mgcv` identity. The Python backend intentionally supports the verified frozen default `method='REML'`; other `mgcv::gam()` smoothing criteria remain an explicit unsupported non-default boundary.
39
+
40
+ ## Stable 0.1.0 exception review — 2026-08-30
41
+
42
+ Every remaining entry was reviewed before the 0.1.0 release-candidate freeze.
43
+ All are **retained deliberately**; none is an unexplained implementation gap:
44
+
45
+ 1. **R ecosystem objects → Python-native adapters:** TraMineR/seqHMM/arules/igraph
46
+ object identity is runtime-specific. The Python adapters preserve the tested data
47
+ contract and expose native Python/NetworkX structures.
48
+ 2. **Base-R graphics → Matplotlib:** plot-data contracts, public defaults, and call
49
+ semantics are tested. Pixel-level identity across rendering engines is neither
50
+ meaningful nor claimed.
51
+ 3. **R RNG streams → NumPy RNG streams:** declared Python seeds are deterministic and
52
+ global-RNG isolation/algorithmic contracts are tested; cross-language random draws
53
+ are not expected to be bit-for-bit identical.
54
+ 4. **`mgcv::gam()` → `mssm` GAMM:** the frozen default REML contract is calibrated
55
+ cross-language, including `k=3/4/5`, state/transition outcomes, participant random
56
+ effects, and extrapolation. Exact penalty/coefficient identity and non-default mgcv
57
+ smoothing criteria are outside the validated Python contract.
58
+
59
+ These retained boundaries are compatible with a stable Python API because they are
60
+ explicit, tested, and arise from language/backend differences rather than silent
61
+ behavioral drift.
62
+
63
+ ## Frozen-test translation status
64
+
65
+ All **130 / 130** frozen R `test_that()` blocks have one dedicated Python translation test. The mapping is machine-readable in `reference/test_parity_matrix.json` and human-readable in `PARITY_TEST_MATRIX.md`.
66
+
67
+ Behavioral-contract coverage, deterministic oracle coverage, and deliberate backend translations are reported separately so that one does not overstate the other.