{"id":29586735,"url":"https://github.com/alonfnt/notata","last_synced_at":"2025-07-20T03:31:24.231Z","repository":{"id":305296660,"uuid":"1022505709","full_name":"alonfnt/notata","owner":"alonfnt","description":"A lightweight Python library for saving simulation or experiment results in a standardized, reproducible format.  Designed for scientists and researchers running simulations.","archived":false,"fork":false,"pushed_at":"2025-07-19T10:32:18.000Z","size":13,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-19T13:15:25.119Z","etag":null,"topics":["logging","python","scientific-computing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alonfnt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-19T08:07:18.000Z","updated_at":"2025-07-19T10:56:54.000Z","dependencies_parsed_at":"2025-07-19T13:15:36.709Z","dependency_job_id":"ed6adcaa-db5e-42e8-a8de-6cbac09ddfdd","html_url":"https://github.com/alonfnt/notata","commit_stats":null,"previous_names":["alonfnt/notata"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/alonfnt/notata","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alonfnt%2Fnotata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alonfnt%2Fnotata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alonfnt%2Fnotata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alonfnt%2Fnotata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alonfnt","download_url":"https://codeload.github.com/alonfnt/notata/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alonfnt%2Fnotata/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266063102,"owners_count":23870719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["logging","python","scientific-computing"],"created_at":"2025-07-20T03:31:23.848Z","updated_at":"2025-07-20T03:31:24.219Z","avatar_url":"https://github.com/alonfnt.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# notata\n\n[![tests](https://github.com/alonfnt/notata/actions/workflows/pytest.yml/badge.svg)](https://github.com/alonfnt/notata/actions/workflows/pytest.yml)\n[![PyPI](https://img.shields.io/pypi/v/notata.svg)](https://pypi.org/project/notata/)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg style=\"width: 500px; height: auto;\" alt=\"notata\" src=\"https://github.com/user-attachments/assets/54a59260-1dbf-4ff5-9fb0-046dd6e4f5f8\" /\u003e\n\u003c/p\u003e\n\n`notata` is a minimal library for **structured filesystem logging of scientific runs**.\n\nOne `Logbook` -\u003e one run directory: parameters, arrays, plots, artifacts, metadata, timestamped log. Explicit. Reproducible. Grep‑friendly.\n\n## Installation\n```bash\npip install notata\n```\n\n## Quick Start\n### Context Manager\n```python\nfrom notata import Logbook\nimport numpy as np\n\nwith Logbook(\"oscillator_dt1e-3\", params={\"omega\": 2.0, \"dt\": 1e-3, \"steps\": 10_000}) as log:\n    omega = 2.0\n    dt = 1e-3\n    steps = 10_000\n    x, v = 1.0, 0.0\n\n    xs = np.empty(steps)\n    vs = np.empty(steps)\n    E  = np.empty(steps)\n\n    for n in range(steps):\n        a = -omega**2 * x\n        x += v*dt + 0.5*a*dt*dt\n        a_new = -omega**2 * x\n        v += 0.5*(a + a_new)*dt\n        xs[n], vs[n] = x, v\n        E[n] = 0.5*(v**2 + (omega*x)**2)\n        if (n+1) % 2000 == 0:\n            log.info(f\"step={n+1} x={x:.4f} v={v:.4f} E={E[n]:.6f}\")\n\n    log.save_arrays(\"trajectory\", x=xs, v=vs)\n    log.save_numpy(\"energy\", E)\n    log.save_json(\"final_state\", {\"x\": float(x), \"v\": float(v), \"E\": float(E[-1])})\n```\n\n### Manual Lifecycle\n```python\nfrom notata import Logbook\nimport numpy as np\n\nlog = Logbook(\"heat_manual\", params={\"Nx\": 64, \"Ny\": 64, \"kappa\": 0.01, \"steps\": 500})\nNx = Ny = 64\nkappa = 0.01\ndx = 1.0\ndt = 0.2 * dx*dx / kappa\n\nX, Y = np.meshgrid(np.linspace(-1,1,Nx), np.linspace(-1,1,Ny), indexing=\"ij\")\nT = np.exp(-6*(X**2 + Y**2))\n\nsnap_every = 100\nfor step in range(500):\n    lap = (np.roll(T,1,0)+np.roll(T,-1,0)+np.roll(T,1,1)+np.roll(T,-1,1)-4*T)\n    T += kappa * dt * lap\n    if (step+1) % snap_every == 0:\n        log.save_numpy(f\"T_step{step+1}\", T, category=\"data/intermediate\")\n        log.info(f\"step={step+1} maxT={T.max():.4f}\")\nlog.save_json(\"final_stats\", {\"max\": float(T.max()), \"mean\": float(T.mean())})\nlog.mark_complete()\n```\n\n### Failure capture\n```python\nfrom notata import Logbook\nimport numpy as np\n\nlog = Logbook(\"unstable_run\", params={\"dt\": 0.5})\ntry:\n    dt = 0.5  # too large for stability\n    x, v, w = 1.0, 0.0, 5.0\n    for step in range(1000):\n        a = -w**2 * x\n        v += a * dt\n        x += v * dt\n        if not np.isfinite(x):\n            raise RuntimeError(\"Diverged\")\n    log.mark_complete()\nexcept Exception as e:\n    log.mark_failed(str(e))\n```\n\n## Output format\nData is stored as following:\n```bash\nlog_\u003crun_id\u003e/\n  log.txt\n  metadata.json\n  params.yaml\n  data/\n  plots/\n  artifacts/\n```\n\nwhere the files follow:\n\n| Path / Pattern                | Purpose / Format                                                                                      |\n|------------------------------|--------------------------------------------------------------------------------------------------------|\n| `log.txt`                    | Plain text log; lines: `[YYYY-MM-DDTHH:MM:SS] LEVEL message`                                           |\n| `metadata.json`              | Run metadata: `status`, `start_time`, optional `end_time`, `runtime_sec`, optional `failure_reason`, `run_id` |\n| `params.yaml` / `params.json`| Parameter snapshot (latest saved form)                                                                 |\n| `data/*.npz`                 | Array archives; single array → key `data`; multi-array save → keys = argument names                    |\n| `data/**/`                   | Additional numeric outputs (via `category=\"data/...\"`)                                                 |\n| `plots/*.png|pdf|svg`        | Saved figures (`save_plot`)                                                                            |\n| `artifacts/*.txt`            | Text artifacts (`save_text`)                                                                           |\n| `artifacts/*.json`           | JSON artifacts (`save_json`)                                                                           |\n| `artifacts/*.pkl`            | Pickled objects (`save_pickle`)                                                                        |\n| `artifacts/*` (other)        | Raw bytes (`save_bytes`)                                                                               |\n| `artifacts/**/`              | Nested artifact categories (e.g. `category=\"artifacts/logs\"`)                                          |\n\n## Citation\nYou don't have to, but if you use `notata` in your research and need to reference it, please cite it as follows:\n```\n@software{notata_2025,\n  author  = {Albert Alonso},\n  title   = {notata: Structured Filesystem Logging for Scientific Runs},\n  url     = {https://github.com/alonfnt/notata},\n  version = {0.1.0},\n  year    = {2025}\n}\n```\n\n## License\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falonfnt%2Fnotata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falonfnt%2Fnotata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falonfnt%2Fnotata/lists"}