__init__.py


analyser.py


   vswr(model, Z0 = 50):
        Return the antenna VSWR at the feed point assuming a 50 ohm system
        Or another value if specified

   get_gains_at_gain_point(model):

   plot_pattern_gains(model, azimuth_deg = None, elevation_deg = None, components = ['vert_gain_dBi', 'horiz_gain_dBi'], gain_scale_max = 0, gain_scale_range_dB = 30):
        Read the radiation pattern into a Python dictionary:
        'azimuth_deg': float,
        'elevation_deg': float,
        'vert_gain_dBi': float,
        'horiz_gain_dBi': float,
        'total_gain_dBi': float,
        'axial_ratio_dB': float,
        'tilt_deg': float,
        'sense': string,
        'E_theta_mag': float,
        'E_theta_phase_deg': float,
        'E_phi_mag': float,
        'E_phi_phase_deg': float

modeller.py


class NECModel:

   set_name(name):
            Set the name of the model. This is used in NEC input file generation and is reflected in the NEC
            output file name. It is permissible to use this function to re-set the name after a NEC run has completed,
            so that the analysis continues (with updated input parameters) and outputs more than one test case

   set_wire_conductivity(sigma):
            Set wire conductivity to be assumed for all wires that don't have an explicitly-set load.

   set_frequency(MHz):
            Request NEC to perform all analysis at the specified frequency. 

   set_gain_point(azimuth_deg, elevation_deg):
            Set the azimuth and elevation of a single gain point that
            must appear in the output radiation pattern

   set_angular_resolution(az_step_deg, el_step_deg):
            Set resolution required in az and el in degrees
            If a ground is specified, NEC will be asked for a hemisphere, otherwise a sphere

   set_ground(eps_r, sigma, **origin_height):
            Sets the ground relative permitivity and conductivity. Currently limited to simple choices.
            If eps_r = 1, nec is told to use no ground (free space model), and you may omit the origin height parameter
            If you don't call this function, free space will be assumed.
            Othewise you should set the origin height so that the antenna reference point X,Y,Z = (0,0,0) is set to be
            the specified distance above ground.
            Parameters:
                eps_r (float): relative permittivity (relative dielectric constant) of the ground
                sigma (float): conductivity of the ground in mhos/meter
                origin_height_{units_string} (float): Height of antenna reference point X,Y,Z = (0,0,0)

   place_RLC_load(geomObj, R_Ohms, L_uH, C_pf, load_type = 'series', load_alpha_object=-1, load_wire_index=-1, load_alpha_wire=-1):
            inserts a single segment containing an RLC load into an existing geometry object
            Position within the object is specied as
            EITHER:
              load_alpha_object (range 0 to 1) as a parameter specifying the length of
                                wire traversed to reach the item by following each wire in the object,
                                divided by the length of all wires in the object
                                (This is intended to be used for objects like circular loops where there
                                are many short wires each of the same length)
            OR:
              load_wire_index AND load_alpha_wire
              which specify the i'th wire (0 to n-1) in the n wires in the object, and the distance along that
              wire divided by that wire's length

            NEC LD card specification: https://www.nec2.org/part_3/cards/ld.html

   place_feed( geomObj, feed_alpha_object=-1, feed_wire_index=-1, feed_alpha_wire=-1):
            Inserts a single segment containing the excitation point into an existing geometry object.
            Position within the object is specied as
            EITHER:
              feed_alpha_object (range 0 to 1) as a parameter specifying the length of
                                wire traversed to reach the item by following each wire in the object,
                                divided by the length of all wires in the object
                                (This is intended to be used for objects like circular loops where there
                                are many short wires each of the same length)
            OR:
              feed_wire_index AND feed_alpha_wire
              which specify the i'th wire (0 to n-1) in the n wires in the object, and the distance along that
              wire divided by that wire's length

   add(geomObj, wireframe_color = 'darkgoldenrod'):
            Add a completed component to the specified model: model_name.add(component_name). Any changes made
            to the component after this point are ignored.

   write_nec():
            Write the entire model to the NEC input file ready for analysis. At this point, the function
            "show_wires_from_file" may be used to see the specified geometry in a 3D view.

   run_nec():
        Pass the model file to NEC for analysis and wait for the output.

