text:
"""
    GAMBAR

Gyromagnetic ratio for ¹H with units Hz/G.
"""
const GAMBAR = 4258

"""
    GAMMA

Gyromagnetic ratio for ¹H with units rad/s/G.
"""
const GAMMA  = 2π * GAMBAR

"""
    AbstractSpin

Abstract type for representing individual spins.
"""
abstract type AbstractSpin end

"""
    Spin([M,] M0, T1, T2, Δf[, pos]) <: AbstractSpin

Create an object that represents a single spin.

# Properties
- `M::Vector{Float64} = [0.0, 0.0, M0]`: Magnetization vector [Mx, My, Mz]
- `M0::Real`: Equilibrium magnetization
- `T1::Real`: Spin-lattice recovery time constant (ms)
- `T2::Real`: Spin-spin recovery time constant (ms)
- `Δf::Real`: Off-resonance frequency (Hz)
- `pos::Vector{<:Real} = [0, 0, 0]`: Spatial location [x, y, z] (cm)
- `signal::Complex{Float64}`: Signal produced by the spin

# Examples
```jldoctest
julia> spin = Spin([1.0, 2.0, 3.0], 1, 1000, 100, 3); spin.signal
1.0 + 2.0im
```
"""
struct Spin <: AbstractSpin
    M::Vector{Float64}
    M0::Float64
    T1::Float64
    T2::Float64
    Δf::Float64
    pos::Vector{Float64}

    # Default constructor with optional argument pos
    Spin(M::Vector{<:Real}, M0, T1, T2, Δf, pos = [0,0,0]) =
        new(M, M0, T1, T2, Δf, pos)

    # If magnetization vector is not specified then use equilibrium
    Spin(M0::Real, T1, T2, Δf, pos = [0,0,0]) =
        new([0,0,M0], M0, T1, T2, Δf, pos)
end

"""
    SpinMC([M,] M0, frac, T1, T2, Δf, τ[, pos]) <: AbstractSpin

Create an object that represents a single spin with multiple compartments.

# Properties
- `N::Integer = length(frac)`: Number of compartments
- `Meq::Vector{Float64} = vcat([[0, 0, frac[n] * M0] for n = 1:N]...)`:
    Equilibrium magnetization vector
- `M::Vector{Float64} = Meq`: Magnetization vector
    [M1x, M1y, M1z, M2x, M2y, M2z, ...]
- `M0::Real`: Equilibrium magnetization
- `frac::Vector{<:Real}`: Volume fraction of each compartment
- `T1::Vector{<:Real}`: Spin-lattice recovery time constants (ms)
- `T2::Vector{<:Real}`: Spin-spin recovery time constants (ms)
- `Δf::Vector{<:Real}`: Off-resonance frequencies (Hz)
- `τ::Vector{<:Real}`: Residence times (inverse exchange rates) (ms)
    [τ12, τ13, ..., τ1N, τ21, τ23, ..., τ2N, ...]
- `pos::Vector{<:Real} = [0, 0, 0]`: Spatial location [x, y, z] (cm)
- `A::Matrix{Float64} = ...`: Matrix of system dynamics; see slide 22 in
    https://web.stanford.edu/class/rad229/Notes/B1-Bloch-Simulations.pdf
- `signal::Complex{Float64}`: Signal produced by the spin

# Examples
```jldoctest
julia> M = [1.0, 2.0, 3.0, 0.2, 0.1, 1.0];

julia> frac = [0.8, 0.2];

julia> τ = [Inf, Inf];

julia> spin = SpinMC(M, 1, frac, [900, 400], [80, 20], [3, 13], τ); spin.signal
1.2 + 2.1im
```
"""
struct SpinMC <: AbstractSpin
    N::Int
    M::Vector{Float64} # [3N]
    Meq::Vector{Float64} # [3N]
    M0::Float64
    frac::Vector{Float64} # [N]
    T1::Vector{Float64} # [N]
    T2::Vector{Float64} # [N]
    Δf::Vector{Float64} # [N]
    τ::Vector{Float64} # [N*(N-1)]
    pos::Vector{Float64}
    A::Matrix{Float64} # [3N,3N]

    SpinMC(M::Vector{<:Real}, M0, frac, T1, T2, Δf, τ, pos = [0,0,0]) = begin
        N = length(frac)
        Meq = vcat([[0, 0, frac[n] * M0] for n = 1:N]...)
        r = zeros(N, N) # 1/ms
        itmp = 1
        for j = 1:N, i = 1:N
            if i != j
                r[i,j] = 1 / τ[itmp]
                itmp += 1
            end
        end
        A = zeros(3N, 3N)
        for j = 1:N, i = 1:N
            ii = 3i-2:3i
            jj = 3j-2:3j
            if i == j
                tmp = sum(r[:,i]) # 1/ms
                r1 = -1 / T1[i] - tmp # 1/ms
                r2 = -1 / T2[i] - tmp # 1/ms
                Δω = 2π * Δf[i] / 1000 # rad/ms
                A[ii,jj] = [r2 Δω 0; -Δω r2 0; 0 0 r1] # Left-handed rotation
            else
                A[ii,jj] = r[i,j] * Diagonal(ones(Bool, 3))
            end
        end
        new(N, M, Meq, M0, frac, T1, T2, Δf, τ, pos, A)
    end

    # If magnetization vector is not specified then use equilibrium
    SpinMC(M0::Real, frac, T1, T2, Δf, τ, pos = [0,0,0]) = begin
        M = vcat([[0, 0, frac[n] * M0] for n = 1:length(frac)]...)
        SpinMC(M, M0, frac, T1, T2, Δf, τ, pos)
    end
end

# Override Base.getproperty to allow users to type spin.signal to compute the
# signal generated by the spin
Base.getproperty(spin::Spin, s::Symbol) = begin
    if s == :signal
        M = getfield(spin, :M)
        return complex(M[1], M[2])
    else
        return getfield(spin, s)
    end
end

Base.getproperty(spin::SpinMC, s::Symbol) = begin
    if s == :signal
        M = getfield(spin, :M)
        return complex(sum(M[1:3:end]), sum(M[2:3:end]))
    else
        return getfield(spin, s)
    end
end

"""
    freeprecess(spin, t)

Simulate free-precession for the given spin.

# Arguments
- `spin::AbstractSpin`: Spin that is free-precessing
- `t::Real`: Duration of free-precession (ms)

# Return
- `A::Matrix`: Matrix that describes relaxation and precession
- `B::Vector`: Vector that describes recovery

# Examples
```jldoctest
julia> spin = Spin([1.0, 0.0, 0.0], 1, 1000, 100, 3.75)
Spin([1.0, 0.0, 0.0], 1.0, 1000.0, 100.0, 3.75, [0.0, 0.0, 0.0])

julia> (A, B) = freeprecess(spin, 100); A * spin.M + B
3-element Array{Float64,1}:
 -0.2601300475114444
 -0.2601300475114445
  0.09516258196404048
```
"""
freeprecess(spin::Spin, t::Real) =
    freeprecess(t, spin.M0, spin.T1, spin.T2, spin.Δf)

function freeprecess(spin::SpinMC, t::Real)

    E = exp(t * spin.A)
    B = (Diagonal(ones(Bool, size(E, 1))) - E) * spin.Meq
    return (E, B)

end

"""
    freeprecess(spin, t, grad)

Simulate free-precession for the given spin in the presence of a gradient.

# Arguments
- `spin::AbstractSpin`: Spin that is free-precessing
- `t::Real`: Duration of free-precession (ms)
- `grad::AbstractVector{<:Real}`: Gradient amplitudes [gx, gy, gz] (G/cm)

# Return
- `A::Matrix`: Matrix that describes relaxation and precession
- `B::Vector`: Vector that describes recovery

# Examples
```jldoctest
julia> spin = Spin([1.0, 0.0, 0.0], 1, 1000, 100, 0, [0, 0, 3.75])
Spin([1.0, 0.0, 0.0], 1.0, 1000.0, 100.0, 0.0, [0.0, 0.0, 3.75])

julia> (A, B) = freeprecess(spin, 100, [0, 0, 1/GAMBAR]); A * spin.M + B
3-element Array{Float64,1}:
 -0.2601300475114444
 -0.2601300475114445
  0.09516258196404048
```
"""
function freeprecess(spin::Spin, t::Real, grad::AbstractArray{<:Real,1})

    gradfreq = GAMBAR * sum(grad .* spin.pos) # Hz
    freeprecess(t, spin.M0, spin.T1, spin.T2, spin.Δf + gradfreq)

end

# See equation (6.9) in Gopal Nataraj's PhD thesis
function freeprecess(spin::SpinMC, t::Real, grad::AbstractArray{<:Real,1})

    gradfreq = GAMMA * sum(grad .* spin.pos) / 1000 # rad/ms
    ΔA = diagm(1 => repeat([gradfreq, 0, 0], spin.N), # Left-handed rotation
              -1 => repeat([-gradfreq, 0, 0], spin.N))[1:3spin.N,1:3spin.N]
    E = exp(t * (spin.A + ΔA))
    B = (Diagonal(ones(Bool, size(E, 1))) - E) * spin.Meq
    return (E, B)

end

"""
    freeprecess!(spin, ...)

Apply free-precession to the given spin.
"""
function freeprecess!(spin::AbstractSpin, args...)

    (A, B) = freeprecess(spin, args...)
    applydynamics!(spin, A, B)

end

"""
    excitation(spin, θ, α)

Simulate instantaneous excitation with flip angle `α` about an axis that makes
angle `θ` with the positive x-axis.

# Arguments
- `spin::AbstractSpin`: Spin to excite
- `θ::Real`: Orientation of the axis about which to excite (rad)
- `α::Real`: Flip angle (rad)

# Return
- `A::Matrix`: Matrix that describes the excitation
- `B::Vector = zeros(length(spin.M))`: Not used, but included because other
    methods of `excitation` return a nontrivial value here

# Examples
```jldoctest
julia> spin = Spin(1, 1000, 100, 3.75)
Spin([0.0, 0.0, 1.0], 1.0, 1000.0, 100.0, 3.75, [0.0, 0.0, 0.0])

julia> (A, _) = excitation(spin, π/4, π/2); A * spin.M
3-element Array{Float64,1}:
  0.7071067811865476
 -0.7071067811865475
  6.123233995736766e-17
```
"""
function excitation(spin::Spin, θ::Real, α::Real)

    A = rotatetheta(θ, α)
    B = zeros(length(spin.M))
    return (A, B)

end

function excitation(spin::SpinMC, θ::Real, α::Real)

    A = kron(Diagonal(ones(Bool, spin.N)), rotatetheta(θ, α))
    B = zeros(length(spin.M))
    return (A, B)

end

"""
    excitation(spin, rf, Δθ, grad, dt)

Simulate non-instantaneous excitation using the hard pulse approximation.

# Arguments
- `spin::AbstractSpin`: Spin to excite
- `rf::Vector{<:Number}`: RF waveform (G); its magnitude determines the flip
    angle and its phase determines the axis of rotation
- `Δθ::Real`: Additional RF phase (e.g., for RF spoiling) (rad)
- `grad::Union{Matrix{<:Real},Vector{<:Real}}`: Gradients to play during
    excitation (G/cm); should be a 3-vector if the gradients are constant during
    excitation, otherwise it should be a 3×(length(rf)) matrix
- `dt::Real`: Time step (ms)

# Return
- `A::Matrix`: Matrix that describes excitation and relaxation
- `B::Vector`: Vector that describes excitation and relaxation
"""
function excitation(spin::AbstractSpin, rf::AbstractArray{<:Number,1}, Δθ::Real,
                    grad::AbstractArray{<:Real,2}, dt::Real)

    T = length(rf)
    α = GAMMA * abs.(rf) * dt/1000 # Flip angle in rad
    θ = angle.(rf) .+ Δθ # RF phase in rad
    A = Diagonal(ones(Bool, length(spin.M)))
    B = zeros(length(spin.M))
    for t = 1:T
        (Af, Bf) = freeprecess(spin, dt/2, grad[:,t])
        (Ae, _) = excitation(spin, θ[t], α[t])
        A = Af * Ae * Af * A
        B = Af * (Ae * (Af * B + Bf)) + Bf
    end
    return (A, B)

end

# Excitation with constant gradient
function excitation(spin::AbstractSpin, rf::AbstractArray{<:Number,1}, Δθ::Real,
                    grad::AbstractArray{<:Real,1}, dt::Real)

    T = length(rf)
    α = GAMMA * abs.(rf) * dt/1000 # Flip angle in rad
    θ = angle.(rf) .+ Δθ # RF phase in rad
    A = Diagonal(ones(Bool, length(spin.M)))
    B = zeros(length(spin.M))
    (Af, Bf) = freeprecess(spin, dt/2, grad)
    for t = 1:T
        (Ae, _) = excitation(spin, θ[t], α[t])
        A = Af * Ae * Af * A
        B = Af * (Ae * (Af * B + Bf)) + Bf
    end
    return (A, B)

end

"""
    excitation!(spin, ...)

Apply excitation to the given spin.
"""
function excitation!(spin::AbstractSpin, θ::Real, α::Real)

    (A, _) = excitation(spin, θ, α)
    applydynamics!(spin, A)

end

# Use this function if using RF spoiling (because A and B need to be
# recalculated for each TR, so directly modifying the magnetization should be
# faster in this case)
function excitation!(spin::AbstractSpin, rf::AbstractArray{<:Number,1}, Δθ::Real,
                     grad::AbstractArray{<:Real,2}, dt::Real)

    T = length(rf)
    α = GAMMA * abs.(rf) * dt/1000 # Flip angle in rad
    θ = angle.(rf) .+ Δθ # RF phase in rad
    for t = 1:T
        (Af, Bf) = freeprecess(spin, dt/2, grad[:,t])
        (Ae, _) = excitation(spin, θ[t], α[t])
        applydynamics!(spin, Af, Bf)
        applydynamics!(spin, Ae)
        applydynamics!(spin, Af, Bf)
    end

end

function excitation!(spin::AbstractSpin, rf::AbstractArray{<:Number,1}, Δθ::Real,
                     grad::AbstractArray{<:Real,1}, dt::Real)

    T = length(rf)
    α = GAMMA * abs.(rf) * dt/1000 # Flip angle in rad
    θ = angle.(rf) .+ Δθ # RF phase in rad
    (Af, Bf) = freeprecess(spin, dt/2, grad)
    for t = 1:T
        (Ae, _) = excitation(spin, θ[t], α[t])
        applydynamics!(spin, Af, Bf)
        applydynamics!(spin, Ae)
        applydynamics!(spin, Af, Bf)
    end

end

"""
    spoil(spin)

Simulate ideal spoiling (i.e., setting the transverse component of the spin's
magnetization to 0).

# Arguments
- `spin::AbstractSpin`: Spin to spoil

# Return
- `S::Matrix`: Matrix that describes ideal spoiling

# Examples
```jldoctest
julia> spin = Spin([1, 0.4, 5], 1, 1000, 100, 0)
Spin([1.0, 0.4, 5.0], 1.0, 1000.0, 100.0, 0.0, [0.0, 0.0, 0.0])

julia> S = spoil(spin); S * spin.M
3-element Array{Float64,1}:
 0.0
 0.0
 5.0
```
"""
spoil(spin::Spin) = [0 0 0; 0 0 0; 0 0 1]
spoil(spin::SpinMC) = kron(Diagonal(ones(Bool, spin.N)), [0 0 0; 0 0 0; 0 0 1])

"""
    spoil!(spin)

Apply ideal spoiling to the given spin.
"""
function spoil!(spin::Spin)

    spin.M[1:2] .= 0
    return nothing

end

function spoil!(spin::SpinMC)

    spin.M[1:3:end] .= 0
    spin.M[2:3:end] .= 0
    return nothing

end

"""
    combine(D...)

Combine the matrices and vectors that describe the dynamics of a spin into one
matrix and one vector.

# Arguments
- `D::Tuple{<:AbstractArray{<:Real,2},<:AbstractVector{<:Real}}...`: List of
    pairs of matrices and vectors, i.e., ((A1, B1), (A2, B2), ...), where the
    A's are matrices and the B's are vectors

# Return
- `A::Matrix`: Matrix that describes the spin dynamics
- `B::Vector`: Vector that describes the spin dynamics

# Examples
```jldoctest
julia> spin = Spin(1, 1000, 100, 3.75)
Spin([0.0, 0.0, 1.0], 1.0, 1000.0, 100.0, 3.75, [0.0, 0.0, 0.0])

julia> D1 = excitation(spin, 0, π/2);

julia> D2 = freeprecess(spin, 100);

julia> (A, B) = combine(D1, D2); A * spin.M + B
3-element Array{Float64,1}:
 -0.2601300475114444
 -0.2601300475114445
  0.09516258196404054
```
"""
function combine(D::Tuple{<:AbstractArray{<:Real,2},<:AbstractArray{<:Real,1}}...)

  (A, B) = D[1]
  for i = 2:length(D)
    (Ai, Bi) = D[i]
    A = Ai * A
    B = Ai * B + Bi
  end
  return (A, B)

end

"""
    applydynamics!(spin, A[, B])

Apply dynamics to the given spin.

# Arguments
- `spin::AbstractSpin`: Spin to which to apply dynamics
- `A::Matrix`: Matrix with dynamics
- `B::Vector = zeros(length(spin.M))`: Vector with dynamics

# Examples
```jldoctest
julia> spin = Spin(1, 1000, 100, 3.75)
Spin([0.0, 0.0, 1.0], 1.0, 1000.0, 100.0, 3.75, [0.0, 0.0, 0.0])

julia> (A, _) = excitation(spin, 0, π/2); applydynamics!(spin, A)

julia> (A, B) = freeprecess(spin, 100); applydynamics!(spin, A, B)

julia> spin.M
3-element Array{Float64,1}:
 -0.2601300475114444
 -0.2601300475114445
  0.09516258196404054
```
"""
function applydynamics!(spin::AbstractSpin, A::AbstractArray{<:Real,2},
                        B::AbstractArray{<:Real,1})

  spin.M[:] = A * spin.M + B
  return nothing

end

function applydynamics!(spin::AbstractSpin, A::AbstractArray{<:Real,2})

  spin.M[:] = A * spin.M
  return nothing

end


text:
module MIME

using Hiccup
using HypertextLiteral
using ..Chess, ..Chess.PGN

export html

const BOARD_SIZE = 280
const DARK_SQUARE_COLOR = "#a4704b"
const LIGHT_SQUARE_COLOR = "#ffd7a6"
const HIGHLIGHT_COLOR = "#47d18b"

function squarecolor(file, rank)
    if iseven(file + rank)
        LIGHT_SQUARE_COLOR
    else
        DARK_SQUARE_COLOR
    end
end

function imgurl(p::Piece)::String
    c = pcolor(p)
    t = ptype(p)
    "https://raw.githubusercontent.com/romstad/Chess.jl/master/img/" *
    tochar(c) *
    lowercase(tochar(t)) *
    ".svg"
end

function squarehighlight(s)
    f = file(s).val - 1
    r = rank(s).val - 1
    Node(
        :circle,
        Dict(
            :cx => f + 0.5,
            :cy => r + 0.5,
            :r => 0.4,
            :fill => HIGHLIGHT_COLOR,
            :opacity => 0.5,
        ),
    )
end

function squarehighlights(ss::SquareSet)
    Node(:g, map(squarehighlight, Chess.squares(ss)))
end

function square(file::Int, rank::Int, piece)
    Node(
        :g,
        Node(
            :rect,
            Dict(
                :fill => squarecolor(file, rank),
                :x => file,
                :y => rank,
                :width => 1,
                :height => 1,
            ),
        ),
        if piece == EMPTY
            Node(:g)
        else
            Node(
                :image,
                Dict(
                    Symbol("xlink:href") => imgurl(piece),
                    :x => file,
                    :y => rank,
                    :width => 1,
                    :height => 1,
                ),
            )
        end,
    )
end

function square(s::Square, piece)
    f = file(s).val - 1
    r = rank(s).val - 1
    square(f, r, piece)
end

function squares(board)
    Node(:g, map(s -> square(Square(s), pieceon(board, Square(s))), 1:64))
end

function svg(; board = emptyboard(), highlight = SS_EMPTY)
    Node(
        :svg,
        Dict(
            :style => "float: left; margin-right: 20px",
            :viewBox => "0 0 8 8",
            :width => BOARD_SIZE,
            :height => BOARD_SIZE,
        ),
        [squares(board), squarehighlights(highlight)],
    )
end

function lichesslink(board)
    Node(:a, Dict(:href => lichessurl(board), :target => "_blank"), "Open in lichess")
end

function description(board)
    buf = IOBuffer()
    Chess.castlestring(board, buf)
    Node(
        :div,
        [
            Node(:p, sidetomove(board) == WHITE ? "White to move" : "Black to move"),
            board.castlerights == 0 ? "" : Node(:p, "Castle rights: " * String(take!(buf))),
            epsquare(board) == SQ_NONE ? "" :
            Node(:p, "En passant square: " * tostring(epsquare(board))),
            Node(:p, lichesslink(board)),
        ],
    )
end

function html(board::Board; highlight = SS_EMPTY)
    Node(
        :div,
        Dict(:class => "chessboard"),
        [svg(board = board, highlight = highlight), description(board)],
    )
end

function html(ss::SquareSet)
    Node(:div, Dict(:class => "chessboard"), svg(highlight = ss))
end

function jsify(g)
    replace("'$(gametopgn(g))'", "\n" => "\\n")
end

function html(g::SimpleGame)
    Node(
        :div,
        Dict(:class => "game"),
        [
            svg(board = board(g)),
            Node(:p, Chess.formatmoves(g, "👉")),
            Node(
                :a,
                Dict(
                    :href => "",
                    :onclick =>
                        "navigator.clipboard.writeText($(jsify(g))).then(function(){},function(){});window.open('https://lichess.org/paste','_blank');",
                ),
                "Open in lichess",
            ),
        ],
    )
end

const GAME_CSS = """
.game {
    text-color: blue;
}
"""

function html(g::Game)
    Node(
        :div,
        Dict(:class => "game", :style => GAME_CSS),
        [
            svg(board = board(g)),
            Node(:p, format_game(g)),
            Node(
                :a,
                Dict(
                    :href => "",
                    :onclick =>
                        "navigator.clipboard.writeText($(jsify(g))).then(function(){},function(){});window.open('https://lichess.org/paste','_blank');",
                ),
                "Open in lichess",
            ),
        ],
    )
end

function format_game(g::Game)

    function movestyle(depth)
        if depth == 0
            "font-weight: bold; color: #000000;"
        elseif depth == 1
            "font-weight: bold; color: #777777;"
        else
            "font-weight: bold; color: #bbbbbb;"
        end
    end

    function fmt_move(node, child, movenum, depth, blackmovenum)
        ms = movetosan(node.board, lastmove(child.board))
        space = blackmovenum ? "" : " "
        if sidetomove(node.board) == WHITE
            @htl(
                "$space$(string(movenum ÷ 2 + 1)). $ms"
            )
        elseif blackmovenum || isnothing(node.parent)
            @htl(
                "$space$(string(movenum ÷ 2 + 1))... $ms"
            )
        else
            @htl("$space$ms")
        end
    end

    COMMENT_STYLE = "color: blue;"

    function fmt_precomment(comment)
        if isnothing(comment)
            @htl("")
        else
            @htl("$comment ")
        end
    end

    function fmt_comment(comment)
        if isnothing(comment)
            @htl("")
        else
            @htl(" $comment")
        end
    end

    function fmt_nag(nag)
        if isnothing(nag)
            @htl("")
        else
            @htl(" \$$nag")
        end
    end

    function fmt_child(child, movenum, blackmovenum, depth)
        move = fmt_move(child.parent, child, movenum, depth, blackmovenum)
        precmt = fmt_precomment(precomment(child))
        cmt = fmt_comment(comment(child))
        nag = fmt_nag(Chess.nag(child))

        @htl("$precmt$move$nag$cmt")
    end

    function fmt_subvars(node, movenum, depth)
        if length(node.children) < 2
            @htl("")
        else
            vars = [
                @htl(
                    " ($(fmt_child(c, movenum, true, depth+1))$(fmt_var(c, movenum+1, depth+1)))"
                ) for c in node.children[2:end]
            ]
            @htl("$vars")
        end
    end

    function fmt_var(node, movenum, depth)
        if !isempty(node.children)
            cni = node == g.node ? " 👉" : ""
            child = first(node.children)
            childhtml = fmt_child(child, movenum, false, depth)
            cont = fmt_var(child, movenum + 1, depth)
            subvars = fmt_subvars(node, movenum, depth)
            @htl("$cni$(fmt_child(child, movenum, false, depth))$subvars$cont")
        elseif node == g.node
            @htl(" 👉")
        else
            @htl("")
        end
    end

    fmt_var(g.root, 0, 0)
end

end

ext: jl


text:
@testset "Spaces" begin
  Qx, x = PolynomialRing(FlintQQ, "x")
  K, a = NumberField(x^2 - 2, "a1")
  Kt, t = K["t"]

  E, b = NumberField(t^2 + 3)

  F = GF(3)

  Hecke.change_base_ring(::Hecke.NfRel, ::Hecke.gfp_mat) = error("asd")
  @test_throws ErrorException hermitian_space(E, F[1 2; 2 1])

  Hecke.change_base_ring(::Hecke.NfRel, x::Hecke.gfp_mat) = x
  @test_throws ErrorException hermitian_space(E, F[1 2; 2 1])

  V = @inferred hermitian_space(E, FlintQQ[1 2; 2 1])
  @test V isa Hecke.HermSpace
end


text:
## Compute the degree distribution p_k from a vector of degrees

function empirical_dd(degrees)
    # degrees: degrees of each node in a network

    # return proportion of nodes of degree k in a network

    # empty vector for degree distribution
    degrees = Int64.(degrees)
    dd = zeros(maximum(degrees),2)
    dd[:,1] = 1:maximum(degrees)

    # propotion of nodes of degree k
    for i in 1:maximum(degrees)
        dd[i,2] = length(degrees[degrees .== i]) / length(degrees)
    end

    # remove degree 0
    dd = dd[dd[:,2] .> 0, :]

    return dd
end

max_stars_repo_name: FrancisBanville/Trophic-METE

max_issues_repo_name: FrancisBanville/Trophic-METE

max_forks_repo_name: FrancisBanville/Trophic-METE


text:
_nextind(x::AbstractString,i::Int) =
    nextind(x,i)
_prevind(x::AbstractString,i::Int) =
    prevind(x,i)

_nextind(x::AbstractString,i::Int,n::Int) =
    nextind(x,i,n)
_prevind(x::AbstractString,i::Int,n::Int) =
    prevind(x,i,n)
_nextind(x::AbstractVector,i::Int,n::Int=1) =
    i+n
_prevind(x::AbstractVector,i::Int,n::Int=1) =
    i-n

"""
    leftof(str,i,parser,state)

Left of `parser` match in `str` *before* `i` encoded by `state`,
or `i` if `state===nothing`.

!!! note
    override with [`_leftof`](@ref) and  [`_rightof`](@ref).
"""
@inline leftof(str,i,parser,state::Nothing) = i

"""
    rightof(str,i,parser,state)

Left of `parser` match in `str` at `i` encoded by `state`,
or `i` if `state===nothing`.

!!! note
    override with [`_leftof`](@ref) and  [`_rightof`](@ref).
"""
@inline rightof(str,i,parser,state::Nothing) = i

@inline leftof(str,i,parser,state) = _leftof(str,i,parser,state)
@inline rightof(str,i,parser,state) = _rightof(str,i,parser,state)


text:
using Romeo, GLFW, GLAbstraction, Reactive, ModernGL, GLWindow, Color, ImmutableArrays

function main()
    root_area = Romeo.ROOT_SCREEN.area
    nx = 4 # three screens for x /width
    ny = 3 # four screens for y /height
    screen_height_width = lift(root_area) do area
        Vector2{Int}(div(area.w, nx), div(area.h, ny))
    end
    pic = Texture("pic.jpg")
    for x=0:nx-1, y=0:ny-1
        area = lift(Romeo.ROOT_SCREEN.area, screen_height_width) do root_area, wh
            xstart = wh[1]*x
            ystart = wh[2]*y
            Rectangle{Int}(xstart, ystart, wh[1], wh[2])
        end
        screen  = Screen(Romeo.ROOT_SCREEN, area=area)
        viz     = visualize(pic, screen=screen)
        push!(screen.renderlist, viz)
    end

end
main()

while Romeo.ROOT_SCREEN.inputs[:open].value
    glEnable(GL_SCISSOR_TEST)
    Romeo.renderloop(Romeo.ROOT_SCREEN)
    sleep(0.0001)
