Metadata-Version: 2.4
Name: prodnet-generator
Version: 2.2.0
Summary: ProdNet Generator -- firm-level production-network reconstruction toolkit (pipeline + GUI). Formerly netrecon; `import netrecon` remains a permanent alias.
Author-email: Ashwin Bhattathiripad and Vipin P Veetil <vipin@iimk.ac.in>
License: MIT License
        
        Copyright (c) 2026 Ashwin Bhattathiripad and Vipin P Veetil
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://www.vipinveetil.com
Keywords: production networks,input-output,economic networks,network reconstruction,firm-level,gravity model,systemic risk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy<2.0,>=1.21; python_version < "3.13"
Requires-Dist: numpy>=2.1; python_version >= "3.13"
Requires-Dist: scipy<1.14,>=1.10; python_version < "3.13"
Requires-Dist: scipy>=1.14; python_version >= "3.13"
Requires-Dist: pandas<2.3,>=1.5; python_version < "3.13"
Requires-Dist: pandas>=2.2; python_version >= "3.13"
Requires-Dist: numba>=0.58
Requires-Dist: openpyxl>=3.1
Requires-Dist: osqp>=0.6
Requires-Dist: flask>=2.2
Provides-Extra: fit
Requires-Dist: cyipopt>=1.3; extra == "fit"
Requires-Dist: cython>=0.29; extra == "fit"
Provides-Extra: gpu
Requires-Dist: mlx; platform_system == "Darwin" and extra == "gpu"
Provides-Extra: preflight
Requires-Dist: psutil>=5.9; extra == "preflight"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Dynamic: license-file

# ProdNet Generator — firm-level production-network reconstruction toolkit

`prodnet_generator` builds a **firm-level weighted production network for a whole
economy** (up to millions of firms) out of nothing more than published,
sector-level data:

* a **firm-size distribution** (how many firms of each receipt-size sit in each
  industry), and
* a national **input–output (IO) table** (which sectors buy from which).

From those two aggregate objects it reconstructs *who links to whom* and *how many
dollars flow on each edge*, using a **gravity–Bernoulli fitness kernel** (a
hidden-variable link model with firm size as the hidden variable, calibrated to the
IO margins), then closes the network to be irreducible + aperiodic and solves the
dollar weights with a bundled C ADMM min-energy solver.

It is **solver-license-free**: the one-time λ-fit for a *new* economy runs on IPOPT
behind the free **MUMPS** linear solver, and the dollar-weight solve is the bundled
`mew` C program. Reconstructing an economy whose λ is already fitted (e.g. the
bundled demos) needs no NLP solver at all.

> Formerly `netrecon`; `import netrecon` remains a permanent compatibility alias.

---

## Install

```bash
pip install prodnet-generator
```

**Platform:** the published wheel is built for **macOS Apple Silicon (arm64) +
CPython 3.12** and reconstructs networks out of the box — the pipeline (stage
modules, the compiled `mew` / `_candidates` binaries, and two demo economies) is
bundled inside the wheel. It is platform-specific because of those compiled
binaries, so `pip` cleanly refuses to install it on other platforms/Python
versions rather than installing something that would fail at runtime. On any other
system, use the repository (developer) install below.

```python
import prodnet_generator
net = prodnet_generator("Denmark", n_firms=8000, seed=1)   # -> Network (deterministic)
net.n_firms, net.n_edges                                   # (7975, 436633)
```

### Bundled vs. on-demand economies

The wheel ships **two demo economies ready to run — Denmark and Finland.** The four
large economies (**US, Japan, United_Kingdom, Australia**) are not shipped in the
wheel; to reconstruct them from a `pip` install, point `$PRODNET_DATA_DIR` at a
directory holding their `<C>_interfirm` bundles (both the library and the pipeline
honor it):

```bash
export PRODNET_DATA_DIR=/path/to/economy_bundles   # contains US_interfirm/, Japan_interfirm/, ...
```

### Developer / from-source install

A repository checkout runs its own `code_generation/` pipeline (the byte-identical
"golden" path) and carries all six economies under `code_generation/datasets/`:

```bash
git clone git@bitbucket.org:VipinVeetil/prodnet-generator.git
cd prodnet-generator
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e .                     # editable dev install
```