class GeometryObject:

   translate(**params):
            Translate an object by dx, dy, dz
            Arguments are dx_{units}, dy_{units}, dz_{units}

   rotate_ZtoY():
            Rotate the object through 90 degrees around X

   rotate_ZtoX():
            Rotate the object through 90 degrees around Y

   rotate_around_X(angle_deg):
            Rotate the object through angle_deg degrees around X

   rotate_around_Y(angle_deg):
            Rotate the object through angle_deg degrees around Y

   rotate_around_Z(angle_deg):
            Rotate the object through angle_deg degrees around Z

   connect_ends(other, tol=1e-3, verbose = False):
            Check both ends of the wire to see if they lie on any wires in the specified object,
            and if so, split the wires of the specified object so that NEC considers them to be
            a valid T junction. Usage is:

            wire.connect_ends(object, [tol in m], [verbose])

            if verbose is True, details of the wire connection(s) are printed

visualiser.py


   show_wires_from_file(model, n_strands = 8, color = 'darkgoldenrod', alpha = 0.3, view_az = 30, view_el = 30):
        Opens the specified nec input file (*.nec) and reads the geometry,
        then displays the geometry in a 3D projection. The feed is highligted in red.
        Loads are highlighted in green.

optimisers.py


class RandomOptimiser:
        Initialise the optimisation parameters. Details to be written - please see examples for help with parameters.

   optimise(verbose=False, tty=True, show_geometry = True):
            This random optimiser works by simultaneously adjusting all input parameters by a random multiplier (1 + x)
            and comparing the user-specified cost function with the best achieved so far. If the test gives a better
            cost, the test is adopted as the new baseline.

            Note that of course this won't produce good results for any parameters that start off close to or at
            zero and/or have an allowable range with zero close to the middle. Future versions of this optimiser may allow
            specifications to make this work, but for now you should arrange for the input parameters and their
            likely useful range to be away from zero, by using an offset.

            If any parameters seem likely to drift into non-useful ranges, use the 'bounds' specification in the
            initialisation to limit their max and min values.

components.py


