gainlineup

Crates.iogainlineup
lib.rsgainlineup
version0.15.0
created_at2025-02-22 04:13:06.991641+00
updated_at2025-12-28 04:06:39.124381+00
descriptionA Gain Lineup toolbox for RF Modeling
homepagehttps://github.com/iancleary/gainlineup
repositoryhttps://github.com/iancleary/gainlineup
max_upload_size
id1565112
size5,557,672
Ian Cleary (iancleary)

documentation

https://docs.rs/gainlineup

README

gainlineup

Gain Lineups for RF Engineering

Example

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

HTML file created for the files directory by running gainlineup files/wideband.toml in the root of this directory

You can view the HTML source file itself here directly: files/wideband.toml.html.

Configuration Field Aliases

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 pin is in dBW, but the code assumes pin is in dBm, you will get unexpected results. Similarly, if you assume f is in GHz, but the code assumes f is 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.

Commit count: 27

cargo fmt