Metadata-Version: 2.4
Name: scitex
Version: 2.13.0
Summary: A comprehensive Python library for scientific computing and data analysis
Project-URL: Homepage, https://github.com/ywatanabe1989/scitex-code
Project-URL: Documentation, https://scitex.readthedocs.io
Project-URL: Repository, https://github.com/ywatanabe1989/scitex-code
Project-URL: Bug Tracker, https://github.com/ywatanabe1989/scitex-code/issues
Author-email: Yusuke Watanabe <ywatanabe@scitex.ai>
License: AGPL-3.0
License-File: LICENSE
Keywords: data-analysis,machine-learning,neural-networks,research,scientific-computing,signal-processing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Requires-Dist: natsort
Requires-Dist: numpy
Requires-Dist: packaging
Requires-Dist: pandas
Requires-Dist: pyyaml
Requires-Dist: tqdm
Provides-Extra: ai
Requires-Dist: anthropic; extra == 'ai'
Requires-Dist: google-genai; extra == 'ai'
Requires-Dist: groq; extra == 'ai'
Requires-Dist: imbalanced-learn; extra == 'ai'
Requires-Dist: joblib; extra == 'ai'
Requires-Dist: markdown2; extra == 'ai'
Requires-Dist: matplotlib; extra == 'ai'
Requires-Dist: natsort; extra == 'ai'
Requires-Dist: openai; extra == 'ai'
Requires-Dist: pillow; extra == 'ai'
Requires-Dist: pyyaml; extra == 'ai'
Requires-Dist: requests; extra == 'ai'
Requires-Dist: ruamel-yaml; extra == 'ai'
Requires-Dist: scikit-learn; extra == 'ai'
Requires-Dist: scipy; extra == 'ai'
Requires-Dist: seaborn; extra == 'ai'
Requires-Dist: sktime; extra == 'ai'
Requires-Dist: umap-learn; extra == 'ai'
Requires-Dist: xarray; extra == 'ai'
Provides-Extra: all
Requires-Dist: accelerate; extra == 'all'
Requires-Dist: aiohttp; extra == 'all'
Requires-Dist: anthropic; extra == 'all'
Requires-Dist: beautifulsoup4; extra == 'all'
Requires-Dist: bibtexparser; extra == 'all'
Requires-Dist: bitsandbytes; extra == 'all'
Requires-Dist: catboost; extra == 'all'
Requires-Dist: celery; extra == 'all'
Requires-Dist: click; extra == 'all'
Requires-Dist: crawl4ai; extra == 'all'
Requires-Dist: csv2latex; extra == 'all'
Requires-Dist: dearpygui; extra == 'all'
Requires-Dist: einops; extra == 'all'
Requires-Dist: elevenlabs; extra == 'all'
Requires-Dist: fairscale; extra == 'all'
Requires-Dist: fastapi; extra == 'all'
Requires-Dist: feedparser; extra == 'all'
Requires-Dist: figrecipe; extra == 'all'
Requires-Dist: flask; extra == 'all'
Requires-Dist: geom-median; extra == 'all'
Requires-Dist: gitpython; extra == 'all'
Requires-Dist: google-genai; extra == 'all'
Requires-Dist: groq; extra == 'all'
Requires-Dist: gtts; extra == 'all'
Requires-Dist: h5py; extra == 'all'
Requires-Dist: html2text; extra == 'all'
Requires-Dist: httpx; extra == 'all'
Requires-Dist: imbalanced-learn; extra == 'all'
Requires-Dist: ipdb; extra == 'all'
Requires-Dist: ipykernel; extra == 'all'
Requires-Dist: ipython; extra == 'all'
Requires-Dist: joblib; extra == 'all'
Requires-Dist: julius; extra == 'all'
Requires-Dist: jupyter-collaboration; extra == 'all'
Requires-Dist: jupyterlab; extra == 'all'
Requires-Dist: jupytext; extra == 'all'
Requires-Dist: llvmlite>=0.39.0; extra == 'all'
Requires-Dist: lxml; extra == 'all'
Requires-Dist: lxml-html-clean; extra == 'all'
Requires-Dist: markdown; extra == 'all'
Requires-Dist: matplotlib; extra == 'all'
Requires-Dist: mcp; extra == 'all'
Requires-Dist: mne; extra == 'all'
Requires-Dist: mss; extra == 'all'
Requires-Dist: natsort; extra == 'all'
Requires-Dist: nbsphinx; extra == 'all'
Requires-Dist: nest-asyncio; extra == 'all'
Requires-Dist: numcodecs; extra == 'all'
Requires-Dist: obspy; extra == 'all'
Requires-Dist: openai; extra == 'all'
Requires-Dist: opencv-python; extra == 'all'
Requires-Dist: openpyxl; extra == 'all'
Requires-Dist: optuna; extra == 'all'
Requires-Dist: papermill; extra == 'all'
Requires-Dist: pdfplumber; extra == 'all'
Requires-Dist: piexif; extra == 'all'
Requires-Dist: pillow; extra == 'all'
Requires-Dist: playwright>=1.40.0; extra == 'all'
Requires-Dist: plotly; extra == 'all'
Requires-Dist: psutil; extra == 'all'
Requires-Dist: psycopg2-binary; extra == 'all'
Requires-Dist: pybids; extra == 'all'
Requires-Dist: pydantic; extra == 'all'
Requires-Dist: pydub; extra == 'all'
Requires-Dist: pyedflib; extra == 'all'
Requires-Dist: pymatreader; extra == 'all'
Requires-Dist: pymed; extra == 'all'
Requires-Dist: pymupdf; extra == 'all'
Requires-Dist: pypandoc; extra == 'all'
Requires-Dist: pypdf; extra == 'all'
Requires-Dist: pypdf2; extra == 'all'
Requires-Dist: pyperclip; extra == 'all'
Requires-Dist: pyqt6; extra == 'all'
Requires-Dist: pytesseract; extra == 'all'
Requires-Dist: python-docx; extra == 'all'
Requires-Dist: pytorch-optimizer; extra == 'all'
Requires-Dist: pytorch-pretrained-vit; extra == 'all'
Requires-Dist: pyttsx3; extra == 'all'
Requires-Dist: qrcode[pil]; extra == 'all'
Requires-Dist: readability-lxml; extra == 'all'
Requires-Dist: readchar; extra == 'all'
Requires-Dist: requests; extra == 'all'
Requires-Dist: ripple-detection; extra == 'all'
Requires-Dist: ruamel-yaml; extra == 'all'
Requires-Dist: scholarly; extra == 'all'
Requires-Dist: scikit-image; extra == 'all'
Requires-Dist: scikit-learn; extra == 'all'
Requires-Dist: scipy; extra == 'all'
Requires-Dist: seaborn; extra == 'all'
Requires-Dist: selenium; extra == 'all'
Requires-Dist: sktime; extra == 'all'
Requires-Dist: sounddevice; extra == 'all'
Requires-Dist: sqlalchemy; extra == 'all'
Requires-Dist: statsmodels; extra == 'all'
Requires-Dist: streamlit; extra == 'all'
Requires-Dist: sympy; extra == 'all'
Requires-Dist: tenacity; extra == 'all'
Requires-Dist: tensorpac; extra == 'all'
Requires-Dist: termplotlib; extra == 'all'
Requires-Dist: torch; extra == 'all'
Requires-Dist: torchaudio; extra == 'all'
Requires-Dist: torchsummary; extra == 'all'
Requires-Dist: torchvision; extra == 'all'
Requires-Dist: transformers; extra == 'all'
Requires-Dist: umap-learn>=0.5.4; extra == 'all'
Requires-Dist: watchdog; extra == 'all'
Requires-Dist: webdriver-manager; extra == 'all'
Requires-Dist: xarray; extra == 'all'
Requires-Dist: xlrd; extra == 'all'
Requires-Dist: xlsx2csv; extra == 'all'
Requires-Dist: yq; extra == 'all'
Requires-Dist: zarr; extra == 'all'
Provides-Extra: audio
Requires-Dist: elevenlabs; extra == 'audio'
Requires-Dist: gtts; extra == 'audio'
Requires-Dist: mcp; extra == 'audio'
Requires-Dist: pydub; extra == 'audio'
Requires-Dist: pytest-asyncio; extra == 'audio'
Requires-Dist: pyttsx3; extra == 'audio'
Provides-Extra: benchmark
Requires-Dist: psutil; extra == 'benchmark'
Provides-Extra: bridge
Requires-Dist: matplotlib; extra == 'bridge'
Requires-Dist: scipy; extra == 'bridge'
Provides-Extra: browser
Requires-Dist: aiohttp; extra == 'browser'
Requires-Dist: matplotlib; extra == 'browser'
Requires-Dist: playwright>=1.40.0; extra == 'browser'
Provides-Extra: capture
Requires-Dist: mcp; extra == 'capture'
Requires-Dist: mss; extra == 'capture'
Requires-Dist: pillow; extra == 'capture'
Requires-Dist: playwright>=1.40.0; extra == 'capture'
Provides-Extra: cli
Requires-Dist: aiohttp; extra == 'cli'
Requires-Dist: beautifulsoup4; extra == 'cli'
Requires-Dist: click; extra == 'cli'
Requires-Dist: gitpython; extra == 'cli'
Requires-Dist: playwright; extra == 'cli'
Requires-Dist: pyyaml; extra == 'cli'
Requires-Dist: requests; extra == 'cli'
Provides-Extra: cloud
Requires-Dist: matplotlib; extra == 'cloud'
Provides-Extra: config
Requires-Dist: pyyaml; extra == 'config'
Provides-Extra: db
Requires-Dist: psycopg2-binary; extra == 'db'
Requires-Dist: sqlalchemy; extra == 'db'
Provides-Extra: decorators
Requires-Dist: joblib; extra == 'decorators'
Requires-Dist: matplotlib; extra == 'decorators'
Requires-Dist: pytest-asyncio; extra == 'decorators'
Requires-Dist: scipy; extra == 'decorators'
Requires-Dist: tqdm; extra == 'decorators'
Requires-Dist: xarray; extra == 'decorators'
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: jedi; extra == 'dev'
Requires-Dist: line-profiler; extra == 'dev'
Requires-Dist: markdown; extra == 'dev'
Requires-Dist: markdown2; extra == 'dev'
Requires-Dist: matplotlib; extra == 'dev'
Requires-Dist: memory-profiler; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: myst-parser; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pygments; extra == 'dev'
Requires-Dist: pyright; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-env; extra == 'dev'
Requires-Dist: pytest-json-report; extra == 'dev'
Requires-Dist: pytest-mock; extra == 'dev'
Requires-Dist: pytest-testmon; extra == 'dev'
Requires-Dist: pytest-timeout; extra == 'dev'
Requires-Dist: pytest-xdist; extra == 'dev'
Requires-Dist: python-lsp-server; extra == 'dev'
Requires-Dist: pyyaml; extra == 'dev'
Requires-Dist: rope; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: setuptools; extra == 'dev'
Requires-Dist: sphinx; extra == 'dev'
Requires-Dist: sphinx-autobuild; extra == 'dev'
Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
Requires-Dist: stdlib-list; extra == 'dev'
Requires-Dist: tomlkit; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Requires-Dist: types-requests; extra == 'dev'
Requires-Dist: types-setuptools; extra == 'dev'
Requires-Dist: wheel; extra == 'dev'
Provides-Extra: devtools
Requires-Dist: joblib; extra == 'devtools'
Requires-Dist: matplotlib; extra == 'devtools'
Requires-Dist: ruamel-yaml; extra == 'devtools'
Requires-Dist: scipy; extra == 'devtools'
Requires-Dist: seaborn; extra == 'devtools'
Requires-Dist: xarray; extra == 'devtools'
Provides-Extra: diagram
Requires-Dist: pyyaml; extra == 'diagram'
Provides-Extra: dsp
Requires-Dist: h5py; extra == 'dsp'
Requires-Dist: joblib; extra == 'dsp'
Requires-Dist: matplotlib; extra == 'dsp'
Requires-Dist: readchar; extra == 'dsp'
Requires-Dist: ruamel-yaml; extra == 'dsp'
Requires-Dist: scipy; extra == 'dsp'
Requires-Dist: seaborn; extra == 'dsp'
Requires-Dist: sounddevice; extra == 'dsp'
Requires-Dist: tensorpac; extra == 'dsp'
Requires-Dist: xarray; extra == 'dsp'
Provides-Extra: dt
Requires-Dist: matplotlib; extra == 'dt'
Provides-Extra: gen
Requires-Dist: h5py; extra == 'gen'
Requires-Dist: ipython; extra == 'gen'
Requires-Dist: joblib; extra == 'gen'
Requires-Dist: matplotlib; extra == 'gen'
Requires-Dist: pyperclip; extra == 'gen'
Requires-Dist: readchar; extra == 'gen'
Requires-Dist: requests; extra == 'gen'
Requires-Dist: scipy; extra == 'gen'
Requires-Dist: xarray; extra == 'gen'
Provides-Extra: git
Requires-Dist: gitpython; extra == 'git'
Requires-Dist: matplotlib; extra == 'git'
Provides-Extra: heavy
Requires-Dist: catboost; extra == 'heavy'
Requires-Dist: jax; extra == 'heavy'
Requires-Dist: julius; extra == 'heavy'
Requires-Dist: mne; extra == 'heavy'
Requires-Dist: optuna; extra == 'heavy'
Requires-Dist: psutil; extra == 'heavy'
Requires-Dist: pytorch-pretrained-vit; extra == 'heavy'
Requires-Dist: ripple-detection; extra == 'heavy'
Requires-Dist: tensorflow; extra == 'heavy'
Requires-Dist: torch; extra == 'heavy'
Requires-Dist: torchaudio; extra == 'heavy'
Requires-Dist: torchsummary; extra == 'heavy'
Requires-Dist: torchvision; extra == 'heavy'
Requires-Dist: umap-learn; extra == 'heavy'
Provides-Extra: io
Requires-Dist: gitpython; extra == 'io'
Requires-Dist: h5py; extra == 'io'
Requires-Dist: html2text; extra == 'io'
Requires-Dist: joblib; extra == 'io'
Requires-Dist: lxml; extra == 'io'
Requires-Dist: lxml-html-clean; extra == 'io'
Requires-Dist: markdown; extra == 'io'
Requires-Dist: matplotlib; extra == 'io'
Requires-Dist: natsort; extra == 'io'
Requires-Dist: numcodecs; extra == 'io'
Requires-Dist: openpyxl; extra == 'io'
Requires-Dist: pdfplumber; extra == 'io'
Requires-Dist: piexif; extra == 'io'
Requires-Dist: pillow; extra == 'io'
Requires-Dist: plotly; extra == 'io'
Requires-Dist: pyarrow; extra == 'io'
Requires-Dist: pymatreader; extra == 'io'
Requires-Dist: pymupdf; extra == 'io'
Requires-Dist: pypdf; extra == 'io'
Requires-Dist: pypdf2; extra == 'io'
Requires-Dist: python-docx; extra == 'io'
Requires-Dist: pyyaml; extra == 'io'
Requires-Dist: qrcode[pil]; extra == 'io'
Requires-Dist: ruamel-yaml; extra == 'io'
Requires-Dist: scipy; extra == 'io'
Requires-Dist: tqdm; extra == 'io'
Requires-Dist: xarray; extra == 'io'
Requires-Dist: xlrd; extra == 'io'
Requires-Dist: zarr; extra == 'io'
Provides-Extra: linalg
Requires-Dist: geom-median; extra == 'linalg'
Requires-Dist: joblib; extra == 'linalg'
Requires-Dist: matplotlib; extra == 'linalg'
Requires-Dist: scipy; extra == 'linalg'
Requires-Dist: sympy; extra == 'linalg'
Requires-Dist: xarray; extra == 'linalg'
Provides-Extra: logging
Requires-Dist: matplotlib; extra == 'logging'
Provides-Extra: msword
Requires-Dist: pypandoc; extra == 'msword'
Requires-Dist: python-docx; extra == 'msword'
Provides-Extra: nn
Requires-Dist: h5py; extra == 'nn'
Requires-Dist: ipdb; extra == 'nn'
Requires-Dist: joblib; extra == 'nn'
Requires-Dist: matplotlib; extra == 'nn'
Requires-Dist: readchar; extra == 'nn'
Requires-Dist: ruamel-yaml; extra == 'nn'
Requires-Dist: seaborn; extra == 'nn'
Requires-Dist: tensorpac; extra == 'nn'
Requires-Dist: xarray; extra == 'nn'
Provides-Extra: parallel
Requires-Dist: tqdm; extra == 'parallel'
Provides-Extra: path
Requires-Dist: gitpython; extra == 'path'
Requires-Dist: matplotlib; extra == 'path'
Provides-Extra: pd
Requires-Dist: xarray; extra == 'pd'
Provides-Extra: plt
Requires-Dist: joblib; extra == 'plt'
Requires-Dist: matplotlib; extra == 'plt'
Requires-Dist: piexif; extra == 'plt'
Requires-Dist: pillow; extra == 'plt'
Requires-Dist: pyyaml; extra == 'plt'
Requires-Dist: ruamel-yaml; extra == 'plt'
Requires-Dist: scipy; extra == 'plt'
Requires-Dist: seaborn; extra == 'plt'
Requires-Dist: termplotlib; extra == 'plt'
Requires-Dist: xarray; extra == 'plt'
Provides-Extra: repro
Requires-Dist: matplotlib; extra == 'repro'
Provides-Extra: resource
Requires-Dist: h5py; extra == 'resource'
Requires-Dist: joblib; extra == 'resource'
Requires-Dist: matplotlib; extra == 'resource'
Requires-Dist: psutil; extra == 'resource'
Requires-Dist: pyyaml; extra == 'resource'
Requires-Dist: readchar; extra == 'resource'
Requires-Dist: ruamel-yaml; extra == 'resource'
Requires-Dist: scipy; extra == 'resource'
Provides-Extra: scholar
Requires-Dist: aiohttp; extra == 'scholar'
Requires-Dist: beautifulsoup4; extra == 'scholar'
Requires-Dist: bibtexparser; extra == 'scholar'
Requires-Dist: crawl4ai; extra == 'scholar'
Requires-Dist: feedparser; extra == 'scholar'
Requires-Dist: html2text; extra == 'scholar'
Requires-Dist: httpx; extra == 'scholar'
Requires-Dist: matplotlib; extra == 'scholar'
Requires-Dist: natsort; extra == 'scholar'
Requires-Dist: nest-asyncio; extra == 'scholar'
Requires-Dist: openpyxl; extra == 'scholar'
Requires-Dist: pdfplumber; extra == 'scholar'
Requires-Dist: pillow; extra == 'scholar'
Requires-Dist: playwright>=1.40.0; extra == 'scholar'
Requires-Dist: pydantic; extra == 'scholar'
Requires-Dist: pymed; extra == 'scholar'
Requires-Dist: pymupdf; extra == 'scholar'
Requires-Dist: pypdf2; extra == 'scholar'
Requires-Dist: pytesseract; extra == 'scholar'
Requires-Dist: python-docx; extra == 'scholar'
Requires-Dist: pyyaml; extra == 'scholar'
Requires-Dist: requests; extra == 'scholar'
Requires-Dist: ruamel-yaml; extra == 'scholar'
Requires-Dist: scholarly; extra == 'scholar'
Requires-Dist: scikit-learn; extra == 'scholar'
Requires-Dist: seaborn; extra == 'scholar'
Requires-Dist: selenium; extra == 'scholar'
Requires-Dist: sql-manager; extra == 'scholar'
Requires-Dist: sqlalchemy; extra == 'scholar'
Requires-Dist: tenacity; extra == 'scholar'
Requires-Dist: tqdm; extra == 'scholar'
Requires-Dist: watchdog; extra == 'scholar'
Requires-Dist: webdriver-manager; extra == 'scholar'
Provides-Extra: session
Requires-Dist: matplotlib; extra == 'session'
Requires-Dist: pyyaml; extra == 'session'
Provides-Extra: sh
Requires-Dist: matplotlib; extra == 'sh'
Provides-Extra: stats
Requires-Dist: matplotlib; extra == 'stats'
Requires-Dist: scipy; extra == 'stats'
Requires-Dist: statsmodels; extra == 'stats'
Requires-Dist: tabulate; extra == 'stats'
Provides-Extra: str
Requires-Dist: matplotlib; extra == 'str'
Requires-Dist: natsort; extra == 'str'
Requires-Dist: xarray; extra == 'str'
Provides-Extra: tex
Requires-Dist: matplotlib; extra == 'tex'
Provides-Extra: torch
Requires-Dist: torch; extra == 'torch'
Provides-Extra: types
Requires-Dist: xarray; extra == 'types'
Provides-Extra: utils
Requires-Dist: h5py; extra == 'utils'
Requires-Dist: matplotlib; extra == 'utils'
Requires-Dist: natsort; extra == 'utils'
Requires-Dist: tqdm; extra == 'utils'
Requires-Dist: xarray; extra == 'utils'
Provides-Extra: web
Requires-Dist: aiohttp; extra == 'web'
Requires-Dist: anthropic; extra == 'web'
Requires-Dist: beautifulsoup4; extra == 'web'
Requires-Dist: google-genai; extra == 'web'
Requires-Dist: groq; extra == 'web'
Requires-Dist: joblib; extra == 'web'
Requires-Dist: markdown2; extra == 'web'
Requires-Dist: matplotlib; extra == 'web'
Requires-Dist: openai; extra == 'web'
Requires-Dist: pillow; extra == 'web'
Requires-Dist: pytest-asyncio; extra == 'web'
Requires-Dist: readability-lxml; extra == 'web'
Requires-Dist: requests; extra == 'web'
Requires-Dist: ruamel-yaml; extra == 'web'
Requires-Dist: scikit-learn; extra == 'web'
Requires-Dist: scipy; extra == 'web'
Requires-Dist: seaborn; extra == 'web'
Requires-Dist: tqdm; extra == 'web'
Requires-Dist: xarray; extra == 'web'
Provides-Extra: writer
Requires-Dist: csv2latex; extra == 'writer'
Requires-Dist: gitpython; extra == 'writer'
Requires-Dist: matplotlib; extra == 'writer'
Requires-Dist: pytest-asyncio; extra == 'writer'
Requires-Dist: xlsx2csv; extra == 'writer'
Requires-Dist: yq; extra == 'writer'
Description-Content-Type: text/markdown