end
GLFW.Terminate()


text:
# Plots an random example of a prior and the resulting information distribution

using SubmodularMaximization
using Profile
using ProfileView

sparse = false
steps = 10000

grid_size = 10
num_observations = 3
horizon = SubmodularMaximization.default_horizon
num_information_samples = 10

grid = Grid(grid_size, grid_size)
sensor = RangingSensor()

target_state = (2,2)

if sparse
  global histogram_filter = SparseFilter(grid, target_state, threshold=1e-3)
else
  global histogram_filter = Filter(grid, target_state)
end

# Provide one step to produce some uncertainty
process_update!(histogram_filter, transition_matrix(grid))

# Create some fake observations and update the filter
for ii = 1:num_observations
  robot_state = random_state(grid)
  range_observation = generate_observation(grid, sensor, robot_state,
                                           target_state)
  measurement_update!(histogram_filter, robot_state, get_states(grid), sensor,
                      grid, range_observation)
end

function run_test(steps; print=true)
  ifprint(xs...) = if print println(xs...) end

  time = @elapsed for ii = 1:steps
    robot_state = random_state(grid)
    trajectory = fill(robot_state, horizon)

    finite_horizon_information(grid, histogram_filter, sensor,
                               trajectory,
                               num_samples = num_information_samples).reward
  end

  ifprint("Test duration: ", time, " seconds")
  ifprint("  ", time / steps, " seconds per information estimate")
  ifprint("  ", time / (steps * num_information_samples),
          " per information sample")
  ifprint("Note: horizon length is ", horizon)
  ifprint("Note: total number of information samples is ",
          steps * num_information_samples)
end

run_test(1)
@time run_test(steps)

# Run the profiler
Profile.init(n=1000000)
@profview run_test(1, print=false)

Profile.init(n=1000000)
@profview run_test(steps, print=false)

println()
Profile.print(mincount=100, format=:flat)

max_stars_repo_name: mcorah/MultiAgentSensing

max_issues_repo_name: mcorah/MultiAgentSensing

max_forks_repo_name: mcorah/MultiAgentSensing


text:
#include("SegyStruct.jl")
#include("Header.jl")

function SeisToSegy(in,out;su=true)

	if (su==true)
		file_hsize = 0
	else
		file_hsize = 900
		# add commands here to read text and binary headers out.thead and out.bhead and write them to out
	end

	filename_headers = ParseHeaderName(in)
	extent = ReadTextHeader(in)
	n1 = extent.n1
	nx = extent.n2*extent.n3*extent.n4*extent.n5

	stream = open(out,"w")
	total = 60 + n1
	h_segy = Array(SegyHeader,1)
	h_seis = Array(Header,1)
	h1 = Header[]
	push!(h1,Seismic.InitSeisHeader())
	h1[1].o1 = extent.o1
	h1[1].d1 = extent.d1
	h1[1].n1 = extent.n1
	for j = 1 : nx
		if filename_headers != "NULL"
			d,h1,e = SeisRead(in,itrace=j,ntrace=1,group="some")
		else
		println("j=",j)
			d,e = SeisRead(in,itrace=j,ntrace=1,group="some")
		println("size(d)=",size(d))
			h1[1].tracenum = j
		end
		h_segy[1] = MapHeaders(h1,j,"SeisToSegy")
		position = file_hsize + total*(j-1)*4 + segy_count["trace"]
		seek(stream,position)
		write(stream,convert(Array{Float32,1},d[:]))
		PutSegyHeader(stream,h_segy[1],n1,file_hsize,j)
	end
	close(stream)

end


text:
using OmegaGrav
using MatterPower
using Dierckx
using Plots, LaTeXStrings
using OrdinaryDiffEq
# %% Compute the matter power spectrum using CLASS
include("compute_pk_class.jl")
# %% Compute the analytical linear theory result for K/W
# Reference: Equation (12) of Davis, Miller, White, ApJ, 490, 63 (1997).
zini = 9
a = 1/(1+zini):0.01:1.0 # scale factor
nred = length(a)
sol_δθ = setup_growth(Ωm, 1 - Ωm)
KovW = zeros(nred)
for i = 1:nred
    KovW[i] = -2 / 3 * (sol_δθ(a[i])[2] / sol_δθ(a[i])[1])^2 * a[i] / Ωm
end

# %% Compute `Ωgrav = Ωm * W / 2` at various redshifts
Ωgpk = zeros(nred)
Ωglin = zeros(nred)
for ired = 1:nred
    z = 1 / a[ired] - 1
    # Define functions to return linear and non-linear power spectra
    # Note: The CLASS code takes wavenumbers in units of 1/Mpc (no h) and
    # return power spectra in units of Mpc^3 (no 1/h^3).
    pknl_class(kovh) = cosmo.pk(kovh * h0, z) * h0^3
    pklin_class(kovh) = cosmo.pk_lin(kovh * h0, z) * h0^3
    # Spline interpolate in log(k)
    lnk = log(1e-4):0.05:log(100)
    pknl = Spline1D(lnk, pknl_class.(exp.(lnk)))
    pklin = Spline1D(lnk, pklin_class.(exp.(lnk)))
    # %% Compute Ωgrav from non-linear total matter P(k)
    Ωgpk[ired] = ograv_pk(x -> pknl(log(x)), z, Ωm)
    # %% Compute Ωgrav from linear total matter P(k)
    Ωglin[ired] = ograv_pk(x -> pklin(log(x)), z, Ωm)
end
Ωgrav_pklin = Spline1D(a, Ωglin)
Ωgrav_pknl = Spline1D(a, Ωgpk)

# %% Solve the Layzer-Irvine equation
tspan = (1 / (1 + zini), 1.0)
t0 = tspan[1]
## Non-linear P(k)
W(x) = 2 * Ωgrav_pknl(x)
dWda(x) = 2 * derivative(Ωgrav_pknl, x)
f(u, p, t) = -(2 * u + W(t)) / t - dWda(t)
u0 = KovW[1] * W(t0)
prob = ODEProblem(f, u0, tspan)
sol_pknl = solve(prob, Tsit5())
## Linear P(k): This result must agree with the analytical linear theory result
W(x) = 2 * Ωgrav_pklin(x)
dWda(x) = 2 * derivative(Ωgrav_pklin, x)
f(u, p, t) = -(2 * u + W(t)) / t - dWda(t)
u0 = KovW[1] * W(t0)
prob = ODEProblem(f, u0, tspan)
sol_pklin = solve(prob, Tsit5())

#%% Plot results and save to figure4.pdf
## Plot against the scale factor
#p = plot(
#    a,
#    sol_pknl.(a)[:, 1],
#    lw = 2,
#    xlab = "Scale factor, a",
#    ylab = "Comiving Density Parameters",
#    lab = L"\Omega_K: Nonlinear",
#    legend = :topleft,
#    legendfontsize = 12,
#    labelfontsize = 15,
#    ylims = [1e-7, 8e-7],
#    xlims = [0.2, 1.0],
#)
#p = plot!(a, -Ωgrav_pknl.(a), lw = 2, lab = L"-\Omega_W/2: Nonlinear")
#p = plot!(a, sol_pklin.(a)[:, 1], c = 1, lw = 2, ls = :dot, lab = L"\Omega_K: Linear")
#p = plot!(a, -Ωgrav_pklin.(a), c = 2, lw = 2, ls = :dot, lab = L"-\Omega_W/2: Linear")
#p = plot!(a, KovW .* W.(a), ls = :dot, lab = L"K: Linear,~Analytical")
## Plot against the redshift
redshift = 1 ./ a .- 1
p = plot(
    redshift,
    sol_pknl.(a)[:, 1],
    lw = 2,
    xlab = "Redshift, z",
    ylab = "Comiving Density Parameters",
    lab = L"\Omega_K: Nonlinear",
    legend = :topright,
    legendfontsize = 12,
    labelfontsize = 15,
    ylims = [1e-7, 8e-7],
    xlims = [0, 3.0],
)
p = plot!(redshift, -Ωgrav_pknl.(a), lw = 2, lab = L"-\Omega_W/2: Nonlinear")
p = plot!(
    redshift,
    sol_pklin.(a)[:, 1],
    c = 1,
    lw = 2,
    ls = :dot,
    lab = L"\Omega_K: Linear",
)
p = plot!(
    redshift,
    -Ωgrav_pklin.(a),
    c = 2,
    lw = 2,
    ls = :dot,
    lab = L"-\Omega_W/2: Linear",
)
savefig("figure4.pdf")
display(p)

# %% Clean CLASS (the equivalent of the struct_free() in the `main`
# of CLASS. This step is primordial when running in a loop over different
# cosmologies, as you will saturate your memory very fast if you ommit
# it.
cosmo.struct_cleanup()
# If you want to change completely the cosmology, you should also
# clean the arguments, otherwise, if you are simply running on a loop
# of different values for the same parameters, this step is not needed
cosmo.empty()


text:
# Automatically generated using Clang.jl

