EHTModels

Documentation for EHTModels.

EHTModels.AbstractModelType
AbstractModel

The abstract model type. To instantiate your own model type you should subtybe from this model. Additionally you need to implement the following methods to satify the interface: Mandatory Methods

  • isprimitive: defines whether a model is standalone or is defined in terms of other models. is the model is primitive then this should return IsPrimitive() otherwise it returns NotPrimitive()
  • visanalytic: defines whether the model visibilities can be computed analytically. If yes then this should return IsAnalytic() and the user must to define visibility_point. If not analytic then visanalytic should return NotAnalytic().
  • imanalytic: defines whether the model intensities can be computed pointwise. If yes

then this should return IsAnalytic() and the user must to define intensity_point. If not analytic then imanalytic should return NotAnalytic().

  • radialextent: Provides a estimate of the radial extent of the model in the image domain. This is used for estimating the size of the image, and for plotting.
  • flux: Returns the total flux of the model.

Optional Methods:

  • intensity_point: Defines how to compute model intensities pointwise. Note this is must be defined if imanalytic(::Type{YourModel})==IsAnalytic().
  • visibility_point: Defines how to compute model visibilties pointwise. Note this is must be defined if visanalytic(::Type{YourModel})==IsAnalytic().
  • _visibilities: Vectorized version of visibility_point if you can gain additional speed
  • intensitymap: Computes the whole image of the model
  • intensitymap!: Inplace version of intensitymap
EHTModels.AbstractModifierType
abstract type AbstractModifier{M<:AbstractModel} <: AbstractModel

Abstract type for image modifiers. These are some model wrappers that can transform any model using simple Fourier transform properties. By default these modified models will have the same analytic properties as the base unmodified model, i.e.

julia> visanalytic(stretched(Disk(), 2.0, 2.0)) == visanalytic(Disk())
true

Additionally these are classic examples of non-primitive images i.e.,

julia> isprimitive(Comrade.AbstractModifier) == Comrade.NotAnalytic()

As a result of this the implementation of a model is slightly different

This methods assume the modifiers are of the form I(x,y) -> fᵢ(x,y)I(gᵢ(x,y)) V(u,v) -> fᵥ(u,v)V(gᵥ(u,v)) where g are the transformimage/uv functions and f are the scaleimage/uv function. See those docstrings for guidance on implementation details.

EHTModels.AddModelType
struct AddModel{T1, T2} <: EHTModels.CompositeModel{T1, T2}

Pointwise addition of two models in the image and visibility domain. An end user should instead call added or Base.+ when constructing a model

Example

julia> m1 = Disk() + Gaussian()
julia> m2 = added(Disk(), Gaussian()) + Ring()
EHTModels.ButterworthType
Butterworth{T, N}() where {T}

Butterwoth filter in the visibility domain, i.e. the fourier-domain profile

\[ V_N(r) = \left[ 1 + \left( \frac{1}{r}\right)^{2N} \right]^{-1/2}\]

i.e. a unit filtering length and unit flux filter. By default if T isn't given, Butterworth defaults to T=Float64. If futher N isn't given, Butterworth defaults to N=2.

EHTModels.CompositeModelType
abstract type CompositeModel{M1, M2} <: AbstractModel

Abstract type that denotes a composite model. Where we have combined two models together.

Implementation

Any implementation of a composite type must define the following methods:

  • visibility_point
  • uv_combinator
  • imanalytic
  • visanalytic
  • ComradeBase.intensity_point if model intensity is IsAnalytic
  • intensitymap! if model intensity is NotAnalytic
  • intensitymap if model intensity is NotAnalytic
  • flux
  • radialextent
  • visibilities (optional)
EHTModels.ConvolvedModelType
struct ConvolvedModel{M1, M2} <: EHTModels.CompositeModel{M1, M2}

Pointwise addition of two models in the image and visibility domain. An end user should instead call convolved. Also see smoothed(m, σ) for a simplified function that convolves a model m with a Gaussian with standard deviation σ.

EHTModels.DensityAnalyticType
DensityAnalytic

Internal type for specifying the nature of the model functions. Whether they can be easily evaluated pointwise analytic. This is an internal type that may change.