<!-- ---
!-- Timestamp: 2026-01-08 11:41:42
!-- Author: ywatanabe
!-- File: /home/ywatanabe/proj/scitex-code/README.md
!-- --- -->

# SciTeX

A Python framework for scientific research that makes the entire research pipeline more standardized, structured, and reproducible by automating repetitive processes.

Part of the fully open-source SciTeX project: https://scitex.ai

## 📊 Status

<!-- badges -->
<div align="center">
  <table>
    <tr>
      <td align="center"><strong>Package</strong></td>
      <td>
        <a href="https://badge.fury.io/py/scitex"><img src="https://badge.fury.io/py/scitex.svg" alt="PyPI version"></a>
        <a href="https://pypi.org/project/scitex/"><img src="https://img.shields.io/pypi/pyversions/scitex.svg" alt="Python Versions"></a>
        <a href="https://github.com/ywatanabe1989/SciTeX-Code/blob/main/LICENSE"><img src="https://img.shields.io/github/license/ywatanabe1989/SciTeX-Code" alt="License"></a>
      </td>
    </tr>
    <tr>
      <td align="center"><strong>Install</strong></td>
      <td>
        <img src="https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/core.json&label=core" alt="Core Install Time">
        <img src="https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/all.json&label=all" alt="All Install Time">
        <img src="https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/heavy.json&label=heavy" alt="Heavy Install Time">
        <img src="https://img.shields.io/badge/uv-recommended-blue" alt="uv recommended">
      </td>
    </tr>
  </table>
