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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file girder_dashboards_porosity_modeling-0.1.0.tar.gz.
File metadata
- Download URL: girder_dashboards_porosity_modeling-0.1.0.tar.gz
- Upload date:
- Size: 121.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd6bc50d57cdf3bc229118ea29670912bc199a02fe37807fa1d4d9daa38a65f5
|
|
| MD5 |
44f667851a40ec9309957b7caa6780fc
|
|
| BLAKE2b-256 |
accb0647bd07f626fb89ce849462250cc6dd85647bba1452f866c5ef0e31c24c
|
Provenance
The following attestation bundles were made for girder_dashboards_porosity_modeling-0.1.0.tar.gz:
Publisher:
release.yml on imqcam/girder-dashboards-porosity-modeling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
girder_dashboards_porosity_modeling-0.1.0.tar.gz -
Subject digest:
bd6bc50d57cdf3bc229118ea29670912bc199a02fe37807fa1d4d9daa38a65f5 - Sigstore transparency entry: 2335664487
- Sigstore integration time:
-
Permalink:
imqcam/girder-dashboards-porosity-modeling@58ca1881d92bd090af8e20d2a3ac59d0fc079049 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imqcam
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58ca1881d92bd090af8e20d2a3ac59d0fc079049 -
Trigger Event:
push
-
Statement type:
File details
Details for the file girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl.
File metadata
- Download URL: girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl
- Upload date:
- Size: 125.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a317f8de0d558a061c80d27d38f1869fd97bdf9d7fb373b6c32f3e32cf654570
|
|
| MD5 |
6daa8a308ad83224e0c014d86468cdf6
|
|
| BLAKE2b-256 |
ee8b17be9d01ba1eb0db11b8dded06bbde6093153da9c5bc4596e49368271cf2
|
Provenance
The following attestation bundles were made for girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl:
Publisher:
release.yml on imqcam/girder-dashboards-porosity-modeling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
girder_dashboards_porosity_modeling-0.1.0-py3-none-any.whl -
Subject digest:
a317f8de0d558a061c80d27d38f1869fd97bdf9d7fb373b6c32f3e32cf654570 - Sigstore transparency entry: 2335664518
- Sigstore integration time:
-
Permalink:
imqcam/girder-dashboards-porosity-modeling@58ca1881d92bd090af8e20d2a3ac59d0fc079049 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imqcam
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@58ca1881d92bd090af8e20d2a3ac59d0fc079049 -
Trigger Event:
push
-
Statement type: