# ComradeBase

Documentation for ComradeBase.

`ComradeBase.AbstractModel`

`ComradeBase.AbstractPolarizedModel`

`ComradeBase.DensityAnalytic`

`ComradeBase.IntensityMap`

`ComradeBase.IntensityMap`

`ComradeBase.IntensityMap`

`ComradeBase.IntensityMap`

`ComradeBase.IsAnalytic`

`ComradeBase.IsPrimitive`

`ComradeBase.MinimalHeader`

`ComradeBase.NoHeader`

`ComradeBase.NotAnalytic`

`ComradeBase.NotPrimitive`

`ComradeBase.PrimitiveTrait`

`ComradeBase.RectiGrid`

`ComradeBase.RectiGrid`

`ComradeBase.StokesIntensityMap`

`ComradeBase._visibilities`

`ComradeBase._visibilities!`

`ComradeBase.amplitude`

`ComradeBase.amplitudes`

`ComradeBase.axisdims`

`ComradeBase.bispectra`

`ComradeBase.bispectrum`

`ComradeBase.centroid`

`ComradeBase.closure_phase`

`ComradeBase.closure_phases`

`ComradeBase.fieldofview`

`ComradeBase.flux`

`ComradeBase.header`

`ComradeBase.header`

`ComradeBase.imagegrid`

`ComradeBase.imagepixels`

`ComradeBase.imanalytic`

`ComradeBase.intensity_point`

`ComradeBase.intensitymap`

`ComradeBase.intensitymap`

`ComradeBase.intensitymap`

`ComradeBase.intensitymap!`

`ComradeBase.intensitymap!`

`ComradeBase.intensitymap_analytic`

`ComradeBase.intensitymap_analytic!`

`ComradeBase.intensitymap_numeric`

`ComradeBase.intensitymap_numeric!`

`ComradeBase.ispolarized`

`ComradeBase.isprimitive`

`ComradeBase.load`

`ComradeBase.logclosure_amplitude`

`ComradeBase.logclosure_amplitudes`

`ComradeBase.named_dims`

`ComradeBase.phasecenter`

`ComradeBase.pixelsizes`

`ComradeBase.radialextent`

`ComradeBase.save`

`ComradeBase.second_moment`

`ComradeBase.second_moment`

`ComradeBase.stokes`

`ComradeBase.visanalytic`

`ComradeBase.visibilities`

`ComradeBase.visibilities`

`ComradeBase.visibilities!`

`ComradeBase.visibilities!`

`ComradeBase.visibilities_analytic`

`ComradeBase.visibilities_analytic!`

`ComradeBase.visibilities_numeric`

`ComradeBase.visibilities_numeric!`

`ComradeBase.visibility`

`ComradeBase.visibility_point`

`DimensionalData.Dimensions.dims`

`ComradeBase.AbstractModel`

— Type`AbstractModel`

The Comrade 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.`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()`

.

**Optional Methods:**

`ispolarized`

: Specified whether a model is intrinsically polarized (returns`IsPolarized()`

) or is not (returns`NotPolarized()`

), by default a model is`NotPolarized()`

`visibilities_analytic`

: Vectorized version of`visibility_point`

for models where`visanalytic`

returns`IsAnalytic()`

`visibilities_numeric`

: Vectorized version of`visibility_point`

for models where`visanalytic`

returns`NotAnalytic()`

typically these are numerical FT's`intensitymap_analytic`

: Computes the entire image for models where`imanalytic`

returns`IsAnalytic()`

`intensitymap_numeric`

: Computes the entire image for models where`imanalytic`

returns`NotAnalytic()`

`intensitymap_analytic!`

: Inplace version of`intensitymap`

`intensitymap_numeric!`

: Inplace version of`intensitymap`

`ComradeBase.AbstractPolarizedModel`

— Type`abstract type AbstractPolarizedModel <: ComradeBase.AbstractModel`

Type the classifies a model as being intrinsically polarized. This means that any call to visibility must return a `StokesParams`

to denote the full stokes polarization of the model.

`ComradeBase.DensityAnalytic`

