Electrical circuit connectivity (circuits-0.3)
Reads an electrical floor plan (scan, photo or PDF render of an E-sheet) and returns which devices are on which circuit: every receptacle, switch, light fixture, exit sign and junction box it finds, the wiring runs drawn between them, which circuits have a home run, and roughly how much wiring each circuit draws on the sheet.
This is a lite model, trained on synthetic sheets and openly published public drawing sets. It is released for research and evaluation. Constructelligence's proprietary production models are available at constructelligence.co.
It is a drafting aid for takeoff and review. It is not a code-compliance check and it is not an as-built. It reads what is drawn. Accuracy on real sheets is moderate and varies with drafting style (see Results on real E-sheets).
How it works
- CircuitNet is a 1.7M-parameter U-Net that takes grayscale input and produces stride-2
outputs:
peaks: 13 per-class centre heatmaps, already 3ร3-NMS'd (12 symbol classes plus the home-run arrowhead).size: log box size.wire: a single wiring mask. Arcs and home-run lines appear as continuous centre lines, dashed runs are bridged, and walls, door swings, dimension strings and conductor hash marks are excluded.
decode.pyturns those outputs into a graph:- It cuts the mask at every symbol so each drawn run becomes its own stroke, thins the strokes and builds a skeleton graph.
- It resolves crossings: at an X, the two straightest continuations pair up, so runs that cross without a dot stay separate circuits. A dead-straight pair of arms next to a symbol is a run passing by, not landing on it.
- Stroke ends land on symbols or arrowheads, and a union-find groups the devices into circuits.
Classes: receptacle, gfci_receptacle, switch, switch_3way, ceiling_fixture, downlight, troffer, strip_light, exit_sign, junction_box, panelboard, data_outlet, homerun_arrow. data_outlet and panelboard are detected but never wired: data is
low voltage, and panels are fed by home runs.
Results
These are measured on 800 held-out synthetic 512ร512 sheets (seeds never used in training), with scan degradation applied: noise, blur, JPEG, thresholding and faded contrast.
| model | decoder on perfect inputs (ceiling) | nearest-neighbour baseline | |
|---|---|---|---|
| Wiring runs F1 | 0.839 | 0.902 | 0.323 |
| Same-circuit pair F1 | 0.818 | 0.839 | 0.247 |
| Circuits reproduced exactly | 60.3% | 70.7% | 2.3% |
| Home runs found | 90.5% | 95.9% | โ |
| Symbols F1 (all classes) | 0.972 | 1.000 | 1.000 |
- Decoder on perfect inputs feeds the decoder the ground-truth wire mask and symbol boxes. The gap between the model column and this one is the model's error, and the gap between this column and 1.0 is the decoder's.
- Nearest-neighbour baseline uses ground-truth symbols and wires each device to its nearest neighbour. It shows what you would get without reading the wiring at all.
Per-class symbol detection:
| class | GT boxes | precision | recall | F1 |
|---|---|---|---|---|
receptacle |
11000 | 0.958 | 0.999 | 0.978 |
gfci_receptacle |
1595 | 0.988 | 0.881 | 0.931 |
switch |
2008 | 0.891 | 0.946 | 0.917 |
switch_3way |
677 | 0.957 | 0.882 | 0.918 |
ceiling_fixture |
884 | 0.977 | 0.846 | 0.907 |
downlight |
4052 | 0.952 | 0.984 | 0.968 |
troffer |
4266 | 0.994 | 0.998 | 0.996 |
strip_light |
1017 | 0.971 | 0.997 | 0.984 |
exit_sign |
963 | 0.991 | 0.994 | 0.992 |
junction_box |
133 | 0.708 | 0.639 | 0.672 |
panelboard |
19 | 1.000 | 0.684 | 0.812 |
data_outlet |
260 | 0.996 | 0.958 | 0.977 |
homerun_arrow |
7257 | 0.986 | 0.990 | 0.988 |
Results on real E-sheets (held out)
The model was tested on 5 plan regions from 4 real sheets it never trained on: the Colusa County Admin Office lighting plans E1.1 and E1.1A (plus E1.1A's mezzanine), and the Town of Windsor Highway Garage lighting plan E101 and power plan E103 at 1/8"=1'-0". That's 439 circuited devices and 284 drawn runs.
The ground truth is read from each PDF's own vector geometry: circuit-layer strokes are the runs, their ends on fixture symbols are the devices (CAD bends contracted), and filled arrowheads mark home runs. Every sheet was checked for 100% ink alignment. Each region was run at the page's default symbol size, with no per-sheet tuning.
| real sheets, pooled | circuits-0.3 | circuits-0.1 (synthetic only) |
|---|---|---|
| Circuited devices found | 0.695 | 0.731 |
| Wiring runs F1 | 0.519 | 0.343 |
| Wiring runs precision | 0.503 | 0.267 |
| Same-circuit pair F1 | 0.690 | 0.606 |
| Same-circuit pair precision | 0.659 | 0.604 |
| Home runs found | 0.062 | 0.238 |
| region | GT devices | GT runs | devices found | runs F1 | pair F1 | home runs |
|---|---|---|---|---|---|---|
colusa-e11#0 |
112 | 84 | 0.79 | 0.60 | 0.75 | 0.21 |
colusa-e11a#0 |
100 | 78 | 0.82 | 0.64 | 0.83 | 0.14 |
colusa-e11a#1 |
11 | 5 | 0.82 | 0.33 | 1.00 | 0.00 |
windsor-e101#0 |
116 | 75 | 0.68 | 0.43 | 0.30 | 0.00 |
windsor-e103#0 |
100 | 42 | 0.47 | 0.29 | 0.90 | 0.00 |
This is still far below the synthetic numbers, so check real output against the drawing. Home-run detection on real sheets is the weakest part.
Harder synthetic sheets (v2 generator: type tags, ceiling grids, clouds, long linear fixtures), 400 held out: runs F1 0.804, pair F1 0.796, symbols F1 0.952, home runs 87.2%.
Use
pip install onnxruntime numpy pillow
python predict.py plan.png --symbol-px 20 --out circuits.png --json circuits.json
--symbol-px sets the sheet scale: 20 suits a PDF rendered at 150 dpi (tuned on real sheets). The model saw symbols of about
12โ24 px, and the script rescales the sheet to match. Sheets of any size are processed in overlapping 512 px
tiles. The same ONNX also runs in the browser with onnxruntime-web.
Training data
The model trained first on synthetic sheets with exact ground truth, then was fine-tuned on a mix of new synthetic sheets and real public drawing sets. Real training labels come from the PDFs' vector geometry, with no hand labelling:
- Lighting plans: SW Polk Fire District Rickreall Station E-201 and Pender County Hampstead Annex E-111.
- Power plan: SW Polk E-301.
- Negatives: SW Polk A-201 (architectural) and Reading Fire Dept M101/M102 (mechanical) teach "no devices, no wiring". Powder Springs E-101 (circuits by tag) teaches "no drawn wiring".
Real test sheets (Colusa County, Town of Windsor) were never used for training.
The synthetic sheets contain:
- Background: a screened architectural layer with walls (outlined, filled or hatched), doors and door swings, windows, furniture, room tags, column grid bubbles, keynote hexagons and dimension strings.
- Symbols: NECA/ANSI-style devices in several drafting styles.
- Circuits: runs drawn curved, straight or orthogonal, some dashed, some with conductor hash marks and neutral ticks. Home-run arrows are single or double, with circuit tags.
- Routing rules a drafter follows: runs route around other symbols, and arrowheads never touch another run.
The real sheets are public bid and permit documents published by US local governments. They were used to train and evaluate and are not redistributed here.
This repository is inference-only: ONNX weights, the graph decoder and an example. Training code and the synthetic sheet generator are not published.
Limitations
- Real-sheet accuracy is moderate (see the real results above), and it varies a lot by drafting style. Expect misses on symbol styles it hasn't seen. Stroke ends that reach no recognised symbol become "unrecognized" devices, so connectivity survives a missed symbol, but the device type is unknown.
- Text is not read. Circuit numbers beside home runs, panel names and switch letters are not OCR'd, so a circuit is "a group of connected devices with or without a home run", not "LP-1-12".
- Shallow crossings and tangent arcs are where the decoder still merges or splits circuits. That is the ceiling column above.
- Wiring length is measured on the drawing in pixels. It becomes feet only once you apply the sheet scale, and drawn arcs are schematic, not routed conduit.
Files
circuits.onnx: the model. Inputimageis [N,1,H,W] grayscale 0โ255 with H and W multiples of 32. Outputs arepeaks,sizeandwireat H/2 ร W/2.decode.py: the graph decoder (pure Python and NumPy).predict.py: command-line example (onnxruntime only).config.json: classes, strides, decoder thresholds and metrics.example.png/example-circuits.png: a held-out test sheet and the model's reading of it.
- Downloads last month
- 9