EHTModels.DiskType
$(TYPEDEF)

Uniform disk geometrical model, i.e. the intensity profile

\[ I(x,y) = \begin{cases} \pi^{-1} & x^2+y^2 < 1 \\ 0 & x^2+y^2 \geq 0 \end{cases}\]

i.e. a unit radius and unit flux disk. By default if T isn't given, Disk defaults to Float64

EHTModels.GaussianType
struct Gaussian{T} <: GeometricModel

Gaussian with unit standard deviation and flux. By default if T isn't given, Gaussian defaults to Float64

EHTModels.GeometricModelType
abstract type GeometricModel <: AbstractModel

A type that defines it is a geometric model. These are usually primitive models, and are usually analytic in Fourier and the image domain. As a result a user only needs to implement the following methods

  • visibility_point
  • intensity_point
  • radialextent

Note that if the geometric model isn't analytic then the usual methods listed in Comrade.AbstractModel for non-analytic models need to be implemented.

EHTModels.IsAnalyticType
struct IsAnalytic <: EHTModels.DensityAnalytic

Defines a trait that a states that a model is analytic. This is usually used with an abstract model where we use it to specify whether a model has a analytic fourier transform and/or image.

EHTModels.NotAnalyticType
struct NotAnalytic <: EHTModels.DensityAnalytic

Defines a trait that a states that a model is analytic. This is usually used with an abstract model where we use it to specify whether a model has does not have a easy analytic fourier transform and/or intensity function.

EHTModels.PrimitiveTraitType
abstract type PrimitiveTrait

This trait specifies whether the model is a primitive

Notes

This will likely turn into a trait in the future so people can inject their models into Comrade more easily.

EHTModels.RectangleType
$(TYPEDEF)

Uniform rectangle geometrical model, i.e. the intensity profile

\[ I(x,y) = \begin{cases} 1 & |x| < 0.5 and |y| < 0.5 \\ 0 & (otherwise) \end{cases}\]

i.e. a unit length and unit flux rectangle. By default if T isn't given, Rectangle defaults to Float64

EHTModels.RenormalizedModelType
struct RenormalizedModel{M<:AbstractModel, T} <: EHTModels.AbstractModifier{M<:AbstractModel}

Renormalizes the flux of the model to the new value scale*flux(model). We have also overloaded the Base.:* operator as syntactic sugar although I may get rid of this. An end user should not call this directly but instead the renormed function or Base.:* instead.

Example

julia> renormed(Gaussian(), 2.0) == 2.0*Gaussian()
true
EHTModels.RotatedModelType
struct RotatedModel{M<:AbstractModel, T} <: EHTModels.AbstractModifier{M<:AbstractModel}

Type for the rotated model. This is more fine grained constrol of rotated model. An end user should not call this directly but instead the rotated function instead.

EHTModels.ShiftedModelType
struct ShiftedModel{M<:AbstractModel, T} <: EHTModels.AbstractModifier{M<:AbstractModel}

Shifts the model by Δx units in the x-direction and Δy units in the y-direction. An end user should not call this directly but instead the shifted function instead.

EHTModels.StretchedModelType
struct StretchedModel{M<:AbstractModel, T} <: EHTModels.AbstractModifier{M<:AbstractModel}

Stretched the model in the x and y directions, i.e. the new intensity is Iₛ(x,y) = 1/(αβ) I(x/α, y/β), where were renormalize the intensity to preserve the models flux. An end user should not call this directly but instead the stretched function instead.

Base.:+Method
Base.:+(m1::AbstractModel, m2::AbstractModel)

Combine two models to create a composite AddModel. This adds two models pointwise, i.e.

julia> m1 = Gaussian()
julia> m2 = Disk()
julia> visibility(m1+m2, 1.0, 1.0) == visibility(m1, 1.0, 1.0) + visibility(m2, 1.0, 1.0)
true
EHTModels.CircularGaussianFunction
CircularGaussian(F, θmaj, [x0, y0]; [θunit, ϕunit])

Create an circular Gaussian.

Args:

  • F::Real: The total flux desnity of the Gaussian.
  • θfwhm::Real: The FWHM size of the Gaussian.
  • x0, y0::Real: The centoral position in the unit of θunit. Default to 0.
  • θunit::Unitful: The unit for θ, x0 and y0, respectively. Default: θunit=rad.