Fitting a *new* economy's λ-family additionally needs IPOPT behind `cyipopt`
(`pip install 'prodnet-generator[fit]'`, plus `brew install ipopt` or
`conda install -c conda-forge ipopt mumps` if pip can't supply one). A licensed
**HSL / MA97** solver is optional (faster on hard fits): `export
IPOPT_LINEAR_SOLVER=ma97`.

---

## Quickstart

### The Python library (`import prodnet_generator`)

```python
import prodnet_generator

prodnet_generator.available_economies()               # which economies are ready right now
prodnet_generator.capabilities()                      # what can THIS machine reconstruct?

net = prodnet_generator("Denmark", n_firms=8000, seed=1)   # the module is callable
net.n_firms, net.n_edges                                   # (7975, 436633)
W = net.to_scipy()                                         # scipy CSR: W[buyer-1, seller-1] = spend share
net.save("my_denmark_net")                                 # persist weights.csrbin + firm maps
```

`prodnet_generator(...)` forwards to `prodnet_generator.generate(...)`; `reconstruct`
is the same function under its pre-2.0 name, and `import netrecon` re-exports the
whole surface unchanged.

`n_firms` is the primary knob (converted internally to the census subsample
fraction; `seed` fixes everything, so the same call is byte-identical every time).
The library is **hardware-aware**: before a large run it estimates peak RAM and, if
your machine can't fit it, refuses with the largest feasible `n_firms` — or pass
`autoscale=True` to auto-fit, `force=True` to override. The same API is callable
identically from **Python, Cython and C++** (see [`docs/40_interop.md`](docs/40_interop.md)).

### The GUI

The pip install provides console scripts — launch the browser app with:

```bash
prodnet-gui        # aliases: prodnet-run, netrecon-gui, netrecon-run
```

It starts a local Flask server and opens your browser: pick an economy and scale,
tweak the knobs, and download the resulting `weights.csrbin`. See
[`docs/GUI.md`](docs/GUI.md).

### The CLI (repository checkout)

```bash
python code_generation/run_pipeline.py --economy Denmark_interfirm --gamma 0.02 --seed 1 --bin --cpu-draw
```

`--gamma` is the subsample fraction of the census. Output lands in
`outputs/pipe_<tag>/weights.csrbin`. Every stage and knob is documented in
[`docs/PIPELINE.md`](docs/PIPELINE.md).

---

## What's in the box

| Component | What it is |
|---|---|
| **Reconstruction pipeline** (`code_generation/run_pipeline.py` + stages) | Turns `firm-size + IO` into a weighted, irreducible, aperiodic firm network. Bundled inside the wheel under `prodnet_generator/_pipeline/`. |
| **Python library** (`import prodnet_generator`) | The pip-installable, callable API over the pipeline: `prodnet_generator(economy, n_firms=…)`, `capabilities()` / `feasibility()` hardware checks, and two packaged demo economies. Deterministic and callable identically from Python, Cython and C++. |
| **ProdNet Generator GUI** (`code_generation/prodnet_generator/`) | A local Flask browser app — a friendly front end for the pipeline (`prodnet-gui`): presets, knobs, and a results viewer. |
| **ESRI research engines** (`code_else/`) | Firm-level systemic-risk cascades (Linear, Leontief, CES-granular) over a reconstructed network. These are **research scripts in the repository only** — they are *not* part of the installed library or GUI. |

---

## Repository layout

```
prodnet_generator/          the pip package (library)
  api.py                      the callable facade over the pipeline
  hardware.py                 hardware-aware preflight (capabilities/feasibility)
  _pipeline/                  the pipeline bundled into the wheel (code + demo data)

code_generation/            the reconstruction pipeline (dev / golden path)
  run_pipeline.py             Stage B→G driver (solve z → draw → floor → closure → weights)
  census_estimate.py          Stage 1 FlowFit (λ on representative firms) + subsampling
  step2_gravity_bernoulli.py  Stage 1c CPU Bernoulli draw
  gpu_stage_c.py              Stage 1c GPU (Metal/MLX) Bernoulli draw
  step3_degree_floor.py       Stage D: degree-floor repair
  step4_make_irreducible_aperiodic.py  Stages E/F: single-SCC + aperiodic closure
  markov_closure/             Stage 2 "mew" — the C ADMM min-energy dollar-weight solver
  recon_bundle.py             resolve an economy name -> its validated (census, λ, IO) trio
  read_weighted_csr.py        loader for weights.csrbin (CSR / COO)
  datasets/<C>_interfirm/     consistent-model bundle: census.npz, lambda.npz, flow_target_F.txt, input_files/
  prodnet_generator/          the Flask GUI (app.py, runner.py, templates/)

code_else/                  research layer (ESRI engines; not part of the library)
```

---

## Documentation

| Doc | Contents |
|---|---|
| **Library guide** — [`docs/00_index.md`](docs/00_index.md) → [`docs/70_faq.md`](docs/70_faq.md) | The pip-installable API: [quickstart](docs/10_quickstart.md), [method + math](docs/20_method.md), [hardware-awareness](docs/35_hardware.md), [interop](docs/40_interop.md), [cookbook](docs/50_cookbook.md), [API reference](docs/60_api.md), [FAQ](docs/70_faq.md). Also a self-contained offline HTML site at [`docs/html/index.html`](docs/html/index.html). |
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | The pipeline as a data-flow: inputs → Stage 1 fit → draw → closure → Stage 2 weights. |
| [`docs/PIPELINE.md`](docs/PIPELINE.md) | `run_pipeline.py` — every stage and every CLI knob with its locked default. |
| [`docs/GUI.md`](docs/GUI.md) | The ProdNet Generator GUI: launch, presets, knobs, estimate-α, results viewer, routes. |
| [`docs/INPUT_FORMAT.md`](docs/INPUT_FORMAT.md) | The input CSVs the GUI/pipeline consume — columns + examples. |

---

## Authors & license

Created by **Ashwin Bhattathiripad** and **Vipin P Veetil**
(<https://www.vipinveetil.com>). Released under the **MIT License** — see
[`LICENSE`](LICENSE).