— Type`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.

`ComradeBase.IntensityMap`

— Type`struct IntensityMap{T, N, D, A<:AbstractArray{T, N}, G<:ComradeBase.AbstractGrid{D}, R<:Tuple, Na} <: DimensionalData.AbstractDimArray{T, N, D, A<:AbstractArray{T, N}}`

`IntensityMap(data::AbstractArray, g::AbstractGrid)`

This type is the basic array type for all images and models that obey the `ComradeBase`

interface. The type is a subtype of `DimensionalData.AbstractDimArray`

however, we make a few changes to support the Comrade API.

- The dimensions should be specified by an
`AbstractGrid`

interface. Usually users just need the`RectiGrid`

grid, for rectilinear grids. - There are two ways to access the dimensions of the array.
`dims(img)`

will return the usual`DimArray`

dimensions, i.e. a`Tuple{DimensionalData.Dim, ...}`

. The other way to access the array dimensions is using the`getproperty`

, e.g.,`img.X`

will return the RA/X grid locations but stripped of the usual`DimensionalData.Dimension`

material. This`getproperty`

behavior is *NOT CONSIDERED** part of the stable API and may be changed in the future. - Metadata is stored in the
`AbstractGrid`

type through the`header`

property and can be accessed through`metadata`

or`header`

The most common way to create a `IntensityMap`

is to use the function definitions

```
julia> g = imagepixels(10.0, 10.0, 128, 128; header=NoHeader())
julia> X = g.X; Y = g.Y
julia> data = rand(128, 128)
julia> img1 = IntensityMap(data, g)
julia> img2 = IntensityMap(data, (;X, Y); header=header(g))
julia> img1 == img2
true
julia> img3 = IntensityMap(data, 10.0, 10.0; header=NoHeader())
```

Broadcasting, map, and reductions should all just obey the `DimensionalData`

interface.

`ComradeBase.IntensityMap`

— Method`IntensityMap(data::AbstractArray, g::AbstractGrid; refdims=(), name=Symbol(""))`

Creates a IntensityMap with the pixel fluxes `data`

on the grid `g`

. Optionally, you can specify a set of reference dimensions `refdims`

as a tuple and a name for array `name`

.

`ComradeBase.IntensityMap`

— Method`IntensityMap(data::AbstractArray, dims::NamedTuple; header=NoHeader() refdims=(), name=Symbol(""))`

Creates a IntensityMap with the pixel fluxes `data`

with dimensions `dims`

. Note that `dims`

must be a named tuple with names either

- (:X, :Y) for spatial intensity maps
- (:X, :Y, :Ti) for spatial-temporal intensity maps
- (:X, :Y, :F) for spatial-frequency intensity maps
- (:X, :Y, :Ti, :F) for spatial-temporal frequency intensity maps
- (:X, :Y, :F, :Ti) for spatial-frequency-temporal intensity maps

additionally this method assumes that `dims`

is specified in a recti-linear grid.

`ComradeBase.IntensityMap`

— Method`IntensityMap(data::AbstractArray, fovx::Real, fovy::Real, x0::Real=0, y0::Real=0; header=NoHeader())`

Creates a IntensityMap with the pixel fluxes `data`

and a spatial grid with field of view (`fovx`

, `fovy`

) and center pixel offset (`x0`

, `y0`

) and header `header`

.

`ComradeBase.IsAnalytic`

— Type`struct IsAnalytic <: ComradeBase.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.

`ComradeBase.IsPrimitive`

— Type`struct IsPrimitive`

Trait for primitive model

`ComradeBase.MinimalHeader`

— Type`MinimalHeader{T}`

A minimal header type for ancillary image information.

**Fields**

`source`

: Common source name

`ra`

: Right ascension of the image in degrees (J2000)

`dec`

: Declination of the image in degrees (J2000)

`mjd`

: Modified Julian Date in days

`frequency`

: Frequency of the image in Hz

`ComradeBase.NoHeader`

— Type`NoHeader`

`ComradeBase.NotAnalytic`

— Type`struct NotAnalytic <: ComradeBase.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.

`ComradeBase.NotPrimitive`

— Type`struct NotPrimitive`

Trait for not-primitive model

`ComradeBase.PrimitiveTrait`

— Type`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.

`ComradeBase.RectiGrid`

— Type`RectiGrid(dims::NamedTuple{Na}, header=ComradeBase.NoHeader())`

Builds the EHT image dimensions using the names `Na`

and dimensions are the values of `dims`

. You can also optionally has a header that stores additional information from e.g., a FITS header. The type parameter `Na`

defines the names of each dimension. These names are usually one of

(:X, :Y, :Ti, :F)

(:X, :Y, :F, :Ti)

(:X, :Y) # spatial only

where

`:X,:Y`

are the RA and DEC spatial dimensions respectively,`:Ti`

is the

the time direction and `:F`

is the frequency direction.

**Notes**

Instead use the direct `IntensityMap`

function.

`dims = RectiGrid((X=-5.0:0.1:5.0, Y=-4.0:0.1:4.0, Ti=[1.0, 1.5, 1.75], Fr=[230, 345]))`