EHTModels.DiskFilterFunction
DiskFilter(θmaj, [θmin, ϕ]; [θunit, ϕunit])

Create an elliptical Disk filter with the total flux density of unity centered at the origin.

Args:

  • θmaj::Real: The major-axis size of the disk.
  • θmin::Real: The minor-axis size of the disk. If θmin < 0, then θmin = θmax (i.e. circular disk). Default to -1.
  • ϕ::Real: The position angle of the elliptical disk. Default to 0.
  • θunit, ϕunit::Unitful: The unit for θmaj & θmin and ϕ, respectively. Default: θunit=rad and ϕ=deg.
EHTModels.EllipticalGaussianFunction
EllipticalGaussian(F, θmaj, [θmin, ϕ, x0, y0]; [θunit, ϕunit])

Create an elliptical Gaussian.

Args:

  • F::Real: The total flux desnity of the Gaussian.
  • θmaj::Real: The major-axis FWHM size of the Gaussian.
  • θmin::Real: The minor-axis FWHM size of the Gaussian. If θmin < 0, then θmin = θmax (i.e. circular Gaussian). Default to -1.
  • ϕ::Real: The position angle of the Gausian. Default to 0.
  • x0, y0::Real: The centoral position in the unit of θunit. Default to 0.
  • θunit::Unitful: The unit for θmaj, θmin, x0 and y0. Default: θunit=rad.
  • ϕunit::Unitful: The unit for ϕ. Default: ϕ=deg.
EHTModels.GaussianFilterFunction
GaussianFilter(θmaj, [θmin, ϕ]; [θunit, ϕunit])

Create an elliptical Gaussian filter with the total flux density of unity centered at the origin.

Args:

  • θmaj::Real: The major-axis FWHM size of the Gaussian.
  • θmin::Real: The minor-axis FWHM size of the Gaussian. If θmin < 0, then θmin = θmax (i.e. circular Gaussian). Default to -1.
  • ϕ::Real: The position angle of the Gausian. Default to 0.
  • θunit, ϕunit::Unitful: The unit for θmaj & θmin and ϕ, respectively. Default: θunit=rad and ϕ=deg.
EHTModels.RectangleFilterFunction
RectangleFilter(θmaj, [θmin, ϕ]; [θunit, ϕunit])

Create an rectangle filter with the total flux density of unity.

Args:

  • θmaj::Real: The major-axis size of the rectangle.
  • θmin::Real: The minor-axis size of the rectangle. If θmin < 0, then θmin = θmax (i.e. square). Default to -1.
  • ϕ::Real: The position angle of the rectangle. Default to 0.
  • θunit, ϕunit::Unitful: The unit for θmaj & θmin and ϕ, respectively. Default: θunit=rad and ϕ=deg.
EHTModels.addedMethod
added(m1::AbstractModel, m2::AbstractModel)

Combine two models to create a composite AddModel. This adds two models pointwise, i.e.

julia> m1 = Gaussian()
julia> m2 = Disk()
julia> visibility(added(m1,m2), 1.0, 1.0) == visibility(m1, 1.0, 1.0) + visibility(m2, 1.0, 1.0)
true
EHTModels.basemodelMethod
basemodel(model::AbstractModel)

Returns the base model from a modified model. If there is no basemodel this just return the model itself.

Example

julia> basemodel(stretched(Disk(), 1.0, 2.0)) == Disk()
true
EHTModels.componentsMethod
components(m::AbstractModel)

Returns the model components for a composite model. This will return a Tuple with all the models you have constructed.

Example

julia> m = Gaussian() + Disk()
julia> components(m)
(Gaussian{Float64}(), Disk{Float64}())
EHTModels.convolvedMethod
convolved(m1::AbstractModel, m2::AbstractModel)

Convolve two models to create a composite ConvolvedModel.

julia> m1 = Ring()
julia> m2 = Disk()
julia> convolved(m1, m2)
EHTModels.create_filterFunction
create_filter(AbstractModel, θmaj, [θmin, ϕ]; [θunit, ϕunit]) => AbstractModel

