text:
const Tup = Union{Tuple, NamedTuple}
const EmptyTup = Union{Tuple{}, NamedTuple{(), Tuple{}}}

"""
    StructArrays.staticschema(T)

The default schema for an element type `T`. A schema is a `Tuple` or
`NamedTuple` type containing the necessary fields to construct `T`. By default,
this will have fields with the same names and types as `T`.

This can be overloaded for custom types if required, in which case
[`StructArrays.createinstance`](@ref) should also be defined.

```julia-repl
julia> StructArrays.staticschema(Complex{Float64})
NamedTuple{(:re, :im),Tuple{Float64,Float64}}
```
"""
@generated function staticschema(::Type{T}) where {T}
    name_tuple = Expr(:tuple, [QuoteNode(f) for f in fieldnames(T)]...)
    type_tuple = Expr(:curly, :Tuple, [Expr(:call, :fieldtype, :T, i) for i in 1:fieldcount(T)]...)
    Expr(:curly, :NamedTuple, name_tuple, type_tuple)
end

staticschema(::Type{T}) where {T<:Tup} = T

"""
    StructArrays.createinstance(T, args...)

Construct an instance of type `T` from its backing representation. `args` here
are the elements of the `Tuple` or `NamedTuple` type specified
[`staticschema(T)`](@ref).

```julia-repl
julia> StructArrays.createinstance(Complex{Float64}, (re=1.0, im=2.0)...)
1.0 + 2.0im
```
"""
function createinstance(::Type{T}, args...) where {T}
    isconcretetype(T) ? bypass_constructor(T, args) : T(args...)
end

createinstance(::Type{T}, args...) where {T<:Tup} = T(args)


text:
export iscreditcard

function iscreditcard(str::AbstractString)::Bool
    creditCardReg = r"^(?:4[0-9]{12}(?:[0-9]{3,6})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12,15}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14}|^(81[0-9]{14,17}))$"

    sanitized = replace(str, r"[- ]+" => "")
    if !contains(sanitized, creditCardReg)
        return false
    end

    sum = 0
    shouldDouble = false
    for i in reverse(1:length(sanitized))
        digit = parse(Int8, sanitized[i])
        if shouldDouble
            digit *= 2
            if digit > 9
                sum += ((digit % 10) + 1)
            else
                sum += digit
            end
        else
            sum += digit
        end

        shouldDouble = !shouldDouble
    end

    return (sum % 10) === 0 ? true : false
end

ext: jl


text:
function _f(a::String, offset::Int)
    x = split(a, "")
    y = circshift(x, offset)
    z = sum(parse.(Int, x[x .== y]))
    return z
end

function puzzle01(path::String=joinpath(@__DIR__, "..", "data/01.txt"))
    input = readline(normpath(path))
    solution = _f.(input, [1, Int(length(input)/2)])
    return solution
end


text:
using TuringModels

Turing.setadbackend(:reverse_diff)
#nbTuring.turnprogress(false);

d = CSV.read(joinpath(@__DIR__, "..", "..", "data", "chimpanzees.csv"), delim=';');
size(d) # Should be 504x8

# Turing model: pulled_left, actor, condition, prosoc_left

@model m12_4(pulled_left, actor, condition, prosoc_left) = begin
    # Total num of y
    N = length(pulled_left)
    # Separate σ priors for each actor
    σ_actor ~ Truncated(Cauchy(0, 1), 0, Inf)

    # Number of unique actors in the data set
    N_actor = length(unique(actor)) #7

    # Vector of actors (1,..,7) which we'll set priors on
    α_actor = Vector{Real}(undef, N_actor)

    # For each actor [1,..,7] set a prior N(0,σ_actor)
    α_actor ~ [Normal(0, σ_actor)]

    # Prior for intercept, prosoc_left, and the interaction
    α ~ Normal(0, 10)
    βp ~ Normal(0, 10)
    βpC ~ Normal(0, 10)

    logitp = [α + α_actor[actor[i]] +
            (βp + βpC * condition[i]) * prosoc_left[i]
            for i = 1:N]

    # Thanks to Kai Xu for suggesting ones(Int64, N)
    pulled_left ~ VecBinomialLogit(ones(Int64, N), logitp)

end

# Sample

chns = sample(m12_4(
    Vector{Int64}(d[:, :pulled_left]),
    Vector{Int64}(d[:, :actor]),
    Vector{Int64}(d[:, :condition]),
    Vector{Int64}(d[:, :prosoc_left])),
    Turing.NUTS(0.95), 1000);

# Results from rethinking

m124rethinking = "
             Mean StdDev lower 0.89 upper 0.89 n_eff Rhat
 a_actor[1]  -1.13   0.95      -2.62       0.27  2739    1
 a_actor[2]   4.17   1.66       1.80       6.39  3958    1
 a_actor[3]  -1.44   0.95      -2.90      -0.02  2720    1
 a_actor[4]  -1.44   0.94      -2.92      -0.04  2690    1
 a_actor[5]  -1.13   0.94      -2.58       0.31  2727    1
 a_actor[6]  -0.19   0.94      -1.64       1.25  2738    1
 a_actor[7]   1.34   0.97      -0.09       2.87  2889    1
 a            0.42   0.93      -1.00       1.81  2622    1
 bp           0.83   0.26       0.41       1.25  8594    1
 bpC         -0.13   0.30      -0.62       0.34  8403    1
 sigma_actor  2.26   0.94       1.07       3.46  4155    1
";

# Draw summary

describe(chns)

# End of `12/m12.4t.jl`


text:
# Seems like Metadata is not returned via XML in case of the REST API.
# type MetadataEntry
#     name::AbstractString
#     value::AbstractString
# end

const XMLNS_ATTR = "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
xml_hdr(name) = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><$(name) xmlns=\"http://doc.s3.amazonaws.com/2006-03-01\">"
xml_ftr(name) = "</$(name)>"

macro add_amz_hdr(name, value)
    quote
        if ($(esc(value)) != nothing) push!(hdrs, ("x-amz-" * $(esc(name)), string($(esc(value)))  )) end
    end
end

macro chk_n_add(name, value)
    quote
        if ($(esc(value)) != nothing) push!(arr, ($(esc(name)), string($(esc(value)))  )) end
    end
end

macro declare_utype(utype)
    quote
        type $(esc(utype))
            id::AbstractString
            displayName::Union{AbstractString, Void}
        end

        xml(o::$(esc(utype))) = xml($(string(utype)), [("ID", o.id), ("DisplayName", o.displayName)])
        function $(esc(utype))(pd)
            o = $(esc(utype))(LightXML.content(LightXML.find_element(pd, "ID")), LightXML.content(LightXML.find_element(pd, "DisplayName")))
        end
        $(esc(utype))(nothing::Void) = nothing
    end
end

@declare_utype Owner
@declare_utype Initiator
export Owner, Initiator

type GranteeEmail
    email::AbstractString
end
xml(o::GranteeEmail) = xml("Grantee", [("EmailAddress", o.email)], xmlns=$XMLNS_ATTR, xsi_type="AmazonCustomerByEmail")
export GranteeEmail

type GranteeURI
    uri::AbstractString
end
xml(o::GranteeURI) = xml("Grantee", [("URI", o.uri)], xmlns=$XMLNS_ATTR, xsi_type="Group")
export GranteeURI

type GranteeID
    id::AbstractString
    displayName::AbstractString
end
xml(o::GranteeID) = xml("Grantee", [("ID", o.id), ("DisplayName", o.displayName)], xmlns=$XMLNS_ATTR, xsi_type="CanonicalUser")
export GranteeID

type Grant
    grantee::Union{GranteeEmail, GranteeURI, GranteeID}
    permission::AbstractString
end
xml(o::Grant) = xml("Grant", [o.grantee, ("Permission", o.permission)])
# permission must be one of "READ", "WRITE", "READ_ACP", "WRITE_ACP" or "FULL_CONTROL"
function Grant(pd_g)
	## TODO
    grantee_pd = LightXML.find_element(pd_g, "Grantee[1]")
    grantee_type = grantee_pd.attr["xsi:type"]
    if grantee_type == "AmazonCustomerByEmail"
        grantee=GranteeEmail(LightXML.content(LightXML.find_element(grantee_pd, "EmailAddress")))
    elseif grantee_type == "CanonicalUser"
        grantee=GranteeID(LightXML.content(LightXML.find_element(grantee_pd, "ID")), LightXML.content(LightXML.find_element(grantee_pd, "DisplayName")))
    elseif grantee_type == "Group"
        grantee=GranteeURI(LightXML.content(LightXML.find_element(grantee_pd, "URI")))
    else
        error("Unknown grantee type")
    end

    permission = LightXML.content(LightXML.find_element(pd_g, "Permission"))
    Grant(grantee, permission)
end
export Grant

type BucketLoggingStatus
    loggingEnabled::Union{Bool, Void}
    targetBucket::Union{AbstractString, Void}
    targetPrefix::Union{AbstractString, Void}
    targetGrants::Union{Vector{Grant}, Void}
end

BucketLoggingStatus() = BucketLoggingStatus(false, nothing, nothing, nothing)
function BucketLoggingStatus(pd_bls)
    bls = BucketLoggingStatus()
    if length(pd_bls["LoggingEnabled"]) > 0
        bls.targetBucket = LightXML.content(LightXML.find_element(LightXML.find_element(pd_bls, "LoggingEnabled"), "TargetBucket"))
        bls.targetPrefix = LightXML.content(LightXML.find_element(LightXML.find_element(pd_bls, "LoggingEnabled"), "TargetPrefix"))

        ## grants = LightXML.find_element(pd_bls, "LoggingEnabled/TargetGrants/Grant")
        bls.targetGrants = AWS.@parse_vector(AWS.S3.Grant, LightXML.get_elements_by_tagname(LightXML.find_element(LightXML.find_element(pd_bls, "LoggingEnabled"), "TargetGrants"), "Grant"))
    end
    bls
end

function xml(o::BucketLoggingStatus)
    if (o.loggingEnabled)
        xml_hdr("BucketLoggingStatus") *
        xml("TargetBucket", o.targetBucket) *
        xml("TargetPrefix", o.targetPrefix) *
        xml("TargetGrants", o.targetGrants) *
        xml_ftr("BucketLoggingStatus")

    else
        xml_hdr("BucketLoggingStatus") * xml_ftr("BucketLoggingStatus")
    end
end
export BucketLoggingStatus

type AccessControlPolicy
    owner::Owner
    accessControlList::Vector{Grant}
end

function AccessControlPolicy(pd_acl)
    owner = Owner(LightXML.find_element(pd_acl, "Owner"))
    accessControlList = AWS.@parse_vector(AWS.S3.Grant, LightXML.get_elements_by_tagname(LightXML.find_element(pd_acl, "AccessControlList"), "Grant"))
    return AccessControlPolicy(owner, accessControlList)
end

function xml(o::AccessControlPolicy)
    xml_hdr("AccessControlPolicy") *
    xml("Owner", o.owner) *
    xml("AccessControlList", o.accessControlList) *
    xml_ftr("AccessControlPolicy")
end
export AccessControlPolicy
# Storage class must be one of "STANDARD", "REDUCED_REDUNDANCY", "GLACIER" or "UNKNOWN"

type CreateBucketConfiguration
    locationConstraint::Union{AbstractString, Void}
end
CreateBucketConfiguration(pd_cbc) = CreateBucketConfiguration(LightXML.content(LightXML.find_element(pd_cbc, "LocationConstraint")))
xml(o::CreateBucketConfiguration) = xml_hdr("CreateBucketConfiguration") *
                                    xml("LocationConstraint", o.locationConstraint) *
                                    xml_ftr("CreateBucketConfiguration")
export CreateBucketConfiguration

type Contents
    key::Union{AbstractString, Void}
    lastModified::DateTime
    eTag::Union{AbstractString, Void}
    size::Union{Int64, Void}
    owner::Union{Owner, Void}
    storageClass::Union{AbstractString, Void}
