You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
-5Lines changed: 0 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -81,10 +81,6 @@ m([1.2, 0.4])
81
81
It is important to recognize the difference in the order of the dimensions between indexing and calling. Indexing is reverse of the cartesian order, which is the natural way of indexing a multi-dimensional array. If you try calling a model as a function with an index, an error will be thrown.
82
82
83
83
```julia
84
-
# scalar multiplication or division will create a ScaledPSFModel
85
-
20* m # or `m * 20`
86
-
m /20
87
-
88
84
# evaluate `m` over its indices forming an array
89
85
collect(m)
90
86
@@ -97,6 +93,5 @@ m .* arr
97
93
inds =map(intersect, axes(arr), axes(m))
98
94
arr_stamp =@view arr[inds...]
99
95
m_stamp =@view m[inds...]
100
-
amp =1.24
101
96
resid =sum(abs2, arr_stamp .- amp .* m_stamp) # chi-square loss
Copy file name to clipboardExpand all lines: docs/src/index.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,12 +28,12 @@ To import the library
28
28
julia>using PSFModels
29
29
```
30
30
31
-
None of the models are exported to avoid namespace clashes, but it can be verbose. You can either import names directly
31
+
None of the models are exported to avoid namespace clashes, but it can be verbose to continuously rewrite `PSFModels`. You can either import names directly
32
32
33
33
```julia
34
34
julia>using PSFModels: Gaussian
35
35
36
-
julia> model =Gaussian(8)
36
+
julia> model =Gaussian(fwhm=8)
37
37
```
38
38
39
39
or you can create an alias for `PSFModels`
@@ -43,9 +43,9 @@ or you can create an alias for `PSFModels`
In general, the PSFs have a position, a full-width at half-maximum (FWHM) measure, and an amplitude. The position a 1-based pixel coordinate system, where `(1, 1)` represents the *center* of the bottom left pixel. This matches the indexing style of Julia as well as DS9, IRAF, SourceExtractor, and WCS. If a position is not specified, it is set to `(0, 0)`. The FWHM is a consistent scale parameter for the models. All models support a scalar (isotropic) FWHM and a FWHM for each axis (diagonal).
15
+
In general, the PSFs have a position, a full-width at half-maximum (FWHM) measure, and an amplitude. The position follows a 1-based pixel coordinate system, where `(1, 1)` represents the *center* of the bottom left pixel. This matches the indexing style of Julia as well as DS9, IRAF, SourceExtractor, and WCS. If a position is not specified, it is set to `(0, 0)`. The FWHM is a consistent scale parameter for the models. All models support a scalar (isotropic) FWHM and a FWHM for each axis (diagonal).
16
16
17
17
## Usage
18
18
19
-
Using the models should feel just like an array. In fact, `PSFModels.PSFModel <: AbstractMatrix`. However, no data is stored and no allocations have to be made. In other words, representing the models as matrices is merely a convenience, since typically astronomical data is stored in dense arrays.
19
+
Using the models should feel just like an array. In fact, `PSFModels.PSFModel <: AbstractMatrix`. However, no data is stored and no allocations have to be made. In other words, representing the models as matrices is merely a convenience, since typically astronomical data is stored in dense arrays. Another way of thinking of these is a lazy array that applies a function when indexed, rather than returning data stored in memory.
20
20
21
21
```jldoctest model
22
-
julia> m = PSFModels.Gaussian(5); # fwhm of 5 pixels, centered at (0, 0)
22
+
julia> m = PSFModels.Gaussian(fwhm=3); # centered at (0, 0)
It's important to note the difference in the axis ordering between the index-style calls and the function-style calls. The index-style calls are reverse cartesian order (e.g., `(z, y, x)`), while function calls are the typical cartesian order `(x, y, z)`. Regardless, the constructors are always in cartesian order (`(x, y, z)`).
34
35
35
-
To control the amplitude, the best method is using scalar multiplication or division. These operations create another lazy object ([`ScaledPSFModel`](@ref)) that scales the original model without having to broadcast and potentially allocate.
36
+
Because the model is a matrix, it needs to have a size. Each model has a bounding box which can be controlled with the `extent` keyword. By default the extent is set by a scalar factor of the FWHM (e.g., `maxsize * FWHM` pixels), centered around the PSF, and rounded up. We can see how this alters the indices from a typical `Matrix`
36
37
37
38
```jldoctest model
38
-
julia> m_scaled = 20 * m;
39
-
40
-
julia> m_scaled(0, 0)
41
-
20.0
42
-
43
-
julia> m′ = m_scaled / 20;
44
-
45
-
julia> m′(0, 0)
46
-
1.0
47
-
```
48
-
49
-
Because the model is a matrix, it needs to have a size. In this case, the size is `maxsize * FWHM` pixels, centered around the origin, and rounded up. We can see how this alters the indices from a typical `Matrix`
50
-
51
-
```jldoctest model
52
-
julia> size(m)
53
-
(17, 17)
39
+
julia> size(m) # default 'stamp' size is fwhm * 3
40
+
(11, 11)
54
41
55
42
julia> axes(m)
56
-
(-8:8, -8:8)
43
+
(-5:5, -5:5)
57
44
```
58
45
59
46
if we want to collect the model into a dense matrix, regardless of the indexing (e.g. to prepare for cross-correlation), we can simply
60
47
61
48
```jldoctest model
62
49
julia> stamp = collect(m);
50
+
63
51
```
64
52
65
53
these axes are merely a convenience for bounding the model, since they accept any real number as input.
Nice- we only had to reduce ~50 pixels instead of ~10,000 to calculate the aperture sum, all in under a microsecond (on my machine).
90
+
Nice- we only had to reduce ~50 pixels instead of ~1,000,000 to calculate the aperture sum, all in under a microsecond (on my machine).
101
91
102
92
Since the models are lazy, that means the type of the output can be specified, as long as it can be converted to from a real number (so no integer types).
finally, we provide plotting recipes from [RecipesBase.jl](https://github.com/JuliaPlots/RecipesBase.jl), which can be seen in use in the [API/Reference](@ref) section.
@@ -114,82 +105,22 @@ finally, we provide plotting recipes from [RecipesBase.jl](https://github.com/Ju
114
105
using Plots
115
106
model = PSFModels.Gaussian(8)
116
107
plot(model) # default axes
117
-
plot(model, 1:5, 1:5) # custom axes
108
+
plot(model, :, 1:5) # custom axes (y, x)
118
109
plot(model, axes(other)) # use axes from other array
119
110
```
120
-
121
-
!!! tip "Tip: Automatic Differentation"
122
-
Forward-mode AD libraries tend to use dual numbers, which can cause headaches getting the types correct. We recommend using the *primal vector*'s element type to avoid these headaches
123
-
```julia
124
-
# example generative model for position and scalar fwhm
125
-
model(X::AbstractVector{T}) where {T} = PSFModels.Gaussian{T}(X...)
126
-
```
127
111
"""
128
112
module PSFModels
129
113
130
114
using CoordinateTransformations
131
115
using Distances
116
+
using KeywordCalls
132
117
using SpecialFunctions
133
118
using StaticArrays
134
119
135
-
"""
136
-
PSFModels.PSFModel{T} <: AbstractMatrix{T}
137
-
138
-
Abstract type for PSF models.
139
-
140
-
In general, all `PSFModel`s have a set of pre-determined axes (the size is set upon creation) but they are lazy. That is, no memory is allocated and the values are calculated on the fly.
141
-
142
-
# Interface
143
-
The interface to define a model is as follows (for an example model `Model`)
144
-
145
-
| method | description |
146
-
|:-------|:------------|
147
-
| `Model()` | constructor(s) |
148
-
| `Base.size(m::Model)` | size, necessary for `AbstractArray` interface |
149
-
| `Base.axes(m::Model)` | axes, necessary for `AbstractArray` interface |
150
-
| `(m::Model)(point::AbstractVector)` | evaluate the model at the point in 2d space (x, y) |
151
-
152
-
browsing through the implementation of [`PSFModels.Gaussian`](@ref) should give a good idea of how to create a model
0 commit comments