`ComradeBase.RectiGrid`

— Type`RectiGrid(dims::Tuple, header=ComradeBase.NoHeader)`

Builds the EHT image dimensions using the names `Na`

and dimensions `dims`

. You can also optionally has a header that stores additional information from e.g., a FITS header. The type parameter `Na`

defines the names of each dimension. These names are usually one of

- (:X, :Y, :Ti, :F)
- (:X, :Y, :F, :Ti)
- (:X, :Y) # spatial only

where `:X,:Y`

are the RA and DEC spatial dimensions respectively, `:T`

is the the time direction and `:F`

is the frequency direction.

**Notes**

Instead use the direct `IntensityMap`

function.

`dims = RectiGrid((X=-5.0:0.1:5.0, Y=-4.0:0.1:4.0, Ti=[1.0, 1.5, 1.75], F=[230, 345]))`

**Notes**

Warning it is rare you need to access this constructor directly. For spatial intensitymaps just use the `imagepixels`

function.

`ComradeBase.StokesIntensityMap`

— Type`struct StokesIntensityMap{T, N, SI, SQ, SU, SV}`

General struct that holds intensity maps for each stokes parameter. Each image `I, Q, U, V`

must share the same axis dimensions. This type also obeys much of the usual array interface in Julia. The following methods have been implemented:

- size
- eltype (returns StokesParams)
- ndims
- getindex
- setindex!
- pixelsizes
- fieldofview
- imagepixels
- imagegrid
- stokes

This may eventually be phased out for `IntensityMaps`

whose base types are `StokesParams`

, but currently we use this for speed reasons with Zygote.

`ComradeBase._visibilities`

— Function`_visibilities(model::AbstractModel, args...)`

Internal method used for trait dispatch and unpacking of args arguments in `visibilities`

Not part of the public API so it may change at any moment.

`ComradeBase._visibilities!`

— Function`_visibilities!(model::AbstractModel, args...)`

Internal method used for trait dispatch and unpacking of args arguments in `visibilities!`

Not part of the public API so it may change at any moment.

`ComradeBase.amplitude`

— Method`amplitude(model, p)`

Computes the visibility amplitude of model `m`

at the coordinate `p`

. The coordinate `p`

is expected to have the properties `U`

, `V`

, and sometimes `Ti`

and `Fr`

.

If you want to compute the amplitudes at a large number of positions consider using the `amplitudes`

function.

`ComradeBase.amplitudes`

— Method`amplitudes(m::AbstractModel, u::AbstractArray, v::AbstractArray)`

Computes the visibility amplitudes of the model `m`

at the coordinates `p`

. The coordinates `p`

are expected to have the properties `U`

, `V`

, and sometimes `Ti`

and `Fr`

.

`ComradeBase.axisdims`

— Method```
axisdims(img::IntensityMap)
axisdims(img::IntensityMap, p::Symbol)
```

Returns the keys of the `IntensityMap`

as the actual internal `AbstractGrid`

object. Optionall the user can ask for a specific dimension with `p`

`ComradeBase.bispectra`

— Method`bispectra(m, p1, p2, p3)`

Computes the closure phases of the model `m`

at the triangles p1, p2, p3, where `pi`

are coordinates.

`ComradeBase.bispectrum`

— Method`bispectrum(model, p1, p2, p3)`

Computes the complex bispectrum of model `m`

at the uv-triangle p1 -> p2 -> p3

If you want to compute the bispectrum over a number of triangles consider using the `bispectra`

function.

`ComradeBase.centroid`

— Method`centroid(im::AbstractIntensityMap)`

Computes the image centroid aka the center of light of the image.

For polarized maps we return the centroid for Stokes I only.

`ComradeBase.closure_phase`

— Method`closure_phase(model, p1, p2, p3, p4)`

Computes the closure phase of model `m`

at the uv-triangle u1,v1 -> u2,v2 -> u3,v3

If you want to compute closure phases over a number of triangles consider using the `closure_phases`

function.

`ComradeBase.closure_phases`

— Method```
closure_phases(m,
p1::AbstractArray
p2::AbstractArray
p3::AbstractArray
)
```

Computes the closure phases of the model `m`

at the triangles p1, p2, p3, where `pi`

are coordinates.

`ComradeBase.fieldofview`

— Method```
fieldofview(img::IntensityMap)
fieldofview(img::IntensityMapTypes)
```

Returns a named tuple with the field of view of the image.

`ComradeBase.flux`

— Method```
flux(im::IntensityMap)
flux(img::StokesIntensityMap)
```

Computes the flux of a intensity map

`ComradeBase.header`

