| Crates.io | gainlineup |
| lib.rs | gainlineup |
| version | 0.15.0 |
| created_at | 2025-02-22 04:13:06.991641+00 |
| updated_at | 2025-12-28 04:06:39.124381+00 |
| description | A Gain Lineup toolbox for RF Modeling |
| homepage | https://github.com/iancleary/gainlineup |
| repository | https://github.com/iancleary/gainlineup |
| max_upload_size | |
| id | 1565112 |
| size | 5,557,672 |
Gain Lineups for RF Engineering
Here is an example program to use (copy/paste) in main.rs of a new cargo new example-lineup project.
use gainlineup::cascade_vector_return_vector;
use gainlineup::Block;
use gainlineup::Input;
use gainlineup::SignalNode;
fn main() {
println!("\n----------------------------\n");
run();
println!("\n----------------------------\n");
}
fn run() {
println!("Run function executed");
// Add your code logic here
const INPUT_POWER_DBM: f64 = 10.0; // dBm
let input_node = Input {
power_dbm: INPUT_POWER_DBM,
frequency_hz: 1.0e9,
bandwidth_hz: 1.0e6, // Hz, leave as 0.0 or omit for CW
noise_temperature_k: None,
};
let cable_from_signal_generator = Block {
name: "Cable Run from Signal Generator to DUT".to_string(),
gain_db: -6.0,
noise_figure_db: 6.0,
output_p1db_dbm: None,
};
let line_amp: Block = Block {
name: "Line Amp at X GHz".to_string(),
gain_db: 22.0,
noise_figure_db: 6.0,
output_p1db_dbm: None,
};
let cable_run_to_spectrum_analyzer: Block = Block {
name: "Cable Run from DUT to Spectrum Analyzer".to_string(),
gain_db: -6.0,
noise_figure_db: 6.0,
output_p1db_dbm: None,
};
let blocks = vec![
cable_from_signal_generator.clone(),
line_amp.clone(),
cable_run_to_spectrum_analyzer.clone(),
];
let full_cascade: Vec<SignalNode> =
cascade_vector_return_vector(input_node.clone(), blocks.clone());
// println!("{:>8.2} dBm", node.power);`
for (i, node) in full_cascade.iter().enumerate() {
println!();
println!("Node {}: {}", i, node.name);
if i == 0 {
// the formatting `{:>8.2}` aligns positive and negative numbers on the decimal,
// with two digits after the decimal (hundredths place)
println!("Input Level {:>8.2} dBm", node.signal_power_dbm);
} else {
let block_gain =
full_cascade[i].signal_power_dbm - full_cascade[i - 1].signal_power_dbm;
let input_power = node.signal_power_dbm - block_gain;
// the formatting `{:>8.2}` aligns positive and negative numbers on the decimal,
// with two digits after the decimal (hundredths place)
println!("Input Power\t{:>8.2} dBm", input_power);
println!(
"Block Gain:\t{:>8.2} dB (Cumulative Gain: {:>8.2} dB)",
block_gain, node.cumulative_gain_db
);
println!("Noise Figure:\t{:>8.2} dB", node.cumulative_noise_figure_db);
println!("Output Power\t{:>8.2} dBm", node.signal_power_dbm);
}
}
println!();
println!("Final Cascade Summary:");
println!("----------------------");
println!("Number of Blocks: {}", full_cascade.len() - 1);
println!("Pin:\t{:>8.2} dBm", full_cascade[0].signal_power_dbm);
let final_output_power = full_cascade.last().unwrap().signal_power_dbm;
println!("Pout:\t{:>8.2} dBm", final_output_power);
println!(
"Gain:\t{:>8.2} dB",
full_cascade.last().unwrap().cumulative_gain_db
);
println!(
"Noise Figure:\t{:>8.2} dB",
full_cascade.last().unwrap().cumulative_noise_figure_db
);
}
The output is similar to the following:
-Node 0: Cable Run from Signal Generator to DUT Output
Input Level 4.00 dBm
Node 1: Line Amp at X GHz Output
Input Power 4.00 dBm
Block Gain: 22.00 dB (Cumulative Gain: 16.00 dB)
Noise Figure: 6.02 dB
Output Power 26.00 dBm
Node 2: Cable Run from DUT to Spectrum Analyzer Output
Input Power 26.00 dBm
Block Gain: -6.00 dB (Cumulative Gain: 10.00 dB)
Noise Figure: 6.10 dB
Output Power 20.00 dBm
Final Cascade Summary:
----------------------
Number of Blocks: 2
Pin: 4.00 dBm
Pout: 20.00 dBm
Gain: 10.00 dB
Noise Figure: 6.10 dB
----------------------------
The command line interface is more interactive, and allows for the user to use toml files to define the Input, the Blocks, and run the cascade, turning the output into a html file.
gainlineup files/wideband.toml
The contents of that file are:
input_power_dbm = -80.0
frequency_hz = 6.0e9
bandwidth_hz = 1.0e6
[[blocks]]
type = "explicit"
name = "Low Noise Amplifier"
gain_db = 20.0
noise_figure_db = 3.0
[[blocks]]
type = "explicit"
name = "Mixer"
gain_db = 10.0
noise_figure_db = 6.0
[[blocks]]
type = "explicit"
name = "IF Amplifier"
gain_db = 15.0
noise_figure_db = 5.0
The output will be a html file in the same directory as the toml file.
Node 0: Low Noise Amplifier Output
Input Level -60.00 dBm
Node 1: Mixer Output
Input Power -70.00 dBm
Block Gain: 20.00 dB
Block NF: 3.00 dB
Cumulative Gain: 30.00 dB
Cumulative Noise Figure: 3.06 dB
Output Power -50.00 dBm
Node 2: IF Amplifier Output
Input Power -45.00 dBm
Block Gain: 10.00 dB
Block NF: 6.00 dB
Cumulative Gain: 45.00 dB
Cumulative Noise Figure: 3.06 dB
Output Power -35.00 dBm
Final Cascade Summary:
----------------------
Number of Blocks: 2
Pin: -60.00 dBm
Pout: -35.00 dBm
Gain: 45.00 dB
NF: 3.06 dB
'/Users/iancleary/Development/gainlineup/files/wideband.toml' is a Unix Absolute path.
Generating HTML table at: /Users/iancleary/Development/gainlineup/files/wideband.toml.html
file_path in get_file_url function: /Users/iancleary/Development/gainlineup/files/wideband.toml.html
You can open the plot in your browser at:
file:///Users/iancleary/Development/gainlineup/files/wideband.toml.html
Attempting to open plot in your default browser...
Success! Opening: file:///Users/iancleary/Development/gainlineup/files/wideband.toml.html
You can view an example of the html output at files/wideband.toml.html
You can view the HTML source file itself here directly: files/wideband.toml.html.
You can use the following field names with or without unit suffixes. The suffixes are the default, but the aliases are supported for brevity:
| Original Field | Alias (Optional) |
|---|---|
gain_db |
gain |
noise_figure_db |
noise_figure, nf (Noise Figure is NF, Noise Factor is F) |
output_p1db_dbm |
output_p1db, op1db |
input_power_dbm |
input_power, pin |
frequency_hz |
frequency, f |
bandwidth_hz |
bandwidth, bw |
noise_temperature_k |
noise_temperature |
You could define the same configuration as above with the following toml:
pin = -60.0
f = 6.0e9
bw = 1.0e6
[[blocks]]
type = "explicit"
name = "Low Noise Amplifier"
gain = 20.0
nf = 3.0
[[blocks]]
type = "explicit"
name = "Mixer"
gain = 10.0
nf = 6.0
[[blocks]]
type = "explicit"
name = "IF Amplifier"
gain = 15.0
nf = 5.0
However, the unit suffixes are still supported, and are recommended for clarity. Be careful as aliases hide the unit suffixes and might cause unexpected behavior, if you are assuming a different unit suffix than the code... For example, if you assume
pinis in dBW, but the code assumespinis in dBm, you will get unexpected results. Similarly, if you assumefis in GHz, but the code assumesfis in Hz, you will get unexpected results. Also note that nf is the lower case shorthand for noise figure, since NF is used for Noise Figure, while F is used for Noise Factor, see Wikipedia for more information.