const IVIFGEN_MAJOR_VERSION = Int32(5)
const IVIFGEN_MINOR_VERSION = Int32(0)
const IVIFGEN_CLASS_SPEC_MAJOR_VERSION = Int32(5)
const IVIFGEN_CLASS_SPEC_MINOR_VERSION = Int32(0)
const IVIFGEN_DRIVER_VENDOR = "National Instruments"
const IVIFGEN_DRIVER_DESCRIPTION = "IviFgen Class Driver"
const IVIFGEN_ATTR_CACHE = IVI_ATTR_CACHE
const IVIFGEN_ATTR_RANGE_CHECK = IVI_ATTR_RANGE_CHECK
const IVIFGEN_ATTR_QUERY_INSTRUMENT_STATUS = IVI_ATTR_QUERY_INSTRUMENT_STATUS
const IVIFGEN_ATTR_RECORD_COERCIONS = IVI_ATTR_RECORD_COERCIONS
const IVIFGEN_ATTR_SIMULATE = IVI_ATTR_SIMULATE
const IVIFGEN_ATTR_INTERCHANGE_CHECK = IVI_ATTR_INTERCHANGE_CHECK
const IVIFGEN_ATTR_SPY = IVI_ATTR_SPY
const IVIFGEN_ATTR_USE_SPECIFIC_SIMULATION = IVI_ATTR_USE_SPECIFIC_SIMULATION
const IVIFGEN_ATTR_GROUP_CAPABILITIES = IVI_ATTR_GROUP_CAPABILITIES
const IVIFGEN_ATTR_FUNCTION_CAPABILITIES = IVI_ATTR_FUNCTION_CAPABILITIES
const IVIFGEN_ATTR_CLASS_DRIVER_PREFIX = IVI_ATTR_CLASS_DRIVER_PREFIX
const IVIFGEN_ATTR_CLASS_DRIVER_VENDOR = IVI_ATTR_CLASS_DRIVER_VENDOR
const IVIFGEN_ATTR_CLASS_DRIVER_DESCRIPTION = IVI_ATTR_CLASS_DRIVER_DESCRIPTION
const IVIFGEN_ATTR_CLASS_DRIVER_CLASS_SPEC_MAJOR_VERSION = IVI_ATTR_CLASS_DRIVER_CLASS_SPEC_MAJOR_VERSION
const IVIFGEN_ATTR_CLASS_DRIVER_CLASS_SPEC_MINOR_VERSION = IVI_ATTR_CLASS_DRIVER_CLASS_SPEC_MINOR_VERSION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_PREFIX = IVI_ATTR_SPECIFIC_DRIVER_PREFIX
const IVIFGEN_ATTR_SPECIFIC_DRIVER_LOCATOR = IVI_ATTR_SPECIFIC_DRIVER_LOCATOR
const IVIFGEN_ATTR_IO_RESOURCE_DESCRIPTOR = IVI_ATTR_IO_RESOURCE_DESCRIPTOR
const IVIFGEN_ATTR_LOGICAL_NAME = IVI_ATTR_LOGICAL_NAME
const IVIFGEN_ATTR_SPECIFIC_DRIVER_VENDOR = IVI_ATTR_SPECIFIC_DRIVER_VENDOR
const IVIFGEN_ATTR_SPECIFIC_DRIVER_DESCRIPTION = IVI_ATTR_SPECIFIC_DRIVER_DESCRIPTION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION = IVI_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION = IVI_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION
const IVIFGEN_ATTR_INSTRUMENT_FIRMWARE_REVISION = IVI_ATTR_INSTRUMENT_FIRMWARE_REVISION
const IVIFGEN_ATTR_INSTRUMENT_MANUFACTURER = IVI_ATTR_INSTRUMENT_MANUFACTURER
const IVIFGEN_ATTR_INSTRUMENT_MODEL = IVI_ATTR_INSTRUMENT_MODEL
const IVIFGEN_ATTR_SUPPORTED_INSTRUMENT_MODELS = IVI_ATTR_SUPPORTED_INSTRUMENT_MODELS
const IVIFGEN_ATTR_CLASS_DRIVER_REVISION = IVI_ATTR_CLASS_DRIVER_REVISION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_REVISION = IVI_ATTR_SPECIFIC_DRIVER_REVISION
const IVIFGEN_ATTR_DRIVER_SETUP = IVI_ATTR_DRIVER_SETUP
const IVIFGEN_ATTR_CHANNEL_COUNT = IVI_ATTR_CHANNEL_COUNT
const IVIFGEN_ATTR_OUTPUT_MODE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(1)
const IVIFGEN_ATTR_REF_CLOCK_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(2)
const IVIFGEN_ATTR_OUTPUT_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(3)
const IVIFGEN_ATTR_OUTPUT_IMPEDANCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(4)
const IVIFGEN_ATTR_OPERATION_MODE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(5)
const IVIFGEN_ATTR_SAMPLE_CLOCK_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(21)
const IVIFGEN_ATTR_SAMPLE_CLOCK_OUTPUT_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(22)
const IVIFGEN_ATTR_TERMINAL_CONFIGURATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(31)
const IVIFGEN_ATTR_FUNC_WAVEFORM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(101)
const IVIFGEN_ATTR_FUNC_AMPLITUDE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(102)
const IVIFGEN_ATTR_FUNC_DC_OFFSET = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(103)
const IVIFGEN_ATTR_FUNC_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(104)
const IVIFGEN_ATTR_FUNC_START_PHASE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(105)
const IVIFGEN_ATTR_FUNC_DUTY_CYCLE_HIGH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(106)
const IVIFGEN_ATTR_ARB_WAVEFORM_HANDLE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(201)
const IVIFGEN_ATTR_ARB_GAIN = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(202)
const IVIFGEN_ATTR_ARB_OFFSET = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(203)
const IVIFGEN_ATTR_ARB_SAMPLE_RATE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(204)
const IVIFGEN_ATTR_MAX_NUM_WAVEFORMS = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(205)
const IVIFGEN_ATTR_WAVEFORM_QUANTUM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(206)
const IVIFGEN_ATTR_MIN_WAVEFORM_SIZE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(207)
const IVIFGEN_ATTR_MAX_WAVEFORM_SIZE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(208)
const IVIFGEN_ATTR_ARB_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(209)
const IVIFGEN_ATTR_ARB_SEQUENCE_HANDLE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(211)
const IVIFGEN_ATTR_MAX_NUM_SEQUENCES = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(212)
const IVIFGEN_ATTR_MIN_SEQUENCE_LENGTH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(213)
const IVIFGEN_ATTR_MAX_SEQUENCE_LENGTH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(214)
const IVIFGEN_ATTR_MAX_LOOP_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(215)
const IVIFGEN_ATTR_MIN_WAVEFORM_SIZE64 = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(221)
const IVIFGEN_ATTR_MAX_WAVEFORM_SIZE64 = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(222)
const IVIFGEN_ATTR_BINARY_ALIGNMENT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(241)
const IVIFGEN_ATTR_SAMPLE_BIT_RESOLUTION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(242)
const IVIFGEN_ATTR_OUTPUT_DATA_MASK = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(261)
const IVIFGEN_ATTR_SEQUENCE_DEPTH_MAX = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(281)
const IVIFGEN_ATTR_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(302)
const IVIFGEN_ATTR_INTERNAL_TRIGGER_RATE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(310)
const IVIFGEN_ATTR_START_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(320)
const IVIFGEN_ATTR_START_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(321)
const IVIFGEN_ATTR_START_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(322)
const IVIFGEN_ATTR_START_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(323)
const IVIFGEN_ATTR_STOP_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(330)
const IVIFGEN_ATTR_STOP_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(331)
const IVIFGEN_ATTR_STOP_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(332)
const IVIFGEN_ATTR_STOP_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(333)
const IVIFGEN_ATTR_HOLD_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(340)
const IVIFGEN_ATTR_HOLD_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(341)
const IVIFGEN_ATTR_HOLD_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(342)
const IVIFGEN_ATTR_HOLD_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(343)
const IVIFGEN_ATTR_BURST_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(350)
const IVIFGEN_ATTR_RESUME_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(360)
const IVIFGEN_ATTR_RESUME_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(361)
const IVIFGEN_ATTR_RESUME_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(362)
const IVIFGEN_ATTR_RESUME_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(363)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(370)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(371)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(372)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(373)
const IVIFGEN_ATTR_AM_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(401)
const IVIFGEN_ATTR_AM_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(402)
const IVIFGEN_ATTR_AM_INTERNAL_DEPTH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(403)
const IVIFGEN_ATTR_AM_INTERNAL_WAVEFORM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(404)
const IVIFGEN_ATTR_AM_INTERNAL_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(405)
const IVIFGEN_ATTR_FM_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(501)
const IVIFGEN_ATTR_FM_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(502)
const IVIFGEN_ATTR_FM_INTERNAL_DEVIATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(503)
const IVIFGEN_ATTR_FM_INTERNAL_WAVEFORM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(504)
const IVIFGEN_ATTR_FM_INTERNAL_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(505)
const IVIFGEN_ATTR_DATAMARKER_AMPLITUDE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(601)
const IVIFGEN_ATTR_DATAMARKER_BIT_POSITION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(602)
const IVIFGEN_ATTR_DATAMARKER_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(603)
const IVIFGEN_ATTR_DATAMARKER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(604)
const IVIFGEN_ATTR_DATAMARKER_DESTINATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(605)
const IVIFGEN_ATTR_DATAMARKER_POLARITY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(606)
const IVIFGEN_ATTR_DATAMARKER_SOURCE_CHANNEL = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(607)
const IVIFGEN_ATTR_SPARSEMARKER_AMPLITUDE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(701)
const IVIFGEN_ATTR_SPARSEMARKER_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(702)
const IVIFGEN_ATTR_SPARSEMARKER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(703)
const IVIFGEN_ATTR_SPARSEMARKER_DESTINATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(704)
const IVIFGEN_ATTR_SPARSEMARKER_POLARITY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(705)
const IVIFGEN_ATTR_SPARSEMARKER_WFMHANDLE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(706)
const IVIFGEN_VAL_OUTPUT_FUNC = Int32(0)
const IVIFGEN_VAL_OUTPUT_ARB = Int32(1)
const IVIFGEN_VAL_OUTPUT_SEQ = Int32(2)
const IVIFGEN_VAL_OUT_MODE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_OUT_MODE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_OPERATE_CONTINUOUS = Int32(0)
const IVIFGEN_VAL_OPERATE_BURST = Int32(1)
const IVIFGEN_VAL_OP_MODE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_OP_MODE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_REF_CLOCK_INTERNAL = Int32(0)
const IVIFGEN_VAL_REF_CLOCK_EXTERNAL = Int32(1)
const IVIFGEN_VAL_REF_CLOCK_RTSI_CLOCK = Int32(101)
const IVIFGEN_VAL_CLK_SRC_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_CLK_SRC_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_WFM_SINE = Int32(1)
const IVIFGEN_VAL_WFM_SQUARE = Int32(2)
const IVIFGEN_VAL_WFM_TRIANGLE = Int32(3)
const IVIFGEN_VAL_WFM_RAMP_UP = Int32(4)
const IVIFGEN_VAL_WFM_RAMP_DOWN = Int32(5)
const IVIFGEN_VAL_WFM_DC = Int32(6)
const IVIFGEN_VAL_WFM_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_WFM_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_EXTERNAL = Int32(1)
const IVIFGEN_VAL_SOFTWARE_TRIG = Int32(2)
const IVIFGEN_VAL_INTERNAL_TRIGGER = Int32(3)
const IVIFGEN_VAL_TTL0 = Int32(111)
const IVIFGEN_VAL_TTL1 = Int32(112)
const IVIFGEN_VAL_TTL2 = Int32(113)
const IVIFGEN_VAL_TTL3 = Int32(114)
const IVIFGEN_VAL_TTL4 = Int32(115)
const IVIFGEN_VAL_TTL5 = Int32(116)
const IVIFGEN_VAL_TTL6 = Int32(117)
const IVIFGEN_VAL_TTL7 = Int32(118)
const IVIFGEN_VAL_ECL0 = Int32(119)
const IVIFGEN_VAL_ECL1 = Int32(120)
const IVIFGEN_VAL_PXI_STAR = Int32(131)
const IVIFGEN_VAL_RTSI_0 = Int32(141)
const IVIFGEN_VAL_RTSI_1 = Int32(142)
const IVIFGEN_VAL_RTSI_2 = Int32(143)
const IVIFGEN_VAL_RTSI_3 = Int32(144)
const IVIFGEN_VAL_RTSI_4 = Int32(145)
const IVIFGEN_VAL_RTSI_5 = Int32(146)
const IVIFGEN_VAL_RTSI_6 = Int32(147)
const IVIFGEN_VAL_TRIG_SRC_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_TRIGGER_SOURCE_NONE = ""
const IVIFGEN_VAL_TRIGGER_SOURCE_IMMEDIATE = "Immediate"
const IVIFGEN_VAL_TRIGGER_SOURCE_EXTERNAL = "External"
const IVIFGEN_VAL_TRIGGER_SOURCE_INTERNAL = "Internal"
const IVIFGEN_VAL_TRIGGER_SOURCE_SOFTWARE = "Software"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN0 = "LAN0"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN1 = "LAN1"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN2 = "LAN2"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN3 = "LAN3"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN4 = "LAN4"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN5 = "LAN5"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN6 = "LAN6"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN7 = "LAN7"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI0 = "LXI0"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI1 = "LXI1"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI2 = "LXI2"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI3 = "LXI3"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI4 = "LXI4"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI5 = "LXI5"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI6 = "LXI6"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI7 = "LXI7"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL0 = "TTL0"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL1 = "TTL1"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL2 = "TTL2"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL3 = "TTL3"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL4 = "TTL4"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL5 = "TTL5"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL6 = "TTL6"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL7 = "TTL7"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_STAR = "PXI_STAR"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG0 = "PXI_TRIG0"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG1 = "PXI_TRIG1"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG2 = "PXI_TRIG2"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG3 = "PXI_TRIG3"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG4 = "PXI_TRIG4"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG5 = "PXI_TRIG5"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG6 = "PXI_TRIG6"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG7 = "PXI_TRIG7"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXIE_DSTARA = "PXIe_DSTARA"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXIE_DSTARB = "PXIe_DSTARB"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXIE_DSTARC = "PXIe_DSTARC"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI0 = "RTSI0"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI1 = "RTSI1"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI2 = "RTSI2"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI3 = "RTSI3"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI4 = "RTSI4"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI5 = "RTSI5"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI6 = "RTSI6"
const IVIFGEN_VAL_SAMPLE_CLOCK_SOURCE_INTERNAL = Int32(0)
const IVIFGEN_VAL_SAMPLE_CLOCK_SOURCE_EXTERNAL = Int32(1)
const IVIFGEN_VAL_MARKER_POLARITY_ACTIVE_HIGH = Int32(0)
const IVIFGEN_VAL_MARKER_POLARITY_ACTIVE_LOW = Int32(1)
const IVIFGEN_VAL_AM_INTERNAL = Int32(0)
const IVIFGEN_VAL_AM_EXTERNAL = Int32(1)
const IVIFGEN_VAL_AM_SOURCE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_AM_SOURCE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_AM_INTERNAL_SINE = Int32(1)
const IVIFGEN_VAL_AM_INTERNAL_SQUARE = Int32(2)
const IVIFGEN_VAL_AM_INTERNAL_TRIANGLE = Int32(3)
const IVIFGEN_VAL_AM_INTERNAL_RAMP_UP = Int32(4)
const IVIFGEN_VAL_AM_INTERNAL_RAMP_DOWN = Int32(5)
const IVIFGEN_VAL_AM_INTERNAL_WFM_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_AM_INTERNAL_WFM_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_FM_INTERNAL = Int32(0)
const IVIFGEN_VAL_FM_EXTERNAL = Int32(1)
const IVIFGEN_VAL_FM_SOURCE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_FM_SOURCE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_FM_INTERNAL_SINE = Int32(1)
const IVIFGEN_VAL_FM_INTERNAL_SQUARE = Int32(2)
const IVIFGEN_VAL_FM_INTERNAL_TRIANGLE = Int32(3)
const IVIFGEN_VAL_FM_INTERNAL_RAMP_UP = Int32(4)
const IVIFGEN_VAL_FM_INTERNAL_RAMP_DOWN = Int32(5)
const IVIFGEN_VAL_FM_INTERNAL_WFM_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_FM_INTERNAL_WFM_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_BINARY_ALIGNMENT_LEFT = Int32(0)
const IVIFGEN_VAL_BINARY_ALIGNMENT_RIGHT = Int32(1)
const IVIFGEN_VAL_BINARY_ALIGNMENT_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_BINARY_ALIGNMENT_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_SINGLE_ENDED = Int32(0)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_DIFFERENTIAL = Int32(1)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_TRIGGER_POSITIVE = Int32(0)
const IVIFGEN_VAL_TRIGGER_NEGATIVE = Int32(1)
const IVIFGEN_VAL_TRIGGER_EITHER = Int32(2)
const IVIFGEN_VAL_TRIGGER_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_TRIGGER_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_ALL_WAVEFORMS = -(Int32(1))
const IVIFGEN_VAL_ALL_SEQUENCES = -(Int32(1))
const IVIFGEN_ERROR_NO_WFMS_AVAILABLE = IVI_CLASS_ERROR_BASE + Int32(4)
const IVIFGEN_ERROR_WFM_IN_USE = IVI_CLASS_ERROR_BASE + Int32(8)
const IVIFGEN_ERROR_NO_SEQS_AVAILABLE = IVI_CLASS_ERROR_BASE + Int32(9)
const IVIFGEN_ERROR_SEQ_IN_USE = IVI_CLASS_ERROR_BASE + Int32(13)
const IVIFGEN_ERROR_INVALID_WFM_CHANNEL = IVI_CLASS_ERROR_BASE + Int32(14)
const IVIFGEN_ERROR_TRIGGER_NOT_SOFTWARE = IVI_CROSS_CLASS_ERROR_BASE + Int32(1)
const IVIFGEN_ERRMSG_NO_WFMS_AVAILABLE = "The function generator's waveform memory is full."
const IVIFGEN_ERRMSG_WFM_IN_USE = "The waveform is currently in use."
const IVIFGEN_ERRMSG_NO_SEQS_AVAILABLE = "The function generator's sequence memory is full."
const IVIFGEN_ERRMSG_SEQ_IN_USE = "The sequence is currently in use."
const IVIFGEN_ERRMSG_INVALID_WFM_CHANNEL = "The waveform was created on a different channel than the one for which it is being configured."
const IVIFGEN_ERRMSG_TRIGGER_NOT_SOFTWARE = "The trigger source is not set to software trigger."

# Skipping MacroDefinition: IVIFGEN_ERROR_CODES_AND_MSGS { IVIFGEN_ERROR_NO_WFMS_AVAILABLE , IVIFGEN_ERRMSG_NO_WFMS_AVAILABLE } , { IVIFGEN_ERROR_WFM_IN_USE , IVIFGEN_ERRMSG_WFM_IN_USE } , { IVIFGEN_ERROR_NO_SEQS_AVAILABLE , IVIFGEN_ERRMSG_NO_SEQS_AVAILABLE } , { IVIFGEN_ERROR_SEQ_IN_USE , IVIFGEN_ERRMSG_SEQ_IN_USE } , { IVIFGEN_ERROR_INVALID_WFM_CHANNEL , IVIFGEN_ERRMSG_INVALID_WFM_CHANNEL } , { IVIFGEN_ERROR_TRIGGER_NOT_SOFTWARE , IVIFGEN_ERRMSG_TRIGGER_NOT_SOFTWARE }

