# mvnayagam/pypsc architecture

> Architecture diagram of the GitHub repository mvnayagam/pypsc, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/mvnayagam/pypsc
- Repository: https://github.com/mvnayagam/pypsc

## Overview

#### Purpose and execution model
pypsc is a Python scientific-computing library for recovering 1D-projected independent-scatterer coordinates from diffraction structure-factor amplitudes or intensities. It replaces Fourier inversion with Parameter Space Concept (PSC): represent each reflection as a piecewise analytic isosurface, linearize it into feasible polytopes, then intersect constraints to retain all compatible structures. There is no standalone application/server entry point; notebooks are the primary interactive entry points: `examples/ex01-EPA/EPA.ipynb`, `examples/ex02-NEPA/NEPA.ipynb`, and `examples/ex03-MCEPA/mcsolver.ipynb`.

#### Core diffraction and parameter-space model
Low-level PSC mathematics is organized in `lib/`. Scattering factors and reciprocal/parameter-space calculations are provided by `lib/getscatteringfactor.py` and `lib/gspacer.py`; origin handling is separated in `lib/choiceoforigin.py`. These inputs define reflection-specific constraints over fractional atomic-coordinate parameter space, rather than reconstructing density from a Fourier map.

#### Linearization pipeline
`lib/linearizer.py` converts amplitude/intensity isosurfaces into linearized representations suitable for geometric solving. `lib/checklinearizer.py` validates that approximation, creating an explicit numerical-quality boundary before constraints are used downstream. The README’s tolerance warning is architecturally important: the external Python `polytope` package underlies feasible-region operations and must be configured with tighter `ABS_TOL` for fractional-coordinate precision.

#### Constraint intersection and solution lifecycle
The main deterministic solver is `lib/pscsolver.py`. It combines reflection constraints through geometric intersection (`lib/intersector.py`) and subdivision/tessellation (`lib/tessellator.py`) to derive candidate solution regions. Candidate regions are then consolidated and filtered through `lib/solutionmerger.py` and `lib/solutionselector.py`. This establishes the main control flow: diffraction observations → linearized repeated constraints → polytope intersections → merged/selected structural solutions.

#### Persistence and downstream analysis
Solutions and intermediate PSC/polytope results are persisted as HDF5, evidenced by the solver outputs under `examples/ex01-EPA/` and `examples/ex02-NEPA/`. `lib/solutionIO.py` is the write/read boundary, while `lib/solutionreader.py` provides result consumption. HDF5 files allow expensive solver runs to be inspected and plotted later rather than requiring an in-memory interactive session.

#### Monte Carlo and dimensional extensions
`lib/mcsolver.py` orchestrates Monte Carlo-oriented solving, with example outputs collected in `examples/ex03-MCEPA/temp/`. The `lib/2DandMC/` subtree contains specialized workflows for 2D parameter spaces and Monte Carlo variants: `lib/2DandMC/MCin2DPS_EPA.py`, `lib/2DandMC/MCin2DPS_nEPA.py`, and `lib/2DandMC/MCinNDPS_EPA.py`. These branch from the deterministic PSC pipeline to simulate or explore random structures while retaining EPA/nEPA-specific handling.

#### User-facing visualization and support layer
Notebooks compose library routines with analysis/plotting utilities, including `tools/plot3DMCresults.py`, `tools/x3Dplot.py`, and `utils/plothdf.py`. Logging is centralized in `config/logconfig.py` and `utils/logger.py`. The repository’s material runtime is Python, packaged through `pyproject.toml`; principal external dependencies include the polytope geometry package and an HDF5-capable Python stack implied by persisted `.h5` results.