— Method`header(g::AbstractGrid)`

Returns the headerinformation of the dimensions `g`

`ComradeBase.header`

— Method`header(img::IntensityMap)`

Retrieves the header of an IntensityMap

`ComradeBase.imagegrid`

— Method`imagegrid(k::IntensityMap)`

Returns the grid the `IntensityMap`

is defined as. Note that this is unallocating since it lazily computes the grid. The grid is an example of a DimArray and works similarly. This is useful for broadcasting a model across an abritrary grid.

`ComradeBase.imagepixels`

— Method```
imagepixels(img::IntensityMap)
imagepixels(img::IntensityMapTypes)
```

Returns a abstract spatial dimension with the image pixels locations `X`

and `Y`

.

`ComradeBase.imanalytic`

— Method`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.

`ComradeBase.intensity_point`

— Function`intensity_point(model::AbstractModel, p)`

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.

`ComradeBase.intensitymap`

— Function`intensitymap(model::AbstractModel, p::AbstractGrid)`

Computes the intensity map of model. For the inplace version see `intensitymap!`

`ComradeBase.intensitymap`

— Function`intensitymap(s, fovx, fovy, nx, ny, x0=0.0, y0=0.0)`

Creates a *spatial only* IntensityMap intensity map whose pixels in the `x`

, `y`

direction are such that the image has a field of view `fovx`

, `fovy`

, with the number of pixels `nx`

, `ny`

, and the origin or phase center of the image is at `x0`

, `y0`

.

`ComradeBase.intensitymap!`

— Function`intensitymap!(buffer::AbstractDimArray, model::AbstractModel)`

Computes the intensity map of `model`

by modifying the `buffer`

`ComradeBase.intensitymap!`

— Method`intensitymap!(img::AbstractIntensityMap, mode;, executor = SequentialEx())`

Computes the intensity map or *image* of the `model`

. This updates the `IntensityMap`

object `img`

.

Optionally the user can specify the `executor`

that uses `FLoops.jl`

to specify how the loop is done. By default we use the `SequentialEx`

which uses a single-core to construct the image.

`ComradeBase.intensitymap`

— Method`intensitymap(model::AbstractModel, dims::AbstractGrid)`

Computes the intensity map or *image* of the `model`

. This returns an `IntensityMap`

which is a `IntensityMap`

with `dims`

an `AbstractGrid`

as dimensions.

`ComradeBase.intensitymap_analytic`

— Function`intensitymap_analytic(m::AbstractModel, p::AbstractGrid)`

Computes the `IntensityMap`

of a model `m`

using the image dimensions `p`

by broadcasting over the analytic `intensity_point`

method.

`ComradeBase.intensitymap_analytic!`

— Function```
intensitymap_analytic!(img::IntensityMap, m::AbstractModel)
intensitymap_analytic!(img::StokesIntensityMap, m::AbstractModel)
```

Updates the `img`

using the model `m`

by broadcasting over the analytic `intensity_point`

method.

`ComradeBase.intensitymap_numeric`

— Function`intensitymap_numeric(m::AbstractModel, p::AbstractGrid)`

Computes the `IntensityMap`

of a model `m`

at the image positions `p`

using a numerical method. This has to be specified uniquely for every model `m`

if `imanalytic(typeof(m)) === NotAnalytic()`

. See `Comrade.jl`

for example implementations.

`ComradeBase.intensitymap_numeric!`

— Function```
intensitymap_numeric!(img::IntensityMap, m::AbstractModel)
intensitymap_numeric!(img::StokesIntensityMap, m::AbstractModel)
```

Updates the `img`

using the model `m`

using a numerical method. This has to be specified uniquely for every model `m`

if `imanalytic(typeof(m)) === NotAnalytic()`

. See `Comrade.jl`

for example implementations.

`ComradeBase.ispolarized`

— Method`ispolarized(::Type)`

Trait function that defines whether a model is polarized or not.

`ComradeBase.isprimitive`

— Function`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()
```

`ComradeBase.load`

— Method`ComradeBase.load(fitsfile::String, IntensityMap)`

This loads in a fits file that is more robust to the various imaging algorithms in the EHT, i.e. is works with clean, smili, eht-imaging. The function returns an tuple with an intensitymap and a second named tuple with ancillary information about the image, like the source name, location, mjd, and radio frequency.

`ComradeBase.logclosure_amplitude`

— Method`logclosure_amplitude(model, p1, p2, p3, p4)`

Computes the log-closure amplitude of model `m`

at the uv-quadrangle u1,v1 -> u2,v2 -> u3,v3 -> u4,v4 using the formula

\[C = \log\left|\frac{V(u1,v1)V(u2,v2)}{V(u3,v3)V(u4,v4)}\right|\]

If you want to compute log closure amplitudes over a number of triangles consider using the `logclosure_amplitudes`

function.

`ComradeBase.logclosure_amplitudes`

— Method```
logclosure_amplitudes(m::AbstractModel,
p1,
p2,
p3,
p4
)
```

Computes the log closure amplitudes of the model `m`

at the quadrangles p1, p2, p3, p4.

`ComradeBase.named_dims`

— Method`named_dims(g::AbstractGrid)`

Returns a named tuple containing the dimensions of `g`

. For a unnamed version see `dims`

`ComradeBase.phasecenter`

— Method```
phasecenter(img::IntensityMap)
phasecenter(img::StokesIntensitymap)
```

Computes the phase center of an intensity map. Note this is the pixels that is in the middle of the image.

`ComradeBase.pixelsizes`

— Method```
pixelsizes(img::IntensityMap)
pixelsizes(img::AbstractGrid)
```

Returns a named tuple with the spatial pixel sizes of the image.

`ComradeBase.radialextent`

— Function`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`

`ComradeBase.save`

— Method`ComradeBase.save(file::String, img::IntensityMap, obs)`

Saves an image to a fits file. You can optionally pass an EHTObservation so that ancillary information will be added.

`ComradeBase.second_moment`

— Method`second_moment(im::AbstractIntensityMap; center=true)`

Computes the image second moment tensor of the image. By default we really return the second **cumulant** or centered second moment, which is specified by the `center`

argument.

`ComradeBase.second_moment`

— Method`second_moment(im::AbstractIntensityMap; center=true)`

Computes the image second moment tensor of the image. By default we really return the second **cumulant** or centered second moment, which is specified by the `center`

argument.

For polarized maps we return the second moment for Stokes I only.

`ComradeBase.stokes`

— Method`stokes(m::AbstractPolarizedModel, p::Symbol)`

Extract the specific stokes component `p`

from the polarized model `m`

`ComradeBase.visanalytic`

— Method`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.