</div>

<details>
<summary><strong>Module Status - Tests & Installation</strong></summary>

### Core Modules

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`io`](./src/scitex/io#readme) | Universal I/O (30+ formats) | `scitex[io]` ![io](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/io.json) | [![io](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-io.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-io.yml) |
| [`path`](./src/scitex/path#readme) | Path utilities | `scitex[path]` ![path](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/path.json) | [![path](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-path.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-path.yml) |
| [`str`](./src/scitex/str#readme) | String processing | `scitex[str]` ![str](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/str.json) | [![str](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-str.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-str.yml) |
| [`dict`](./src/scitex/dict#readme) | Dictionary utilities | core ![dict](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/dict.json) | [![dict](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dict.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dict.yml) |
| [`types`](./src/scitex/types#readme) | Type checking | core ![types](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/types.json) | [![types](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-types.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-types.yml) |
| [`config`](./src/scitex/config#readme) | Configuration management | `scitex[config]` ![config](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/config.json) | [![config](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-config.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-config.yml) |
| [`utils`](./src/scitex/utils#readme) | General utilities | `scitex[utils]` ![utils](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/utils.json) | [![utils](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-utils.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-utils.yml) |
| [`decorators`](./src/scitex/decorators#readme) | Function decorators | `scitex[decorators]` ![decorators](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/decorators.json) | [![decorators](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-decorators.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-decorators.yml) |
| [`logging`](./src/scitex/logging#readme) | Structured logging | `scitex[logging]` ![logging](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/logging.json) | [![logging](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-logging.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-logging.yml) |
| [`gen`](./src/scitex/gen#readme) | Project setup | `scitex[gen]` ![gen](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/gen.json) | [![gen](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-gen.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-gen.yml) |

### Data Science & Statistics

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`stats`](./src/scitex/stats#readme) | Statistical tests & analysis | `scitex[stats]` ![stats](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/stats.json) | [![stats](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-stats.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-stats.yml) |
| [`pd`](./src/scitex/pd#readme) | Pandas extensions | `scitex[pd]` ![pd](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/pd.json) | [![pd](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-pd.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-pd.yml) |
| [`linalg`](./src/scitex/linalg#readme) | Linear algebra | `scitex[linalg]` ![linalg](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/linalg.json) | [![linalg](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-linalg.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-linalg.yml) |
| [`plt`](./src/scitex/plt#readme) | Enhanced matplotlib | `scitex[plt]` ![plt](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/plt.json) | [![plt](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-plt.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-plt.yml) |
| [`dsp`](./src/scitex/dsp#readme) | Signal processing | `scitex[dsp]` ![dsp](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/dsp.json) | [![dsp](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dsp.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dsp.yml) |

### AI & Machine Learning

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`ai`](./src/scitex/ai#readme) | GenAI (7 providers) | `scitex[ai]` ![ai](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/ai.json) | [![ai](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-ai.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-ai.yml) |
| [`nn`](./src/scitex/nn#readme) | Neural network layers | `scitex[nn]` ![nn](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/nn.json) | [![nn](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-nn.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-nn.yml) |
| [`torch`](./src/scitex/torch#readme) | PyTorch utilities | `scitex[torch]` ![torch](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/torch.json) | [![torch](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-torch.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-torch.yml) |

### System & Tools

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`cli`](./src/scitex/cli#readme) | Command-line tools | `scitex[cli]` ![cli](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/cli.json) | [![cli](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-cli.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-cli.yml) |
| [`sh`](./src/scitex/sh#readme) | Shell utilities | `scitex[sh]` ![sh](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/sh.json) | [![sh](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-sh.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-sh.yml) |
| [`git`](./src/scitex/git#readme) | Git operations | `scitex[git]` ![git](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/git.json) | [![git](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-git.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-git.yml) |
| [`session`](./src/scitex/session#readme) | Session management | `scitex[session]` ![session](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/session.json) | [![session](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-session.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-session.yml) |
| [`resource`](./src/scitex/resource#readme) | System monitoring | `scitex[resource]` ![resource](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/resource.json) | [![resource](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-resource.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-resource.yml) |
| [`db`](./src/scitex/db#readme) | Database abstractions | `scitex[db]` ![db](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/db.json) | [![db](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-db.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-db.yml) |

### Research & Publishing

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`writer`](./src/scitex/writer#readme) | Document generation | `scitex[writer]` ![writer](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/writer.json) | [![writer](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-writer.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-writer.yml) |
| [`tex`](./src/scitex/tex#readme) | LaTeX processing | `scitex[tex]` ![tex](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/tex.json) | [![tex](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-tex.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-tex.yml) |
| [`msword`](./src/scitex/msword#readme) | MS Word conversion | `scitex[msword]` ![msword](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/msword.json) | [![msword](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-msword.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-msword.yml) |
| [`scholar`](./src/scitex/scholar#readme) | Literature management | `scitex[scholar]` ![scholar](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/scholar.json) | [![scholar](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-scholar.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-scholar.yml) |
| [`diagram`](./src/scitex/diagram#readme) | Diagram generation | `scitex[diagram]` ![diagram](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/diagram.json) | [![diagram](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-diagram.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-diagram.yml) |

### Web & Automation

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`web`](./src/scitex/web#readme) | Web scraping | `scitex[web]` ![web](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/web.json) | [![web](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-web.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-web.yml) |
| [`browser`](./src/scitex/browser#readme) | Browser automation | `scitex[browser]` ![browser](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/browser.json) | [![browser](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-browser.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-browser.yml) |

### Other Modules

| Module | Description | Install (Time) | Tests |
|--------|-------------|----------------|-------|
| [`audio`](./src/scitex/audio#readme) | Audio processing | `scitex[audio]` ![audio](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/audio.json) | [![audio](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-audio.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-audio.yml) |
| [`capture`](./src/scitex/capture#readme) | Screen capture | `scitex[capture]` ![capture](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/capture.json) | [![capture](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-capture.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-capture.yml) |
| [`repro`](./src/scitex/repro#readme) | Reproducibility | `scitex[repro]` ![repro](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/repro.json) | [![repro](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-repro.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-repro.yml) |
| [`benchmark`](./src/scitex/benchmark#readme) | Performance testing | `scitex[benchmark]` ![benchmark](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/benchmark.json) | [![benchmark](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-benchmark.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-benchmark.yml) |
| [`security`](./src/scitex/security#readme) | Security utilities | `scitex[security]` ![security](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/security.json) | [![security](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-security.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-security.yml) |
| [`dt`](./src/scitex/dt#readme) | Datetime utilities | `scitex[dt]` ![dt](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/dt.json) | [![dt](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dt.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dt.yml) |
| [`dev`](./src/scitex/dev#readme) | Development tools | `scitex[dev]` ![dev](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/dev.json) | [![dev](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dev.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-dev.yml) |
| [`schema`](./src/scitex/schema#readme) | Data schemas | `scitex[schema]` ![schema](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/schema.json) | [![schema](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-schema.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-schema.yml) |
| [`bridge`](./src/scitex/bridge#readme) | Module integration | `scitex[bridge]` ![bridge](https://img.shields.io/endpoint?url=https://ywatanabe1989.github.io/scitex-code/badges/bridge.json) | [![bridge](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-bridge.yml/badge.svg)](https://github.com/ywatanabe1989/scitex-code/actions/workflows/test-bridge.yml) |

</details>

## 📦 Installation

``` bash
uv pip install scitex[all]     # Recommended: Full installation with all modules
uv pip install scitex          # Core only (numpy, pandas, PyYAML, tqdm)
uv pip install scitex[heavy]   # Include heavy deps (torch, mne, optuna, etc.)
```

> **Note**: Heavy dependencies (torch, mne, optuna, catboost, jax, tensorflow, umap-learn)
> are optional and NOT included by default. Install with `scitex[heavy]` if needed.
> Modules gracefully handle missing dependencies with `*_AVAILABLE` flags.

<details>
<summary><strong>Arial Font Setup for Figures</strong></summary>

``` bash
# Ubuntu
sudo apt update
sudo apt-get install ttf-mscorefonts-installer
sudo DEBIAN_FRONTEND=noninteractive \
    apt install -y ttf-mscorefonts-installer
sudo mkdir -p /usr/share/fonts/truetype/custom
sudo cp /mnt/c/Windows/Fonts/arial*.ttf /usr/share/fonts/truetype/custom/
sudo fc-cache -fv
rm ~/.cache/matplotlib -rf

# WSL
mkdir -p ~/.local/share/fonts/windows
cp /mnt/c/Windows/Fonts/arial*.ttf ~/.local/share/fonts/windows/
fc-cache -fv ~/.local/share/fonts/windows
rm ~/.cache/matplotlib -rf
```

``` python
# Check
import matplotlib
print(matplotlib.rcParams['font.family'])

import matplotlib.font_manager as fm
fonts = fm.findSystemFonts()
print("Arial found:", any("Arial" in f or "arial" in f for f in fonts))
[a for a in fonts if "Arial" in a or "arial" in a][:5]

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.family"] = "Arial"
mpl.rcParams["font.sans-serif"] = ["Arial"]  # 念のため

fig, ax = plt.subplots(figsize=(3, 2))
ax.text(0.5, 0.5, "Arial Test", fontsize=32, ha="center", va="center")
ax.set_axis_off()

fig.savefig("arial_test.png", dpi=300)
plt.close(fig)
```

</details>

## Why SciTeX?

SciTeX automates research analysis code.

<!-- **What SciTeX Automates:**
 !-- - ✅ Symlink management for centralized outputs
 !-- - ✅ Error handling and directory cleanup
 !-- - ✅ Global variable injection (CONFIG, plt, COLORS, logger, rng)
 !-- 
 !-- **Research Benefits:**
 !-- - 📊 **Figures + data always together** - CSV auto-exported from every plot
 !-- - 🔄 **Perfect reproducibility** - Every run tracked with unique session ID
 !-- - 🌍 **Universal format** - CSV data readable anywhere
 !-- - 📝 **Zero manual work** - Metadata embedded automatically
 !-- - 🎯 **3.3× less code** - Focus on research, not infrastructure -->


<details>
<summary><strong><code>@scitex.session</code></strong> — Reproducible Experiment Tracking + Auto-CLI</summary>

Standardized outputs with automatic logging. Scripts and outputs closely linked for full traceability.

**Auto-CLI Generation**: Function arguments automatically become argparse options:

```python
# /path/to/script.py
import scitex as stx

@stx.session
def main(
    # arg1,                     # Required: -a ARG1, --arg1 ARG1
    # kwarg1="value1",          # Optional: -k KWARG1, --kwarg1 KWARG1 (default: value1)
    CONFIG=stx.INJECTED,        # Auto-injected from $(pwd)/config/*.yaml files
    plt=stx.INJECTED,           # Pre-configured matplotlib
    COLORS=stx.INJECTED,        # Color palette
    rng=stx.INJECTED,           # Seeded random generator
    logger=stx.INJECTED,        # Session logger
):
    """This docstring becomes --help description."""
    
    stx.io.save(results, "results.csv", symlink_to="./data/")
    # SUCC: Saved to: /path/to/script_out/tmp.txt (4.0 B)
    # SUCC: Symlinked: /path/to/script_out/tmp.txt ->
    # SUCC:            ./data/tmp.txt
    
    return 0
```

```bash
$ python script.py --help
usage: script.py [-a ARG1] [-k KWARG1]
  -a ARG1, --arg1 ARG1     (required)
  -k KWARG1, --kwarg1 KWARG1  (default: value1)

$ python script.py -a myvalue
# Runs with arg1="myvalue", kwarg1="value1"
```

**Output Structure**:
```bash
/path/to/script.py
/path/to/script_out/
├── FINISHED_SUCCESS/
│    └── 2025-01-08_12-30-00_AbC1/ # Session ID allocated
│        ├── results.csv
│        ├── CONFIGS/
│        │   ├── CONFIG.pkl    # Python object
│        │   └── CONFIG.yaml   # Human-readable
│        └── logs/
│            ├── stderr.log    # Standard Errors
│            └── stdout.log    # Standard Outputs
├── FINISHED_FAILED/
│    └── ...
└── RUNNING/
     └── ...
```

</details>

<details>
<summary><strong><code>scitex.plt</code></strong> — Auto-Export Figures with Data</summary>

Figures and data always together. CSV auto-exported from every plot.

```python
import scitex as stx

fig, ax = stx.plt.subplots()
ax.plot_line(x, y)  # Data tracked automatically
stx.io.save(fig, "plot.png")
# Creates: plot.png + plot.csv
```

</details>

<details>
<summary><strong><code>scitex.io</code></strong> — Universal File I/O (30+ formats)</summary>

One API for all formats: CSV, JSON, YAML, pickle, NumPy, HDF5, Zarr, PyTorch, images, PDFs, EEG formats.

```python
import scitex as stx

# Unified API Call for +30 formats
stx.io.save(df, "output.csv")
stx.io.save(arr, "output.npy")
stx.io.save(fig, "output.jpg")

# Round Trip Loading
df = stx.io.load("output.csv")
arr = stx.io.load("output.npy")
```

</details>

<details>
<summary><strong><code>scitex.stats</code></strong> — Publication-Ready Statistics (23 tests)</summary>

Automatic assumption checking, effect sizes, multiple comparison corrections, 9 export formats.

```python
import scitex as stx

result = stx.stats.test_ttest_ind(
    group1, group2,
    return_as="dataframe"  # or "latex", "markdown", "excel"
)
# Includes: p-value, effect size, CI, normality check, power analysis
```

</details>

<details>
<summary><strong><code>scitex.scholar</code></strong> — Literature Management & BibTeX Enrichment</summary>

BibTeX enrichment with abstracts for LLM context, DOI resolution, PDF download, Impact Factor.

```bash
scitex scholar bibtex papers.bib --project myresearch --num-workers 8
```

```bibtex
# Before: Minimal BibTeX
@article{Smith2024,
  title = {Neural Networks},
  author = {Smith, John},
  doi = {10.1038/s41586-024-00001-1}
}

# After: Enriched with abstract for LLM context
@article{Smith2024,
  title = {Neural Networks for Brain Signal Analysis},
  author = {Smith, John and Lee, Alice},
  doi = {10.1038/s41586-024-00001-1},
  journal = {Nature},
  year = {2024},
  abstract = {We present a novel deep learning approach...},  # Rich context for LLMs
  impact_factor = {64.8}
}
```

</details>

<details>
<summary><strong><code>scitex.writer</code></strong> — LaTeX Manuscript Management</summary>

Python interface for LaTeX manuscripts with git-based version control.

```python
from scitex.writer import Writer

writer = Writer("my_paper")
intro = writer.manuscript.contents.introduction

lines = intro.read()
intro.write(lines + ["New paragraph..."])
intro.commit("Update introduction")

result = writer.compile_manuscript()
```

</details>

<details>
<summary><strong><code>scitex.ai</code></strong> — Unified AI/ML Interface (7 providers)</summary>

Single API for OpenAI, Anthropic, Google, Perplexity, DeepSeek, Groq, local models.

```python
from scitex.ai.genai import GenAI

ai = GenAI(provider="openai")
response = ai("Explain this data pattern")

# Switch providers instantly
ai = GenAI(provider="anthropic", model="claude-3-opus-20240229")
```

</details>

## 🖥️ CLI Commands

SciTeX provides a comprehensive command-line interface:

<details>
<summary><strong>CLI Commands</strong></summary>

```bash
# SciTeX Cloud (https://scitex.ai)
scitex cloud login                    # Login to SciTeX Cloud
scitex cloud clone user/project       # Clone from cloud
scitex cloud create my-project        # Create new repository
scitex cloud enrich -i refs.bib -o enriched.bib  # BibTeX enrichment API

# Configuration
scitex config list                    # Show all configured paths
scitex config init                    # Initialize directories

# Research Tools
scitex scholar bibtex papers.bib      # Process BibTeX, download PDFs
scitex scholar single --doi "10.1038/nature12373"

# TIP: Get BibTeX from Scholar QA (https://scholarqa.allen.ai/chat/)
#      Ask questions → Export All Citations → Save as .bib file
scitex stats recommend --data data.csv

# Media
scitex audio speak "Hello world"
scitex capture snap --output screenshot.jpg

# Document Processing
scitex tex compile manuscript.tex
scitex writer compile my_paper

# Utilities
scitex resource usage                 # System resource monitoring
scitex security check --save          # Security audit
scitex web get-urls https://example.com
scitex completion                     # Enable tab completion
```

</details>

## 🔌 MCP Servers

<details>
<summary><strong>Model Context Protocol (MCP) servers for AI agent integration</strong></summary>

SciTeX provides Model Context Protocol (MCP) servers for AI agent integration:

| Server | Description |
|--------|-------------|
| `scitex-audio` | Text-to-speech for agent feedback |
| `scitex-capture` | Screen monitoring and capture |
| `scitex-plt` | Matplotlib figure creation |
| `scitex-stats` | Automated statistical testing |
| `scitex-scholar` | PDF download and metadata enrichment |
| `scitex-diagram` | Mermaid and flowchart creation |
| `scitex-template` | Project scaffolding |
| `scitex-canvas` | Scientific figure canvas |

**Claude Desktop Configuration** (`~/.config/claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "scitex-audio": {
      "command": "scitex-audio"
    },
    "scitex-capture": {
      "command": "scitex-capture"
    },
    "scitex-scholar": {
      "command": "scitex-scholar"
    }
  }
}
```

</details>

## 🚀 Quick Start


### Research Analysis with **70% Less Code**

Compare these two implementations that produce **identical research outputs**:

#### With SciTeX ([57 Lines of Code]((./examples/demo_session_plt_io.py)))

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Timestamp: "2025-11-18 09:34:36 (ywatanabe)"
# File: /home/ywatanabe/proj/scitex-code/examples/demo_session_plt_io.py


"""Minimal Demonstration for scitex.{session,io,plt}"""

import numpy as np
import scitex as stx


def demo(filename, verbose=False):
    """Show metadata without QR code (just embedded)."""

    # matplotlib.pyplot wrapper.
    fig, ax = stx.plt.subplots()

    t = np.linspace(0, 2, 1000)
    signal = np.sin(2 * np.pi * 5 * t) * np.exp(-t / 2)

    ax.plot_line(t, signal)  # Original plot for automatic CSV export
    ax.set_xyt(
        "Time (s)",
        "Amplitude",
        "Clean Figure (metadata embedded, no QR overlay)",
    )

    # Saving: stx.io.save(obj, rel_path, **kwargs)
    stx.io.save(
        fig,
        filename,
        metadata={"exp": "s01", "subj": "S001"},  # with meatadata embedding
        symlink_to="./data",  # Symlink for centralized outputs
        verbose=verbose,  # Automatic terminal logging (no manual print())
    )
    fig.close()

    # Loading: stx.io.load(path)
    ldir = __file__.replace(".py", "_out")
    img, meta = stx.io.load(
        f"{ldir}/{filename}",
        verbose=verbose,
    )


@stx.session
def main(filename="demo.jpg", verbose=True):
    """Run demo for scitex.{session,plt,io}."""

    demo(filename, verbose=verbose)

    return 0


if __name__ == "__main__":
    main()
```


<details>
<summary><strong>Equivalent Script without SciTeX ([188 Lines of Code](./examples/demo_session_plt_io_pure_python.py)), requiring 3.3× more code</strong></summary>

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Timestamp: "2025-11-18 09:34:51 (ywatanabe)"
# File: /home/ywatanabe/proj/scitex-code/examples/demo_session_plt_io_pure_python.py


"""Minimal Demonstration - Pure Python Version"""

import argparse
import json
import logging
import os
import shutil
import sys
from datetime import datetime
from pathlib import Path
import random
import string

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from PIL.PngImagePlugin import PngInfo


def generate_session_id():
    """Generate unique session ID."""
    timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    random_suffix = ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))
    return f"{timestamp}_{random_suffix}"


def setup_logging(log_dir):
    """Set up logging infrastructure."""
    log_dir.mkdir(parents=True, exist_ok=True)
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    
    stdout_handler = logging.FileHandler(log_dir / "stdout.log")
    stderr_handler = logging.FileHandler(log_dir / "stderr.log")
    console_handler = logging.StreamHandler(sys.stdout)
    
    formatter = logging.Formatter('%(levelname)s: %(message)s')
    stdout_handler.setFormatter(formatter)
    stderr_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)
    
    logger.addHandler(stdout_handler)
    logger.addHandler(stderr_handler)
    logger.addHandler(console_handler)
    
    return logger


def save_plot_data_to_csv(fig, output_path):
    """Extract and save plot data."""
    csv_path = output_path.with_suffix('.csv')
    data_lines = ["ax_00_plot_line_0_line_x,ax_00_plot_line_0_line_y"]
    
    for ax in fig.get_axes():
        for line in ax.get_lines():
            x_data = line.get_xdata()
            y_data = line.get_ydata()
            for x, y in zip(x_data, y_data):
                data_lines.append(f"{x},{y}")
    
    csv_path.write_text('\n'.join(data_lines))
    return csv_path, csv_path.stat().st_size / 1024


def embed_metadata_in_image(image_path, metadata):
    """Embed metadata into image file."""
    img = Image.open(image_path)
    
    if image_path.suffix.lower() in ['.png']:
        pnginfo = PngInfo()
        for key, value in metadata.items():
            pnginfo.add_text(key, str(value))
        img.save(image_path, pnginfo=pnginfo)
    elif image_path.suffix.lower() in ['.jpg', '.jpeg']:
        json_path = image_path.with_suffix(image_path.suffix + '.meta.json')
        json_path.write_text(json.dumps(metadata, indent=2))
        img.save(image_path, quality=95)


def save_figure(fig, output_path, metadata=None, symlink_to=None, logger=None):
    """Save figure with metadata and symlink."""
    output_path = Path(output_path)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    
    if metadata is None:
        metadata = {}
    metadata['url'] = 'https://scitex.ai'
    
    if logger:
        logger.info(f"📝 Saving figure with metadata to: {output_path}")
        logger.info(f"  • Embedded metadata: {metadata}")
    
    csv_path, csv_size = save_plot_data_to_csv(fig, output_path)
    if logger:
        logger.info(f"✅ Saved to: {csv_path} ({csv_size:.1f} KiB)")
    
    fig.savefig(output_path, dpi=150, bbox_inches='tight')
    embed_metadata_in_image(output_path, metadata)
    
    if symlink_to:
        symlink_dir = Path(symlink_to)
        symlink_dir.mkdir(parents=True, exist_ok=True)
        symlink_path = symlink_dir / output_path.name
        if symlink_path.exists() or symlink_path.is_symlink():
            symlink_path.unlink()
        symlink_path.symlink_to(output_path.resolve())


    def demo(output_dir, filename, verbose=False, logger=None):
    """Generate, plot, and save signal."""
    fig, ax = plt.subplots(figsize=(8, 6))
    
    t = np.linspace(0, 2, 1000)
    signal = np.sin(2 * np.pi * 5 * t) * np.exp(-t / 2)
    
    ax.plot(t, signal)
    ax.set_xlabel("Time (s)")
    ax.set_ylabel("Amplitude")
    ax.set_title("Damped Oscillation")
    ax.grid(True, alpha=0.3)
    
    output_path = output_dir / filename
    save_figure(fig, output_path, metadata={"exp": "s01", "subj": "S001"},
                symlink_to=output_dir.parent / "data", logger=logger)
    plt.close(fig)
    
    return 0


def main():
    """Run demo - Pure Python Version."""
    parser = argparse.ArgumentParser(description="Run demo - Pure Python Version")
    parser.add_argument('-f', '--filename', default='demo.jpg')
    parser.add_argument('-v', '--verbose', type=bool, default=True)
    args = parser.parse_args()
    
    session_id = generate_session_id()
    script_path = Path(__file__).resolve()
    output_base = script_path.parent / (script_path.stem + "_out")
    running_dir = output_base / "RUNNING" / session_id
    logs_dir = running_dir / "logs"
    config_dir = running_dir / "CONFIGS"
    
    logger = setup_logging(logs_dir)
    
    print("=" * 40)
    print(f"Pure Python Demo")
    print(f"{session_id} (PID: {os.getpid()})")
    print(f"\n{script_path}")
    print(f"\nArguments:")
    print(f"    filename: {args.filename}")
    print(f"    verbose: {args.verbose}")
    print("=" * 40)
    
    config_dir.mkdir(parents=True, exist_ok=True)
    config_data = {
        'ID': session_id,
        'FILE': str(script_path),
        'SDIR_OUT': str(output_base),
        'SDIR_RUN': str(running_dir),
        'PID': os.getpid(),
        'ARGS': vars(args)
    }
    (config_dir / "CONFIG.json").write_text(json.dumps(config_data, indent=2))
    
    try:
        result = demo(output_base, args.filename, args.verbose, logger)
        success_dir = output_base / "FINISHED_SUCCESS" / session_id
        success_dir.parent.mkdir(parents=True, exist_ok=True)
        shutil.move(str(running_dir), str(success_dir))
        logger.info(f"\n✅ Script completed: {success_dir}")
        return result
    except Exception as e:
        error_dir = output_base / "FINISHED_ERROR" / session_id
        error_dir.parent.mkdir(parents=True, exist_ok=True)
        shutil.move(str(running_dir), str(error_dir))
        logger.error(f"\n❌ Error: {e}", exc_info=True)
        raise


if __name__ == "__main__":
    sys.exit(main())
```

</details>


## 📖 Documentation

<details>
<summary><strong>Resources</strong></summary>

### Online Documentation
- **[Read the Docs](https://scitex.readthedocs.io/)**: Complete API reference and guides
- **[Interactive Examples](https://scitex.readthedocs.io/en/latest/examples/index.html)**: Browse all tutorial notebooks
- **[Quick Start Guide](https://scitex.readthedocs.io/en/latest/getting_started.html)**: Get up and running quickly

### Local Resources
- **[Master Tutorial Index](./examples/00_SCITEX_MASTER_INDEX.ipynb)**: Comprehensive guide to all features
- **[Examples Directory](./examples/)**: 25+ Jupyter notebooks covering all modules
- **[Module List](./docs/scitex_modules.csv)**: Complete list of all functions
- **(Experimental) [MCP Servers Documentation](./mcp_servers/README.md)**

### Key Tutorials
1. **[I/O Operations](./examples/01_scitex_io.ipynb)**: Essential file handling (start here!)
2. **[Plotting](./examples/14_scitex_plt.ipynb)**: Publication-ready visualizations
3. **[Statistics](./examples/11_scitex_stats.ipynb)**: Research-grade statistical analysis
4. **[Scholar](./examples/16_scitex_scholar.ipynb)**: Literature management with impact factors
5. **[AI/ML](./examples/16_scitex_ai.ipynb)**: Complete machine learning toolkit

</details>

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.


## 📄 License

AGPL-3.0.

## 📧 Contact

Yusuke Watanabe (ywatanabe@scitex.ai)

<!-- EOF -->