girder-dashboards-porosity-modeling
Porosity modelling for laser powder bed fusion metals, as a dashboard for girder-dashboards.
It is the web front end of PorosityModel —
the modular lack-of-fusion / keyhole / gas pore framework from CMU's EMIT Lab — and
nothing else. Every number it reports comes out of
porosity_modeling.execute_porosity_model, called with the arguments that
project's Dash GUI assembled. This package replaces the GUI; it does not
reimplement the science.
| Dash GUI | This dashboard | |
|---|---|---|
| Measured data | a path in a text box (data/), downloaded from Figshare when absent |
two Girder items, configured by a site admin — or your own CSVs, uploaded per run |
| Material files | files inside the wheel | a curated Girder folder, plus the wheel's own |
| Parameter form | one flat sorted list of every field | two groups: process parameters, and the properties the melt pool model requires |
| Result | a PNG of a matplotlib figure | an interactive plot of the same numbers |
| Outputs | files in a directory on the server | a Girder folder per run, shared and downloadable like any other data |
| Concurrency | one process, one run | a Celery job per run, with an in-process fallback |
Installing
pip install girder-dashboards-porosity-modeling
girder build # or restart Girder
Then enable it at #plugins/dashboards/config — like every dashboard, it is
provisioned disabled.
Installing porosity_modeling
porosity_modeling is a hard requirement and is not on PyPI:
imqcam/PorosityModel is a private repository whose CI publishes the wheel as the
porosity-modeling-dist artifact of its ci.yml run (kept 90 days; tagged
releases also attach it to the GitHub release). Making that wheel resolvable is
the installer's job, and two ways are supported:
1. A wheel directory (what a Docker build should do). Copy the wheel into the
image and point pip at it, so the ordinary pip install of this package resolves
the dependency like any other:
COPY porosity_modeling-*.whl /wheels/
ENV PIP_FIND_LINKS=/wheels
RUN pip install girder-dashboards-porosity-modeling
This is the recommended shape because it survives a plain pip install -e . — the
form deployment tooling such as wholetale-docker/build_plugins.sh uses — with
nothing extra to remember.
2. Install the wheel first.
pip install ./porosity_modeling-0.1.0-py3-none-any.whl
pip install girder-dashboards-porosity-modeling
Either way it has to happen in both the Girder environment and the Celery
worker environment. If it is missing, the dashboard says so on a banner and every
endpoint returns 503 rather than a run failing on an ImportError a minute in.
Configuring
Settings live on the dashboard document and are edited from the gear on the
dashboard card (#plugins/dashboards/config).
| Setting | What it is |
|---|---|
poreDataItemId |
Girder item holding poredf.csv (or poredf.csv.gz) — one row per pore the X-µCT measured |
parametersItemId |
Girder item holding parameters.csv — one row per measured coupon |
materialFolderId |
Girder folder of material property files, one JSON item each |
exampleParamsItemId |
Girder item holding a process-parameter JSON for "Load example case". Falls back to the wheel's params.json |
defaultTotalPores |
Pre-filled sample count (10000) |
maxTotalPores |
Ceiling on one run (200000) |
defaultPoreModels |
Pore sources ticked on arrival (["lof","keyhole","gas"]) |
defaultMeltpoolModel |
Melt pool model pre-selected ("Rosenthal") |
These are editable from the dashboard itself: an admin sees an Instance dataset
panel at the foot of the page with, for each setting, a Girder browser to pick an
existing item and an Upload… button to put a table there from their own machine —
into a public Porosity Modeling Data folder, because read access is checked against
whoever runs the model, so a private one would work for the admin and be missing for
everyone else. Plus a Check the dataset button that reports whether the pair can actually be used — including the
Geometry values the coupons contain and the (Power, Velocity) range they cover,
which are otherwise unknowable and are each a silent failure when a run gets them
wrong. The raw-JSON editor on the plugin config page still works and still reaches
the settings this panel does not edit.
Nothing has to be configured for the dashboard to work: with no dataset items it
offers only the upload-your-own path, and the wheel's bundled material models are
always listed. The datasets are the two committed in the PorosityModel repository
under data/; upload them into two items and name the items here.
The two tables are a matched pair, joined on their coupon Name column: the
pore table says which coupon each pore came from, and the coupon table says what
that coupon was built at and how much of it was inspected. Half of one dataset and
half of another share no coupon names, match nothing, and the run fails with "All
pore densities are zero" — which is why the dashboard takes both from one place or
both from the run folder, never one of each.
Neither is the process parameters of the build being predicted. Those are a form
field, one build's worth, looked up against the coupon table; parameters.csv is
the 61-coupon table looked up in. They share five column names, which is the whole
reason the distinction needs stating.
Material items
An item in materialFolderId is offered when its JSON supplies every property the
selected melt pool model's getpropnames() names — compatibility is computed from
the keys, never from the file being called *_rosenthal.json. Two pieces of item
metadata are read when present:
| Key | Effect |
|---|---|
materialName |
Selecting the material also fills in the Material process parameter, which the bundled files cannot do — "Material": "Ti6Al4V" is a process parameter and is not in ti64_rosenthal.json |
description |
Shown with the material |
A run
A run is a Girder folder in the user's own space, so it is shared, ACL'd and deleted like any other data:
<user>/Porosity Modeling/
2026-07-27 15-51-32/
poredf.csv only when the user uploaded their own
parameters.csv likewise
params.json these four are exactly what a `porosity-model`
mp_params.json CLI run writes into its output directory
samples.csv
number_density.pdf
results.json the numbers the dashboard plots
run.log everything the model printed
number_density.pdf is kept even though the dashboard draws its own chart: a run
folder should be the same artifact a CLI run produces. results.json carries the
output of the same visualization.ndplot.get_number_density call the PDF is drawn
from, so the plot on screen and the figure in the file are one calculation, not
two that ought to agree.
Execution
The run is a Celery task on the local queue. Where no worker is consuming it,
the same code runs in a daemon thread of the Girder process instead — so a plain
girder serve is a working deployment. Both produce an ordinary Girder job, and
the dashboard cannot tell which happened.
The worker needs HTTP access to Girder and nothing else: both reference tables
arrive through GirderFileId transforms and every output leaves through
girder_client. It does need girder-dashboards-porosity-modeling and the
porosity_modeling wheel installed.
REST API
Under /api/v1/porosity. Every route is @access.user and checks the dashboard's
own ACL, so disabling the dashboard disables the functionality rather than merely
hiding the card.
| Route | Purpose |
|---|---|
GET /porosity/capability |
dependency probe, worker availability, settings, model lists, whether the configured dataset is usable |
GET /porosity/parameters |
the fields a combination of models requires, partitioned into process and material |
GET /porosity/material |
the material library for a melt pool model, values inline, each flagged compatible or not |
GET /porosity/example |
the example process parameters |
GET/POST /porosity/run |
list runs; create a run folder |
GET/DELETE /porosity/run/{id} |
run state; delete the folder |
POST /porosity/run/{id}/execute |
schedule the run; returns the job |
Development
(cd girder_dashboards_porosity_modeling/web_client && npm ci && npm run build)
pip install -e .
pytest girder_dashboards_porosity_modeling/tests
ruff check .
Build the web client before running the Python tests. load() calls
registerPluginStaticContent, which md5-hashes every listed file, so with no
bundle in web_client/dist it raises FileNotFoundError and every test using the
server fixture errors out. The girder-dashboards bundle must exist too, since
loading this plugin loads that one.
Licence
BSD-3-Clause. The research code it drives, PorosityModel, is MIT, © its authors:
Justin P. Miner and Sneha Prabha Narra, Carnegie Mellon University. Please cite the
X-µCT datasets listed in that repository's README if you use the reference data.
Metadata
Release files for girder-dashboards-porosity-modeling 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| girder_dashboards_porosity_modeling-0.1.0.tar.gz | 121.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 246.7 kB
Release files / girder_dashboards_porosity_modeling-0.1.0.tar.gz
| Download URL | girder_dashboards_porosity_modeling-0.1.0.tar.gz |
|---|---|
| Size | 121.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bd6bc50d57cdf3bc229118ea29670912bc199a02fe37807fa1d4d9daa38a65f5
|
|
BLAKE2b-256 checksum How to use checksums |
accb0647bd07f626fb89ce849462250cc6dd85647bba1452f866c5ef0e31c24c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.
Transparency logRelease files / girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl
| Download URL | girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl |
|---|---|
| Size | 125.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a317f8de0d558a061c80d27d38f1869fd97bdf9d7fb373b6c32f3e32cf654570
|
|
BLAKE2b-256 checksum How to use checksums |
ee8b17be9d01ba1eb0db11b8dded06bbde6093153da9c5bc4596e49368271cf2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.
Transparency log