Main entry points: [`lib/pscsolver.py`](https://github.com/mvnayagam/pypsc/blob/main/lib/pscsolver.py) (PSC solver), [`lib/mcsolver.py`](https://github.com/mvnayagam/pypsc/blob/main/lib/mcsolver.py) (Monte Carlo solver), [`lib/gspacer.py`](https://github.com/mvnayagam/pypsc/blob/main/lib/gspacer.py) (Reciprocal parameter space), [`lib/intersector.py`](https://github.com/mvnayagam/pypsc/blob/main/lib/intersector.py) (Polytope intersection)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interactive["Interactive workflows"]
  node_epa_notebook["EPA notebook<br/>Jupyter notebook<br/>[EPA.ipynb]"]
  node_nepa_notebook["nEPA notebook<br/>Jupyter notebook<br/>[NEPA.ipynb]"]
  node_mc_notebook["MC solver notebook<br/>Jupyter notebook<br/>[mcsolver.ipynb]"]
end

subgraph group_psc["PSC solver core"]
  node_scattering["Scattering factors<br/>PSC math"]
  node_parameter_space["Reciprocal parameter space<br/>PSC math<br/>[gspacer.py]"]
  node_origin["Origin choice<br/>coordinate handling<br/>[choiceoforigin.py]"]
  node_linearizer["Isosurface linearizer<br/>constraint builder<br/>[linearizer.py]"]
  node_linear_check["Linearization validation<br/>quality gate<br/>[checklinearizer.py]"]
  node_deterministic_solver{{"PSC solver<br/>deterministic orchestrator<br/>[pscsolver.py]"}}
  node_intersector["Polytope intersection<br/>geometry stage<br/>[intersector.py]"]
  node_tessellator["Subdivision and tessellation<br/>geometry stage<br/>[tessellator.py]"]
  node_merger["Solution merger<br/>candidate consolidation<br/>[solutionmerger.py]"]
  node_selector["Solution selector<br/>candidate filter"]
  node_polytope["polytope package<br/>external geometry dependency"]
end

subgraph group_extensions["Monte Carlo extensions"]
  node_mc_solver{{"Monte Carlo solver<br/>stochastic orchestrator<br/>[mcsolver.py]"}}
  node_mc_2d["2D MC EPA workflow<br/>specialized workflow<br/>[MCin2DPS_EPA.py]"]
  node_mc_nd["ND MC EPA workflow<br/>specialized workflow<br/>[MCinNDPS_EPA.py]"]
end

subgraph group_results["Results and analysis"]
  node_solution_io["Solution HDF5 I/O<br/>persistence boundary<br/>[solutionIO.py]"]
  node_hdf5_results[("HDF5 results<br/>persisted solver output")]
  node_solution_reader["Solution reader<br/>result consumption<br/>[solutionreader.py]"]
  node_plotting["Plotting utilities<br/>visualization<br/>[plot3DMCresults.py]"]
  node_logging["Central logging<br/>runtime support<br/>[logger.py]"]
end

node_epa_notebook -->|"runs PSC solving"| node_deterministic_solver
node_nepa_notebook -->|"runs PSC solving"| node_deterministic_solver
node_mc_notebook -->|"runs stochastic solving"| node_mc_solver
node_scattering -->|"defines reflection inputs"| node_parameter_space
node_origin -->|"sets coordinate convention"| node_parameter_space
node_parameter_space -->|"reflection isosurfaces"| node_linearizer
node_linearizer -->|"linearized constraints"| node_linear_check
node_linear_check -->|"validated constraints"| node_deterministic_solver
node_deterministic_solver -->|"intersects feasible regions"| node_intersector
node_deterministic_solver -->|"subdivides regions"| node_tessellator
node_intersector -->|"candidate regions"| node_merger
node_tessellator -->|"tessellated candidates"| node_merger
node_merger -->|"consolidated solutions"| node_selector
node_selector -->|"selected solutions"| node_solution_io
node_solution_io -->|"writes and reads"| node_hdf5_results
node_hdf5_results -->|"loads results"| node_solution_reader
node_solution_reader -->|"analysis data"| node_plotting
node_polytope -.->|"feasible-region operations"| node_intersector
node_polytope -.->|"polytope operations"| node_tessellator
node_mc_solver -.->|"reuses PSC pipeline"| node_deterministic_solver
node_mc_solver -->|"drives 2D variants"| node_mc_2d
node_mc_solver -->|"drives ND variants"| node_mc_nd
node_deterministic_solver -.->|"runtime diagnostics"| node_logging

click node_epa_notebook "https://github.com/mvnayagam/pypsc/blob/main/examples/ex01-EPA/EPA.ipynb"
click node_nepa_notebook "https://github.com/mvnayagam/pypsc/blob/main/examples/ex02-NEPA/NEPA.ipynb"
click node_mc_notebook "https://github.com/mvnayagam/pypsc/blob/main/examples/ex03-MCEPA/mcsolver.ipynb"
click node_scattering "https://github.com/mvnayagam/pypsc/blob/main/lib/getscatteringfactor.py"
click node_parameter_space "https://github.com/mvnayagam/pypsc/blob/main/lib/gspacer.py"
click node_origin "https://github.com/mvnayagam/pypsc/blob/main/lib/choiceoforigin.py"
click node_linearizer "https://github.com/mvnayagam/pypsc/blob/main/lib/linearizer.py"
click node_linear_check "https://github.com/mvnayagam/pypsc/blob/main/lib/checklinearizer.py"
click node_deterministic_solver "https://github.com/mvnayagam/pypsc/blob/main/lib/pscsolver.py"
click node_intersector "https://github.com/mvnayagam/pypsc/blob/main/lib/intersector.py"
click node_tessellator "https://github.com/mvnayagam/pypsc/blob/main/lib/tessellator.py"
click node_merger "https://github.com/mvnayagam/pypsc/blob/main/lib/solutionmerger.py"
click node_selector "https://github.com/mvnayagam/pypsc/blob/main/lib/solutionselector.py"
click node_solution_io "https://github.com/mvnayagam/pypsc/blob/main/lib/solutionIO.py"
click node_solution_reader "https://github.com/mvnayagam/pypsc/blob/main/lib/solutionreader.py"
click node_plotting "https://github.com/mvnayagam/pypsc/blob/main/tools/plot3DMCresults.py"
click node_mc_solver "https://github.com/mvnayagam/pypsc/blob/main/lib/mcsolver.py"
click node_mc_2d "https://github.com/mvnayagam/pypsc/blob/main/lib/2DandMC/MCin2DPS_EPA.py"
click node_mc_nd "https://github.com/mvnayagam/pypsc/blob/main/lib/2DandMC/MCinNDPS_EPA.py"
click node_logging "https://github.com/mvnayagam/pypsc/blob/main/utils/logger.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_epa_notebook,node_nepa_notebook,node_mc_notebook toneBlue
class node_scattering,node_parameter_space,node_origin,node_linearizer,node_linear_check,node_deterministic_solver,node_intersector,node_tessellator,node_merger,node_selector,node_polytope toneAmber
class node_mc_solver,node_mc_2d,node_mc_nd toneMint
class node_solution_io,node_hdf5_results,node_solution_reader,node_plotting,node_logging toneRose
```

## Components

### Interactive workflows

Notebook-driven scientific workflows.

- [EPA notebook](https://github.com/mvnayagam/pypsc/blob/main/examples/ex01-EPA/EPA.ipynb): Jupyter notebook · `examples/ex01-EPA/EPA.ipynb`
- [nEPA notebook](https://github.com/mvnayagam/pypsc/blob/main/examples/ex02-NEPA/NEPA.ipynb): Jupyter notebook · `examples/ex02-NEPA/NEPA.ipynb`
- [MC solver notebook](https://github.com/mvnayagam/pypsc/blob/main/examples/ex03-MCEPA/mcsolver.ipynb): Jupyter notebook · `examples/ex03-MCEPA/mcsolver.ipynb`

### PSC solver core

Diffraction constraints through deterministic solution selection.

- [Scattering factors](https://github.com/mvnayagam/pypsc/blob/main/lib/getscatteringfactor.py): PSC math · `lib/getscatteringfactor.py`
- [Reciprocal parameter space](https://github.com/mvnayagam/pypsc/blob/main/lib/gspacer.py): PSC math · `lib/gspacer.py`
- [Origin choice](https://github.com/mvnayagam/pypsc/blob/main/lib/choiceoforigin.py): coordinate handling · `lib/choiceoforigin.py`
- [Isosurface linearizer](https://github.com/mvnayagam/pypsc/blob/main/lib/linearizer.py): constraint builder · Converts amplitude or intensity isosurfaces into linear constraints. · `lib/linearizer.py`
- [Linearization validation](https://github.com/mvnayagam/pypsc/blob/main/lib/checklinearizer.py): quality gate · Validates numerical approximation before solving. · `lib/checklinearizer.py`
- [PSC solver](https://github.com/mvnayagam/pypsc/blob/main/lib/pscsolver.py): deterministic orchestrator · `lib/pscsolver.py`
- [Polytope intersection](https://github.com/mvnayagam/pypsc/blob/main/lib/intersector.py): geometry stage · `lib/intersector.py`
- [Subdivision and tessellation](https://github.com/mvnayagam/pypsc/blob/main/lib/tessellator.py): geometry stage · `lib/tessellator.py`
- [Solution merger](https://github.com/mvnayagam/pypsc/blob/main/lib/solutionmerger.py): candidate consolidation · `lib/solutionmerger.py`
- [Solution selector](https://github.com/mvnayagam/pypsc/blob/main/lib/solutionselector.py): candidate filter · `lib/solutionselector.py`
- **polytope package**: external geometry dependency · Requires tightened ABS_TOL for fractional-coordinate precision.

### Monte Carlo extensions

Stochastic and higher-dimensional PSC workflows.

- [Monte Carlo solver](https://github.com/mvnayagam/pypsc/blob/main/lib/mcsolver.py): stochastic orchestrator · `lib/mcsolver.py`
- [2D MC EPA workflow](https://github.com/mvnayagam/pypsc/blob/main/lib/2DandMC/MCin2DPS_EPA.py): specialized workflow · `lib/2DandMC/MCin2DPS_EPA.py`
- [ND MC EPA workflow](https://github.com/mvnayagam/pypsc/blob/main/lib/2DandMC/MCinNDPS_EPA.py): specialized workflow · `lib/2DandMC/MCinNDPS_EPA.py`

### Results and analysis

HDF5 persistence and visualization.

- [Solution HDF5 I/O](https://github.com/mvnayagam/pypsc/blob/main/lib/solutionIO.py): persistence boundary · `lib/solutionIO.py`
- **HDF5 results**: persisted solver output · Stores solutions and intermediate PSC/polytope results.
- [Solution reader](https://github.com/mvnayagam/pypsc/blob/main/lib/solutionreader.py): result consumption · `lib/solutionreader.py`
- [Plotting utilities](https://github.com/mvnayagam/pypsc/blob/main/tools/plot3DMCresults.py): visualization · `tools/plot3DMCresults.py`
- [Central logging](https://github.com/mvnayagam/pypsc/blob/main/utils/logger.py): runtime support · `utils/logger.py`

## Connections

- EPA notebook → PSC solver: runs PSC solving
- nEPA notebook → PSC solver: runs PSC solving
- MC solver notebook → Monte Carlo solver: runs stochastic solving
- Scattering factors → Reciprocal parameter space: defines reflection inputs
- Origin choice → Reciprocal parameter space: sets coordinate convention
- Reciprocal parameter space → Isosurface linearizer: reflection isosurfaces
- Isosurface linearizer → Linearization validation: linearized constraints
- Linearization validation → PSC solver: validated constraints
- PSC solver → Polytope intersection: intersects feasible regions
- PSC solver → Subdivision and tessellation: subdivides regions
- Polytope intersection → Solution merger: candidate regions
- Subdivision and tessellation → Solution merger: tessellated candidates
- Solution merger → Solution selector: consolidated solutions
- Solution selector → Solution HDF5 I/O: selected solutions
- Solution HDF5 I/O → HDF5 results: writes and reads
- HDF5 results → Solution reader: loads results
- Solution reader → Plotting utilities: analysis data
- polytope package → Polytope intersection: feasible-region operations
- polytope package → Subdivision and tessellation: polytope operations
- Monte Carlo solver → PSC solver: reuses PSC pipeline
- Monte Carlo solver → 2D MC EPA workflow: drives 2D variants
- Monte Carlo solver → ND MC EPA workflow: drives ND variants
- PSC solver → Central logging: runtime diagnostics
