Design, simulate, optimize and match a two-element HB9CV beam antenna with NEC-2 (nec2c).
HB9CV Studio is a Python toolkit for radio amateurs and antenna builders. It writes NEC-2 models of the classic HB9CV (two driven elements fed through a crossed phasing line), runs them through nec2c (a C port of NEC-2), and turns the results into the numbers and drawings you need to build the antenna: gain, front-to-back ratio, beamwidth, input impedance, VSWR, matching network and a complete build sheet.
Author: Emiliano Gonzalez - LU3VEA
It comes in two parts:
| File | What it is |
|---|---|
hb9cv.py |
The engine: a command-line tool with four modes (generate, optimize, match, sweep). |
hb9cv_gui.py |
HB9CV Studio, a graphical front end that exposes every option, shows the command it runs, and plots the results. |
Modelling
- Classic HB9CV with an open-wire or coax phasing line (
tl), a lumped LC network (lc), or an ideal current/voltage drive as a theoretical reference (ideal). - T-match or centre feed, isolated elements or element centres bonded to a metal boom (
--mount contact). - Stepped (telescopic) tubes, separate rear/front diameters, conductor losses (
LD 5). - Up to 2 extra reflectors and 5 directors.
- Free space or real ground (average, good, perfect or custom εr/σ), horizontal or vertical polarization, and an optional metal mast.
- Separate T-match taps and T-bar offsets on the rear and front elements (
--tap-rear-mm,--tap-front-mm,--tap-offset-rear-mm,--tap-offset-front-mm). - Phasing line synthesized from the actual two-port response of the elements: the two probe patterns are superposed to get the exact pattern for any line, and the line that maximizes the chosen objective (gain, F/B, or both) is picked, at the horizon in free space or at the take-off angle over ground. The textbook 180° − kd rule (equal element currents) is reported as a diagnostic only, because unequal elements and T-matches move the F/B optimum away from it.
Analysis
- Gain in dBi and dBd, realized gain, take-off angle, and azimuth/elevation half-power beamwidth.
- Front-to-back ratio in four variants: point (180°), rear sector (default 150–210°), rear cone at any elevation (worst direction within the sector half-angle of the back direction, on a 5° rear half-sphere grid plus a 2° grid over the cone), and rear average (power average of that cone, a smooth front-to-rear ratio). A direction without radiation counts as −80 dBi, so an exact null gives a finite F/B.
- Input impedance, VSWR, and 2:1 bandwidth from a frequency sweep.
- Quality checks: average-gain test, NEC power-budget check (unphysical runs are rejected), segmentation convergence (gain, F/B, R_in and |Zin|; on by default in optimize, where |ΔZin| is reported as the Zin uncertainty), wire-clearance check, thin-wire rule warnings, and warnings for phasing lines that cannot be built straight (too short, folded, or a synthesized line at the limit of its range).
- Automatic NEC kernel (
--kernel auto): the extended thin-wire kernel (EK) is used when segments are shorter than 8 wire radii (thick tubes, T-match junctions), so the input impedance converges with the segmentation. T-match models typically show an average gain of about 0.95 (gains about 0.2 dB low): a known NEC-2 limit at thick-wire junctions, reported but within the 0.5 dB tolerance. - Sensitivity studies: metal boom, mast, mast length, height sweep, and common-mode current on the feed line.
Optimization
- Exact inner solver for the phase network (
--inner-line, default): two probe runs per geometry, over all the scored frequencies, give the pattern and Zin of the antenna for any line, so the line length (and, with--line-z0-range, the open-wire Z0) that maximizes the score is chosen per geometry, and the candidate's results come from the superposed probe fields (exact for the linear NEC model; the final model is simulated in full as a check). The line is not a grid dimension, and the closed-form line of an exact rear null is reported. - Search variables: element lengths, the rear and front T-match taps and T-bar offsets (moved separately;
--tap-symmetrickeeps one of each,--no-search-barskeeps the bar offset), spacing, tube diameter (purchasable sizes) and every reflector/director length and spacing. - Reflector/director lengths are also tuned on a multiport model (
--parasitic-inner, 3 rounds by default): probe runs with a port at every feed point and parasitic centre give the antenna for any reactance at those centres, a length change acts as such a reactance, and the lengths that maximize the score on that model are simulated and kept only when they improve the design. - Grid (optionally plus
--lhsLatin-hypercube samples), then a local search from--startsdistinct basins: a coordinate pattern search that combines all improving moves and stops at the step tolerance, followed by a Nelder–Mead search on normalized variables (adaptive coefficients, one restart), or CMA-ES (--search cmaes, whole populations in parallel). Budgets are counted in nec2c simulations; the stop reason of every stage is printed, and so are the search limits the best model sits on. - Objectives:
front-back,gainorbalance, scored over a band (default: 3 points at--freq±0.7 %, so a null at a single frequency is never rewarded) with a smooth worst case (--band-softness), an F/B ceiling (--fb-cap), constraints (--min-fb,--min-gain) and a penalty for very reactive inputs (--q-weight). The default F/B metric is the rear cone.--pareto Nprints the gain / F/B trade-off of the best geometry. - Optional scoring through an L-network built from components with finite Q.
- An impedance window for Rin and |Xin|. If no candidate meets it, the closest one is still written.
- First-order tolerance sensitivity of the best design (
--sensitivity): every build dimension moved by its tolerance, with the score, F/B, gain and Zin changes, and the worst-case and RSS drops (also in the JSON and the build sheet). - Monte-Carlo tolerance analysis that re-ranks distinct designs (one per basin) by their 10th-percentile score; line
length, VF, Z0 and series-capacitor tolerances can also be optimized inside the line solver at no simulation cost
(
--robust-inner N).
Matching
- Ideal L-network for any NEC result or a typed R + jX: every solution of both topologies (series or shunt branch on the antenna side, up to four networks), with low-pass, high-pass or best-over-the-band selection.
- Component losses from Q, capacitor ESL and coil stray capacitance.
- Bandwidth sweep with commercial (E-series) values and worst-case component tolerances (corners and edge midpoints of the tolerance box).
Output
- A
.necdeck, the nec2c.outresult, and a JSON summary of the main results. - A Markdown/JSON build sheet: cut lengths, spacing, boom, phasing line (total conductor length, connections and crossing included), T-match, matching network (single-ended and balanced form) and a tuning procedure.
- A CSV of every optimizer candidate and CSVs of frequency and matching sweeps.
GUI
- Every command-line option is available in seven tabs, each with a full help panel.
- Options that the selected mode does not use are greyed out.
- Live command preview and log, a Stop button, and presets.
- Antenna drawing to scale, polar and rectangular pattern cuts, and an interactive 3D pattern.
- L-network schematic, plus VSWR and impedance plots.
- Author, license and project link (clickable) at the bottom of the window.
- English, Spanish and Italian interface; scales for high-DPI screens (Ctrl + / Ctrl − / Ctrl 0).
| Radiation pattern | 3D pattern |
|---|---|
![]() |
![]() |
| L-network matching | Optimized design |
|---|---|
![]() |
![]() |
| Linux (Fedora, Debian, Ubuntu, Linux Mint) | Windows 10 / 11 | |
|---|---|---|
| Python | 3.9 or newer with Tk and venv (distribution packages) | 3.9 or newer from python.org (includes Tk) |
| Python packages | customtkinter, matplotlib, numpy (installed in a virtual environment) |
same |
| nec2c | distribution package nec2c, or compiled from source |
nec2c.exe included in the project (installed automatically) |
nec2c is needed for simulation, optimization and the pattern plots. Without it you can still write models and design
matching networks from typed impedances. The engine hb9cv.py only uses the Python standard library; the three
packages are for the GUI.
The installers below do everything for you. The manual steps are listed after each installer for reference.
Tested distributions: Fedora, Debian, Ubuntu and Linux Mint (and their derivatives).
git clone https://github.com/hiperiondev/hb9cv_studio.git hb9cv-studio
cd hb9cv-studio
./install.shRun install.sh as your normal user, not with sudo. It calls sudo itself for the system packages, so it may ask for your
password. The installer:
- installs the system packages:
- Fedora:
sudo dnf install python3 python3-pip python3-tkinter nec2c - Debian / Ubuntu / Mint:
sudo apt install python3 python3-venv python3-pip python3-tk nec2c
- Fedora:
- if the distribution has no
nec2cpackage, compiles it from source (tools/build_nec2c.sh, which needsgcc); - copies the program to
~/.local/share/hb9cv-studio; - creates a virtual environment there with
customtkinter,matplotlibandnumpy; - creates the commands
hb9cv-studio(GUI) andhb9cv(command line) in~/.local/bin; - adds HB9CV Studio with its icon to the applications menu.
| Option | Effect |
|---|---|
--prefix DIR |
install somewhere else |
--no-system-deps |
skip dnf/apt (install Python, Tk and nec2c yourself) |
--build-nec2c / --no-build-nec2c |
always / never compile nec2c from source |
--no-desktop |
no menu entry |
-y |
do not ask questions |
Start the program from the applications menu, or from a terminal:
hb9cv-studio # graphical interface
hb9cv --help # command lineIf the shell says hb9cv-studio: command not found, log out and back in once. Most distributions add ~/.local/bin to
the PATH at login once the folder exists. Alternatively run ~/.local/bin/hb9cv-studio.
- Update:
git pull, then./install.shagain (your settings are kept). - Uninstall:
./uninstall.sh(add--purgeto also remove the settings file~/.hb9cv_gui.json). System packages are left installed.
# Fedora
sudo dnf install python3 python3-pip python3-tkinter nec2c
# Debian / Ubuntu / Linux Mint
sudo apt install python3 python3-venv python3-pip python3-tk nec2c
cd hb9cv-studio
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python hb9cv_gui.py # GUI
.venv/bin/python hb9cv.py --help # command lineIf your distribution has no nec2c package, tools/build_nec2c.sh compiles it into bin/ next to the program, where
it is found automatically.
- Download the project: Code → Download ZIP on GitHub. Extract it, for example to
Downloads\hb9cv-studio. - Double-click
install.bat. If Windows SmartScreen warns you, choose More info → Run anyway. - Answer the questions. The installer works for your user only and needs no administrator rights. It:
- looks for Python 3.9+ with Tk. If there is none, it offers to install Python 3.12 with
winget; - copies the program to
%LOCALAPPDATA%\Programs\HB9CV-Studio; - creates a virtual environment there with
customtkinter,matplotlibandnumpy; - installs the
nec2c.exeincluded in the project folder, together with any runtime DLLs next to it, into itsbinfolder, and checks that it runs. Only when the project has no workingnec2c.exe(and none is in thePATH) does it offer to compile one: it installs MSYS2 withwinget(about 500 MB, several minutes the first time); - creates HB9CV Studio shortcuts in the Start menu and on the desktop. The Start menu folder also links to the three manuals and to the uninstaller.
- looks for Python 3.9+ with Tk. If there is none, it offers to install Python 3.12 with
PowerShell options, for example
powershell -ExecutionPolicy Bypass -File install.ps1 -AddToPath -Yes:
| Option | Effect |
|---|---|
-InstallDir DIR |
install somewhere else |
-Nec2c C:\path\nec2c.exe |
install this nec2c.exe instead of the one in the project (its runtime DLLs are copied too) |
-SkipNec2c |
do not look for or compile nec2c |
-AddToPath |
add the program folder to your PATH, so hb9cv and hb9cv-studio work in any terminal |
-NoShortcuts |
no Start menu or desktop shortcuts |
-Yes |
do not ask questions |
Start the program from the Start menu or the desktop. The command line is hb9cv.cmd in the program folder
(or just hb9cv with -AddToPath):
hb9cv --help
hb9cv --mode generate --run -o first.nec- Update: download the new version and run
install.batagain. - Uninstall: use Start menu → HB9CV Studio → Uninstall HB9CV Studio, or run
uninstall.bat(add-Purgeto also remove the settings file). Python and MSYS2 are left installed; remove them from Settings → Apps if you no longer need them.
- Install Python 3 from https://www.python.org/downloads/. Tick Add python.exe to PATH and keep tcl/tk and IDLE selected.
- Nothing to do for nec2c: the
nec2c.exein the project folder is found automatically. To use a different one, write its path in the nec2c field of the window. To rebuild it from source, install MSYS2; then, in the MSYS2 MSYS terminal in the project folder, runpacman -S --needed gcc tar curl gitandbash tools/build_nec2c.sh bin. The shippednec2c.exeitself is cross-compiled on Linux withbash tools/build_nec2c.sh --mingw .(self-contained, no runtime DLLs; seeNOTICE-nec2c.txt). - In a terminal opened in the project folder:
py -m venv .venv
.venv\Scripts\pip install -r requirements.txt
.venv\Scripts\pythonw hb9cv_gui.py
.venv\Scripts\python hb9cv.py --helpAlternative: WSL. On Windows 11 you can also use the Linux installation inside WSL (Ubuntu) with
wsl --install. The GUI opens as a normal window through WSLg.
- the
nec2cfield of the GUI, or--nec2c PATH(a file, or a folder containingnec2c/nec2c.exe); - the
HB9CV_NEC2Cenvironment variable; - the
PATH; - the
binfolder next tohb9cv.py(where the installers andtools/build_nec2c.shput it); - on Windows, the
nec2c.exein the project folder itself.
Keep hb9cv.py and hb9cv_gui.py in the same folder.
Start HB9CV Studio from the menu (or hb9cv-studio). To open it with a complete 146 MHz optimization ready to run:
hb9cv-studio --load-default-example # Linux, after install.sh
python3 hb9cv_gui.py --load-default-example # from the source folder- Choose a Work folder; all output files go there.
- Keep the mode on generate, tick Run nec2c after generating, and press Run.
- Read the results in the Antenna, Pattern 2D, Pattern 3D, Summary and Log tabs.
With the defaults this gives a classic 145 MHz HB9CV:
Rear 1034.5 mm, front 958.6 mm, spacing 258.4 mm (0.125 λ)
Gain 6.61 dBi (4.46 dBd), F/B 16.3 dB, HPBW 67° (azimuth)
Zin 64.6 − 9.8j Ω, VSWR 1.36:1 vs 50 Ω, 2:1 bandwidth 143.5–149.0 MHz
The Copy cmd button copies the equivalent command line.
hb9cv --help # after the installer (Linux, or Windows with -AddToPath)
python3 hb9cv.py --help # from the source folder (Windows: py hb9cv.py --help)The examples below use python3 hb9cv.py. After installing, hb9cv does the same.
| Mode | Purpose |
|---|---|
generate |
Write a NEC model of the HB9CV and optionally run nec2c (--run). |
optimize |
Search the geometry with nec2c and write the best model and its build sheet. |
match |
Design an ideal L-network for the NEC input impedance (or --r/--x) at one frequency. |
sweep |
Evaluate that L-network over frequency, with commercial values and tolerances. |
Typical workflow:
# 1. find a good geometry for the 2 m band
python3 hb9cv.py --mode optimize --freq 146 --band 145,147,3 \
--spacing-values 0.1,0.125,0.15 --tolerance-mc 100 --tol-top-k 3 \
--build-sheet hb9cv_build.md -o hb9cv_opt.nec
# 2. simulate a model over frequency (impedance vs f, 2:1 bandwidth)
python3 hb9cv.py --mode generate --fsweep 140,150,0.5 --run -o sweep.nec
# 3. design the matching network at 145 MHz with real component Q
python3 hb9cv.py --mode match --nec-out sweep.out --freq 145 --q-l 150 --q-c 500
# 4. check it over the band with ±5 % parts
python3 hb9cv.py --mode sweep --nec-out sweep.out --design-freq 145 --tol-l 5 --tol-c 5More examples:
# over average ground at 10 m, horizontal polarization
python3 hb9cv.py --mode generate --ground average --height-m 10 --run -o ground.nec
# HB9CV with one reflector and two directors
python3 hb9cv.py --mode generate --reflectors 1 --directors 2 --run -o yagi.nec
# highest gain with at least 20 dB F/B, free line Z0, and the gain / F/B trade-off of the result
python3 hb9cv.py --mode optimize --objective gain --min-fb 20 --line-z0-range 150,400 --pareto 8
# trust checks: segmentation convergence and robustness (boom, mast, coax without choke)
python3 hb9cv.py --mode generate --robustness --check-convergence -o check.necThe comma-list options accept a leading minus sign in both forms,
--line-offset-values -10,0,10and--line-offset-values=-10,0,10. For any other option whose value starts with a minus sign, use the=form.
All files are written to the working directory (the GUI's work folder).
| File | Produced by | Content |
|---|---|---|
name.nec |
generate, optimize | NEC-2 deck (geometry, excitation, TL/NT, loads, ground, RP cards) |
name.out |
--run, optimize |
nec2c output |
name.freqs.json |
--run, optimize |
exact frequencies of the deck (used by match/sweep) |
name_build.md / .json |
--build-sheet |
build sheet: cut lengths, boom, phasing line, T-match, tuning |
hb9cv_scan.csv |
optimize (--csv) |
every candidate with its dimensions and score |
hb9cv_scan_pareto.csv |
optimize --pareto |
gain / F/B trade-off of the best geometry |
lnetwork_sweep.csv |
sweep | VSWR and impedances of the matching network vs frequency |
--json-out FILE |
all modes | main results as JSON (read by the GUI) |
Full user manuals with screenshots of every function, written for first-time users:
Each manual covers installation, a tour of the window, a first-antenna tutorial, how to read every result, parasitic elements, ground, frequency sweeps, the optimizer, matching, the build sheet, quality checks, the command line, troubleshooting, and a complete reference of every option.
The built-in help (--help, and the ? badge next to each field in the GUI) explains every option in detail.
- NEC uses straight thin wires and ideal sources and transmission lines. Real clamps, insulators, spacers, bends and nearby objects shift resonance and impedance. Treat the results as a design starting point and tune the built antenna with an antenna analyzer or VNA.
- The NEC source is balanced. A real build needs a 1:1 current balun or common-mode choke at the feed point;
without one the coax shield radiates and the F/B and Zin change.
--feedline-length-mand--cm-sensitivityestimate the effect. - The boom is not modelled by default (insulating boom assumed). Use
--mount contact,--boom-isolatedor--robustnessfor a metal boom. - The kernel is chosen automatically (
--kernel auto: extended thin-wire kernel when segments are shorter than 8 wire radii;--kernel thin/--kernel extendedforce one). Every run is checked against the NEC power budget, and unphysical results are rejected. - The NEC values of the series capacitor, the T-match taps and the matching network carry the Zin uncertainty that the convergence check reports; set them on the bench.
- The matching network is a lumped, single-frequency design. Layout parasitics are only approximated (ESL, coil stray C).
- The text printed by
hb9cv.py(log, warnings, build sheet) is in English. The GUI is available in English, Spanish and Italian.
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt pytest
.venv/bin/python -m pytest testsTests marked as needing nec2c are skipped when nec2c is not found.
hb9cv.py engine (CLI): generate / optimize / match / sweep
hb9cv_gui.py HB9CV Studio graphical interface
requirements.txt Python packages (customtkinter, matplotlib, numpy)
install.sh, uninstall.sh Linux installer / uninstaller (Fedora, Debian, Ubuntu, Mint)
nec2c.exe nec2c for Windows (GPL-3.0, see NOTICE-nec2c.txt), installed by install.bat
NOTICE-nec2c.txt origin, license and source of nec2c.exe
install.bat, install.ps1 Windows installer (install.bat runs install.ps1)
uninstall.bat, uninstall.ps1 Windows uninstaller
tools/build_nec2c.sh downloads and compiles nec2c (Linux, MSYS2 on Windows, or --mingw for nec2c.exe)
tools/mingw-compat/ POSIX shim used by the MinGW build of nec2c.exe
assets/ application icon (PNG, ICO)
tests/test_hb9cv.py regression tests (pytest)
docs/manual/ user manuals (EN / ES / IT, PDF)
docs/images/ screenshots used in this README
LICENSE GNU General Public License v3
Bug reports and pull requests are welcome. Please include:
- the exact command (the GUI's Copy cmd button gives it);
- the output of the Log tab;
- the nec2c version and your operating system (distribution and version, or Windows version).
Run the tests before submitting changes. Contributions are accepted under the same license as the project (GPL-3.0-or-later).
Emiliano Gonzalez - LU3VEA
Copyright (C) 2026 Emiliano Gonzalez - LU3VEA
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file or https://www.gnu.org/licenses/ for details.
The user manuals in docs/manual/ are distributed under the same license.
nec2c.exe is a separate program, nec2c by Neoklis Kyriazis (5B4AZ) and contributors, also under the GPL v3. Its
source is at https://github.com/KJ7LNW/nec2c; see NOTICE-nec2c.txt.
73 and good building! — LU3VEA