const NIFGEN_MAJOR_VERSION = 17
const NIFGEN_MINOR_VERSION = 800
const NIFGEN_ATTR_OUTPUT_MODE = IVIFGEN_ATTR_OUTPUT_MODE
const NIFGEN_ATTR_OUTPUT_ENABLED = IVIFGEN_ATTR_OUTPUT_ENABLED
const NIFGEN_ATTR_DIGITAL_GAIN = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(254)
const NIFGEN_ATTR_ANALOG_PATH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(222)
const NIFGEN_ATTR_LOAD_IMPEDANCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(220)
const NIFGEN_ATTR_OUTPUT_IMPEDANCE = IVIFGEN_ATTR_OUTPUT_IMPEDANCE
const NIFGEN_ATTR_TERMINAL_CONFIGURATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(365)
const NIFGEN_ATTR_COMMON_MODE_OFFSET = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(366)
const NIFGEN_ATTR_CHANNEL_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(369)
const NIFGEN_ATTR_ABSOLUTE_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(413)
const NIFGEN_ATTR_ANALOG_FILTER_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(103)
const NIFGEN_ATTR_DIGITAL_FILTER_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(102)
const NIFGEN_ATTR_DIGITAL_FILTER_INTERPOLATION_FACTOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(218)
const NIFGEN_ATTR_FLATNESS_CORRECTION_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(323)
const NIFGEN_ATTR_ANALOG_DATA_MASK = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(234)
const NIFGEN_ATTR_ANALOG_STATIC_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(235)
const NIFGEN_ATTR_DIGITAL_DATA_MASK = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(236)
const NIFGEN_ATTR_DIGITAL_STATIC_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(237)
const NIFGEN_ATTR_DIGITAL_PATTERN_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(101)
const NIFGEN_ATTR_AUX_POWER_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(411)
const NIFGEN_ATTR_IDLE_BEHAVIOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(377)
const NIFGEN_ATTR_IDLE_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(378)
const NIFGEN_ATTR_WAIT_BEHAVIOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(379)
const NIFGEN_ATTR_WAIT_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(380)
const NIFGEN_ATTR_ARB_GAIN = IVIFGEN_ATTR_ARB_GAIN
const NIFGEN_ATTR_ARB_OFFSET = IVIFGEN_ATTR_ARB_OFFSET
const NIFGEN_ATTR_WAVEFORM_QUANTUM = IVIFGEN_ATTR_WAVEFORM_QUANTUM
const NIFGEN_ATTR_MAX_NUM_WAVEFORMS = IVIFGEN_ATTR_MAX_NUM_WAVEFORMS
const NIFGEN_ATTR_MIN_WAVEFORM_SIZE = IVIFGEN_ATTR_MIN_WAVEFORM_SIZE
const NIFGEN_ATTR_MAX_WAVEFORM_SIZE = IVIFGEN_ATTR_MAX_WAVEFORM_SIZE
const NIFGEN_ATTR_ARB_WAVEFORM_HANDLE = IVIFGEN_ATTR_ARB_WAVEFORM_HANDLE
const NIFGEN_ATTR_ARB_MARKER_POSITION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(327)
const NIFGEN_ATTR_ARB_REPEAT_COUNT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(328)
const NIFGEN_ATTR_ARB_SEQUENCE_HANDLE = IVIFGEN_ATTR_ARB_SEQUENCE_HANDLE
const NIFGEN_ATTR_MAX_NUM_SEQUENCES = IVIFGEN_ATTR_MAX_NUM_SEQUENCES
const NIFGEN_ATTR_MIN_SEQUENCE_LENGTH = IVIFGEN_ATTR_MIN_SEQUENCE_LENGTH
const NIFGEN_ATTR_MAX_SEQUENCE_LENGTH = IVIFGEN_ATTR_MAX_SEQUENCE_LENGTH
const NIFGEN_ATTR_MAX_LOOP_COUNT = IVIFGEN_ATTR_MAX_LOOP_COUNT
const NIFGEN_ATTR_SCRIPT_TO_GENERATE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(270)
const NIFGEN_ATTR_FILE_TRANSFER_BLOCK_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(240)
const NIFGEN_ATTR_DATA_TRANSFER_BLOCK_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(241)
const NIFGEN_ATTR_DATA_TRANSFER_MAXIMUM_BANDWIDTH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(373)
const NIFGEN_ATTR_DIRECT_DMA_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(244)
const NIFGEN_ATTR_DIRECT_DMA_WINDOW_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(245)
const NIFGEN_ATTR_DIRECT_DMA_WINDOW_ADDRESS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(274)
const NIFGEN_ATTR_STREAMING_WAVEFORM_NAME = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(326)
const NIFGEN_ATTR_STREAMING_WAVEFORM_HANDLE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(324)
const NIFGEN_ATTR_STREAMING_SPACE_AVAILABLE_IN_WAVEFORM = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(325)
const NIFGEN_ATTR_STREAMING_WRITE_TIMEOUT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(409)
const NIFGEN_ATTR_DATA_TRANSFER_PREFERRED_PACKET_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(374)
const NIFGEN_ATTR_DATA_TRANSFER_MAXIMUM_IN_FLIGHT_READS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(375)
const NIFGEN_ATTR_PCI_DMA_OPTIMIZATIONS_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(362)
const NIFGEN_ATTR_OSP_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(246)
const NIFGEN_ATTR_OSP_IQ_RATE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(248)
const NIFGEN_ATTR_OSP_DATA_PROCESSING_MODE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(247)
const NIFGEN_ATTR_OSP_MODE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(370)
const NIFGEN_ATTR_OSP_FREQUENCY_SHIFT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(371)
const NIFGEN_ATTR_OSP_CARRIER_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(249)
const NIFGEN_ATTR_OSP_CARRIER_FREQUENCY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(250)
const NIFGEN_ATTR_OSP_CARRIER_PHASE_I = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(251)
const NIFGEN_ATTR_OSP_CARRIER_PHASE_Q = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(252)
const NIFGEN_ATTR_OSP_COMPENSATE_FOR_FILTER_GROUP_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(389)
const NIFGEN_ATTR_OSP_FIR_FILTER_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(253)
const NIFGEN_ATTR_OSP_FIR_FILTER_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(255)
const NIFGEN_ATTR_OSP_FIR_FILTER_INTERPOLATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(256)
const NIFGEN_ATTR_OSP_CIC_FILTER_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(257)
const NIFGEN_ATTR_OSP_CIC_FILTER_INTERPOLATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(258)
const NIFGEN_ATTR_OSP_FIR_FILTER_ROOT_RAISED_COSINE_ALPHA = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(259)
const NIFGEN_ATTR_OSP_FIR_FILTER_RAISED_COSINE_ALPHA = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(260)
const NIFGEN_ATTR_OSP_FIR_FILTER_FLAT_PASSBAND = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(261)
const NIFGEN_ATTR_OSP_FIR_FILTER_GAUSSIAN_BT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(262)
const NIFGEN_ATTR_OSP_CIC_FILTER_GAIN = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(263)
const NIFGEN_ATTR_OSP_PRE_FILTER_GAIN_I = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(264)
const NIFGEN_ATTR_OSP_PRE_FILTER_GAIN_Q = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(265)
const NIFGEN_ATTR_OSP_PRE_FILTER_OFFSET_I = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(266)
const NIFGEN_ATTR_OSP_PRE_FILTER_OFFSET_Q = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(267)
const NIFGEN_ATTR_OSP_OVERFLOW_ERROR_REPORTING = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(268)
const NIFGEN_ATTR_OSP_OVERFLOW_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(269)
const NIFGEN_ATTR_P2P_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(391)
const NIFGEN_ATTR_P2P_DESTINATION_CHANNELS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(392)
const NIFGEN_ATTR_P2P_ENDPOINT_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(393)
const NIFGEN_ATTR_P2P_SPACE_AVAILABLE_IN_ENDPOINT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(394)
const NIFGEN_ATTR_P2P_MOST_SPACE_AVAILABLE_IN_ENDPOINT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(395)
const NIFGEN_ATTR_P2P_ENDPOINT_COUNT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(396)
const NIFGEN_ATTR_P2P_DATA_TRANSFER_PERMISSION_INTERVAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(400)
const NIFGEN_ATTR_P2P_DATA_TRANSFER_PERMISSION_INITIAL_CREDITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(408)
const NIFGEN_ATTR_P2P_MANUAL_CONFIGURATION_ENABLED = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(397)
const NIFGEN_ATTR_P2P_DATA_TRANSFER_PERMISSION_ADDRESS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(398)
const NIFGEN_ATTR_P2P_DATA_TRANSFER_PERMISSION_ADDRESS_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(399)
const NIFGEN_ATTR_P2P_ENDPOINT_WINDOW_ADDRESS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(401)
const NIFGEN_ATTR_P2P_ENDPOINT_WINDOW_ADDRESS_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(402)
const NIFGEN_ATTR_P2P_ENDPOINT_WINDOW_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(403)
const NIFGEN_ATTR_P2P_ENDPOINT_FULLNESS_START_TRIGGER_LEVEL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(410)
const NIFGEN_ATTR_P2P_DONE_NOTIFICATION_ADDRESS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(405)
const NIFGEN_ATTR_P2P_DONE_NOTIFICATION_ADDRESS_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(406)
const NIFGEN_ATTR_P2P_DONE_NOTIFICATION_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(407)
const NIFGEN_ATTR_FUNC_WAVEFORM = IVIFGEN_ATTR_FUNC_WAVEFORM
const NIFGEN_ATTR_FUNC_AMPLITUDE = IVIFGEN_ATTR_FUNC_AMPLITUDE
const NIFGEN_ATTR_FUNC_DC_OFFSET = IVIFGEN_ATTR_FUNC_DC_OFFSET
const NIFGEN_ATTR_FUNC_START_PHASE = IVIFGEN_ATTR_FUNC_START_PHASE
const NIFGEN_ATTR_FUNC_DUTY_CYCLE_HIGH = IVIFGEN_ATTR_FUNC_DUTY_CYCLE_HIGH
const NIFGEN_ATTR_SYNC_DUTY_CYCLE_HIGH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(105)
const NIFGEN_ATTR_SYNC_OUT_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(330)
const NIFGEN_ATTR_FUNC_FREQUENCY = IVIFGEN_ATTR_FUNC_FREQUENCY
const NIFGEN_ATTR_FUNC_BUFFER_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(238)
const NIFGEN_ATTR_FUNC_MAX_BUFFER_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(239)
const NIFGEN_ATTR_FREQ_LIST_HANDLE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(208)
const NIFGEN_ATTR_MAX_NUM_FREQ_LISTS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(209)
const NIFGEN_ATTR_MIN_FREQ_LIST_LENGTH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(210)
const NIFGEN_ATTR_MAX_FREQ_LIST_LENGTH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(211)
const NIFGEN_ATTR_MIN_FREQ_LIST_DURATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(212)
const NIFGEN_ATTR_MAX_FREQ_LIST_DURATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(213)
const NIFGEN_ATTR_FREQ_LIST_DURATION_QUANTUM = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(214)
const NIFGEN_ATTR_REFERENCE_CLOCK_SOURCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(113)
const NIFGEN_ATTR_REF_CLOCK_FREQUENCY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(107)
const NIFGEN_ATTR_EXPORTED_REFERENCE_CLOCK_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(321)
const NIFGEN_ATTR_EXPORTED_ONBOARD_REFERENCE_CLOCK_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(322)
const NIFGEN_ATTR_ARB_SAMPLE_RATE = IVIFGEN_ATTR_ARB_SAMPLE_RATE
const NIFGEN_ATTR_CLOCK_MODE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(110)
const NIFGEN_ATTR_SAMPLE_CLOCK_SOURCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(112)
const NIFGEN_ATTR_EXPORTED_SAMPLE_CLOCK_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(320)
const NIFGEN_ATTR_EXPORTED_SAMPLE_CLOCK_DIVISOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(219)
const NIFGEN_ATTR_SAMPLE_CLOCK_TIMEBASE_SOURCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(367)
const NIFGEN_ATTR_SAMPLE_CLOCK_TIMEBASE_RATE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(368)
const NIFGEN_ATTR_EXPORTED_SAMPLE_CLOCK_TIMEBASE_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(329)
const NIFGEN_ATTR_EXPORTED_SAMPLE_CLOCK_TIMEBASE_DIVISOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(230)
const NIFGEN_ATTR_EXTERNAL_SAMPLE_CLOCK_MULTIPLIER = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(376)
const NIFGEN_ATTR_SAMPLE_CLOCK_ABSOLUTE_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(231)
const NIFGEN_ATTR_OSCILLATOR_PHASE_DAC_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(232)
const NIFGEN_ATTR_EXTERNAL_CLOCK_DELAY_BINARY_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(233)
const NIFGEN_ATTR_MARKER_EVENT_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(312)
const NIFGEN_ATTR_MARKER_EVENT_OUTPUT_BEHAVIOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(342)
const NIFGEN_ATTR_MARKER_EVENT_PULSE_POLARITY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(313)
const NIFGEN_ATTR_MARKER_EVENT_PULSE_WIDTH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(340)
const NIFGEN_ATTR_MARKER_EVENT_PULSE_WIDTH_UNITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(341)
const NIFGEN_ATTR_MARKER_EVENT_TOGGLE_INITIAL_STATE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(343)
const NIFGEN_ATTR_MARKER_EVENT_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(354)
const NIFGEN_ATTR_MARKER_EVENT_DELAY_UNITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(355)
const NIFGEN_ATTR_ALL_MARKER_EVENTS_LIVE_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(344)
const NIFGEN_ATTR_MARKER_EVENT_LIVE_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(345)
const NIFGEN_ATTR_ALL_MARKER_EVENTS_LATCHED_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(349)
const NIFGEN_ATTR_MARKER_EVENT_LATCHED_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(350)
const NIFGEN_ATTR_DATA_MARKER_EVENT_DATA_BIT_NUMBER = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(337)
const NIFGEN_ATTR_DATA_MARKER_EVENT_LEVEL_POLARITY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(338)
const NIFGEN_ATTR_DATA_MARKER_EVENT_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(339)
const NIFGEN_ATTR_READY_FOR_START_EVENT_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(310)
const NIFGEN_ATTR_READY_FOR_START_EVENT_LEVEL_ACTIVE_LEVEL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(311)
const NIFGEN_ATTR_READY_FOR_START_EVENT_LIVE_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(348)
const NIFGEN_ATTR_STARTED_EVENT_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(314)
const NIFGEN_ATTR_STARTED_EVENT_OUTPUT_BEHAVIOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(331)
const NIFGEN_ATTR_STARTED_EVENT_LEVEL_ACTIVE_LEVEL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(316)
const NIFGEN_ATTR_STARTED_EVENT_PULSE_POLARITY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(318)
const NIFGEN_ATTR_STARTED_EVENT_PULSE_WIDTH_UNITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(333)
const NIFGEN_ATTR_STARTED_EVENT_PULSE_WIDTH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(335)
const NIFGEN_ATTR_STARTED_EVENT_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(356)
const NIFGEN_ATTR_STARTED_EVENT_DELAY_UNITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(357)
const NIFGEN_ATTR_STARTED_EVENT_LATCHED_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(352)
const NIFGEN_ATTR_DONE_EVENT_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(315)
const NIFGEN_ATTR_DONE_EVENT_OUTPUT_BEHAVIOR = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(332)
const NIFGEN_ATTR_DONE_EVENT_LEVEL_ACTIVE_LEVEL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(317)
const NIFGEN_ATTR_DONE_EVENT_PULSE_POLARITY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(319)
const NIFGEN_ATTR_DONE_EVENT_PULSE_WIDTH_UNITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(334)
const NIFGEN_ATTR_DONE_EVENT_PULSE_WIDTH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(336)
const NIFGEN_ATTR_DONE_EVENT_DELAY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(358)
const NIFGEN_ATTR_DONE_EVENT_DELAY_UNITS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(359)
const NIFGEN_ATTR_DONE_EVENT_LATCHED_STATUS = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(351)
const NIFGEN_ATTR_TRIGGER_MODE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(108)
const NIFGEN_ATTR_BURST_COUNT = IVIFGEN_ATTR_BURST_COUNT
const NIFGEN_ATTR_START_TRIGGER_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(280)
const NIFGEN_ATTR_DIGITAL_EDGE_START_TRIGGER_SOURCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(281)
const NIFGEN_ATTR_DIGITAL_EDGE_START_TRIGGER_EDGE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(282)
const NIFGEN_ATTR_EXPORTED_START_TRIGGER_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(283)
const NIFGEN_ATTR_SCRIPT_TRIGGER_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(290)
const NIFGEN_ATTR_DIGITAL_EDGE_SCRIPT_TRIGGER_SOURCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(291)
const NIFGEN_ATTR_DIGITAL_EDGE_SCRIPT_TRIGGER_EDGE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(292)
const NIFGEN_ATTR_DIGITAL_LEVEL_SCRIPT_TRIGGER_SOURCE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(293)
const NIFGEN_ATTR_DIGITAL_LEVEL_SCRIPT_TRIGGER_ACTIVE_LEVEL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(294)
const NIFGEN_ATTR_EXPORTED_SCRIPT_TRIGGER_OUTPUT_TERMINAL = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(295)
const NIFGEN_ATTR_BUS_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(215)
const NIFGEN_ATTR_MEMORY_SIZE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(242)
const NIFGEN_ATTR_SERIAL_NUMBER = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(243)
const NIFGEN_ATTR_MARKER_EVENTS_COUNT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(271)
const NIFGEN_ATTR_DATA_MARKER_EVENTS_COUNT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(273)
const NIFGEN_ATTR_SCRIPT_TRIGGERS_COUNT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(272)
const NIFGEN_ATTR_VIDEO_WAVEFORM_TYPE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(216)
const NIFGEN_ATTR_FPGA_BITFILE_PATH = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(412)
const NIFGEN_ATTR_FILTER_CORRECTION_FREQUENCY = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(104)
const NIFGEN_ATTR_TRIGGER_SOURCE = IVIFGEN_ATTR_TRIGGER_SOURCE
const NIFGEN_ATTR_SYNCHRONIZATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(111)
const NIFGEN_ATTR_ID_QUERY_RESPONSE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(1)
const NIFGEN_ATTR_GAIN_DAC_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(223)
const NIFGEN_ATTR_OFFSET_DAC_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(224)
const NIFGEN_ATTR_OSCILLATOR_FREQ_DAC_VALUE = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(225)
const NIFGEN_ATTR_CAL_ADC_INPUT = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(227)
const NIFGEN_ATTR_PRE_AMPLIFIER_ATTENUATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(228)
const NIFGEN_ATTR_POST_AMPLIFIER_ATTENUATION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(229)
const NIFGEN_ATTR_CACHE = IVI_ATTR_CACHE
const NIFGEN_ATTR_RANGE_CHECK = IVI_ATTR_RANGE_CHECK
const NIFGEN_ATTR_QUERY_INSTRUMENT_STATUS = IVI_ATTR_QUERY_INSTRUMENT_STATUS
const NIFGEN_ATTR_RECORD_COERCIONS = IVI_ATTR_RECORD_COERCIONS
const NIFGEN_ATTR_SIMULATE = IVI_ATTR_SIMULATE
const NIFGEN_ATTR_INTERCHANGE_CHECK = IVI_ATTR_INTERCHANGE_CHECK
const NIFGEN_ATTR_SPECIFIC_DRIVER_DESCRIPTION = IVI_ATTR_SPECIFIC_DRIVER_DESCRIPTION
const NIFGEN_ATTR_SPECIFIC_DRIVER_PREFIX = IVI_ATTR_SPECIFIC_DRIVER_PREFIX
const NIFGEN_ATTR_SPECIFIC_DRIVER_VENDOR = IVI_ATTR_SPECIFIC_DRIVER_VENDOR
const NIFGEN_ATTR_SPECIFIC_DRIVER_REVISION = IVI_ATTR_SPECIFIC_DRIVER_REVISION
const NIFGEN_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION = IVI_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION
const NIFGEN_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION = IVI_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION
const NIFGEN_ATTR_SUPPORTED_INSTRUMENT_MODELS = IVI_ATTR_SUPPORTED_INSTRUMENT_MODELS
const NIFGEN_ATTR_GROUP_CAPABILITIES = IVI_ATTR_GROUP_CAPABILITIES
const NIFGEN_ATTR_CHANNEL_COUNT = IVI_ATTR_CHANNEL_COUNT
const NIFGEN_ATTR_INSTRUMENT_MANUFACTURER = IVI_ATTR_INSTRUMENT_MANUFACTURER
const NIFGEN_ATTR_INSTRUMENT_MODEL = IVI_ATTR_INSTRUMENT_MODEL
const NIFGEN_ATTR_INSTRUMENT_FIRMWARE_REVISION = IVI_ATTR_INSTRUMENT_FIRMWARE_REVISION
const NIFGEN_ATTR_MODULE_REVISION = IVI_SPECIFIC_PUBLIC_ATTR_BASE + Int32(390)
const NIFGEN_ATTR_IO_RESOURCE_DESCRIPTOR = IVI_ATTR_IO_RESOURCE_DESCRIPTOR
const NIFGEN_ATTR_LOGICAL_NAME = IVI_ATTR_LOGICAL_NAME
const NIFGEN_ATTR_DRIVER_SETUP = IVI_ATTR_DRIVER_SETUP
const NIFGEN_VAL_TRIG_SRC_RANGE = Int32(200)
const NIFGEN_VAL_CLK_SRC_BASE = IVIFGEN_VAL_CLK_SRC_SPECIFIC_EXT_BASE + NIFGEN_VAL_TRIG_SRC_RANGE
const NIFGEN_VAL_OPERATE_CONTINUOUS = IVIFGEN_VAL_OPERATE_CONTINUOUS
const NIFGEN_VAL_OUTPUT_FUNC = IVIFGEN_VAL_OUTPUT_FUNC
const NIFGEN_VAL_OUTPUT_ARB = IVIFGEN_VAL_OUTPUT_ARB
const NIFGEN_VAL_OUTPUT_SEQ = IVIFGEN_VAL_OUTPUT_SEQ
const NIFGEN_VAL_OUTPUT_FREQ_LIST = Int32(101)
const NIFGEN_VAL_OUTPUT_SCRIPT = Int32(102)
const NIFGEN_VAL_50_OHMS = 50.0
const NIFGEN_VAL_75_OHMS = 75.0
const NIFGEN_VAL_MATCHED_LOAD_IMPEDANCE = -1.0
const NIFGEN_VAL_WFM_SINE = IVIFGEN_VAL_WFM_SINE
const NIFGEN_VAL_WFM_SQUARE = IVIFGEN_VAL_WFM_SQUARE
const NIFGEN_VAL_WFM_TRIANGLE = IVIFGEN_VAL_WFM_TRIANGLE
const NIFGEN_VAL_WFM_RAMP_UP = IVIFGEN_VAL_WFM_RAMP_UP
const NIFGEN_VAL_WFM_RAMP_DOWN = IVIFGEN_VAL_WFM_RAMP_DOWN
const NIFGEN_VAL_WFM_DC = IVIFGEN_VAL_WFM_DC
const NIFGEN_VAL_WFM_NOISE = Int32(101)
const NIFGEN_VAL_WFM_USER = Int32(102)
const NIFGEN_VAL_FIRST_WAVEFORM_HANDLE = Int32(10000)
const NIFGEN_VAL_LAST_WAVEFORM_HANDLE = NIFGEN_VAL_FIRST_WAVEFORM_HANDLE + Int32(999)
const NIFGEN_VAL_NO_WAVEFORM = -(Int32(1))
const NIFGEN_VAL_FIRST_SEQUENCE_HANDLE = Int32(100000)
const NIFGEN_VAL_LAST_SEQUENCE_HANDLE = NIFGEN_VAL_FIRST_SEQUENCE_HANDLE + Int32(9999)
const NIFGEN_VAL_NO_SEQUENCE = -(Int32(1))
const NIFGEN_VAL_FIRST_FREQ_LIST_HANDLE = Int32(200000)
const NIFGEN_VAL_LAST_FREQ_LIST_HANDLE = NIFGEN_VAL_FIRST_FREQ_LIST_HANDLE + Int32(9999)
const NIFGEN_VAL_NO_FREQ_LIST = -(Int32(1))
const NIFGEN_VAL_ALL_WAVEFORMS = IVIFGEN_VAL_ALL_WAVEFORMS
const NIFGEN_VAL_ALL_SEQUENCES = IVIFGEN_VAL_ALL_SEQUENCES
const NIFGEN_VAL_ALL_FLISTS = -(Int32(1))
const NIFGEN_VAL_GENERATE_CONTINUOUS = -(Int32(1))
const NIFGEN_VAL_SINGLE_ENDED = Int32(300)
const NIFGEN_VAL_DIFFERENTIAL = Int32(301)
const NIFGEN_VAL_MARKER_EVENT = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(1)
const NIFGEN_VAL_SYNC_OUT = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(2)
const NIFGEN_VAL_ONBOARD_REFERENCE_CLOCK = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(19)
const NIFGEN_VAL_START_TRIGGER = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(4)
const NIFGEN_VAL_SAMPLE_CLOCK_TIMEBASE = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(6)
const NIFGEN_VAL_SYNCHRONIZATION = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(7)
const NIFGEN_VAL_SAMPLE_CLOCK = Int32(101)
const NIFGEN_VAL_REFERENCE_CLOCK = Int32(102)
const NIFGEN_VAL_SCRIPT_TRIGGER = Int32(103)
const NIFGEN_VAL_READY_FOR_START_EVENT = Int32(105)
const NIFGEN_VAL_STARTED_EVENT = Int32(106)
const NIFGEN_VAL_DONE_EVENT = Int32(107)
const NIFGEN_VAL_DATA_MARKER_EVENT = Int32(108)
const NIFGEN_VAL_NONE = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(0)
const NIFGEN_VAL_MARKER = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(1)
const NIFGEN_VAL_OUT_START_TRIGGER = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(4)
const NIFGEN_VAL_BOARD_CLOCK = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(6)
const NIFGEN_VAL_REF_OUT = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(8)
const NIFGEN_VAL_CLOCK_OUT = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(9)
const NIFGEN_VAL_RTSI_7 = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(10)
const NIFGEN_VAL_PFI_0 = IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE + Int32(11)
const NIFGEN_VAL_RISING_EDGE = Int32(101)
const NIFGEN_VAL_FALLING_EDGE = Int32(102)
const NIFGEN_VAL_HIGH = Int32(101)
const NIFGEN_VAL_LOW = Int32(102)
const NIFGEN_VAL_ACTIVE_HIGH = Int32(101)
const NIFGEN_VAL_ACTIVE_LOW = Int32(102)
const NIFGEN_VAL_PULSE = Int32(101)
const NIFGEN_VAL_LEVEL = Int32(102)
const NIFGEN_VAL_TOGGLE = Int32(103)
const NIFGEN_VAL_SAMPLE_CLOCK_PERIODS = Int32(101)
const NIFGEN_VAL_SECONDS = Int32(102)
const NIFGEN_VAL_TRIG_NONE = Int32(101)
const NIFGEN_VAL_DIGITAL_EDGE = Int32(102)
const NIFGEN_VAL_DIGITAL_LEVEL = Int32(103)
const NIFGEN_VAL_SOFTWARE_EDGE = Int32(104)
const NIFGEN_VAL_SOFTWARE_LEVEL = Int32(105)
const NIFGEN_VAL_P2P_ENDPOINT_FULLNESS = Int32(106)
const NIFGEN_VAL_SINGLE = Int32(1)
const NIFGEN_VAL_CONTINUOUS = Int32(2)
const NIFGEN_VAL_STEPPED = Int32(3)
const NIFGEN_VAL_BURST = Int32(4)
const NIFGEN_VAL_EXTERNAL_SAMPLE_RATE = -1.0
const NIFGEN_VAL_HIGH_RESOLUTION = Int32(0)
const NIFGEN_VAL_DIVIDE_DOWN = Int32(1)
const NIFGEN_VAL_AUTOMATIC = Int32(2)
const NIFGEN_VAL_HOLD_LAST_VALUE = Int32(400)
const NIFGEN_VAL_JUMP_TO_VALUE = Int32(401)
const NIFGEN_VAL_INFINITE_LOOP = Int32(0)
const NIFGEN_VAL_WHOLE_BUFFER = Int32(0)
const NIFGEN_VAL_NO_MARKER = -(Int32(1))
const NIFGEN_VAL_MARKER_QUANTUM = Int32(8)
const NIFGEN_VAL_BUS_INVALID = Int32(0)
const NIFGEN_VAL_BUS_AT = Int32(1)
const NIFGEN_VAL_BUS_PCI = Int32(2)
const NIFGEN_VAL_BUS_PXI = Int32(3)
const NIFGEN_VAL_BUS_VXI = Int32(4)
const NIFGEN_VAL_BUS_PCMCIA = Int32(5)
const NIFGEN_VAL_BUS_PXIE = Int32(6)
const NIFGEN_VAL_PAL_B = Int32(0)
const NIFGEN_VAL_PAL_D = Int32(1)
const NIFGEN_VAL_PAL_G = Int32(2)
const NIFGEN_VAL_PAL_H = Int32(3)
const NIFGEN_VAL_PAL_I = Int32(4)
const NIFGEN_VAL_PAL_M = Int32(5)
const NIFGEN_VAL_PAL_N = Int32(6)
const NIFGEN_VAL_NTSC_M = Int32(7)
const NIFGEN_VAL_WAVEFORM_POSITION_START = Int32(0)
const NIFGEN_VAL_WAVEFORM_POSITION_CURRENT = Int32(1)
const NIFGEN_VAL_MAIN_ANALOG_PATH = Int32(0)
const NIFGEN_VAL_DIRECT_ANALOG_PATH = Int32(1)
const NIFGEN_VAL_FIXED_LOW_GAIN_ANALOG_PATH = Int32(2)
const NIFGEN_VAL_FIXED_HIGH_GAIN_ANALOG_PATH = Int32(3)
const NIFGEN_VAL_ANALOG_OUTPUT = Int32(0)
const NIFGEN_VAL_INTERNAL_VOLTAGE_REFERENCE = Int32(1)
const NIFGEN_VAL_GROUND = Int32(2)
const NIFGEN_VAL_ANALOG_OUTPUT_DIFFERENTIAL = Int32(3)
const NIFGEN_VAL_ANALOG_OUTPUT_PLUS = Int32(4)
const NIFGEN_VAL_ANALOG_OUTPUT_MINUS = Int32(5)
const NIFGEN_VAL_EXT_CAL_ABORT = Int32(0)
const NIFGEN_VAL_EXT_CAL_COMMIT = Int32(1)
const NIFGEN_VAL_IDLE = Int32(0)
const NIFGEN_VAL_WAITING_FOR_START_TRIGGER = Int32(100)
const NIFGEN_VAL_RUNNING = Int32(200)
const NIFGEN_VAL_DONE = Int32(600)
const NIFGEN_VAL_HARDWARE_ERROR = Int32(1000)
const NIFGEN_VAL_LITTLE_ENDIAN = Int32(0)
const NIFGEN_VAL_BIG_ENDIAN = Int32(1)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_OFF_0DB = Int32(0)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_OFF_3DB = Int32(1)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_OFF_6DB = Int32(2)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_OFF_9DB = Int32(3)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_OFF_12DB = Int32(4)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_ON_0DB = Int32(5)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_ON_3DB = Int32(6)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_ON_6DB = Int32(7)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_ON_9DB = Int32(8)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_FILTER_ON_12DB = Int32(9)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_0DB = Int32(0)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_12DB = Int32(1)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_24DB = Int32(2)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_36DB = Int32(3)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_0DB = Int32(4)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_12DB = Int32(5)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_24DB = Int32(6)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_36DB = Int32(7)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_0DB_50OHMS = Int32(0)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_0DB_75OHMS = Int32(1)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_12DB_50OHMS = Int32(2)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_12DB_75OHMS = Int32(3)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_24DB_50OHMS = Int32(4)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_24DB_75OHMS = Int32(5)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_36DB_50OHMS = Int32(6)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_LOW_GAIN_36DB_75OHMS = Int32(7)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_0DB_50OHMS = Int32(8)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_0DB_75OHMS = Int32(9)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_12DB_50OHMS = Int32(10)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_12DB_75OHMS = Int32(11)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_24DB_50OHMS = Int32(12)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_24DB_75OHMS = Int32(13)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_36DB_50OHMS = Int32(14)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_HIGH_GAIN_36DB_75OHMS = Int32(15)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_DIFFERENTIAL = Int32(16)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_RSE = Int32(17)
const NIFGEN_VAL_CAL_CONFIG_DIRECT_PATH_50OHMS = Int32(0)
const NIFGEN_VAL_CAL_CONFIG_DIRECT_PATH_75OHMS = Int32(1)
const NIFGEN_VAL_CAL_CONFIG_DIRECT_PATH_DIFFERENTIAL = Int32(2)
const NIFGEN_VAL_CAL_CONFIG_GLOBAL = -(Int32(1))
const NIFGEN_VAL_CAL_CONFIG_LOW_GAIN_PATH_PRE_AMP_0DB = Int32(0)
const NIFGEN_VAL_CAL_CONFIG_LOW_GAIN_PATH_PRE_AMP_3DB = Int32(1)
const NIFGEN_VAL_CAL_CONFIG_LOW_GAIN_PATH_PRE_AMP_6DB = Int32(2)
const NIFGEN_VAL_CAL_CONFIG_LOW_GAIN_PATH_PRE_AMP_9DB = Int32(3)
const NIFGEN_VAL_CAL_CONFIG_LOW_GAIN_PATH_PRE_AMP_12DB = Int32(4)
const NIFGEN_VAL_CAL_CONFIG_HIGH_GAIN_PATH_PRE_AMP_0DB = Int32(5)
const NIFGEN_VAL_CAL_CONFIG_HIGH_GAIN_PATH_PRE_AMP_3DB = Int32(6)
const NIFGEN_VAL_CAL_CONFIG_HIGH_GAIN_PATH_PRE_AMP_6DB = Int32(7)
const NIFGEN_VAL_CAL_CONFIG_HIGH_GAIN_PATH_PRE_AMP_9DB = Int32(8)
const NIFGEN_VAL_CAL_CONFIG_HIGH_GAIN_PATH_PRE_AMP_12DB = Int32(9)
const NIFGEN_VAL_CAL_CONFIG_DIRECT_PATH = Int32(10)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH = Int32(11)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_0DB = Int32(12)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_9DB = Int32(13)
const NIFGEN_VAL_CAL_CONFIG_MAIN_PATH_33DB = Int32(14)
const NIFGEN_VAL_OSP_REAL = Int32(0)
const NIFGEN_VAL_OSP_COMPLEX = Int32(1)
const NIFGEN_VAL_OSP_IF = Int32(0)
const NIFGEN_VAL_OSP_BASEBAND = Int32(1)
const NIFGEN_VAL_OSP_FLAT = Int32(0)
const NIFGEN_VAL_OSP_RAISED_COSINE = Int32(1)
const NIFGEN_VAL_OSP_ROOT_RAISED_COSINE = Int32(2)
const NIFGEN_VAL_OSP_GAUSSIAN = Int32(3)
const NIFGEN_VAL_OSP_CUSTOM = Int32(4)
const NIFGEN_VAL_ERROR_REPORTING_ERROR = Int32(0)
const NIFGEN_VAL_ERROR_REPORTING_DISABLED = Int32(2)
const NIFGEN_VAL_OSP_OVERFLOW_NONE = Int32(0)
const NIFGEN_VAL_OSP_OVERFLOW_PRE_FILTER_GAIN_I = Int32(1)
const NIFGEN_VAL_OSP_OVERFLOW_PRE_FILTER_GAIN_Q = Int32(2)
const NIFGEN_VAL_OSP_OVERFLOW_PRE_FILTER_OFFSET_I = Int32(4)
const NIFGEN_VAL_OSP_OVERFLOW_PRE_FILTER_OFFSET_Q = Int32(8)
const NIFGEN_VAL_OSP_OVERFLOW_FIR_FILTER_I = Int32(16)
const NIFGEN_VAL_OSP_OVERFLOW_PFIR_FILTER_I = Int32(16)
const NIFGEN_VAL_OSP_OVERFLOW_FIR_FILTER_Q = Int32(32)
const NIFGEN_VAL_OSP_OVERFLOW_PFIR_FILTER_Q = Int32(32)
const NIFGEN_VAL_OSP_OVERFLOW_CIC_FILTER_I = Int32(64)
const NIFGEN_VAL_OSP_OVERFLOW_CIC_FILTER_Q = Int32(128)
const NIFGEN_VAL_OSP_OVERFLOW_COMPLEX_DATA = Int32(256)
const NIFGEN_VAL_OSP_OVERFLOW_CFIR_FILTER_I = Int32(512)
const NIFGEN_VAL_OSP_OVERFLOW_CFIR_FILTER_Q = Int32(1024)
const NIFGEN_VAL_OSP_OVERFLOW_EQUALIZER = Int32(2048)
const NIFGEN_VAL_ADDR_PHYSICAL = Int32(0)
const NIFGEN_VAL_ADDR_VIRTUAL = Int32(1)
const NIFGEN_ERROR_TRIGGER_NOT_SOFTWARE = IVIFGEN_ERROR_TRIGGER_NOT_SOFTWARE
const NIFGEN_ERROR_NOT_CONFIGURABLE = 0xbffa2001
const NIFGEN_ERROR_NOT_GENERATING = 0xbffa2002
const NIFGEN_ERROR_INVALID_MODE = 0xbffa2003
const NIFGEN_ERROR_NO_WFMS_AVAILABLE = IVIFGEN_ERROR_NO_WFMS_AVAILABLE
const NIFGEN_ERROR_INVALID_WFM_LENGTH = 0xbffa2005
const NIFGEN_ERROR_INVALID_WFM_ELEMENT = 0xbffa2006
const NIFGEN_ERROR_INVALID_WAVEFORM = 0xbffa2007
const NIFGEN_ERROR_WFM_IN_USE = IVIFGEN_ERROR_WFM_IN_USE
const NIFGEN_ERROR_NO_SEQS_AVAILABLE = IVIFGEN_ERROR_NO_SEQS_AVAILABLE
const NIFGEN_ERROR_INVALID_SEQ_LENGTH = 0xbffa200a
const NIFGEN_ERROR_INVALID_LOOP_COUNT = 0xbffa200b
const NIFGEN_ERROR_INVALID_SEQUENCE = 0xbffa200c
const NIFGEN_ERROR_SEQ_IN_USE = IVIFGEN_ERROR_SEQ_IN_USE
const NIFGEN_ERROR_INVALID_SESSION = 0xbffa1190
const NIFGEN_ERROR_DAQ_PARAMETER_CHANGE = IVI_SPECIFIC_ERROR_BASE + Int32(1)
const NIFGEN_ERROR_DAQ_GROUP_CONTROL = IVI_SPECIFIC_ERROR_BASE + Int32(2)
const NIFGEN_ERROR_DAQ_SELECT_SIGNAL = IVI_SPECIFIC_ERROR_BASE + Int32(3)
const NIFGEN_ERROR_DAQ_GROUP_SETUP = IVI_SPECIFIC_ERROR_BASE + Int32(4)
const NIFGEN_ERROR_DAQ_CONFIGURE = IVI_SPECIFIC_ERROR_BASE + Int32(5)
const NIFGEN_ERROR_DAQ_INIT_BOARD = IVI_SPECIFIC_ERROR_BASE + Int32(6)
const NIFGEN_ERROR_DAQ_WFM_LOAD = IVI_SPECIFIC_ERROR_BASE + Int32(7)
const NIFGEN_ERROR_DAQ_GET_ATTRIBUTE = IVI_SPECIFIC_ERROR_BASE + Int32(8)
const NIFGEN_ERROR_INVALID_FREQ_LIST = IVI_SPECIFIC_ERROR_BASE + Int32(9)
const NIFGEN_ERROR_NO_FREQ_LISTS_AVAILABLE = IVI_SPECIFIC_ERROR_BASE + Int32(10)
const NIFGEN_ERROR_INVALID_FREQ_LIST_LENGTH = IVI_SPECIFIC_ERROR_BASE + Int32(11)
const NIFGEN_ERROR_DAQ_CLOCK_RATE = IVI_SPECIFIC_ERROR_BASE + Int32(12)
const NIFGEN_ERROR_INVALID_SAMPLE_COUNT = IVI_SPECIFIC_ERROR_BASE + Int32(13)
const NIFGEN_ERROR_INVALID_MARKER = IVI_SPECIFIC_ERROR_BASE + Int32(14)
const NIFGEN_ERROR_INVALID_FREQUENCY = IVI_SPECIFIC_ERROR_BASE + Int32(15)
const NIFGEN_ERROR_INVALID_DURATION = IVI_SPECIFIC_ERROR_BASE + Int32(16)
const NIFGEN_ERROR_DAQ_SET_CLOCK = IVI_SPECIFIC_ERROR_BASE + Int32(17)
const NIFGEN_ERROR_DAQ_DEVICE_INFO = IVI_SPECIFIC_ERROR_BASE + Int32(18)
const NIFGEN_ERROR_MAX_TIME_EXCEEDED = IVI_SPECIFIC_ERROR_BASE + Int32(19)
const NIFGEN_ERROR_NO_WFMS_EXIST = IVI_SPECIFIC_ERROR_BASE + Int32(20)
const NIFGEN_ERROR_NO_SEQS_EXIST = IVI_SPECIFIC_ERROR_BASE + Int32(21)
const NIFGEN_ERROR_NO_WFM_SPECIFIED = IVI_SPECIFIC_ERROR_BASE + Int32(22)
const NIFGEN_ERROR_NO_SEQ_SPECIFIED = IVI_SPECIFIC_ERROR_BASE + Int32(23)
const NIFGEN_ERROR_INVALID_DURING_SIMULATION = IVI_SPECIFIC_ERROR_BASE + Int32(24)
const NIFGEN_ERROR_CAL_ADC_OVER_RANGE = IVI_SPECIFIC_ERROR_BASE + Int32(25)
const NIFGEN_ERROR_CAL_ADC_UNDER_RANGE = IVI_SPECIFIC_ERROR_BASE + Int32(26)
const NIFGEN_ERROR_HWS_ERROR = IVI_SPECIFIC_ERROR_BASE + Int32(27)
const NIFGEN_ERROR_INSTRUMENT_ALREADY_IN_USE = IVI_SPECIFIC_ERROR_BASE + Int32(28)
const NIFGEN_ERROR_SAMPLE_RATE_INVALID_FOR_INTERPOLATION = IVI_SPECIFIC_ERROR_BASE + Int32(29)
const NIFGEN_ERROR_CODE_LAST = IVI_SPECIFIC_ERROR_BASE + Int32(100)
const NIFGEN_WARN_CODE_BASE = IVI_SPECIFIC_WARN_BASE + Int32(0)

