Physics-constrained analysis of thin-film photovoltaic device and material characterisation: seventeen measurement techniques and the solar-simulator mismatch correction, one set of conventions, cross-checks between them, and every number traceable to an equation, a test and a side-car file.
Physiscore recomputes device and material parameters from the measured curves rather than copying an instrument's summary block, applies the standard physical models (one-diode equivalent circuit, detailed balance, Tauc/Urbach, Scherrer/Williamson–Hall, Shirley background, Mott–Gurney, Mott–Schottky, equivalent circuits with a Kramers–Kronig test …) with stated defaults, and reports each quantity with its fit quality. The algorithms are documented with equations and references in docs/METHODS.md and validated against closed-form synthetic data in docs/VALIDATION.md.
| Technique | Derived quantities |
|---|---|
| J–V (light) | Voc, Jsc, FF, PCE, Vmpp, Rs, Rsh from the curve; one-diode fit (Jph, J0, n, Rs, Rsh); forward/reverse hysteresis index; group statistics; Jsc mismatch vs EQE |
| J–V (dark) | ideality factor n and J0 (sliding window), Rsh,dark, full one-diode fit with Rs, Cheung dV/dlnJ |
| EQE | AM1.5G-integrated Jsc (ASTM G173-03), Eg from dEQE/dE (Rau), Urbach energy, J0,rad, Voc,rad, Shockley–Queisser limits, ΔV1/ΔV2/ΔV3 loss breakdown |
| Absorbance | Tauc band gap with automatic linear region and standard error, derivative Eg, Urbach energy; A or α basis |
| XRD | ALS background, simultaneous pseudo-Voigt fitting, d-spacing, Scherrer (instrument-corrected), Williamson–Hall with uncertainties, Kα2 stripping, crystallinity index, cubic lattice parameter (Nelson–Riley) |
| PL | Savitzky–Golay + ALS, Gaussian/Voigt single or AIC-selected multi-component fits, energy axis with Jacobian, FWHM in nm and meV, quenching efficiency |
| Raman / FTIR | arPLS/ALS baselines, band detection and Lorentzian/Gaussian fitting, peak-shift tables, band library, T↔A |
| SEM | watershed grain segmentation, size distribution with D10/D50/D90 and log-normal fit |
| XPS | Shirley background, Voigt singlet/doublet fitting, charge referencing, atomic concentration |
| Light intensity | ideality factor from Voc against ln(irradiance) with its error, Jsc ∝ I^α, Suns-Voc pseudo J-V, pseudo fill factor and the transport loss, local ideality |
| SCLC | ohmic, trap-filling and Child regimes from the local slope, V_TFL and trap density with its resolution limit, Mott–Gurney mobility (optionally Murgatroyd), conductivity and n0, sweep hysteresis |
| Impedance | complex least-squares fit of R(RC), R(RQ), R(RC)(RC) or R(RQ)(RQ) chosen by AICc, parameter errors, time constants, effective capacitance, linear Kramers–Kronig test, distribution of relaxation times (regularised, processes and their resistances) |
| C–V (Mott–Schottky) | straight section of 1/C² found automatically, doping density, built-in voltage, depletion width, doping profile N(W), full-depletion limit N_min |
| TRPL | one to three exponentials or a stretched exponential chosen by AICc (Poisson maximum likelihood for counts), reconvolution with a Gaussian or measured instrument response, amplitude- and intensity-weighted mean lifetimes, τ(1/e), differential lifetime, diffusion length |
| PLQY and QFLS | absorptance and absolute PLQY from integrating-sphere spectra (de Mello), or a PLQY series against intensity; QFLS by detailed balance with J0,rad from the EQE of the stack, the band gap or entered; non-radiative loss −kT ln PLQY; QFLS/q − Voc; implied ideality factor, implied J-V, FF and efficiency |
| Stability | T80 (measured, or extrapolated and marked as such), burn-in amplitude and time constant, stabilised Ts80, loss rate per 1000 h, ISOS protocol on record |
| Spectral mismatch | mismatch factor M of the solar simulator for each test cell (IEC 60904-7) from the lamp spectrum and the reference-cell response; Jsc under AM1.5G and on the simulator; IEC 60904-9 spectral match class (2007 and 2020 editions) |
| Device summary | J-V + EQE (+ absorbance, PL) of one device: Jsc cross-check (with the J-V current divided by M when given), band gap from three techniques, Voc vs Voc,rad and Voc,SQ with the loss breakdown, fractions of the SQ limits |
Interpretation in every window turns the results into findings by explicit rules - fill-factor loss split, ideality regime, statistics between conditions, voltage losses, Williamson–Hall strain, secondary phases, metallic lead in XPS, trap density against its resolution limit, Kramers–Kronig validity of an impedance spectrum, an extrapolated T80 and more - each with its evidence, threshold, reference and next step. It runs offline, needs no account and gives the same text for the same data (METHODS §16).
Open data reads a file, recognises the measurement from its name, column headers and numbers, and opens it in the right tool; Workspace folder lists a whole project that way, and the Results tab collects the key numbers of everything exported below that folder into one table (and one Excel workbook). The recognition is a list of scored rules (METHODS §23). Every graph has a data reader, a plot-details dialog, a data worksheet and a figure export at journal column widths.
Many files at once: Compare files in the spectroscopy tools and physiscore batch on the
command line tabulate whole series; XRD patterns can be matched against reference peak
lists; J-V curves can come from instrument text exports or from CSV/Excel files.
All screenshots show synthetic example data (analytical models with noise), produced by
python tools/screenshots.py; the user guide explains every window.
More: workspace tab, interpretation, light intensity, C-V, stability, dark J-V, absorbance, PL, FE-SEM, Raman, FTIR, comparing files, updates tab.
| Document | Content |
|---|---|
| USER_GUIDE.md | every window step by step, outputs, settings, troubleshooting |
| METHODS.md | equation, procedure, defaults and reference of every reported quantity |
| VALIDATION.md | each estimator against closed-form synthetic data |
| FILE_FORMATS.md | accepted input layouts and the files Physiscore writes |
| CLI.md | command-line reference |
| INSTALL.md | installers, first start, checksums, automatic updates |
| ARCHITECTURE.md | module layout, principles, adding a tool, release checks |
| CHANGELOG.md | changes by version |
Ready-to-run programs (no Python needed) are attached to the latest release:
| System | File |
|---|---|
| Windows 10/11 (64-bit) | Physiscore-<version>-windows-x64-setup.exe (installer) or …-windows-x64-portable.zip |
| macOS, Apple silicon | Physiscore-<version>-macos-arm64.dmg |
| macOS, Intel | Physiscore-<version>-macos-x86_64.dmg |
| Ubuntu / Debian | physiscore_<version>_amd64.deb |
| Other Linux | Physiscore-<version>-linux-x86_64.tar.gz (run install.sh) |
Installation steps, first-start prompts of unsigned builds, checksums and uninstalling: docs/INSTALL.md. Installed copies update themselves (Tools → Updates: download and install, only notify, or off).
Python 3.10 or newer.
git clone https://github.com/jongsu-king/physiscore.git
cd physiscore
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python Physiscore_Launcher.pypython Physiscore_Launcher.py --tool "J-V Curve" opens one analysis window directly,
--spectra XRD|PL|XPS the auto-fit workspace, and --open FILE ... (or --open FOLDER)
starts with those measurements recognised and opened.
The same cores run without the GUI, for batch processing and scripts:
python physiscore_cli.py jv measurements/2026-01-20 --area 0.04 # Excel + statistics + hysteresis
python physiscore_cli.py eqe device_A_eqe.csv --voc 1.12 --json # Eg, Eu, Voc,rad, SQ, ΔV1..3
python physiscore_cli.py abs film.xlsx --sheet UV --mode direct # Tauc Eg ± error, Urbach
python physiscore_cli.py xrd pattern.txt --instrument-fwhm 0.06 --strip-ka2
python physiscore_cli.py pl spectrum.csv --max-peaks 3
python physiscore_cli.py vib raman.csv --technique raman
python physiscore_cli.py device --jv cell.txt --eqe cell_eqe.csv # cross-technique summary
python physiscore_cli.py sclc eod.csv --thickness 500 --eps 25 # regimes, trap density, mobility
python physiscore_cli.py intensity --jv-set 100mW.txt 50mW.txt 10mW.txt # n_id, Jsc exponent, pseudo FF
python physiscore_cli.py trpl decay.csv --model auto --interpret # lifetimes + findings
python physiscore_cli.py eis spectrum.csv --out eis.xlsx # circuit by AICc, Kramers-Kronig
python physiscore_cli.py cv mott.csv --area 0.1 --thickness 500 # N, Vbi, W, N_min
python physiscore_cli.py stability mppt/*.csv --protocol ISOS-L-1 # T80, burn-in, rate
python physiscore_cli.py plqy film_sphere.csv --radiative eqe --eqe-file stack_eqe.csv # PLQY, QFLS
python physiscore_cli.py mismatch cell_eqe.csv --sim lamp.csv --ref refcell_sr.csv # M, simulator class
python physiscore_cli.py detect project/ # which measurement is in which file
python physiscore_cli.py collect project/ --out results.xlsx # key numbers of every export
python physiscore_cli.py batch abs series/ --all-columns --out gaps.xlsx # one row per spectrum
python physiscore_cli.py sq 1.60 # Shockley-Queisser limit
python physiscore_cli.py validate # regenerate the validation table--json prints the full result for other programs; pip install . also installs a
physiscore console command.
import numpy as np
from scripts.JV.jv_core import compute_jv_parameters, fit_single_diode
from scripts.EQE.eqe_core import analyze_eqe
from scripts.XRD.xrd_core import detect_peaks_and_fit, williamson_hall
from scripts.TRPL import trpl_core
from scripts.SCLC import sclc_core
p = compute_jv_parameters(v, j, pin_mw_cm2=100.0) # Voc, Jsc, FF, PCE, Rs, Rsh ...
d = fit_single_diode(v, j) # Jph, J0, n, Rs, Rsh, R2
e = analyze_eqe(wavelength_nm, eqe_percent, voc_measured_v=1.10)
peaks, y_fit = detect_peaks_and_fit(two_theta, intensity, instrumental_fwhm_deg=0.05)
wh = williamson_hall(peaks["2Theta"], peaks["FWHM"], instrumental_fwhm_deg=0.05)
t = trpl_core.analyse(time_ns, counts) # model by AICc, lifetimes, chi2_red
s = sclc_core.analyse(v, j_ma_cm2, thickness_nm=500, eps_r=25) # regimes, V_TFL, n_t, mobilityEvery transport core (sclc_core, intensity_core, trpl_core, eis_core, cv_core,
stability_core, plqy_core, mismatch_core) has the same shape: analyse(...) returns a dictionary, checks(r) the
validity checks, summary_rows(r) the table shown in the window and simulate(...) the
forward model the tests use.
Shared primitives (baselines, line shapes, multi-peak fitting with AICc model
selection, Jacobian nm→eV conversion) live in scripts/common/spectral.py.
Settings are kept in physisfera_config.json (next to the source checkout, or in the
per-user settings folder of an installed copy: %APPDATA%\Physiscore,
~/Library/Application Support/Physiscore, ~/.config/Physiscore). The main window's
Settings dialog edits them:
| Key | Meaning | Default |
|---|---|---|
cell_area_cm2 |
device area for the current-density conversion (scales Jsc and PCE linearly; re-read for every analysis) | 0.04 |
theme |
light or dark appearance (applies after restart) |
light |
origin_path |
OriginLab executable for the optional Origin export (Windows) | "" |
The file also remembers the workspace folder and the parameters last used in each transport tool. The interpretation panels need no key and no network: they are rule-based (see METHODS §16). The only network access of the program is the update check against the GitHub releases page, which can be switched off. See CONFIG.md.
pip install pytest
pytest -q # 583 tests on closed-form synthetic data
python tools/validation_report.py # the table in docs/VALIDATION.md
python tools/gui_smoke.py # every window, the launcher and a session (needs a display)Measured example files (a perovskite XRD pattern, XPS region scans) live in a local
rawdata/ folder that is not published; the tests that need them are skipped when it is
absent.
A software paper is in preparation; please cite the archived release in the meantime:
Kim, K., Shin, J., Lim, J., Ji, H., Lee, S.-E., & Lee, J. (2026). Physiscore (Version 3.7.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.22267588
The concept DOI always resolves to the latest archived release. Full metadata is in
CITATION.cff; the methods and their references are in docs/METHODS.md.
MIT — see LICENSE.
Copyright © 2026 Hybrid Materials and Optoelectronics Laboratory (H-MOL), Incheon National University.