class components:
        Sets object_counter to starting_tag_nr (tags number identifies an object)
        and loads the _units module class _units()

   copy_of(existing_obj):
        Returns a clone of existing_obj with a new iTag

   wire_Z(**dimensions):
        Create a straight wire aligned along the Z-axis, centered at the origin.

        The wire extends from -length/2 to +length/2 on the Z-axis, with the specified diameter.

        dimensions:
            length_{units_string} (float): Length of the wire. 
            wire_diameter_{units_string} (float): Diameter of the wire.
            In each case, the unit suffix (e.g., _mm, _m) must be present in the units class dictionary '_UNIT_FACTORS' (see units.py)
        Returns:
            obj (GeometryObject): The constructed geometry object with the defined wire.

   rect_loop_XZ(**dimensions):
        Create a rectangular wire loop in the XZ plane, centered at the origin, with the specified wire diameter.
        The 'side' wires extend from Z=-length/2 to Z=+length/2 at X = +/- width/2.
        The 'top/bottom' wires extend from X=-width/2 to X=+width/2 at Z = +/- length/2.
        dimensions:
            length_{units_string} (float): 'Length' (extension along Z) of the rectangle. 
            width_{units_string} (float): 'Width' (extension along X) of the rectangle. 
            wire_diameter_{units_string} (float): Diameter of the wires.
            In each case, the unit suffix (e.g., _mm, _m) must be present in the units class dictionary '_UNIT_FACTORS' (see units.py)
        Returns:
            obj (GeometryObject): The constructed geometry object with the defined wires.

   connector(from_object, from_wire_index, from_alpha_wire, to_object, to_wire_index, to_alpha_wire, wire_diameter_mm = 1.0):
        Create a single wire from a specified point on the from_object to a specified point on the to_object.
        The point on an object is specified as {ftom|to}_wire_index AND {ftom|to}_alpha_wire, which specify respectively:
              the i'th wire in the n wires in the object, and
              the distance along that wire divided by that wire's length
        Arguments:
            from_object (GeometryObject), from_wire_index (int, 0 .. n_wires_in_from_object - 1), from_alpha_wire (float, 0 .. 1)
            to_object (GeometryObject), to_wire_index (int, 0 .. n_wires_in_to_object - 1), to_alpha_wire (float, 0 .. 1)
        Returns:
            obj (GeometryObject): The constructed geometry object with the defined wire.

   helix(wires_per_turn, sense, taper_factor = 1.0, **dimensions):
        Create a single helix with axis = Z axis
        Arguments_
            sense ("LH"|"RH") - the handedness of the helix          
            wires_per_turn (int) - the number of wires to use to represent the helix, per turn
            dimensions:
                radius_{units} (float) - helix radius 
                length_{units} (float) - helix length along Z 
                pitch_{units} (float)  - helix length along Z per whole turn
                wire_diameter_{units} (float) - diameter of wire making the helix
                In each case above, the units suffix (e.g., _mm, _m) must be present in the units class dictionary '_UNIT_FACTORS' (see units.py)
        Returns:
            obj (GeometryObject): The constructed geometry object representing the helix.

   flexi_helix(sense, wires_per_turn, n_cos,r_cos_params,p_cos_params, **dimensions):
        Create a helix along the Z axis where radius and pitch vary as scaled sums of cosines:

            r(Z) = r0 * Σ [RA_i * cos(i * π * Z / l + RP_i)] for i=0..n-1
            p(Z) = p0 * Σ [PA_i * cos(i * π * Z / l + PP_i)] for i=0..n-1

        The geometry is generated by stepping through helical phase (φ), and computing local radius and pitch from cosine series 
        as functions of normalized φ (mapped to Z via cumulative pitch integration).

        Parameters:
            sense (str): "RH" or "LH" handedness
            wires_per_turn (int): Resolution (segments per full turn)
            n_cos (int): Number of cosine terms
            r_cos_params (list of tuples): [(RA0, RP0), ...] radius amplitudes and phases
            p_cos_params (list of tuples): [(PA0, PP0), ...] pitch amplitudes and phases
            dimensions:
                l_{units} (float): Approximate helix length along Z
                r0_{units} (float): Base radius scale factor
                p0_{units} (float): Base pitch scale factor (length per full turn)
                wire_diameter_{units} (float): Wire thickness

        Returns:
            GeometryObject: The constructed helix geometry object.

   circular_arc(n_wires, arc_phi_deg, **dimensions):
        Create a single circular arc in the XY plane centred on the origin
        Arguments:
            n_wires (int) - the number of wires to use to represent the arc         
            arc_phi_deg (float) - the angle subtended at the origin by the arc in degrees. Note that a continuous circular loop can be constructed by specifying arc_phi_deg = 360.
            dimensions:
                radius_{units} (float) - helix radius 
                wire_diameter_{units} (float) - diameter of wire making the helix
                In each case above, the units suffix (e.g., _mm, _m) must be present in the units class dictionary '_UNIT_FACTORS' (see units.py)
        Returns:
            obj (GeometryObject): The constructed geometry object representing the helix.

   thin_sheet(model, epsillon_r = 1.0, conductivity = 1e12, force_odd = True, close_start = True, close_end = True, close_bottom = True, close_top = True, enforce_exact_pitch = True, **dimensions):
        Creates a grid of wires interconnected at segment level to economically model a flat sheet
        which is normal to the x axis and extends from z=-height/2 to z= height/2, and y = -length/2 to length/2
        
        Models *either* conductive or dielectric sheet, not both:
            Set epsillon_r to 1.0 for conducting sheet
            Set epsillon_r > 1.0 for dielectric sheet 

        Arguments:
            model - the object model being built
            epsillon_r - relative dielectric constant
            force_odd = true ensures wires cross at y=z=0
            The four 'close_' parameters determine whether or not the edges are 'sealed' with a final wire (if True) or
            not (if False) so that the grid can be joined to other grids without wires overlapping:
                close_end = True completes the grid with a final end z wire at y = length/2 
                close_start = True starts the grid with a z wire at y = -length/2 
                close_top = True completes the grid with a y wire at z = height/2 
                close_bottom = True starts the grid with a y wire at z = -height/2 
            enforce_exact_pitch: if True, length and height are adjusted to fit an integer number
            of grid cells of the specified pitch. If False, length and height remain as specified and
            the grid pitch in Y and Z is adjusted to fit the number of grid cells calculated from the
            grid pitch and force_odd value. Behaviour prior to V2.0.3 was enforce_exact_pitch.

        Required dimensions are:
            length_
            height_
            grid_pitch_
            dielectric_thickness_ (for dielectric sheets only)
        Optional dimensions are:
            conducting_wire_diameter_ (for conducting sheets only, default is 1mm)


Made with Docu-lite 1.5.1 by Alan Robinson: github.com/G1OJS/docu-lite/