end
function Contents(pd_le)
    key = LightXML.content(LightXML.find_element(pd_le, "Key"))
    datestr = LightXML.content(LightXML.find_element(pd_le, "LastModified"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")
    etag = LightXML.content(LightXML.find_element(pd_le, "ETag"))
    size = AWS.safe_parseint64(LightXML.content(LightXML.find_element(pd_le, "Size")))
    owner=Owner(LightXML.find_element(pd_le, "Owner"))
    storageClass = LightXML.content(LightXML.find_element(pd_le, "StorageClass"))

    Contents(key, t, etag, size, owner, storageClass)
end
export Contents

type CommonPrefixes
    prefix::Union{AbstractString, Void}
end
CommonPrefixes(pd_cp) = CommonPrefixes(LightXML.content(LightXML.find_element(pd_cp, "Prefix")))
export CommonPrefixes

type ListBucketResult
    name::Union{AbstractString, Void}
    prefix::Union{AbstractString, Void}
    marker::Union{AbstractString, Void}
    nextMarker::Union{AbstractString, Void}
    maxKeys::Union{Int, Void}
    delimiter::Union{AbstractString, Void}
    isTruncated::Union{Bool, Void}
    contents::Vector{Contents}
    commonPrefixes::Vector{CommonPrefixes}

    ListBucketResult() = new(nothing,nothing,nothing,nothing,nothing,nothing,nothing,Contents[], CommonPrefixes[])
end

function ListBucketResult(pd_lbr)
    lbr = ListBucketResult()
    lbr.name = LightXML.content(LightXML.find_element(pd_lbr, "Name"))
    lbr.prefix = LightXML.content(LightXML.find_element(pd_lbr, "Prefix"))
    lbr.marker = LightXML.content(LightXML.find_element(pd_lbr, "Marker"))
    lbr.nextMarker = LightXML.find_element(pd_lbr, "NextMarker") != nothing ? LightXML.content(LightXML.find_element(pd_lbr, "NextMarker")) : ""
    lbr.maxKeys = AWS.safe_parseint(LightXML.content(LightXML.find_element(pd_lbr, "MaxKeys")))
    lbr.delimiter = LightXML.find_element(pd_lbr, "Delimiter") != nothing ?LightXML.content(LightXML.find_element(pd_lbr, "Delimiter")) : ""
    lbr.isTruncated = AWS.safe_parsebool(LightXML.content(LightXML.find_element(pd_lbr, "IsTruncated")))
    lbr.contents = AWS.@parse_vector(AWS.S3.Contents, LightXML.get_elements_by_tagname(pd_lbr, "Contents"))
    lbr.commonPrefixes = AWS.@parse_vector(AWS.S3.CommonPrefixes, LightXML.get_elements_by_tagname(pd_lbr, "CommonPrefixes"))
    lbr
end
export ListBucketResult

type Version
    key::Union{AbstractString, Void}
    versionId::Union{AbstractString, Void}
    isLatest::Union{Bool, Void}
    lastModified::DateTime
    eTag::Union{AbstractString, Void}
    size::Union{Int64, Void}
    owner::Union{Owner, Void}
    storageClass::Union{AbstractString, Void}
end
function Version(pd_v)
    key = LightXML.content(LightXML.find_element(pd_v, "Key"))
    versionId = LightXML.content(LightXML.find_element(pd_v, "VersionId"))
    isLatest = (lowercase(LightXML.content(LightXML.find_element(pd_v, "IsLatest"))) == "true") ? true : false
    datestr = LightXML.content(LightXML.find_element(pd_v, "LastModified"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")
    etag = LightXML.content(LightXML.find_element(pd_v, "ETag"))
    size = AWS.safe_parseint64(LightXML.content(LightXML.find_element(pd_v, "Size")))
    owner=Owner(LightXML.find_element(pd_v, "Owner"))
    storageClass = LightXML.content(LightXML.find_element(pd_v, "StorageClass"))

    Version(key, versionId, isLatest, t, etag, size, owner, storageClass)
end
export Version

type DeleteMarker
    key::Union{AbstractString, Void}
    versionId::Union{AbstractString, Void}
    isLatest::Union{Bool, Void}
    lastModified::DateTime
    owner::Union{Owner, Void}
end
function DeleteMarker(pd_dm)
    key = LightXML.content(LightXML.find_element(pd_dm, "Key"))
    versionId = LightXML.content(LightXML.find_element(pd_dm, "VersionId"))
    isLatest = (lowercase(LightXML.content(LightXML.find_element(pd_dm, "IsLatest"))) == "true") ? true : false
    datestr = LightXML.content(LightXML.find_element(pd_dm, "LastModified"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")
    owner=Owner(LightXML.find_element(pd_dm, "Owner"))
    DeleteMarker(key, versionId, isLatest, t, owner)
end
export DeleteMarker

type ListVersionsResult
    name::Union{AbstractString, Void}
    prefix::Union{AbstractString, Void}
    keyMarker::Union{AbstractString, Void}
    versionIdMarker::Union{AbstractString, Void}
    nextKeyMarker::Union{AbstractString, Void}
    nextVersionIdMarker::Union{AbstractString, Void}
    maxKeys::Union{Int, Void}
    delimiter::Union{AbstractString, Void}
    isTruncated::Union{Bool, Void}
    version::Union{Vector{Version}, Void}
    deleteMarker::Union{Vector{DeleteMarker}, Void}
    commonPrefixes::Union{Vector{CommonPrefixes}, Void}

    ListVersionsResult() = new()
end
function ListVersionsResult(pd_lvr)
    lvr = ListVersionsResult()
    lvr.name = LightXML.content(LightXML.find_element(pd_lvr, "Name"))
    lvr.prefix = LightXML.content(LightXML.find_element(pd_lvr, "Prefix"))
    lvr.keyMarker = LightXML.content(LightXML.find_element(pd_lvr, "KeyMarker"))
    lvr.versionIdMarker = LightXML.content(LightXML.find_element(pd_lvr, "VersionIdMarker"))
    lvr.nextKeyMarker = LightXML.content(LightXML.find_element(pd_lvr, "NextKeyMarker"))
    lvr.nextVersionIdMarker = LightXML.content(LightXML.find_element(pd_lvr, "NextVersionIdMarker"))
    lvr.maxKeys = AWS.safe_parseint(LightXML.content(LightXML.find_element(pd_lvr, "MaxKeys")))
    lvr.delimiter = LightXML.content(LightXML.find_element(pd_lvr, "Delimiter"))
    lvr.isTruncated = AWS.safe_parsebool(LightXML.content(LightXML.find_element(pd_lvr, "IsTruncated")))
    lvr.version = AWS.@parse_vector(AWS.S3.Version, LightXML.get_elements_by_tagname(pd_lvr, "Version"))
    lvr.deleteMarker = AWS.@parse_vector(AWS.S3.DeleteMarker, LightXML.get_elements_by_tagname(pd_lvr, "DeleteMarker"))
    lvr.commonPrefixes = AWS.@parse_vector(AWS.S3.CommonPrefixes, LightXML.get_elements_by_tagname(pd_lvr, "CommonPrefixes"))
    lvr
end
export ListVersionsResult

type Bucket
    name::Union{AbstractString, Void}
    creationDate::DateTime
end
function Bucket(pd_b)
    datestr = LightXML.content(LightXML.find_element(pd_b, "CreationDate"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")

    Bucket(LightXML.content(LightXML.find_element(pd_b, "Name")), t)
end
export Bucket

type ListAllMyBucketsResult
    owner::Union{Owner, Void}
    buckets::Vector{Bucket}
end
function ListAllMyBucketsResult(pd_lab)
    owner = Owner(LightXML.find_element(pd_lab, "Owner"))
    buckets = AWS.@parse_vector(AWS.S3.AWS.S3.Bucket, LightXML.get_elements_by_tagname(LightXML.find_element(pd_lab, "Buckets"), "Bucket"))
    ListAllMyBucketsResult(owner, buckets)
end
export ListAllMyBucketsResult

type CopyObjectResult
    lastModified::DateTime
    eTag::Union{AbstractString, Void}
end
function CopyObjectResult(pd_cor)
    datestr = LightXML.content(LightXML.find_element(pd_cor, "LastModified"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")

    CopyObjectResult(t, LightXML.content(LightXML.find_element(pd_cor, "ETag")))
end
export CopyObjectResult

type RequestPaymentConfiguration
    payer::Union{AbstractString, Void}
end
xml(o::RequestPaymentConfiguration) = xml_hdr("RequestPaymentConfiguration") * xml("Payer", o.payer) * xml_ftr("RequestPaymentConfiguration")
RequestPaymentConfiguration(pd_rpc) = RequestPaymentConfiguration(LightXML.content(LightXML.find_element(pd_rpc, "Payer")))
export RequestPaymentConfiguration

type VersioningConfiguration
    status::Union{AbstractString, Void}
    mfaDelete::Union{AbstractString, Void}
end
function xml(o::VersioningConfiguration)
    xml_hdr("VersioningConfiguration") *
    ((o.status != "") ? xml("Status", o.status) : "") *
    ((o.mfaDelete != "") ? xml("MfaDelete", o.mfaDelete) : "")  *
    xml_ftr("VersioningConfiguration")
end
function VersioningConfiguration(pd_vc)
    status = LightXML.find_element(pd_vc, "Status")  != nothing ? LightXML.content(LightXML.find_element(pd_vc, "Status")) : ""
    mfaDelete = LightXML.find_element(pd_vc, "MfaDelete") != nothing ? LightXML.content(LightXML.find_element(pd_vc, "MfaDelete")) : ""

    VersioningConfiguration(status, mfaDelete)
end
export VersioningConfiguration

type TopicConfiguration
    topic::Union{AbstractString, Void}
    event::Vector{AbstractString}
end
function TopicConfiguration(pd_tc)
    topic = LightXML.content(LightXML.find_element(pd_tc, "Topic"))
    event = AbstractString[]
    for pde in LightXML.find_element(pd_tc, "Event")
        ## push!(event, pde.text)
        push!(event, LightXML.content(pde))
    end
    TopicConfiguration(topic, event)
end
function xml(o::TopicConfiguration)
    topic = xml("Topic", o.topic)
    events = ""
    for e in o.event
        events = events * xml("Event", e)
    end

    xml("TopicConfiguration", topic * events)
end
export TopicConfiguration

type NotificationConfiguration
    topicConfiguration::Union{Vector{TopicConfiguration}, Void}
end
NotificationConfiguration(pd) = NotificationConfiguration(AWS.@parse_vector(AWS.S3.TopicConfiguration, LightXML.get_elements_by_tagname(pd, "TopicConfiguration")))

function xml(o::NotificationConfiguration)
    if o.topicConfiguration == nothing
        xml("NotificationConfiguration", "")
    else
        topics = ""
        for t in o.topicConfiguration
            topics = topics * xml("TopicConfiguration", t)
        end
        xml("NotificationConfiguration", topics)
    end
end
export NotificationConfiguration

type InitiateMultipartUploadResult
    bucket::Union{AbstractString, Void}
    key::Union{AbstractString, Void}
    uploadId::Union{AbstractString, Void}
end
function InitiateMultipartUploadResult(pd)
    InitiateMultipartUploadResult(LightXML.content(LightXML.find_element(pd, "Bucket")), LightXML.content(LightXML.find_element(pd, "Key")), LightXML.content(LightXML.find_element(pd, "UploadId")))
end
export InitiateMultipartUploadResult

type CopyPartResult
   lastModified::DateTime
   eTag::Union{AbstractString, Void}
end
function CopyPartResult(pd)
    datestr = LightXML.content(LightXML.find_element(pd, "LastModified"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S")
    CopyPartResult(t, LightXML.content(LightXML.find_element(pd, "ETag")))
end
export CopyPartResult

type Part
    partNumber::Union{AbstractString, Void}
    lastModified::Union{DateTime, Void}
    eTag::Union{AbstractString, Void}
    size::Union{Int64, Void}

    Part(partNumber, eTag) = new(partNumber, nothing, eTag, nothing)
    Part(partNumber, lastModified, eTag, size) = new(partNumber, lastModified, eTag, size)
end
# We don't need to xmlify lastModified and Size...
xml(o::Part) = xml("Part", [("PartNumber", o.partNumber), ("ETag", o.eTag)])
function Part(pd)
    datestr = LightXML.content(LightXML.find_element(pd, "LastModified"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")

    Part(LightXML.content(LightXML.find_element(pd, "PartNumber")), t, LightXML.content(LightXML.find_element(pd, "ETag")), int64(LightXML.content(LightXML.find_element(pd, "Size"))))
end
export Part

type CompleteMultipartUpload
    parts::Vector{Part}
end
xml(o::CompleteMultipartUpload) = xml("CompleteMultipartUpload", o.parts)
export CompleteMultipartUpload

type CompleteMultipartUploadResult
    location::Union{AbstractString, Void}
    bucket::Union{AbstractString, Void}
    key::Union{AbstractString, Void}
    eTag::Union{AbstractString, Void}
end
CompleteMultipartUploadResult(pd) =
    CompleteMultipartUploadResult(
        LightXML.content(LightXML.find_element(pd, "Location")),
        LightXML.content(LightXML.find_element(pd, "Bucket")),
        LightXML.content(LightXML.find_element(pd, "Key")),
        LightXML.content(LightXML.find_element(pd, "ETag")),
    )
export CompleteMultipartUploadResult

type ListPartsResult
    bucket::Union{AbstractString, Void}
    key::Union{AbstractString, Void}
    uploadId::Union{AbstractString, Void}
    initiator::Initiator
    owner::Union{Owner, Void}
    storageClass::Union{AbstractString, Void}
    partNumberMarker::Union{AbstractString, Void}
    nextPartNumberMarker::Union{AbstractString, Void}
    maxParts::Union{Int, Void}
    isTruncated::Union{Bool, Void}
    parts::Vector{Part}
end
function ListPartsResult(pd)
    ListPartsResult(
        LightXML.content(LightXML.find_element(pd, "Bucket")),
        LightXML.content(LightXML.find_element(pd, "Key")),
        LightXML.content(LightXML.find_element(pd, "UploadId")),
        Initiator(LightXML.find_element(pd, "Initiator")),
        Owner(LightXML.find_element(pd, "Owner")),
        LightXML.content(LightXML.find_element(pd, "StorageClass")),
        LightXML.content(LightXML.find_element(pd, "PartNumberMarker")),
        LightXML.content(LightXML.find_element(pd, "NextPartNumberMarker")),
        int(LightXML.content(LightXML.find_element(pd, "MaxParts"))),
        (lowercase(LightXML.content(LightXML.find_element(pd, "IsTruncated"))) == "true") ? true : false,
        AWS.@parse_vector(AWS.S3.Part, LightXML.get_elements_by_tagname(pd, "Part"))
    )
end
export ListPartsResult

type Upload
    key::Union{AbstractString, Void}
    uploadId::Union{AbstractString, Void}
    initiator::Union{Initiator, Void}
    owner::Union{Owner, Void}
    storageClass::Union{AbstractString, Void}
    initiated::Union{DateTime, Void}
end
function Upload(pd)
    datestr = LightXML.content(LightXML.find_element(pd, "Initiated"))
    t = DateTime(datestr[1:end-1], "y-m-dTH:M:S.s")
    Upload(
        LightXML.content(LightXML.find_element(pd, "Key")),
        LightXML.content(LightXML.find_element(pd, "UploadId")),
        Initiator(LightXML.find_element(pd, "Initiator")),
        Owner(LightXML.find_element(pd, "Owner")),
        LightXML.content(LightXML.find_element(pd, "StorageClass")),
        t
    )
end
export Upload

type ListMultipartUploadsResult
    bucket::Union{AbstractString, Void}
    prefix::Union{AbstractString, Void}
    keyMarker::Union{AbstractString, Void}
    uploadIdMarker::Union{AbstractString, Void}
    nextKeyMarker::Union{AbstractString, Void}
    nextUploadIdMarker::Union{AbstractString, Void}
    maxUploads::Union{Int, Void}
    delimiter::Union{AbstractString, Void}
    isTruncated::Union{Bool, Void}
    upload::Union{Vector{Upload}, Void}
    commonPrefixes::Union{Vector{CommonPrefixes}, Void}
end
function ListMultipartUploadsResult(pd)
    ListMultipartUploadsResult(
        LightXML.content(LightXML.find_element(pd, "Bucket")),
        LightXML.content(LightXML.find_element(pd, "Prefix")),
        LightXML.content(LightXML.find_element(pd, "KeyMarker")),
        LightXML.content(LightXML.find_element(pd, "UploadIdMarker")),
        LightXML.content(LightXML.find_element(pd, "NextKeyMarker")),
        LightXML.content(LightXML.find_element(pd, "NextUploadIdMarker")),
        AWS.safe_parseint(LightXML.content(LightXML.find_element(pd, "MaxUploads"))),
        LightXML.content(LightXML.find_element(pd, "Delimiter")),
        AWS.safe_parsebool(LightXML.content(LightXML.find_element(pd, "IsTruncated"))),
        AWS.@parse_vector(AWS.S3.Upload, LightXML.get_elements_by_tagname(pd, "Upload")),
        AWS.@parse_vector(AWS.S3.CommonPrefixes, LightXML.get_elements_by_tagname(pd, "CommonPrefixes"))
    )
end
export ListMultipartUploadsResult

type CORSRule
    id::Union{AbstractString, Void}
    allowedMethod::Union{Vector{AbstractString}, Void}
    allowedOrigin::Union{Vector{AbstractString}, Void}
    allowedHeader::Union{Vector{AbstractString}, Void}
    maxAgeSeconds::Union{AbstractString, Int}
    exposeHeader::Union{Vector{AbstractString}, Void}
end

xml(o::CORSRule) = xml("CORSRule", [
        ("ID", o.id),
        ("AllowedMethod", o.allowedMethod),
        ("AllowedOrigin", o.allowedOrigin),
        ("AllowedHeader", o.allowedHeader),
        ("MaxAgeSeconds", o.maxAgeSeconds),
        ("ExposeHeader", o.exposeHeader)
    ])

function CORSRule(pd)
    id = LightXML.content(LightXML.find_element(pd, "ID"))
    allowedMethod = parse_vector_as(AbstractString, "AllowedMethod", LightXML.get_elements_by_tagname(pd, "AllowedMethod"))
    allowedOrigin = parse_vector_as(AbstractString, "AllowedOrigin", LightXML.get_elements_by_tagname(pd, "AllowedOrigin"))
    allowedHeader = parse_vector_as(AbstractString, "AllowedHeader", LightXML.get_elements_by_tagname(pd, "AllowedHeader"))
    seconds = LightXML.content(LightXML.find_element(pd, "MaxAgeSeconds"))
    if (seconds != nothing) maxAgeSeconds = int(seconds) end
    exposeHeader = parse_vector_as(AbstractString, "ExposeHeader", LightXML.get_elements_by_tagname(pd, "ExposeHeader"))

    CORSRule(id, allowedMethod, allowedOrigin, allowedHeader, maxAgeSeconds, exposeHeader)

end
export CORSRule

type CORSConfiguration
    corsrules::Vector{CORSRule}
end
xml(o::CORSConfiguration) = xml("CORSConfiguration", o.corsrules)
CORSConfiguration(pd) = AWS.@parse_vector(AWS.S3.CORSRule, LightXML.get_elements_by_tagname(pd, "CORSRule"))

type S3Error
    code::Union{AbstractString, Void}
    message::Union{AbstractString, Void}
    hostId::Union{AbstractString, Void}
    requestId::Union{AbstractString, Void}
end
function S3Error(pde)
    code = LightXML.content(LightXML.find_element(pde, "Code"))
    message = LightXML.content(LightXML.find_element(pde, "Message"))

    # this might be redundant as it often returns empty, AWS docs
    # at http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
    # are incomplete
    _resrce = LightXML.find_element(pde, "Resource")
    resource =  _resrce != Void() ? LightXML.content(_resrce) : Void()

    _sig = LightXML.find_element(pde, "SignatureProvided")
    signature =  _sig != Void() ? LightXML.content(_sig) : Void()

    hostId = LightXML.content(LightXML.find_element(pde, "HostId"))
    requestId = LightXML.content(LightXML.find_element(pde, "RequestId"))

    S3Error(code, message, hostId, requestId)
end

export CORSConfiguration

type S3PartTag
    part_number::AbstractString
    etag::AbstractString
end
xml(o::S3PartTag) = xml("Part", [("PartNumber", o.part_number), ("ETag", o.etag)])

type CopyMatchOptions
    if_match::Union{AbstractString, Void}
    if_none_match::Union{AbstractString, Void}
    if_unmodified_since::Union{AbstractString, Void}
    if_modified_since::Union{AbstractString, Void}
    CopyMatchOptions(;if_match=nothing, if_none_match=nothing, if_unmodified_since=nothing, if_modified_since=nothing) = begin
        new(if_match, if_none_match, if_unmodified_since, if_modified_since)
    end
end
function amz_headers(hdrs, o::CopyMatchOptions)
    @add_amz_hdr("copy-source-if-match", o.if_match)
    @add_amz_hdr("copy-source-if-none-match", o.if_none_match)
    @add_amz_hdr("copy-source-if-unmodified-since", o.if_unmodified_since)
    @add_amz_hdr("copy-source-if-modified-since", o.if_modified_since)
    hdrs
end
export S3PartTag

type S3_ACL_Grantee
    email_address::Union{AbstractString, Void}
    id::Union{AbstractString, Void}
    uri::Union{AbstractString, Void}
    S3_ACL_Grantee() = new(nothing, nothing, nothing)
end
function hdr_str(g::S3_ACL_Grantee)
    if g.email_address != nothing
        return "emailAddress=$(g.email_address)"
    elseif g.id != nothing
        return "id=$(g.id)"
    elseif g.uri != nothing
        return "uri=$(g.uri)"
    else
        error("At least one of the grantee types must be defined.")
    end
end
export S3_ACL_Grantee

type S3_ACL
    acl::Union{AbstractString, Void}
    grant_read::Vector{S3_ACL_Grantee}
    grant_write::Vector{S3_ACL_Grantee}
    grant_read_acp::Vector{S3_ACL_Grantee}
    grant_write_acp::Vector{S3_ACL_Grantee}
    grant_full_control::Vector{S3_ACL_Grantee}

    S3_ACL() = new(nothing, S3_ACL_Grantee[], S3_ACL_Grantee[], S3_ACL_Grantee[], S3_ACL_Grantee[], S3_ACL_Grantee[])
end
function amz_headers(hdrs, o::S3_ACL)
    # Either a canned acl or specific acls (but not both) are supported
    if o.acl != nothing
        @add_amz_hdr("acl", o.acl)
    else
        add_acl_grantee(hdrs, "grant-read", o.grant_read)
        add_acl_grantee(hdrs, "grant-write", o.grant_write)
        add_acl_grantee(hdrs, "grant-read-acp", o.grant_read_acp)
        add_acl_grantee(hdrs, "grant-write-acp", o.grant_write_acp)
        add_acl_grantee(hdrs, "grant-full-control", o.grant_full_control)
    end
    hdrs
end

function add_acl_grantee(hdrs, xamz_name::AbstractString, arr::Vector{S3_ACL_Grantee})
    for a in arr
        @add_amz_hdr(xamz_name, hdr_str(a))
    end
    hdrs
end
export S3_ACL

type CopyObjectOptions
# All are x-amz options
    copy_source::AbstractString
    metadata_directive::Union{AbstractString, Void}
    match_options::Union{CopyMatchOptions, Void}

# x-amz only header fields
    server_side_encryption::Union{AbstractString, Void}
    storage_class::Union{AbstractString, Void}
    website_redirect_location::Union{AbstractString, Void}
    acl::Union{S3_ACL, Void}

    CopyObjectOptions(copy_source; metadata_directive=nothing, match_options=nothing,
        server_side_encryption=nothing, storage_class=nothing, website_redirect_location=nothing, acl=nothing) = begin
            new(copy_source, metadata_directive,  match_options, server_side_encryption, storage_class, website_redirect_location, acl)
    end

end
function amz_headers(hdrs, o::CopyObjectOptions)
    @add_amz_hdr("copy-source", o.copy_source)
    @add_amz_hdr("metadata-directive", o.metadata_directive)

    if (o.match_options != nothing)
        hdrs = amz_headers(hdrs, o.match_options)
    end

    @add_amz_hdr("server-side-encryption", o.server_side_encryption)
    @add_amz_hdr("storage-class", o.storage_class)
    @add_amz_hdr("website-redirect-location", o.website_redirect_location)

    if o.acl != nothing
        hdrs = amz_headers(hdrs, o.acl)
    end
    hdrs
end
export CopyObjectOptions

type CopyUploadPartOptions
    copy_source::AbstractString
    source_range::Union{AbstractString, Void}
    match_options::Union{CopyMatchOptions, Void}

    CopyUploadPartOptions(copy_source; source_range=nothing, match_options=nothing) = new(copy_source, source_range, match_options)
end
function amz_headers(o::CopyUploadPartOptions)
    hdrs = [("x-amz-copy-source", o.copy_source)]
    @add_amz_hdr("source-range", o.source_range)
    hdrs = (o.match_options != nothing) ? amz_headers(hdrs, o.match_options) : hdrs
    hdrs
end
export CopyUploadPartOptions

type PutObjectOptions
# Standard HTTP headers
    cache_control::Union{AbstractString, Void}
    content_disposition::Union{AbstractString, Void}
    content_encoding::Union{AbstractString, Void}
    cont_typ::Union{AbstractString, Void}
#Expect  not supported...
    expires::Union{DateTime, Void}

# x-amz header fields
    meta::Union{Dict{AbstractString, AbstractString}, Void}
    server_side_encryption::Union{AbstractString, Void}
    storage_class::Union{AbstractString, Void}
    website_redirect_location::Union{AbstractString, Void}
    acl::Union{S3_ACL, Void}

    PutObjectOptions(;cache_control=nothing,content_disposition=nothing,content_encoding=nothing,
                        cont_typ=nothing,expires=nothing,meta=nothing,server_side_encryption=nothing,
                        storage_class=nothing,website_redirect_location=nothing,acl=nothing) = begin
            new(cache_control,content_disposition,content_encoding,cont_typ,expires,meta,server_side_encryption,storage_class,website_redirect_location,acl)
    end
end
function amz_headers(hdrs, o::PutObjectOptions)
    if (o.meta != nothing)
        for t in collect(o.meta)
            @add_amz_hdr("meta-" * t[1], t[2])
        end
    end

    @add_amz_hdr("server-side-encryption", o.server_side_encryption)
    @add_amz_hdr("storage-class", o.storage_class)
    @add_amz_hdr("website-redirect-location", o.website_redirect_location)

    if o.acl != nothing
        hdrs = amz_headers(hdrs, o.acl)
    end
    hdrs
end

function http_headers(arr, o::PutObjectOptions)
    @chk_n_add("Cache-Control", o.cache_control)
    @chk_n_add("Content-Disposition", o.content_disposition)
    @chk_n_add("Content-Encoding", o.content_encoding)
    @chk_n_add("Expires", rfc1123_date(o.expires))
    arr
end
export PutObjectOptions

type GetObjectOptions
    # These go into the query string
    response_cont_typ::Union{AbstractString, Void}
    response_content_language::Union{AbstractString, Void}
    response_expires::Union{AbstractString, Void}
    response_cache_control::Union{AbstractString, Void}
    response_content_disposition::Union{AbstractString, Void}
    response_content_encoding::Union{AbstractString, Void}

    # These go into the header
    range::Union{AbstractString, Void}
    if_modified_since::Union{DateTime, Void}
    if_unmodified_since::Union{DateTime, Void}
    if_match::Union{AbstractString, Void}
    if_none_match::Union{AbstractString, Void}

    GetObjectOptions(;response_cont_typ=nothing, response_content_language=nothing, response_expires=nothing, response_cache_control=nothing, response_content_disposition=nothing,
        response_content_encoding=nothing, range=nothing, if_modified_since=nothing, if_unmodified_since=nothing, if_match=nothing, if_none_match=nothing) = begin
            new(response_cont_typ, response_content_language, response_expires, response_cache_control, response_content_disposition,response_content_encoding, range, if_modified_since, if_unmodified_since, if_match, if_none_match)
        end
end
function http_headers(arr, o::GetObjectOptions)
    @chk_n_add("Range", o.range)
    @chk_n_add("If-Modified-Since", rfc1123_date(o.if_modified_since))
    @chk_n_add("If-Unmodified-Since", rfc1123_date(o.if_unmodified_since))
    @chk_n_add("If-Match", o.if_match)
    @chk_n_add("If-None-Match", o.if_none_match)
    arr
end

function query_params(arr, o::GetObjectOptions)
    @chk_n_add("response-cont-typ", o.response_cont_typ)
    @chk_n_add("response-content-language", o.response_content_language)
    @chk_n_add("response-expires", o.response_expires)
    @chk_n_add("response-cache-control", o.response_cache_control)
    @chk_n_add("response-content-disposition", o.response_content_disposition)
    @chk_n_add("response-content-encoding", o.response_content_encoding)
    arr
end
export GetObjectOptions

type ObjectType
    key::AbstractString
    versionId::Union{AbstractString, Void}
    ObjectType(key) = ObjectType(key, nothing)
    ObjectType(key, version) = new(key, version)
end
function xml(o::ObjectType)
    xml("Object", [("Key", o.key), ("VersionId", o.versionId)])
end
export ObjectType

type DeleteObjectsType
    quiet::Bool
    objects::Vector{ObjectType}
    DeleteObjectsType() = DeleteObjectsType(false, ObjectType[])
    DeleteObjectsType(objects) = DeleteObjectsType(objects, false)
    DeleteObjectsType(objects, quiet) = new(quiet, objects)
end
function xml(o::DeleteObjectsType)
    xml("Delete", [("Quiet", o.quiet); o.objects])
end
export DeleteObjectsType

type Tag
    key::AbstractString
    value::AbstractString
end
xml(o::Tag) = xml("Tag", [("Key", o.key), ("Value", o.value)])
export Tag

# Not a xmlns type
type Tagging
    tagSet::Vector{Tag}
end
xml(o::Tagging) = xml("Tagging", [("TagSet", o.tagSet)])
export Tagging

type GetBucketUploadsOptions
    delimiter::Union{AbstractString, Void}
    key_marker::Union{AbstractString, Void}
    max_uploads::Union{Int, Void}
    prefix::Union{AbstractString, Void}
    upload_id_marker::Union{AbstractString, Void}

    GetBucketUploadsOptions(; delimiter=nothing, key_marker=nothing, max_uploads=nothing, prefix=nothing, upload_id_marker=nothing) = begin
        new(delimiter, key_marker, max_uploads, prefix, upload_id_marker)
    end
end
function get_subres(arr, o::GetBucketUploadsOptions)
    @chk_n_add("delimiter", o.delimiter)
    @chk_n_add("key-marker", o.key_marker)
    @chk_n_add("max-uploads", o.max_uploads)
    @chk_n_add("prefix", o.prefix)
    @chk_n_add("upload-id-marker", o.upload_id_marker)
    arr
end
export GetBucketUploadsOptions

type GetBucketObjectVersionsOptions
    delimiter::Union{AbstractString, Void}
    key_marker::Union{AbstractString, Void}
    max_keys::Union{Int, Void}
    prefix::Union{AbstractString, Void}
    version_id_marker::Union{AbstractString, Void}
    GetBucketObjectVersionsOptions(; delimiter=nothing, key_marker=nothing, max_keys=nothing, prefix=nothing, version_id_marker=nothing) = begin
        new(delimiter, key_marker, max_keys, prefix, version_id_marker)
    end
end
function get_subres(arr, o::GetBucketObjectVersionsOptions)
    @chk_n_add("delimiter", o.delimiter)
    @chk_n_add("key-marker", o.key_marker)
    @chk_n_add("max-keys", o.max_keys)
    @chk_n_add("prefix", o.prefix)
    @chk_n_add("version-id-marker", o.version_id_marker)
    arr
end
export GetBucketObjectVersionsOptions

type GetBucketOptions
    delimiter::Union{AbstractString, Void}
    marker::Union{AbstractString, Void}
    max_keys::Union{Int, Void}
    prefix::Union{AbstractString, Void}
    GetBucketOptions(;delimiter=nothing, marker=nothing, max_keys=nothing, prefix=nothing) = new(delimiter, marker, max_keys, prefix)
end
function get_subres(arr, o::GetBucketOptions)
    @chk_n_add("delimiter", o.delimiter)
    @chk_n_add("marker", o.marker)
    @chk_n_add("max-keys", o.max_keys)
    @chk_n_add("prefix", o.prefix)
    arr
end
export GetBucketOptions

type Deleted
    key::Union{AbstractString, Void}
    version_id::Union{AbstractString, Void}
    marker::Union{Bool, Void}
    marker_version_id::Union{AbstractString, Void}
end
Deleted() = Deleted(nothing,nothing,nothing,nothing)
function Deleted(pd)
    d = Deleted()
    d.key = LightXML.content(LightXML.find_element(pd, "Key"))
    d.version_id = LightXML.find_element(pd, "VersionId") != nothing ? LightXML.content(LightXML.find_element(pd, "VersionId")) : nothing
    d.marker = LightXML.find_element(pd, "DeleteMarker") != nothing ? AWS.safe_parsebool(LightXML.content(LightXML.find_element(pd, "DeleteMarker"))) : nothing
    d.marker_version_id = LightXML.find_element(pd, "DeleteMarkerVersionId") != nothing ? LightXML.content(LightXML.find_element(pd, "DeleteMarkerVersionId")) : nothing
    d
end
export Deleted

type DeleteError
    key::Union{AbstractString, Void}
    version_id::Union{AbstractString, Void}
    code::Union{AbstractString, Void}
    message::Union{AbstractString, Void}
end
DeleteError() = DeleteError(nothing,nothing,nothing,nothing)
function DeleteError(pd)
    de = DeleteError()
    de.key = LightXML.content(LightXML.find_element(pd, "Key"))
    de.version_id = LightXML.find_element(pd, "VersionId") != nothing ? LightXML.content(LightXML.find_element(pd, "VersionId")) : nothing
    de.code = LightXML.find_element(pd, "Code") != nothing ? LightXML.content(LightXML.find_element(pd, "Code")) : nothing
    de.message = LightXML.find_element(pd, "Message") != noting ?LightXML.content(LightXML.find_element(pd, "Message")) : nothing
    de
end
export DeleteError

type DeleteResult
    deleted::Union{Vector{Deleted}, Void}
    delete_errors::Union{Vector{DeleteError}, Void}
end
DeleteResult() = DeleteResult(nothing, nothing)
function DeleteResult(pd)
    dr = DeleteResult()
    dr.deleted = LightXML.get_elements_by_tagname(pd, "Deleted") != nothing ? AWS.@parse_vector(AWS.S3.Deleted, LightXML.get_elements_by_tagname(pd, "Deleted")) : nothing
    dr.delete_errors = LightXML.find_element(pd, "Errors") != nothing ? AWS.@parse_vector(AWS.S3.DeleteError, LightXML.find_element(pd, "Errors")) : nothing
    dr
end
export DeleteResult


text:
using VLKeggSDK
using DataFrames

# get pathways for E. coli -
organism_code = "eco"

# get codes -
pathway_table = get_pathways_for_organism(organism_code) |> check |> DataFrame


text:
"""
Lookup the nearest neighbors and teh estimate matrix to get a rough estimate.
"""
function get_travel_time_estimate(halton_nn_tree::BallTree, loc1::LatLonCoords, loc2::LatLonCoords,
                                  estimate_matrix::Matrix{Float64}, time_scale::Float64)

    # Get the nearest neighbor for each location
    # IMP - If they are the same, return 0.0
    loc1_vect = convert_to_vector(loc1)
    loc1_idxs, _ = knn(halton_nn_tree, loc1_vect, 1)
    loc1_idx = loc1_idxs[1]

    loc2_vect = convert_to_vector(loc2)
    loc2_idxs, _ = knn(halton_nn_tree, loc2_vect, 1)
    loc2_idx = loc2_idxs[1]

    # Returns 0.0 if same!
    tt_est = estimate_matrix[loc1_idx, loc2_idx]

    # Use direct distance divided by speed if 0.0
    if tt_est == 0.0
        tt_est = Distances.evaluate(EuclideanLatLongMetric(), convert_to_vector(loc1), convert_to_vector(loc2)) / 0.00777 # Avg. drone speed
    end

    return tt_est/time_scale
end

function generate_package_request(lat_dist::Distribution, lon_dist::Distribution, current_time::Float64,
                                  tw_duration::Float64, rng::RNG=Random.GLOBAL_RNG) where {RNG <: AbstractRNG}

    delivery = (lat = rand(rng, lat_dist), lon = rand(rng, lon_dist))

    # Randomness in walking time and in duration
    start_time = current_time + rand(rng, Distributions.Uniform(tw_duration/2.0, tw_duration))
    duration = rand(rng, Distributions.Uniform(tw_duration/2.0, tw_duration))
    time_window = (start_time, start_time + duration)

    return Package(delivery, time_window)
end

function sample_true_delivery_return_time(drone_pkg_window::SVector{3,Float64}, current_time::Float64,
                                         std_scale::Float64, rng::RNG=Random.GLOBAL_RNG) where {RNG <: AbstractRNG}

    travel_time = drone_pkg_window[3] - drone_pkg_window[2]

    meanval = travel_time
    stdval = travel_time/std_scale
    tt_dist = Distributions.Epanechnikov(meanval, stdval)

    true_delivery_time = current_time + rand(rng, tt_dist)
    true_delivery_time = (true_delivery_time <= drone_pkg_window[1]) ? drone_pkg_window[1] : true_delivery_time

    true_return_time = ceil(true_delivery_time) + rand(rng, tt_dist)

    return (true_delivery_time, true_return_time)
end # end function

# For simulator - Set downtime based on distance between pickup and dropoff - but no uncertainty there
function setup_routing_sim(params_fn::String, halton_nn_tree, estimate_matrix::Matrix{Float64};
                           num_init_requests::Int64=5, new_request_prob::Float64=0.75, delivery_reward::Float64=1000.0,
                           time_window_duration::Float64=30.0, rng::RNG=Random.GLOBAL_RNG) where {RNG <: AbstractRNG}

    # Parse the parameters for the relevant city
    city_params = parse_city_params(params_fn)
    lat_dist = Distributions.Uniform(city_params.lat_start, city_params.lat_end)
    lon_dist = Distributions.Uniform(city_params.lon_start, city_params.lon_end)

    # Update the number of active packages etc.
    active_packages = Dict{String,Package}()

    for n = 1:num_init_requests
        new_package_name = string("pkg",n)

        new_package = generate_package_request(lat_dist, lon_dist, 0.0, time_window_duration, rng)
        active_packages[new_package_name] = new_package
    end

    return RoutingSimulator(current_time=0.0, city_params=city_params, new_request_prob=new_request_prob, delivery_reward=delivery_reward,
                            time_window_duration=time_window_duration, halton_nn_tree=halton_nn_tree, estimate_matrix=estimate_matrix,
                            active_packages=active_packages, num_total_packages=num_init_requests, num_active_packages=num_init_requests)
end

## Need something that maintains the TRUE pickup and dropoff times but only uses them when called upon
# 1. Generate new request based on probability
# 2. If new time is > TRUE pickup, simulate pickup (same for dropoff)
# 3. Assign drones as free or active; Update current pos of drone if picked / dropped off
function update_routing_sim!(sim::RoutingSimulator, server::RoutingAllocation,
                            rng::RNG=Random.GLOBAL_RNG) where {RNG <: AbstractRNG}

    # First update the simulator and server time
    old_time = sim.current_time
    sim.current_time += 1
    server.current_time += 1

    curr_drone_locs_cols = Tuple{LatLonCoords,Symbol}[]
    curr_sites_locs_cols = Tuple{LatLonCoords,Symbol}[]

    # Simulate any true pickups and dropoffs
    keys_to_del = Set{Tuple{String,String}}()
    busy_packages_to_del = Set{String}()
    done_packages_to_del = Set{String}()
    for (k,v) in server.agent_task_allocation
        drone_nm = k
        package_nm, _ = v

        # Lookup true delivery and return times
        delivery, return_time = sim.true_delivery_return[(drone_nm, package_nm)]

        # For pickup, assign package to drone and mark package inactive
        if delivery > old_time && delivery <= sim.current_time

            server.agent_prop_set[drone_nm].current_package = ""
            server.agent_prop_set[drone_nm].at_depot = false # For good measure

            # Need to check if it reached in time!
            if delivery <= sim.busy_packages[package_nm].time_window[2]
                sim.delivered_packages += 1
                @info "$(drone_nm) has delivered $(package_nm)!"

                # Drone is green and at package location
                push!(curr_drone_locs_cols, (sim.busy_packages[package_nm].delivery, :green))

            else
                sim.late_packages += 1
                @info "$(package_nm) was not delivered in time!"

                # Drone is green and at package location
                push!(curr_drone_locs_cols, (sim.busy_packages[package_nm].delivery, :red))

            end

            push!(busy_packages_to_del, package_nm)
            sim.done_packages[package_nm] = sim.busy_packages[package_nm]

            # Increment loss with difference from start of window
            sim.sum_of_delivery_time += delivery - server.agent_task_windows[(drone_nm, package_nm)][1]

        # For dropoff, free up drone and setup deletion of (drone,package) keys
        elseif return_time > old_time && return_time <= sim.current_time

            # Drone at depot again
            server.agent_prop_set[drone_nm].at_depot = true
            push!(keys_to_del, (drone_nm, package_nm))
            @info "$(drone_nm) back at depot!"
            push!(done_packages_to_del, package_nm)

            # Drone is blue and at depot
            push!(curr_drone_locs_cols, (server.agent_set[drone_nm].depot_loc, :blue))

        else
            ## NOTE: Super hacky, only for plotting
            if haskey(sim.busy_packages, package_nm) == false && haskey(sim.done_packages, package_nm) == false
                continue
            end
            depot_loc = server.agent_set[drone_nm].depot_loc

            if sim.current_time < delivery
                pp_loc = sim.busy_packages[package_nm].delivery
                maxdiff = max(delivery, return_time - delivery)
                interp_factor = (delivery - sim.current_time)/maxdiff
                new_lat = depot_loc.lat + (1.0 - interp_factor)*(pp_loc.lat - depot_loc.lat)
                new_lon = depot_loc.lon + (1.0 - interp_factor)*(pp_loc.lon - depot_loc.lon)
            else
                pp_loc = sim.done_packages[package_nm].delivery
                interp_factor = (return_time - sim.current_time)/(return_time - delivery)
                new_lat = depot_loc.lat + (interp_factor)*(pp_loc.lat - depot_loc.lat)
                new_lon = depot_loc.lon + (interp_factor)*(pp_loc.lon - depot_loc.lon)
                # @infiltrate
            end
            # @infiltrate

            push!(curr_drone_locs_cols, ((lat=new_lat, lon=new_lon), :blue))

        end # if delivery >
    end # for (k,v)

    # Delete bookkeeping keys for dropped off package
    for k in keys_to_del
        delete!(sim.true_delivery_return, k)
        delete!(server.agent_task_windows, k)
        delete!(server.agent_task_allocation, k[1]) # Only delete the agent key
    end

    for r in busy_packages_to_del
        delete!(sim.busy_packages, r)
    end # for r

    for r in done_packages_to_del
        delete!(sim.done_packages, r)
    end

    # Now deal with deliveries that were never attempted?
    packages_to_del = Set{String}()
    for (package_nm, rp) in sim.active_packages
        if rp.time_window[2] <= sim.current_time
            @info "$(package_nm) was not even attempted!"
            sim.late_packages += 1
            push!(packages_to_del, package_nm)

            # Add package location with red
            push!(curr_sites_locs_cols, (rp.delivery, :red))
        end
    end

    for r in packages_to_del
        delete!(sim.active_packages, r)
        sim.num_active_packages -= 1
    end # for r

    # Finally, generate new packages
    if rand(rng) <= sim.new_request_prob
        lat_dist = Distributions.Uniform(sim.city_params.lat_start, sim.city_params.lat_end)
        lon_dist = Distributions.Uniform(sim.city_params.lon_start, sim.city_params.lon_end)
        new_package = generate_package_request(lat_dist, lon_dist, sim.current_time,
                                                sim.time_window_duration, rng)
        sim.num_total_packages += 1
        sim.num_active_packages += 1
        new_package_nm = string("pkg",sim.num_total_packages)
        @info "$(new_package_nm) added!"
        sim.active_packages[new_package_nm] = new_package
    end # if rand(rng)

    # Grey packages
    for (pkg_nm, pp) in sim.active_packages
        push!(curr_sites_locs_cols, (pp.delivery, :grey))
    end
    for (pkg_nm, pp) in sim.busy_packages
        push!(curr_sites_locs_cols, (pp.delivery, :grey))
    end

    sim.curr_drone_site_locs = CurrDroneSiteLocs(curr_drone_locs_cols, curr_sites_locs_cols)
end # function

function update_time_windows!(sim::RoutingSimulator, server::RoutingAllocation)

    @assert sim.current_time == server.current_time

    # We look at all active packages and update their time windows w.r.t the drones
    for (drone_nm,drone_props) in server.agent_prop_set

        interaction_events = server.agent_prop_set[drone_nm].interaction_events
        drone = server.agent_set[drone_nm]

        for (package_nm,rp) in sim.active_packages
            if ~(haskey(server.agent_task_windows, (drone_nm, package_nm)))
                # Compute downtime in terms of dropoff time
                return_time = get_travel_time_estimate(sim.halton_nn_tree, rp.delivery,
                                                        drone.depot_loc, sim.estimate_matrix, sim.time_scale)

                # Insert interaction event timestamps
                ie_timestamps = Dict{MODE,Float64}(START=>rp.time_window[1], FINISH=>rp.time_window[2],
                                                   SUCCESS=>ceil(rp.time_window[2])+return_time)
                push!(interaction_events, InteractionEvent(drone_nm, package_nm, ie_timestamps))

                # Update time windows on the assignment server side
                server.agent_task_windows[(drone_nm, package_nm)] = [rp.time_window[1], rp.time_window[2], ceil(rp.time_window[2])+return_time]
            end # if ~(haskey)
        end # for (package,rp)

        # Sort the temporal event list
        sort!(interaction_events, by=x->x.timestamps[SUCCESS])
        server.agent_prop_set[drone_nm].interaction_events = interaction_events
    end

end # function update_time_windows

function parse_routing_commandline()

    s = ArgParseSettings()

    @add_arg_table s begin
        "--trials", "-n"
            arg_type = Int64
            default = 100
        "--timesteps", "-t"
            arg_type = Int64
            default = 500
        "--n_drones", "-d"
            arg_type = Int64
        "--n_depots", "-e"
            arg_type = Int64
        "--new_request_prob", "-p"
            arg_type = Float64
        "--time_window", "-w"
            arg_type = Float64
        "baseline"
            help = "Which method to evaluate (dispatch/hungarian/css)"
            required = true
        "out_file_name"
            required = true
    end

    return parse_args(s)
end # end function parse routing


text:
include("bandec_trans.jl")

function compile_matrix_symm(alpha_real::Vector,alpha_imag::Vector,beta_real::Vector,beta_imag::Vector, w::Vector ,t::Vector,
       nex::Int64,aex::Array,al_small::Array,indx::Vector{Int64})

# The vectors are arranged as:
# [x_k {{r^R_{k+1,i},r^I_{k+1,i}},i=1..p} {{l^R_{k+1,i},l^I_{k+1,i},i=1..p} x_{k+1} ...]
# For a total of (N-1)*(4(p-p0)+2p0+1)+1 = N(4(p-p0)+2p0+1)-4p equations.
# The equations are arranged as:
# 1). Equation 61 (real only; one single equation);
# 2). Equation 60 (real & imaginary; i=1..p);
# 3). Equation 59 (real & imagingary; i=1..p).

n = length(t)
p = length(alpha_real)
czero = zero(eltype(alpha_real))
p0 = 0
for i=1:p
  if beta_imag[i] == czero
    p0 += 1
  end
end
# nex = (n-1)*(4(p-p0)+2p0+1)+1
m1 = p0+2(p-p0+1)
if p == p0
  m1 = p0+1
end
width = 2m1+1
@assert(size(aex)==(width,nex))
@assert(size(al_small)==(m1,nex))
@assert(length(indx)==nex)
@assert(length(beta_real)==p)
@assert(length(beta_imag)==p)
@assert(length(w)==n)
for j=1:nex
  for i=1:width
    aex[i,j]=czero
  end
  for i=1:m1
    al_small[i,j]=czero
  end
end
#println("aex, al_small set to zero")
# Do the first row, eqn (61), which is a special case since l_1 = 0:
irow = 1
k = 1
d = sum(alpha_real)+w
jcol0 = 1
# Factor multiplying x_1:
jcol = jcol0-irow + m1+1
aex[jcol,irow] = d[k]/2.0
one_type = one(eltype(alpha_real))
gamma_real = zeros(eltype(alpha_real),p)
gamma_imag = zeros(eltype(alpha_real),p)
ebt = czero
phi = czero
for j=1:p0
  ebt = exp(-beta_real[j]*(t[k+1]-t[k]))
  gamma_real[j] =  ebt*cos(phi)
# Factor multiplying r^R_{2,j}:
  jcol0 = 1+j
  jcol = jcol0-irow + m1+1
  aex[jcol,irow]= gamma_real[j]
end
for j=(p0+1):p
  ebt = exp(-beta_real[j]*(t[k+1]-t[k]))
  phi = beta_imag[j]*(t[k+1]-t[k])
  gamma_real[j] =  ebt*cos(phi)
  gamma_imag[j] = -ebt*sin(phi)
# Factor multiplying r^R_{2,j}:
  jcol0 = 1+p0+(j-p0-1)*2+1
  jcol = jcol0-irow + m1+1
  aex[jcol,irow]= gamma_real[j]
# Factor multiplying r^I_{2,j}:
  jcol0 = 1+p0+(j-p0-1)*2+2
  jcol = jcol0-irow + m1+1
  aex[jcol,irow]= gamma_imag[j]
end
gamma_real_km1=copy(gamma_real)
gamma_imag_km1=copy(gamma_imag)
# Now, loop over the middle part of the matrix
for k=2:n
  if k < n
    for j=1:p
      ebt = exp(-beta_real[j]*(t[k+1]-t[k]))
      phi = beta_imag[j]*(t[k+1]-t[k])
      gamma_real[j] =  ebt*cos(phi)
      gamma_imag[j] = -ebt*sin(phi)
    end
  end
  for j=1:p0
# Real part of equation (60):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + j
# Factors multiplying (l^R_{k,j})
    if k > 2
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 +2p-p0 + j
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real_km1[j]
    end
# Factor multiply x_k:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = gamma_real_km1[j]
# Factor multipling l^R_{k+1,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 +2p-p0 + j
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Real part of equation (59):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + j
# Factor multiplying r^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + j
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Factor multiplying x_k:
    jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = alpha_real[j]/2.0
# Factor multiplying r^R_{k+1,j}:
    if k < n
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + j
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real[j]
    end
  end
  for j=(p0+1):p
# Real part of equation (60):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
# Factors multiplying (l^R_{k,j},l^I_{k,j})
    if k > 2
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real_km1[j]
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_imag_km1[j]
    end
# Factor multiply x_k:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = gamma_real_km1[j]
# Factor multipling l^R_{k+1,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 +1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Imaginary part of equation (60):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
# Factors multiplying (l^R_{k,j},l^I_{k,j}):
    if k > 2
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] =  gamma_imag_km1[j]
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 +  (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = -gamma_real_km1[j]
    end
# Factor multiply x_k:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = gamma_imag_km1[j]
# Factor multiplying l^I_{k+1,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 2
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  one_type
# Real part of equation (59):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 1
# Factor multiplying r^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Factor multiplying x_k:
    jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = alpha_real[j]/2.0
# Factor multiplying r^R_{k+1,j}:
    if k < n
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real[j]
# Factor multiplying r^I_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] =  gamma_imag[j]
    end
# Imaginary part of equation (59):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 2
# Factor multiplying r^I_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  one_type
# Factor multiplying x_k:
    jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = alpha_imag[j]/2.0
# Factor multiplying r^R_{k+1,j}:
    if k < n
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_imag[j]
# Factor multiplying r^I_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = -gamma_real[j]
    end
  end
# Equation (61), only real:
  irow = (k-1)*(4(p-p0)+2p0+1) + 1
# Factor multiplying x_k:
  jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
  jcol = jcol0-irow + m1+1
  aex[jcol,irow] = d[k]/2.0
  for j=1:p0
# Factor multiplying l^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + j
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  alpha_real[j]/2.0
    if k < n
# Factor multiplying r^R_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + j
      jcol = jcol0-irow + m1+1
      aex[jcol,irow]=  gamma_real[j]
    end
  end
  for j=(p0+1):p
# Factor multiplying l^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0+ (j-p0-1)*2 + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  alpha_real[j]/2.0
# Factor multiplying l^I_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0+ (j-p0-1)*2 + 2
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  alpha_imag[j]/2.0
    if k < n
# Factor multiplying r^R_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow]=  gamma_real[j]
# Factor multiplying r^I_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow]=  gamma_imag[j]
    end
  end
  for j=1:p
    gamma_real_km1[j]=gamma_real[j]
    gamma_imag_km1[j]=gamma_imag[j]
  end
end
# Specify the number of bands below & above the diagonal:
m2 = m1
# Do the band-diagonal LU decomposition (indx is a permutation vector for
# pivoting - d gives the sign of the determinant based on the number of pivots):
d=bandec_trans(aex,nex,m1,m2,al_small,indx)
# Now select solution to compute the log likelihood:
# The equation A^{-1} y = b has been solved in bex (the extended vector).
# So, I need to pick out the b portion from bex, and take the dot product
# with y (which is the residuals of the data minus model, which is correlated
# noise that we are modeling with the multi-Lorentzian covariance function):
logdetofa = n*log(2.0)
for i=1:nex
  logdetofa += log(abs(aex[1,i]))
end
return logdetofa
end

function compile_matrix_symm(alpha_real::Vector,alpha_imag::Vector,beta_real::Vector,beta_imag::Vector, w ,t::Vector,
       nex::Int64,aex::Array,al_small::Array,indx::Vector{Int64})

# The vectors are arranged as:
# [x_k {{r^R_{k+1,i},r^I_{k+1,i}},i=1..p} {{l^R_{k+1,i},l^I_{k+1,i},i=1..p} x_{k+1} ...]
# For a total of (N-1)*(4(p-p0)+2p0+1)+1 = N(4(p-p0)+2p0+1)-4p equations.
# The equations are arranged as:
# 1). Equation 61 (real only; one single equation);
# 2). Equation 60 (real & imaginary; i=1..p);
# 3). Equation 59 (real & imagingary; i=1..p).

n = length(t)
p = length(alpha_real)
czero = zero(eltype(alpha_real))
p0 = 0
for i=1:p
  if beta_imag[i] == czero
    p0 += 1
  end
end
# nex = (n-1)*(4(p-p0)+2p0+1)+1
m1 = p0+2(p-p0+1)
if p == p0
  m1 = p0+1
end
width = 2m1+1
@assert(size(aex)==(width,nex))
@assert(size(al_small)==(m1,nex))
@assert(length(indx)==nex)
@assert(length(beta_real)==p)
@assert(length(beta_imag)==p)
for j=1:nex
  for i=1:width
    aex[i,j]=czero
  end
  for i=1:m1
    al_small[i,j]=czero
  end
end
#println("aex, al_small set to zero")
# Do the first row, eqn (61), which is a special case since l_1 = 0:
irow = 1
k = 1
d = sum(alpha_real)+w
jcol0 = 1
# Factor multiplying x_1:
jcol = jcol0-irow + m1+1
aex[jcol,irow] = d/2.0
one_type = one(eltype(alpha_real))
gamma_real = zeros(eltype(alpha_real),p)
gamma_imag = zeros(eltype(alpha_real),p)
ebt = czero
phi = czero
for j=1:p0
  ebt = exp(-beta_real[j]*(t[k+1]-t[k]))
  gamma_real[j] =  ebt*cos(phi)
# Factor multiplying r^R_{2,j}:
  jcol0 = 1+j
  jcol = jcol0-irow + m1+1
  aex[jcol,irow]= gamma_real[j]
end
for j=(p0+1):p
  ebt = exp(-beta_real[j]*(t[k+1]-t[k]))
  phi = beta_imag[j]*(t[k+1]-t[k])
  gamma_real[j] =  ebt*cos(phi)
  gamma_imag[j] = -ebt*sin(phi)
# Factor multiplying r^R_{2,j}:
  jcol0 = 1+p0+(j-p0-1)*2+1
  jcol = jcol0-irow + m1+1
  aex[jcol,irow]= gamma_real[j]
# Factor multiplying r^I_{2,j}:
  jcol0 = 1+p0+(j-p0-1)*2+2
  jcol = jcol0-irow + m1+1
  aex[jcol,irow]= gamma_imag[j]
end
gamma_real_km1=copy(gamma_real)
gamma_imag_km1=copy(gamma_imag)
# Now, loop over the middle part of the matrix
for k=2:n
  if k < n
    for j=1:p
      ebt = exp(-beta_real[j]*(t[k+1]-t[k]))
      phi = beta_imag[j]*(t[k+1]-t[k])
      gamma_real[j] =  ebt*cos(phi)
      gamma_imag[j] = -ebt*sin(phi)
    end
  end
  for j=1:p0
# Real part of equation (60):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + j
# Factors multiplying (l^R_{k,j})
    if k > 2
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 +2p-p0 + j
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real_km1[j]
    end
# Factor multiply x_k:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = gamma_real_km1[j]
# Factor multipling l^R_{k+1,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 +2p-p0 + j
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Real part of equation (59):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + j
# Factor multiplying r^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + j
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Factor multiplying x_k:
    jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = alpha_real[j]/2.0
# Factor multiplying r^R_{k+1,j}:
    if k < n
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + j
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real[j]
    end
  end
  for j=(p0+1):p
# Real part of equation (60):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
# Factors multiplying (l^R_{k,j},l^I_{k,j})
    if k > 2
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real_km1[j]
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_imag_km1[j]
    end
# Factor multiply x_k:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = gamma_real_km1[j]
# Factor multipling l^R_{k+1,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 +1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Imaginary part of equation (60):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
# Factors multiplying (l^R_{k,j},l^I_{k,j}):
    if k > 2
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] =  gamma_imag_km1[j]
      jcol0 = (k-3)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 +  (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = -gamma_real_km1[j]
    end
# Factor multiply x_k:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = gamma_imag_km1[j]
# Factor multiplying l^I_{k+1,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 2
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  one_type
# Real part of equation (59):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 1
# Factor multiplying r^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = -one_type
# Factor multiplying x_k:
    jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = alpha_real[j]/2.0
# Factor multiplying r^R_{k+1,j}:
    if k < n
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_real[j]
# Factor multiplying r^I_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] =  gamma_imag[j]
    end
# Imaginary part of equation (59):
    irow = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0 + (j-p0-1)*2 + 2
# Factor multiplying r^I_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  one_type
# Factor multiplying x_k:
    jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] = alpha_imag[j]/2.0
# Factor multiplying r^R_{k+1,j}:
    if k < n
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = gamma_imag[j]
# Factor multiplying r^I_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow] = -gamma_real[j]
    end
  end
# Equation (61), only real:
  irow = (k-1)*(4(p-p0)+2p0+1) + 1
# Factor multiplying x_k:
  jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1
  jcol = jcol0-irow + m1+1
  aex[jcol,irow] = d/2.0
  for j=1:p0
# Factor multiplying l^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + j
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  alpha_real[j]/2.0
    if k < n
# Factor multiplying r^R_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + j
      jcol = jcol0-irow + m1+1
      aex[jcol,irow]=  gamma_real[j]
    end
  end
  for j=(p0+1):p
# Factor multiplying l^R_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0+ (j-p0-1)*2 + 1
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  alpha_real[j]/2.0
# Factor multiplying l^I_{k,j}:
    jcol0 = (k-2)*(4(p-p0)+2p0+1) + 1 + 2p-p0 + p0+ (j-p0-1)*2 + 2
    jcol = jcol0-irow + m1+1
    aex[jcol,irow] =  alpha_imag[j]/2.0
    if k < n
# Factor multiplying r^R_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 1
      jcol = jcol0-irow + m1+1
      aex[jcol,irow]=  gamma_real[j]
# Factor multiplying r^I_{k+1,j}:
      jcol0 = (k-1)*(4(p-p0)+2p0+1) + 1 + p0 + (j-p0-1)*2 + 2
      jcol = jcol0-irow + m1+1
      aex[jcol,irow]=  gamma_imag[j]
    end
  end
  for j=1:p
    gamma_real_km1[j]=gamma_real[j]
    gamma_imag_km1[j]=gamma_imag[j]
  end
end
# Specify the number of bands below & above the diagonal:
m2 = m1
# Do the band-diagonal LU decomposition (indx is a permutation vector for
# pivoting - d gives the sign of the determinant based on the number of pivots):
d=bandec_trans(aex,nex,m1,m2,al_small,indx)
# Now select solution to compute the log likelihood:
# The equation A^{-1} y = b has been solved in bex (the extended vector).
# So, I need to pick out the b portion from bex, and take the dot product
# with y (which is the residuals of the data minus model, which is correlated
# noise that we are modeling with the multi-Lorentzian covariance function):
logdetofa = n*log(2.0)
for i=1:nex
  logdetofa += log(abs(aex[1,i]))
end
return logdetofa
end


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, Pkg

name = "librttopo"
version = v"1.1.0"

# Collection of sources required to complete build
sources = [
    ArchiveSource("https://download.osgeo.org/librttopo/src/librttopo-$(version).tar.gz", "a77d8b787ba13f685de819348d5146f9f6ec56fd3bcf71e880dfc5e0086d4cb0")
]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/librttopo*

if [[ ${target} == *-freebsd* ]]; then
    export CPPFLAGS="-I${includedir}"
fi

./configure \
--prefix=${prefix} \
--build=${MACHTYPE} \
--host=${target}

make -j${nproc}
make install
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms()

# The products that we will ensure are always built
products = [
    LibraryProduct("librttopo", :librttopo)
]

# Dependencies that must be installed before this package can be built
dependencies = [
    Dependency(PackageSpec(name="GEOS_jll", uuid="d604d12d-fa86-5845-992e-78dc15976526"))
]

# Build the tarballs, and possibly a `build.jl` as well.
#GEOS uses gcc6
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies; julia_compat="1.6", preferred_gcc_version = v"6")

max_stars_repo_name: plut/Yggdrasil

max_issues_repo_name: plut/Yggdrasil

max_forks_repo_name: plut/Yggdrasil


text:
module CubicEoS

export AbstractEoSComponent, AbstractEoSMixture
export BrusilovskyEoSComponent, BrusilovskyEoSMixture, thermo_buffer
export molar_mass, carbon_number, name, describe, load, components # Do we need to export `load`?
export ncomponents, pressure, wilson_saturation_pressure, compressibility
export log_c_activity!, log_c_activity, log_c_activity_wj!, log_c_activity_wj
export vt_stability, vt_stability_buffer
export vt_flash

include("constants.jl")
include("types.jl")
include("interface.jl")
include("dbload.jl")
include("basic_thermo.jl")
include("chempotential.jl")
include("vt_stability.jl")
include("vt_flash.jl")
include("newton.jl")

end # module

max_stars_repo_name: vvpisarev/CubicEoS

max_issues_repo_name: vvpisarev/CubicEoS

max_forks_repo_name: vvpisarev/CubicEoS


text:
abstract type AbstractFunction end

abstract type FunctionSignature end
struct InPlace <: FunctionSignature end
struct StaticReturn <: FunctionSignature end
function_signature(fun::AbstractFunction) = InPlace()

abstract type DiffMethod end
struct ForwardAD <: DiffMethod end
struct FiniteDifference <: DiffMethod end
struct UserDefined <: DiffMethod end
default_diffmethod(::AbstractFunction) = UserDefined()
default_signature(::AbstractFunction) = StaticReturn()

abstract type StateVectorType end
struct EuclideanState <: StateVectorType end
struct RotationState <: StateVectorType end
statevectortype(::Type{<:AbstractFunction}) = EuclideanState()
statevectortype(fun::AbstractFunction) = statevectortype(typeof(fun))

dims(fun::AbstractFunction) = (state_dim(fun), control_dim(fun), output_dim(fun))
state_dim(fun::AbstractFunction) = throw(NotImplementedError("state_dim needs to be implemented for $(typeof(fun))."))
control_dim(fun::AbstractFunction) = throw(NotImplementedError("control_dim needs to be implemented for $(typeof(fun))."))
output_dim(fun::AbstractFunction) = throw(NotImplementedError("output_dim needs to be implemented for $(typeof(fun))"))
errstate_dim(fun::AbstractKnotPoint) = state_dim(fun)

Base.size(fun::AbstractFunction) = (state_dim(fun), control_dim(fun), output_dim(fun))
@inline getinputs(z::AbstractVector) = z
@inline setinputs!(dest::AbstractVector{<:Real}, src::AbstractVector{<:Real}) = src
inputtype(::Type{<:AbstractFunction}) = Float64

# Top-level command that can be overridden
# Should only be overridden if using hand-written Jacobian methods
evaluate!(fun::AbstractFunction, y, z::AbstractKnotPoint) = evaluate!(fun, y, state(z), control(z), getparams(z))
evaluate(fun::AbstractFunction, z::AbstractKnotPoint) = evaluate(fun, state(z), control(z), getparams(z))

# Strip the parameter
evaluate!(fun::AbstractFunction, y, x, u, p) = evaluate!(fun, y, x, u)
evaluate(fun::AbstractFunction, x, u, p) = evaluate(fun, x, u)

# Minimal call that must be implemented
evaluate!(fun::AbstractFunction, y, x, u) =
    throw(NotImplementedError("User-defined in-place function not implemented for $(typeof(fun))"))
evaluate(fun::AbstractFunction, x, u) =
    throw(NotImplementedError("User-defined static return function not implemented for $(typeof(fun))"))

# Jacobian
jacobian!(::FunctionSignature, ::UserDefined, fun::AbstractFunction, J, y, z) = jacobian!(fun, J, y, z)
jacobian!(fun::AbstractFunction, J, y, z::AbstractKnotPoint) = jacobian!(fun, J, y, state(z), control(z), getparams(z))
jacobian!(fun::AbstractFunction, J, y, x, u, p) = jacobian!(fun, J, y, x, u)
jacobian!(fun::AbstractFunction, J, y, x, u) = throw(NotImplementedError("User-defined Jacobian not implemented for $(typeof(fun))"))

# Jacobian of Jacobian-vector product
∇jacobian!(::FunctionSignature, ::UserDefined, fun::AbstractFunction, H, b, y, z) =
    ∇jacobian!(fun, H, b, y, z)
∇jacobian!(fun::AbstractFunction, H, b, y, z::AbstractKnotPoint) =
    ∇jacobian!(fun, H, b, y, state(z), control(z), getparams(z))
∇jacobian!(fun::AbstractFunction, H, b, y, x, u, p) =
    ∇jacobian!(fun, H, b, y, state(z), control(z))
∇jacobian!(fun::AbstractFunction, H, b, y, x, u) =
    throw(UserDefined("User-defined Jacobian of Jacobian-vector product is undefined for $(typeof(fun))"))

# Dispatch on `statevectortype` trait
state_diff(fun::AbstractFunction, x, x0) = state_diff(statevectortype(fun), fun, x, x0)
errstate_dim(fun::AbstractFunction) = errstate_dim(statevectortype(fun), fun)
state_diff_jacobian!(fun::AbstractFunction, J, z::AbstractKnotPoint) =
    state_diff_jacobian!(statevectortype(fun), fun, J, state(z))
state_diff_jacobian!(fun::AbstractFunction, J, x) =
    state_diff_jacobian!(statevectortype(fun), fun, J, x)
∇²differential!(fun::AbstractFunction, ∇G, x, dx) =
    ∇²differential!(statevectortype(fun), fun, ∇G, x, dx)

# Euclidean state vectors
state_diff(::EuclideanState, fun::AbstractFunction, x, x0) = x - x0
errstate_dim(::EuclideanState, fun::AbstractFunction) = state_dim(fun)
state_diff_jacobian!(::EuclideanState, fun::AbstractFunction, J, x) = J .= I(state_dim(fun))
∇²differential!(::EuclideanState, fun::AbstractFunction, ∇G, x, dx) = ∇G .= 0

# Some convenience methods
Base.randn(::Type{T}, model::AbstractFunction) where {T} = ((@SVector randn(T, state_dim(model))), (@SVector randn(T, control_dim(model))))
Base.zeros(::Type{T}, model::AbstractFunction) where {T} = ((@SVector zeros(T, state_dim(model))), (@SVector zeros(T, control_dim(model))))
Base.rand(::Type{T}, model::AbstractFunction) where {T} = ((@SVector rand(T, state_dim(model))), (@SVector rand(T, control_dim(model))))
Base.fill(model::AbstractFunction, v) = ((@SVector fill(v, state_dim(model))), (@SVector fill(v, control_dim(model))))

Base.randn(model::AbstractFunction) = Base.randn(Float64, model)
Base.zeros(model::AbstractFunction) = Base.zeros(Float64, model)
Base.rand(model::AbstractFunction) = Base.rand(Float64, model)


text:
using Caesar, RoME, IncrementalInference
using DelimitedFiles

# Visualization
using Cairo, Fontconfig
using Colors, Gadfly
using RoMEPlotting, KernelDensityEstimatePlotting

#Array for synthetic data
posData = zeros(10,2);
posData[:,1] = collect(-4.5:4.5);

testDir = joinpath(ENV["HOME"],"data","synthetic","10dB");
csvWaveData = zeros(8192,10);

# gps covariance
rtkCov = Matrix(Diagonal([0.1;0.1].^2))

## build the factor graph
N = 100
fg = initfg()
addVariable!(fg, :l1, Point2)

for i in 1:10
    sym = Symbol("x$i")
    addVariable!(fg, sym, Point2)
    setVal!(fg, sym, zeros(2,N))
    pp = PriorPoint2(MvNormal(posData[i,1:2], rtkCov) )
    addFactor!(fg, [sym;], pp)
end

dataFile = joinpath(testDir,"1.txt")
csvWaveData = readdlm(dataFile,',',Float64,'\n')
#
cfgFile = joinpath(ENV["HOME"],"data","sas","SAS2D.yaml");
cfgd=loadConfigFile(cfgFile)
chirpFile = joinpath(ENV["HOME"],"data","sas","chirp250.txt");
sas2d = prepareSAS2DFactor(10, csvWaveData, rangemodel=:Correlator, cfgd=cfgd, chirpFile=chirpFile)

#
addFactor!(fg, [:l1;:x1;:x2;:x3;:x4;:x5;:x6;:x7;:x8;:x9;:x10], sas2d, autoinit=false)
#, threadmodel=SingleThreaded )

writeGraphPdf(fg, engine="fdp")

getSolverParams(fg).drawtree = true
getSolverParams(fg).showtree = false

tree = solveTree!(fg)

# drawTree(tree, show=true)

# forward SAS case
# for ti in 1:Threads.nthreads() reset!(sas2d.threadreuse[ti].dbg) end

@time predL1 = IncrementalInference.approxConv(fg, ls(fg, :l1)[1], :l1, N=N)
# setVal!(fg, :l1, zeros(2,N))

predL1 = getVal(fg,:l1)
pllim = 800
X1 = getVal(fg, :x1)
pl = Gadfly.plot(
  Gadfly.layer(x=predL1[1,:][-pllim .< predL1[1,:] .< pllim],y=predL1[2,:][-pllim .< predL1[2,:] .< pllim],   Gadfly.Geom.hexbin(xbincount=200, ybincount=200)),
  Gadfly.layer(x=posData[1,:],y=posData[2,:], Gadfly.Geom.point)
); # for skipping Juno display

pl |> PDF("/tmp/test.pdf"); @async run(`evince /tmp/test.pdf`)
pl |> SVG("/tmp/test.svg", 35cm, 25cm); @async run(`firefox /tmp/test.svg`)

## backwards case

# backwards leave one out case
setVal!(fg, :l1, 1.0*randn(2,N))
setVal!(fg, :x2, rand(MvNormal(posData[2,1:2], 1.0*Matrix{Float64}(Diagonal([1.0;1.0]))),N))
# for ti in 1:Threads.nthreads() reset!(sas2d.threadreuse[ti].dbg) end

@time predX2 = IncrementalInference.approxConv(fg, ls(fg, :l1)[1], :x2, N=N)

pl = Gadfly.plot(
layer(x=predX2[1,:], y=predX2[2,:], Geom.histogram2d(xbincount=500,ybincount=500)),
layer(x=posData[1:5,1],y=posData[1:5,2], Geom.point)
)

pl.coord = Coord.Cartesian(xmin=0,xmax=20,ymin=-50,ymax=-35)
pl |> SVG("/tmp/test.svg", 35cm, 25cm)

pl_wait = plotKDE(kde!(predX2))
pl.layers = [pl.layers; pl_wait.layers]

pl |> SVG("/tmp/test.svg", 35cm, 25cm)

0


text:
if VERSION ≥ v"1.6-"
    try
        pkgid = Base.PkgId(Base.UUID("052768ef-5323-5732-b1bb-66c8b64840ba"), "CUDA")
        Base.require(pkgid)
    catch
        @info "Failed to import CUDA. Trying again with `@stdlib`..."
        push!(LOAD_PATH, "@stdlib")
    end
end
include("load.jl")
FoldsCUDATests.runtests()


text:
configKey = "ROBRECSOLVER_CONFIG"

"""
    loadProperties()

Loads properties stored in an INI file from the specified file location. To change default location set `$configKey` environment variable either in Julia REPL or in `~/.julia/config/startup.jl` and then reload $(current_module()) package:
```julia-repl
julia> ENV[$configKey] = "<path_to_file>"
julia> Pkg.reload("RobRecSolver")
```
Use default properties file `Pkg.dir("RobRecSolver")/conf/config.ini` as a reference.

In order to reset changes simply delete environment variable and reload $(current_module()) package.
"""
loadProperties = let

    function loadProperties()
        path = joinpath("$(Pkg.dir("RobRecSolver"))", "conf", "config.ini")
        if haskey(ENV, configKey)
            path = ENV[configKey]
        end
        @debug "Loading config from $path. If you want to change default config please set up $configKey environment variable"
        conf = ConfParse(path)
        parse_conf!(conf)
        conf
    end

end

"""
    getProperty(parameter[, parameterType, section])

Get value for key of name `parameter` of type `parameterType` from section `section`
from either default properties files or the one specified with a path in `$configKey`.
Argument  `parameterType` defaults to `Int` and `section` defaults to `main`.
"""
getProperty = let

    properties = loadProperties()

    function getProperty(parameter; parameterType=Int, section = "main")
        parse(parameterType, retrieve(properties, section, parameter))
    end

end


text:
# syntax: proto3
using ProtoBuf
import ProtoBuf.meta

struct __enum_NullValue <: ProtoEnum
    NULL_VALUE::Int32
    __enum_NullValue() = new(0)
end #struct __enum_NullValue
const NullValue = __enum_NullValue()

mutable struct Struct_FieldsEntry <: ProtoType
    key::AbstractString
    value::Base.Any
    Struct_FieldsEntry(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct Struct_FieldsEntry (mapentry) (has cyclic type dependency)
const __ftype_Struct_FieldsEntry = Dict(:value => "Value")
meta(t::Type{Struct_FieldsEntry}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES, __ftype_Struct_FieldsEntry)

mutable struct Struct <: ProtoType
    fields::Base.Dict # map entry
    Struct(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct Struct (has cyclic type dependency)
const __ftype_Struct = Dict(:fields => "Base.Dict{AbstractString,Value}")
meta(t::Type{Struct}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES, __ftype_Struct)

mutable struct Value <: ProtoType
    null_value::Int32
    number_value::Float64
    string_value::AbstractString
    bool_value::Bool
    struct_value::Struct
    list_value::Base.Any
    Value(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct Value (has cyclic type dependency)
const __ftype_Value = Dict(:list_value => "ListValue")
const __oneofs_Value = Int[1,1,1,1,1,1]
const __oneof_names_Value = [Symbol("kind")]
meta(t::Type{Value}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, __oneofs_Value, __oneof_names_Value, __ftype_Value)

mutable struct ListValue <: ProtoType
    values::Base.Vector{Value}
    ListValue(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct ListValue (has cyclic type dependency)

export NullValue, Struct_FieldsEntry, Struct, Value, ListValue, Struct_FieldsEntry, Struct, Value, ListValue
# mapentries: "Struct_FieldsEntry"=>("AbstractString", "Value")


text:
# ---
# title: 463. Island Perimeter
# id: problem463
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Hash Table
# link: <https://leetcode.com/problems/island-perimeter/description/>
# hidden: true
# ---
#
# You are given `row x col` `grid` representing a map where `grid[i][j] = 1`
# represents land and `grid[i][j] = 0` represents water.
#
# Grid cells are connected **horizontally/vertically** (not diagonally). The
# `grid` is completely surrounded by water, and there is exactly one island
# (i.e., one or more connected land cells).
#
# The island doesn't have "lakes", meaning the water inside isn't connected to
# the water around the island. One cell is a square with side length 1. The grid
# is rectangular, width and height don't exceed 100. Determine the perimeter of
# the island.
#
#
#
# **Example 1:**
#
# ![](https://assets.leetcode.com/uploads/2018/10/12/island.png)
#
#
#
#     Input: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
#     Output: 16
#     Explanation: The perimeter is the 16 yellow stripes in the image above.
#
#
# **Example 2:**
#
#
#
#     Input: grid = [[1]]
#     Output: 4
#
#
# **Example 3:**
#
#
#
#     Input: grid = [[1,0]]
#     Output: 4
#
#
#
#
# **Constraints:**
#
#   * `row == grid.length`
#   * `col == grid[i].length`
#   * `1 <= row, col <= 100`
#   * `grid[i][j]` is `0` or `1`.
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
let old_pwd = pwd()
cd(dirname(@__FILE__))

@testset "path utilities" begin
    @test Atom.realpath′("./utils.jl") == realpath(@__FILE__)
    @test Atom.realpath′(".././dontexist") == ".././dontexist"

    @test Atom.isuntitled(".\\untitled-asdj2123:12") == true
    @test Atom.isuntitled(".\\untitled-asdj2cx3213") == true
    @test Atom.isuntitled("./untitled-asdj2124o3:12") == true
    @test Atom.isuntitled("./untitled-a1j2124o3:12") == true
    @test Atom.isuntitled("untitled-1651asdsd23") == true
    @test Atom.isuntitled("untitled1651asdsd23") == false
    @test Atom.isuntitled("untitled-1651asdsd23:as") == false
    @test Atom.isuntitled("./utils.jl") == false
    @test Atom.isuntitled("../test/utils.jl") == false

    @test Atom.pkgpath(@__FILE__) == "utils.jl"
    @test Atom.pkgpath("foo/bar/pkgname/src/foobar.jl") == "bar/pkgname/src/foobar.jl"
    @test Atom.pkgpath("foo\\bar\\pkgname ü\\src\\foobar.jl") == "bar\\pkgname ü\\src\\foobar.jl"

    @test Atom.fullpath("untitled-asdj2cx3213") == "untitled-asdj2cx3213"
    @test Atom.fullpath("/test/foobar.jl") == "/test/foobar.jl"
    @test joinpath(split(Atom.fullpath("foobar.jl"), Base.Filesystem.pathsep())[end-1:end]...)  == joinpath("base", "foobar.jl")

    @test Atom.appendline("test.jl", -1) == "test.jl"
    @test Atom.appendline("test.jl", 0) == "test.jl"
    @test Atom.appendline("test.jl", 10) == "test.jl:10"

    @test isfile(Atom.expandpath(Atom.view(first(methods(rand)))[2].file)[2])
end

@testset "REPL path finding" begin
    if Sys.iswindows()
        @test Atom.fullREPLpath(raw"@ Atom C:\Users\ads\.julia\dev\Atom\src\repl.jl:25") == (raw"C:\Users\ads\.julia\dev\Atom\src\repl.jl", 25)
        @test Atom.fullREPLpath(raw"C:\Users\ads\.julia\dev\Atom\src\repl.jl:25") == (raw"C:\Users\ads\.julia\dev\Atom\src\repl.jl", 25)
        @test Atom.fullREPLpath(raw".\foo\bar.jl:1") == (Atom.fullpath(raw".\foo\bar.jl"), 1)
        @test Atom.fullREPLpath(raw"foo\bar.jl:1") == (Atom.fullpath(raw".\foo\bar.jl"), 1)
    else
        @test Atom.fullREPLpath("@ Atom /home/user/foo/.julia/bar.jl:25") == ("/home/user/foo/.julia/bar.jl", 25)
        @test Atom.fullREPLpath("/home/user/foo/.julia/bar.jl:25") == ("/home/user/foo/.julia/bar.jl", 25)
        @test Atom.fullREPLpath("./foo/bar.jl:1") == (Atom.fullpath("./foo/bar.jl"), 1)
        @test Atom.fullREPLpath("foo/bar.jl:1") == (Atom.fullpath("./foo/bar.jl"), 1)
    end
end

@testset "finding dev packages" begin
    @test Atom.finddevpackages() isa AbstractDict
end

# TODO: baselink, edit

cd(old_pwd)
end

@testset "get utilities" begin
    # TODO: others

    @testset "get docs" begin
        using Atom: getdocs
        using Markdown: MD

        # basic
        let doc = getdocs(Main.Junk, "imwithdoc")
            @test occursin("im a doc in Junk", string(doc))
        end

        # use fallback modules if `@doc` is not defined for a module passed as 1st argument
        let mod = Main.Junk.BareJunk
            doc = getdocs(mod, "imwithdoc") # by `@doc` in Main
            @test occursin("im a doc in BareJunk", string(doc))

            doc = getdocs(mod, "imwithdoc", Main.Junk) # by `@doc` in Junk
            @test occursin("im a doc in BareJunk", string(doc))

            # don't error even if `@doc` is not defined for a fallback module
            @test getdocs(mod, "imwithdoc", mod) isa MD
        end
    end
end

@testset "is utilities" begin
    @testset "iskeyword" begin
        using Atom: iskeyword

        @test iskeyword(:begin)
        @test iskeyword("begin")
        @test !iskeyword(:iskeyword)
    end

    @testset "ismacro" begin
        using Atom: ismacro

        @test ismacro("@view")
        @test ismacro("r\"")
        @test ismacro(getfield(Main, Symbol("@view")))
    end
end

@testset "string utilities" begin
    @testset "limiting excessive strings" begin
        using Atom: strlimit

        # only including ASCII
        @test strlimit("julia", 5) == "julia"
        @test strlimit("julia", 4) == "jul…"
        @test strlimit("Julia in the Nutshell", 21, " ...") == "Julia in the Nutshell"
        @test strlimit("Julia in the Nutshell", 20, " ...") == "Julia in the Nut ..."

        # including Unicode: should respect _length_ of strings, not code units
        @test strlimit("jμλια", 5) == "jμλια"
        @test strlimit("jμλια", 4) == "jμλ…"
        @test strlimit("Jμλια in the Nutshell", 21, " ...") == "Jμλια in the Nutshell"
        @test strlimit("Jμλια in the Nutshell", 20, " ...") == "Jμλια in the Nut ..."
    end
end


text:
# To load a matlab data
using MAT

function load_data()
  #=
  This function loads the training, validation and test datas.
  Finally it returns all the needed data for traing and test datas
  Here are the dimensions:

  train_input = <number_of_futures:256> by <number of training cases>
  train_target = sparse vector for each training case <10> by <number of training cases>

  test_input = <number_of_futures:256> by <number of test cases>
  test_target = <10> by <number of training cases>

  ----
  =#

file = matopen("data.mat")
data = read(file, "data")

# Load the training data
train_input = data["training"]["inputs"]
train_target = data["training"]["targets"]

# Load the validation data
valid_input = data["validation"]["inputs"]
valid_target = data["validation"]["targets"]

# Load the test data
test_input = data["test"]["inputs"]
test_target = data["test"]["targets"]

return (train_input,
        train_target,
        valid_input,
        valid_target,
        test_input,
        test_target)
end

max_stars_repo_name: kirnap/Machine-Learning-in-Julia

max_issues_repo_name: kirnap/Machine-Learning-in-Julia

max_forks_repo_name: kirnap/Machine-Learning-in-Julia


text:
push!(LOAD_PATH,"../src/")

using TheDancer
using Base.Test

N, Edisorder, Jdisorder, modelJ, B, dipolestrength, r = init!(3, 0.0, 0.0, 0.001, 298, 20)

"""
Compares the results of a 3-site model when dipole-dipole interactions are/are
not included.

The dipole-dipole interaction field is calculated from the gradient of the
potential, which scales as r^-6 for induced dipoles. The dipoles are first found
from the field established by the charge distribution alone. The field is then
updated to include the dipole-dipole effects and the dipoles are recalculated.

Test will be successful if the effect of including these interactions results in
a difference in the maximum density of less than 0.00001.
"""
function main()

    densities = zeros(2)
    j=0
    for d_d in [false,true]
        j+=1
        S,E,H,psi,dipoles=prepare_model()
        density = abs.(psi.^2)
        for i in 1:200
            S,H,psi,density,dipoles  = AdiabaticPropagation(S,dipoles,E,false,d_d)
        end
        densities[j] = density[2]
    end

    diff = densities[1] - densities[2]
    println(diff)

    ε = 1E-5
    @test  0 ≈ diff atol = ε

end

main()