struct NIComplexNumber_struct
    real::Cint
    imaginary::Cint
end

const NIComplexNumber = NIComplexNumber_struct

struct NIComplexI16_struct
    real::Cint
    imaginary::Cint
end

const NIComplexI16 = NIComplexI16_struct


text:
function Service(session::Session, service_name::AbstractString)
    service_name = service_name_str(service_name)
    check_service_is_open(session, service_name)
    service_handle_ref = Ref{Ptr{Cvoid}}(C_NULL)
    err = blpapi_Session_getService(session.handle, service_handle_ref, service_name)
    error_check(err, "Failed to get service $service_name.")
    service = Service(service_handle_ref[], String(service_name), session)
    @assert unsafe_string(blpapi_Service_name(service.handle)) == String(service_name)
    return service
end

get_num_operations(service::Service) = Int(blpapi_Service_numOperations(service.handle))

function _get_operation_handle(service::Service, index::Integer) :: Ptr{Cvoid}
    operation_handle_ref = Ref{Ptr{Cvoid}}(C_NULL)
    err = blpapi_Service_getOperationAt(service.handle, operation_handle_ref, index - 1)
    error_check(err, "Failed to get operation at index $index for service $(service.name).")
    return operation_handle_ref[]
end

# 1 <= index <= get_num_operations(service)
function get_operation(service::Service, index::Integer) :: Operation
    return Operation(_get_operation_handle(service, index))