Create a filter model by streaching and rotating the given input basemodel.

Args:

  • θmaj::Real: The major-axis size of the rectangle.
  • θmin::Real: The minor-axis size of the rectangle. If θmin < 0, then θmin = θmax (i.e. square). Default to -1.
  • ϕ::Real: The position angle of the rectangle. Default to 0.
  • θunit, ϕunit::Unitful: The unit for θmaj & θmin and ϕ, respectively. Default: θunit=rad and ϕ=deg.
EHTModels.fluxFunction
flux(model::AbstractModel)

Returns the total flux of the model.

EHTModels.imanalyticMethod
imanalytic(::Type{<:AbstractModel})

Determines whether the model is pointwise analytic in the image domain, i.e. we can evaluate its intensity at an arbritrary point. If IsAnalytic() then it will try to call intensity_point to calculate the intensity.

EHTModels.intensity_pointFunction
intensity_point(model::AbstractModel, x, y, args...)

Function that computes the pointwise intensity if the model has the trait in the image domain IsAnalytic(). Otherwise it will use construct the image in visibility space and invert it.

EHTModels.intensitymap!Function
intensitymap!(buffer::AbstractMatrix, model::AbstractModel, args...)

Computes the intensity map of model by modifying the buffer

EHTModels.isprimitiveFunction
isprimitive(::Type)

Dispatch function that specifies whether a type is a primitive Comrade model. This function is used for dispatch purposes when composing models.

Notes

If a user is specifying their own model primitive model outside of Comrade they need to specify if it is primitive

struct MyPrimitiveModel end
ComradeBase.isprimitive(::Type{MyModel}) = ComradeBase.IsPrimitive()
EHTModels.posangleMethod
posangle(model)

Returns the rotation angle of the rotated model

EHTModels.radialextentFunction
radialextent(model::AbstractModel)

Provides an estimate of the radial size/extent of the model. This is used internally to estimate image size when plotting and using modelimage

EHTModels.renormedMethod
renormed(model, f)

Renormalizes the model m to have total flux f*flux(m). This can also be done directly by calling Base.:* i.e.,

julia> renormed(m, f) == f*M
true
EHTModels.rotatedMethod
rotated(model, ξ)

Rotates the model by an amount ξ in radians in the clockwise direction.

EHTModels.scale_imageFunction
scale_image(model::AbstractModifier, x, y)

Returns a number of how to to scale the image intensity at x y for an modified model

EHTModels.scale_uvFunction
scale_image(model::AbstractModifier, u, v)

Returns a number on how to scale the image visibility at u v for an modified model

EHTModels.shiftedMethod
shifted(model, Δx, Δy)

Shifts the model m in the image domain by an amount Δx,Δy in the x and y directions respectively.

EHTModels.smoothedMethod
smoothed(m::AbstractModel, σ::Number)

Smooths a model m with a Gaussian kernel with standard deviation σ.

Notes

This uses convolved to created the model, i.e.

julia> m1 = Disk()
julia> m2 = Gaussian()
julia> convolved(m1, m2) == smoothed(m1, 1.0)
true
EHTModels.stretchedMethod
stretched(model, α, β)

Stretches the model m according to the formula Iₛ(x,y) = 1/(αβ) I(x/α, y/β), where were renormalize the intensity to preserve the models flux.

EHTModels.transform_imageFunction
transform_image(model::AbstractModifier, x, y)

Returns a transformed x and y according to the model modifier

EHTModels.transform_uvFunction
transform_uv(model::AbstractModifier, u, v)

Returns a transformed u and v according to the model modifier

EHTModels.visanalyticMethod
visanalytic(::Type{<:AbstractModel})

Determines whether the model is pointwise analytic in Fourier domain, i.e. we can evaluate its fourier transform at an arbritrary point. If IsAnalytic() then it will try to call visibility_point to calculate the complex visibilities. Otherwise it fallback to using the FFT that works for all models that can compute an image.

EHTModels.visibility_pointFunction
visibility_point(model::AbstractModel, u, v, args...)

Function that computes the pointwise visibility. This must be implemented in the model interface if visanalytic(::Type{MyModel}) == IsAnalytic()