`ComradeBase.visibilities`

— Function`visibilities(model::AbstractModel, args...)`

Computes the complex visibilities at the locations given by `args...`

`ComradeBase.visibilities!`

— Function`visibilities!(vis::AbstractArray, model::AbstractModel, args...)`

Computes the complex visibilities `vis`

in place at the locations given by `args...`

`ComradeBase.visibilities!`

— Method`visibilities!(vis, m, p)`

Computes the visibilities `vis`

in place of the model `m`

using the coordinates `p`

. The coordinates `p`

are expected to have the properties `U`

, `V`

, and sometimes `T`

and `F`

.

`ComradeBase.visibilities`

— Method`visibilities(m, p)`

Computes the visibilities of the model `m`

using the coordinates `p`

. The coordinates `p`

are expected to have the properties `U`

, `V`

, and sometimes `T`

and `F`

.

`ComradeBase.visibilities_analytic`

— Function`visibilties_analytic(model, u, v, time, freq)`

Computes the visibilties of a `model`

using using the analytic visibility expression given by `visibility_point`

.

`ComradeBase.visibilities_analytic!`

— Function`visibilties_analytic!(vis, model, u, v, time, freq)`

Computes the visibilties of a `model`

in-place, using using the analytic visibility expression given by `visibility_point`

.

`ComradeBase.visibilities_numeric`

— Function`visibilties_numeric(model, u, v, time, freq)`

Computes the visibilties of a `model`

using a numerical fourier transform. Note that none of these are implemented in `ComradeBase`

. For implementations please see `Comrade`

.

`ComradeBase.visibilities_numeric!`

— Function`visibilties_numeric!(vis, model, u, v, time, freq)`

Computes the visibilties of a `model`

in-place using a numerical fourier transform. Note that none of these are implemented in `ComradeBase`

. For implementations please see `Comrade`

.

`ComradeBase.visibility`

— Method`visibility(mimg, p)`

Computes the complex visibility of model `m`

at coordinates `p`

. `p`

corresponds to the coordinates of the model. These need to have the properties `U`

, `V`

and sometimes `Ti`

for time and `Fr`

for frequency.

**Notes**

If you want to compute the visibilities at a large number of positions consider using the `visibilities`

.

`ComradeBase.visibility_point`

— Function`visibility_point(model::AbstractModel, p)`

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

`DimensionalData.Dimensions.dims`

— Method`dims(g::AbstractGrid)`

Returns a tuple containing the dimensions of `g`

. For a named version see `ComradeBase.named_dims`