end

function get_operation(service::Service, name::AbstractString) :: Operation
    operation_handle_ref = Ref{Ptr{Cvoid}}(C_NULL)
    err = blpapi_Service_getOperation(service.handle, operation_handle_ref, name, C_NULL)
    error_check(err, "Failed to get operation $name from $(service.name).")
    return Operation(operation_handle_ref[])
end

function has_operation(service::Service, name::AbstractString) :: Bool
    operation_handle_ref = Ref{Ptr{Cvoid}}(C_NULL)
    err = blpapi_Service_getOperation(service.handle, operation_handle_ref, name, C_NULL)
    return err == 0
end

"""
    list_operation_names(service::Service) :: Vector{String}

List operation names available for `service`.
"""
function list_operation_names(service::Service) :: Vector{String}
    num_operations = get_num_operations(service)

    if num_operations == 0
        return Vector{String}()
    else
        operation_names = Vector{String}(undef, num_operations)

        for i in 1:num_operations
            op_handle = _get_operation_handle(service, i)
            ptr_check(op_handle)
            operation_names[i] = unsafe_string(blpapi_Operation_name(op_handle))
        end

        return operation_names
    end
end

function Operation(op_handle::Ptr{Cvoid})

    ptr_check(op_handle, "Failed to create Operation")

    function _request_definition(op_handle::Ptr{Cvoid})
        request_definition_handle_ref = Ref{Ptr{Cvoid}}(C_NULL)
        err = blpapi_Operation_requestDefinition(op_handle, request_definition_handle_ref)
        error_check(err, "Failed to get request definition from operation $(unsafe_string(blpapi_Operation_name(op_handle))).")
        return SchemaElementDefinition(request_definition_handle_ref[])
    end

    function _response_definitions(op_handle::Ptr{Cvoid}) :: Vector{AbstractSchemaElementDefinition}
        num_response_definitions = blpapi_Operation_numResponseDefinitions(op_handle)

        if num_response_definitions == 0
            return Vector{AbstractSchemaElementDefinition}()
        else
            @assert num_response_definitions > 0 "Failed to get response definitions from operation $(unsafe_string(blpapi_Operation_name(op_handle)))."
            defs = Vector{AbstractSchemaElementDefinition}(undef, num_response_definitions)

            for i in 1:num_response_definitions
                el_def_handle_ref = Ref{Ptr{Cvoid}}(C_NULL)
                err = blpapi_Operation_responseDefinition(op_handle, el_def_handle_ref, i-1)
                error_check(err, "Failed to get response definition $i from operation $(unsafe_string(blpapi_Operation_name(op_handle)))")
                defs[i] = SchemaElementDefinition(el_def_handle_ref[])
            end

            return defs
        end
    end

    return Operation(
            unsafe_string(blpapi_Operation_name(op_handle)),
            _request_definition(op_handle),
            _response_definitions(op_handle)
        )
end

Base.getindex(service::Service, operation_name::AbstractString) = get_operation(service, operation_name)

max_stars_repo_licenses: OpenSSL MIT

max_issues_repo_licenses: OpenSSL MIT

max_forks_repo_licenses: OpenSSL MIT


text:
module LowRankIntegrators
using Reexport, UnPack
import DifferentialEquations: step!, set_u!, init

@reexport using LinearAlgebra, DifferentialEquations, LowRankArithmetic

include("utils.jl")
export orthonormalize!, GradientDescent, QR, SVD, SecondMomentMatching, normal_component

include("primitives.jl")
export MatrixDEProblem, MatrixDataProblem, MatrixHybridProblem
       DLRIntegrator, DLRSolution,
       solve

include("integrators.jl")
export ProjectorSplitting, PrimalLieTrotter, DualLieTrotter, Strang,
       UnconventionalAlgorithm,
       RankAdaptiveUnconventionalAlgorithm,
       DOAlgorithm, DirectTimeMarching,
       RankAdaptiveUnconventionalAlgorithm,
       GreedyIntegrator,
       step!, init
end


text:
####
#### Numerical methods for simulating Hamiltonian trajectory.
####

# TODO: The type `<:Tuple{Integer,Bool}` is introduced to address
# https://github.com/TuringLang/Turing.jl/pull/941#issuecomment-549191813
# We might want to simplify it to `Tuple{Int,Bool}` when we figured out
# why the it behaves unexpected on Windos 32.

"""
$(TYPEDEF)

Represents an integrator used to simulate the Hamiltonian system.

# Implementation
A `AbstractIntegrator` is expected to have the following implementations:
- `stat`(@ref)
- `nom_step_size`(@ref)
- `step_size`(@ref)
"""
abstract type AbstractIntegrator end

stat(::AbstractIntegrator) = NamedTuple()

"""
    nom_step_size(::AbstractIntegrator)

Get the nominal integration step size. The current integration step size may
differ from this, for example if the step size is jittered. Nominal step size is
usually used in adaptation.
"""
nom_step_size(i::AbstractIntegrator) = step_size(i)

"""
    step_size(::AbstractIntegrator)

Get the current integration step size.
"""
function step_size end

"""
    update_nom_step_size(i::AbstractIntegrator, ϵ) -> AbstractIntegrator

Return a copy of the integrator `i` with the new nominal step size ([`nom_step_size`](@ref))
`ϵ`.
"""
function update_nom_step_size end

abstract type AbstractLeapfrog{T} <: AbstractIntegrator end

step_size(lf::AbstractLeapfrog) = lf.ϵ
jitter(::Union{AbstractRNG, AbstractVector{<:AbstractRNG}}, lf::AbstractLeapfrog) = lf
temper(lf::AbstractLeapfrog, r, ::NamedTuple{(:i, :is_half),<:Tuple{Integer,Bool}}, ::Int) = r
stat(lf::AbstractLeapfrog) = (step_size=step_size(lf), nom_step_size=nom_step_size(lf))

update_nom_step_size(lf::AbstractLeapfrog, ϵ) = @set lf.ϵ = ϵ

function step(
    lf::AbstractLeapfrog{T},
    h::Hamiltonian,
    z::P,
    n_steps::Int=1;
    fwd::Bool=n_steps > 0,  # simulate hamiltonian backward when n_steps < 0
    full_trajectory::Val{FullTraj} = Val(false)
) where {T<:AbstractScalarOrVec{<:AbstractFloat}, P<:PhasePoint, FullTraj}
    n_steps = abs(n_steps)  # to support `n_steps < 0` cases

    ϵ = fwd ? step_size(lf) : -step_size(lf)
    ϵ = ϵ'

    res = if FullTraj
        Vector{P}(undef, n_steps)
    else
        z
    end

    @unpack θ, r = z
    @unpack value, gradient = z.ℓπ
    for i = 1:n_steps
        # Tempering
        r = temper(lf, r, (i=i, is_half=true), n_steps)
        # Take a half leapfrog step for momentum variable
        r = r - ϵ / 2 .* gradient
        # Take a full leapfrog step for position variable
        ∇r = ∂H∂r(h, r)
        θ = θ + ϵ .* ∇r
        # Take a half leapfrog step for momentum variable
        @unpack value, gradient = ∂H∂θ(h, θ)
        r = r - ϵ / 2 .* gradient
        # Tempering
        r = temper(lf, r, (i=i, is_half=false), n_steps)
        # Create a new phase point by caching the logdensity and gradient
        z = phasepoint(h, θ, r; ℓπ=DualValue(value, gradient))
        # Update result
        if FullTraj
            res[i] = z
        else
            res = z
        end
        if !isfinite(z)
            # Remove undef
            if FullTraj
                res = res[isassigned.(Ref(res), 1:n_steps)]
            end
            break
        end
    end
    return res
end

"""
$(TYPEDEF)

Leapfrog integrator with fixed step size `ϵ`.

# Fields

$(TYPEDFIELDS)
"""
struct Leapfrog{T<:AbstractScalarOrVec{<:AbstractFloat}} <: AbstractLeapfrog{T}
    "Step size."
    ϵ       ::  T
end
Base.show(io::IO, l::Leapfrog) = print(io, "Leapfrog(ϵ=$(round.(l.ϵ; sigdigits=3)))")

### Jittering

"""
$(TYPEDEF)

Leapfrog integrator with randomly "jittered" step size `ϵ` for every trajectory.

# Fields

$(TYPEDFIELDS)

# Description
This is the same as `LeapFrog`(@ref) but with a "jittered" step size. This means
that at the beginning of each trajectory we sample a step size `ϵ` by adding or
subtracting from the nominal/base step size `ϵ0` some random proportion of `ϵ0`,
with the proportion specified by `jitter`, i.e. `ϵ = ϵ0 - jitter * ϵ0 * rand()`.
p
Jittering might help alleviate issues related to poor interactions with a fixed step size:
- In regions with high "curvature" the current choice of step size might mean over-shoot
  leading to almost all steps being rejected. Randomly sampling the step size at the
  beginning of the trajectories can therefore increase the probability of escaping such
  high-curvature regions.
- Exact periodicity of the simulated trajectories might occur, i.e. you might be so
  unlucky as to simulate the trajectory forwards in time `L ϵ` and ending up at the
  same point (which results in non-ergodicity; see Section 3.2 in [1]). If momentum
  is refreshed before each trajectory, then this should not happen *exactly* but it
  can still be an issue in practice. Randomly choosing the step-size `ϵ` might help
  alleviate such problems.

# References
1. Neal, R. M. (2011). MCMC using Hamiltonian dynamics. Handbook of Markov chain Monte Carlo, 2(11), 2. ([arXiv](https://arxiv.org/pdf/1206.1901))
"""
struct JitteredLeapfrog{FT<:AbstractFloat,T<:AbstractScalarOrVec{FT}} <: AbstractLeapfrog{T}
    "Nominal (non-jittered) step size."
    ϵ0      ::  T
    "The proportion of the nominal step size `ϵ0` that may be added or subtracted."
    jitter  ::  FT
    "Current (jittered) step size."
    ϵ       ::  T
end

JitteredLeapfrog(ϵ0, jitter) = JitteredLeapfrog(ϵ0, jitter, ϵ0)

function Base.show(io::IO, l::JitteredLeapfrog)
    print(io, "JitteredLeapfrog(ϵ0=$(round.(l.ϵ0; sigdigits=3)), jitter=$(round.(l.jitter; sigdigits=3)), ϵ=$(round.(l.ϵ; sigdigits=3)))")
end

nom_step_size(lf::JitteredLeapfrog) = lf.ϵ0

update_nom_step_size(lf::JitteredLeapfrog, ϵ0) = @set lf.ϵ0 = ϵ0

# Jitter step size; ref: https://github.com/stan-dev/stan/blob/1bb054027b01326e66ec610e95ef9b2a60aa6bec/src/stan/mcmc/hmc/base_hmc.hpp#L177-L178
function _jitter(
    rng::Union{AbstractRNG, AbstractVector{<:AbstractRNG}},
    lf::JitteredLeapfrog{FT,T}
) where {FT<:AbstractFloat,T<:AbstractScalarOrVec{FT}}
    ϵ = lf.ϵ0 .* (1 .+ lf.jitter .* (2 .* rand(rng) .- 1))
    return @set lf.ϵ = ϵ
end

jitter(rng::AbstractRNG, lf::JitteredLeapfrog) = _jitter(rng, lf)

jitter(
    rng::AbstractVector{<:AbstractRNG},
    lf::JitteredLeapfrog{FT,T}
) where {FT<:AbstractFloat,T<:AbstractScalarOrVec{FT}} = _jitter(rng, lf)

### Tempering
# TODO: add ref or at least explain what exactly we're doing
"""
$(TYPEDEF)

Tempered leapfrog integrator with fixed step size `ϵ` and "temperature" `α`.

# Fields

$(TYPEDFIELDS)

# Description

Tempering can potentially allow greater exploration of the posterior, e.g.
in a multi-modal posterior jumps between the modes can be more likely to occur.
"""
struct TemperedLeapfrog{FT<:AbstractFloat,T<:AbstractScalarOrVec{FT}} <: AbstractLeapfrog{T}
    "Step size."
    ϵ       ::  T
    "Temperature parameter."
    α       ::  FT
end

function Base.show(io::IO, l::TemperedLeapfrog)
    print(io, "TemperedLeapfrog(ϵ=$(round.(l.ϵ; sigdigits=3)), α=$(round.(l.α; sigdigits=3)))")
end

"""
    temper(lf::TemperedLeapfrog, r, step::NamedTuple{(:i, :is_half),<:Tuple{Integer,Bool}}, n_steps::Int)

Tempering step. `step` is a named tuple with
- `i` being the current leapfrog iteration and
- `is_half` indicating whether or not it's (the first) half momentum/tempering step
"""
function temper(lf::TemperedLeapfrog, r, step::NamedTuple{(:i, :is_half),<:Tuple{Integer,Bool}}, n_steps::Int)
    if step.i > n_steps
        throw(BoundsError("Current leapfrog iteration exceeds the total number of steps."))
    end
    i_temper = 2(step.i - 1) + 1 + !step.is_half    # counter for half temper steps
    return i_temper <= n_steps ? r * sqrt(lf.α) : r / sqrt(lf.α)
end