diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 8548ea1..e72f65c 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-10-25T13:31:30","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-02T13:21:36","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/dev/datasets/datasets/index.html b/dev/datasets/datasets/index.html index 28e0244..87a875c 100644 --- a/dev/datasets/datasets/index.html +++ b/dev/datasets/datasets/index.html @@ -6,5 +6,5 @@ match_domains = true, background = nothing, ancillary = nothing, -)source

Dataset abstraction

Datasets must define a small API to make fitting possible. The picture to have in mind when considering the different domains is as follows: the model is trying to predict the objective. It does so by taking in input domain and maps it to some output domain.

That means make_output_domain and make_objective_domain correspond to the $(X,Y)$ values of the data that the model is trying to fit, whilst the model is evaluated on the make_model_domain, which need not be the same as the output domain.

In other cases, the objective_transformer acts to transform the output of the model onto the output domain.

Mathematically, expressing the output domain $X$, the model domain $D$, the model output $M(D)$ and objective $S$, along with the transformer as $T$, then the relationship between the different domains is

\[\hat{S} = T \times M(D),\]

Both $\hat{S}$ and $S$ are defined over $X$. The various fitting operations try to find model paramters that make $\hat{S}$ and $S$ as close as possible.

SpectralFitting.AbstractDatasetType
abstract type AbstractDataset

Abstract type for use in fitting routines. High level representation of some underlying data structures.

Fitting data is considered to have an objective and a domain. As the domain may be, for example, energy bins (high and low), or fourier frequencies (single value), the purpose of this abstraction is to provide some facility for translating between these representations for the models to fit with. This is done by checking that the AbstractLayout of the model and data are compatible, or at least have compatible translations.

Must implement a minimal set of accessor methods. These are paired with objective and domain parlance. Note that these functions are prefixed with make_* and not get_* to represent that there may be allocations or work going into the translation. Usage of these functions should be sparse in the interest of performance.

The arrays returned by the make_* functions must correspond to the AbstractLayout specified by the caller.

Additionally there is an objective transformer that transforms the output of the model onto the output domain:

Finally, to make all of the fitting for different statistical regimes work efficiently, datasets should inform which units are preferred to fit. They may also give the error statistics they prefer, and a label name primarily used to disambiguate:

source
SpectralFitting.make_objective_varianceFunction
make_objective_variance(layout::AbstractLayout, dataset::AbstractDataset)

Make the variance vector associated with each objective point.

source
SpectralFitting.make_objectiveFunction
make_objective(layout::AbstractLayout, dataset::AbstractDataset)

Returns the array used as the target for model fitting. The array must correspond to the data AbstractLayout specified by the layout parameter.

In as far as it can be guarunteed, the memory in the returned array will not be mutated by any fitting procedures.

Domain for this objective should be returned by make_model_domain.

source
SpectralFitting.make_domain_varianceFunction
make_domain_variance(layout::AbstractLayout, dataset::AbstractDataset)

Make the variance vector associated with the domain.

source
SpectralFitting.make_model_domainFunction
make_model_domain(layout::AbstractLayout, dataset::AbstractDataset)

Returns the array used as the domain for the modelling. This is paired with make_domain_variance

source
SpectralFitting.make_output_domainFunction
make_output_domain(layout::AbstractLayout, dataset::AbstractDataset)

Returns the array used as the output domain. That is, in cases where the model input and output map to different domains, the input domain is said to be the model domain, the input domain is said to be the model domain.

The distinction is mainly used for the purposes of simulating data and for visualising data.

source

Underlying data layouts

SpectralFitting.AbstractLayoutType
abstract type AbstractLayout end

The data layout primarily concerns the relationship between the objective and the domain. It is used to work out whether a model and a dataset are fittable, and if not, whether a translation in the output of the model to the domain of the model is possible.

The following methods may be used to interrogate support:

  • preferred_support for inferring the preferred support of a model when multiple supports are possible.
  • common_support to obtain the common support of two structures

The following method is also used to define the support of a model or dataset:

For cases where unit information needs to be propagated, an AbstractLayout can also be used to ensure the units are compatible. To query the units of a layout, use

source
SpectralFitting.OneToOneType
struct OneToOne <: AbstractLayout end

Indicates there is a one-to-one (injective) correspondence between each input value and each output value. That is to say

length(objective) == length(domain)
source
SpectralFitting.ContiguouslyBinnedType
struct ContiguouslyBinned <: AbstractLayout end

Contiguously binned data layout means that the domain describes high and low bins, with the objective being the value in that bin. This means

length(objective) + 1== length(domain)

Note that the contiguous qualifer is to mean there is no gaps in the bins, and that

\[\Delta E_i = E_{i+1} - E_{i}\]

source
SpectralFitting.common_supportFunction
common_support(x, y)

Find the common AbstractLayout of x and y, following the ordering of preferred_support.

source
SpectralFitting.preferred_supportFunction
preferred_support(x)

Get the preferred AbstractLayout of x. If multiple supports are available, the DEFAULT_SUPPORT_ORDERING is followed:

DEFAULT_SUPPORT_ORDERING = (ContiguouslyBinned{Nothing}(nothing), OneToOne{Nothing}(nothing))
source
SpectralFitting.supportsFunction
supports(x::Type)

Used to define whether a given type has support for a specific AbstractLayout. Should return a tuple of the supported layouts. This method should be implemented to express new support, not the query method.

To query, there is

supports(layout::AbstractLayout, x)::Bool

Example

supports(::Type{typeof(x)}) = (OneToOne(),)
-@assert supports(ContiguouslyBinned(), x) == false
source
+)source

Dataset abstraction

Datasets must define a small API to make fitting possible. The picture to have in mind when considering the different domains is as follows: the model is trying to predict the objective. It does so by taking in input domain and maps it to some output domain.

That means make_output_domain and make_objective_domain correspond to the $(X,Y)$ values of the data that the model is trying to fit, whilst the model is evaluated on the make_model_domain, which need not be the same as the output domain.

In other cases, the objective_transformer acts to transform the output of the model onto the output domain.

Mathematically, expressing the output domain $X$, the model domain $D$, the model output $M(D)$ and objective $S$, along with the transformer as $T$, then the relationship between the different domains is

\[\hat{S} = T \times M(D),\]

Both $\hat{S}$ and $S$ are defined over $X$. The various fitting operations try to find model paramters that make $\hat{S}$ and $S$ as close as possible.

SpectralFitting.AbstractDatasetType
abstract type AbstractDataset

Abstract type for use in fitting routines. High level representation of some underlying data structures.

Fitting data is considered to have an objective and a domain. As the domain may be, for example, energy bins (high and low), or fourier frequencies (single value), the purpose of this abstraction is to provide some facility for translating between these representations for the models to fit with. This is done by checking that the AbstractLayout of the model and data are compatible, or at least have compatible translations.

Must implement a minimal set of accessor methods. These are paired with objective and domain parlance. Note that these functions are prefixed with make_* and not get_* to represent that there may be allocations or work going into the translation. Usage of these functions should be sparse in the interest of performance.

The arrays returned by the make_* functions must correspond to the AbstractLayout specified by the caller.

Additionally there is an objective transformer that transforms the output of the model onto the output domain:

Finally, to make all of the fitting for different statistical regimes work efficiently, datasets should inform which units are preferred to fit. They may also give the error statistics they prefer, and a label name primarily used to disambiguate:

source
SpectralFitting.make_objective_varianceFunction
make_objective_variance(layout::AbstractLayout, dataset::AbstractDataset)

Make the variance vector associated with each objective point.

source
SpectralFitting.make_objectiveFunction
make_objective(layout::AbstractLayout, dataset::AbstractDataset)

Returns the array used as the target for model fitting. The array must correspond to the data AbstractLayout specified by the layout parameter.

In as far as it can be guarunteed, the memory in the returned array will not be mutated by any fitting procedures.

Domain for this objective should be returned by make_model_domain.

source
SpectralFitting.make_domain_varianceFunction
make_domain_variance(layout::AbstractLayout, dataset::AbstractDataset)

Make the variance vector associated with the domain.

source
SpectralFitting.make_model_domainFunction
make_model_domain(layout::AbstractLayout, dataset::AbstractDataset)

Returns the array used as the domain for the modelling. This is paired with make_domain_variance

source
SpectralFitting.make_output_domainFunction
make_output_domain(layout::AbstractLayout, dataset::AbstractDataset)

Returns the array used as the output domain. That is, in cases where the model input and output map to different domains, the input domain is said to be the model domain, the input domain is said to be the model domain.

The distinction is mainly used for the purposes of simulating data and for visualising data.

source

Underlying data layouts

SpectralFitting.AbstractLayoutType
abstract type AbstractLayout end

The data layout primarily concerns the relationship between the objective and the domain. It is used to work out whether a model and a dataset are fittable, and if not, whether a translation in the output of the model to the domain of the model is possible.

The following methods may be used to interrogate support:

  • preferred_support for inferring the preferred support of a model when multiple supports are possible.
  • common_support to obtain the common support of two structures

The following method is also used to define the support of a model or dataset:

For cases where unit information needs to be propagated, an AbstractLayout can also be used to ensure the units are compatible. To query the units of a layout, use

source
SpectralFitting.OneToOneType
struct OneToOne <: AbstractLayout end

Indicates there is a one-to-one (injective) correspondence between each input value and each output value. That is to say

length(objective) == length(domain)
source
SpectralFitting.ContiguouslyBinnedType
struct ContiguouslyBinned <: AbstractLayout end

Contiguously binned data layout means that the domain describes high and low bins, with the objective being the value in that bin. This means

length(objective) + 1== length(domain)

Note that the contiguous qualifer is to mean there is no gaps in the bins, and that

\[\Delta E_i = E_{i+1} - E_{i}\]

source
SpectralFitting.common_supportFunction
common_support(x, y)

Find the common AbstractLayout of x and y, following the ordering of preferred_support.

source
SpectralFitting.preferred_supportFunction
preferred_support(x)

Get the preferred AbstractLayout of x. If multiple supports are available, the DEFAULT_SUPPORT_ORDERING is followed:

DEFAULT_SUPPORT_ORDERING = (ContiguouslyBinned{Nothing}(nothing), OneToOne{Nothing}(nothing))
source
SpectralFitting.supportsFunction
supports(x::Type)

Used to define whether a given type has support for a specific AbstractLayout. Should return a tuple of the supported layouts. This method should be implemented to express new support, not the query method.

To query, there is

supports(layout::AbstractLayout, x)::Bool

Example

supports(::Type{typeof(x)}) = (OneToOne(),)
+@assert supports(ContiguouslyBinned(), x) == false
source
diff --git a/dev/datasets/mission-support/index.html b/dev/datasets/mission-support/index.html index 1197023..7121b01 100644 --- a/dev/datasets/mission-support/index.html +++ b/dev/datasets/mission-support/index.html @@ -1,2 +1,2 @@ -Mission support · SpectralFitting.jl
+Mission support · SpectralFitting.jl
diff --git a/dev/examples/examples/6739ab7a.svg b/dev/examples/examples/97837bbc.svg similarity index 83% rename from dev/examples/examples/6739ab7a.svg rename to dev/examples/examples/97837bbc.svg index d25b186..2562366 100644 --- a/dev/examples/examples/6739ab7a.svg +++ b/dev/examples/examples/97837bbc.svg @@ -1,44 +1,44 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/examples/index.html b/dev/examples/examples/index.html index 72c07c3..69ba2a6 100644 --- a/dev/examples/examples/index.html +++ b/dev/examples/examples/index.html @@ -9,4 +9,4 @@ flux = invokemodel(energy, model) -plot(energy[1:end-1], flux)Example block output

Note this energy grid may be arbitrarily spaced, but, like XSPEC, assumes the bins are contiguous, i.e. that the high energy limit of one bin is the low energy limit of the next.

The full model library of available models is listed in Model index.

+plot(energy[1:end-1], flux)Example block output

Note this energy grid may be arbitrarily spaced, but, like XSPEC, assumes the bins are contiguous, i.e. that the high energy limit of one bin is the low energy limit of the next.

The full model library of available models is listed in Model index.

diff --git a/dev/examples/optimizers/index.html b/dev/examples/optimizers/index.html index 6c8ca56..421a234 100644 --- a/dev/examples/optimizers/index.html +++ b/dev/examples/optimizers/index.html @@ -17,4 +17,4 @@ ylims = (1e-3, 1.3) ) -my_plot(data) +my_plot(data) diff --git a/dev/examples/sherpa-example/0d3d0e36.svg b/dev/examples/sherpa-example/4737f72c.svg similarity index 68% rename from dev/examples/sherpa-example/0d3d0e36.svg rename to dev/examples/sherpa-example/4737f72c.svg index f5873e5..6debcf5 100644 --- a/dev/examples/sherpa-example/0d3d0e36.svg +++ b/dev/examples/sherpa-example/4737f72c.svg @@ -1,321 +1,321 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/sherpa-example/ce106354.svg b/dev/examples/sherpa-example/a7f0c316.svg similarity index 86% rename from dev/examples/sherpa-example/ce106354.svg rename to dev/examples/sherpa-example/a7f0c316.svg index 03d6a77..8853890 100644 --- a/dev/examples/sherpa-example/ce106354.svg +++ b/dev/examples/sherpa-example/a7f0c316.svg @@ -1,63 +1,63 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/dev/examples/sherpa-example/dfd3ba37.svg b/dev/examples/sherpa-example/be2d61ac.svg similarity index 64% rename from dev/examples/sherpa-example/dfd3ba37.svg rename to dev/examples/sherpa-example/be2d61ac.svg index 3275926..15eeeff 100644 --- a/dev/examples/sherpa-example/dfd3ba37.svg +++ b/dev/examples/sherpa-example/be2d61ac.svg @@ -1,319 +1,319 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/sherpa-example/89f94673.svg b/dev/examples/sherpa-example/dec337c6.svg similarity index 67% rename from dev/examples/sherpa-example/89f94673.svg rename to dev/examples/sherpa-example/dec337c6.svg index bd5e75e..cc300fd 100644 --- a/dev/examples/sherpa-example/89f94673.svg +++ b/dev/examples/sherpa-example/dec337c6.svg @@ -1,243 +1,243 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/sherpa-example/d1690db8.svg b/dev/examples/sherpa-example/f69b8548.svg similarity index 84% rename from dev/examples/sherpa-example/d1690db8.svg rename to dev/examples/sherpa-example/f69b8548.svg index b9603f1..8d2d484 100644 --- a/dev/examples/sherpa-example/d1690db8.svg +++ b/dev/examples/sherpa-example/f69b8548.svg @@ -1,46 +1,46 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/examples/sherpa-example/index.html b/dev/examples/sherpa-example/index.html index e988b90..a41faec 100644 --- a/dev/examples/sherpa-example/index.html +++ b/dev/examples/sherpa-example/index.html @@ -14,15 +14,15 @@ y_noisy = y .+ (0.2 * randn(length(y))) -scatter(x, y_noisy)Example block output

To make this into a fittable dataset, we observe that our layout is injective (i.e. length(x) == length(y)). This is subtly different from how the majority of spectral models are implemented, which usually assume some kind of binning (length(x) == length(y) + 1). Fortunately, SpectralFitting.jl can track this for us, and do various conversion to make the models work correctly for the data. We need only tell the package what our AbstractLayout is:

data = InjectiveData(x, y_noisy; name = "example")
InjectiveData with 200 data points:
+scatter(x, y_noisy)
Example block output

To make this into a fittable dataset, we observe that our layout is injective (i.e. length(x) == length(y)). This is subtly different from how the majority of spectral models are implemented, which usually assume some kind of binning (length(x) == length(y) + 1). Fortunately, SpectralFitting.jl can track this for us, and do various conversion to make the models work correctly for the data. We need only tell the package what our AbstractLayout is:

data = InjectiveData(x, y_noisy; name = "example")
InjectiveData with 200 data points:
 │   Name                  : example
 │   . Domain (min/max)    : (-5.0000, 5.0)
 │   . Codomain (min/max)  : (-0.42323, 3.3787)
-└ 

The data prints the data card, which provides us some high level information about our data at a glance. We can plot the data trivially using one of the Plots.jl recipes

plot(data, markersize = 3)
Example block output

Next we want to specify a model to fit to this data. Models that are prefixed with XS_ are models that are linked from the XSPEC model library, provided via LibXSPEC_jll. For a full list of the models, see Models index.

Warning

It is advised to use the Julia implemented models. This allows various calculations to benefit from automatic differentiation, efficient multi-threading, GPU offloading, and various other useful things, see Why & how.

model = GaussianLine(μ = FitParam(0.0))
┌ GaussianLine
+└ 

The data prints the data card, which provides us some high level information about our data at a glance. We can plot the data trivially using one of the Plots.jl recipes

plot(data, markersize = 3)
Example block output

Next we want to specify a model to fit to this data. Models that are prefixed with XS_ are models that are linked from the XSPEC model library, provided via LibXSPEC_jll. For a full list of the models, see Models index.

Warning

It is advised to use the Julia implemented models. This allows various calculations to benefit from automatic differentiation, efficient multi-threading, GPU offloading, and various other useful things, see Why & how.

model = GaussianLine(μ = FitParam(0.0))
┌ GaussianLine
 │      K ->  1 ± 0.1  ∈ [ 0, Inf ]   FREE
 │      μ ->  0 ± 0    ∈ [ 0, Inf ]   FREE
 │      σ ->  1 ± 0.1  ∈ [ 0, Inf ]   FREE
-└ 

We can plot our model over the same domain range quite easily too:

plot(data.domain[1:end-1], invokemodel(data.domain, model))
Example block output

Note that we've had to adjust the domain here. As stated before, most models are implemented for binned data, and therefore return one fewer bin than given.

SpectralFitting.jl adopts the SciML problem-solver abstraction, so to fit a model to data we specify a FittingProblem:

prob = FittingProblem(model => data)
┌ FittingProblem:
+└ 

We can plot our model over the same domain range quite easily too:

plot(data.domain[1:end-1], invokemodel(data.domain, model))
Example block output

Note that we've had to adjust the domain here. As stated before, most models are implemented for binned data, and therefore return one fewer bin than given.

SpectralFitting.jl adopts the SciML problem-solver abstraction, so to fit a model to data we specify a FittingProblem:

prob = FittingProblem(model => data)
┌ FittingProblem:
 │   . Models     : 1
 │   . Datasets   : 1
 │   Parameter Summary:
@@ -36,7 +36,7 @@
 │   . σᵤ    : [9.2751, 0.071547, 0.071547]
 │   . χ²    : 7.7600 
 └ 

The result card tells us a little bit about how successful the fit was. We further inspect the fit by overplotting result on the data:

plot(data, markersize = 3)
-plot!(result)
Example block output

We can create a contour plot of the fit statistic by evaluating the result everywhere on the grid and measuring the statistic:

amps = range(50, 200, 50)
+plot!(result)
Example block output

We can create a contour plot of the fit statistic by evaluating the result everywhere on the grid and measuring the statistic:

amps = range(50, 200, 50)
 devs = range(0.5, 1.2, 50)
 
 stats = [
@@ -54,4 +54,4 @@
     xlabel = "K",
     ylabel = "σ"
 )
-scatter!([result.u[1]], [result.u[3]])
Example block output

Simultaneous fits

+scatter!([result.u[1]], [result.u[3]])Example block output

Simultaneous fits

diff --git a/dev/fitting/index.html b/dev/fitting/index.html index 6899637..b81ca5a 100644 --- a/dev/fitting/index.html +++ b/dev/fitting/index.html @@ -1,2 +1,2 @@ -Fitting spectral models · SpectralFitting.jl
+Fitting spectral models · SpectralFitting.jl
diff --git a/dev/index.html b/dev/index.html index e9667cf..73ae361 100644 --- a/dev/index.html +++ b/dev/index.html @@ -2,4 +2,4 @@ Home · SpectralFitting.jl

SpectralFitting.jl Documentation

Fast and flexible spectral fitting in Julia.

SpectralFitting.jl is a package for defining and fitting spectral models, with a number of utilities to make model composition easy and invocation fast. SpectralFitting can be extended with LibXSPEC_jll.jl via XSPECModels.jl to expose the library of models from HEASoft XSPEC, and provides helper functions for operating with spectral data from a number of different missions. The package natively uses LsqFit.jl to fit parameters using the Levenberg-Marquardt algorithm, but makes it easy to use Optim.jl for more specialized fitting algorithms, or Turing.jl for Bayesian inference and MCMC.

SpectralFitting is designed to be extended, such that new models are simple to create, and new dataset processing pipelines for different missions are brief to define. Where performance is key, SpectralFitting helps you define fast and AD-compatible surrogates of spectral models using Surrogates.jl, and embed them in the model composition algebra.

To get started, add the AstroRegistry from the University of Bristol and then install:

julia>]
 pkg> registry add https://github.com/astro-group-bristol/AstroRegistry
 pkg> add SpectralFitting

Then use

using SpectralFitting
-# ....

See Walkthrough for an example walkthrough the package.

For more University of Bristol Astrophysics Group codes, see our GitHub organisation.

+# ....

See Walkthrough for an example walkthrough the package.

For more University of Bristol Astrophysics Group codes, see our GitHub organisation.

diff --git a/dev/models/composite-models/index.html b/dev/models/composite-models/index.html index cdd40ef..3d9d351 100644 --- a/dev/models/composite-models/index.html +++ b/dev/models/composite-models/index.html @@ -1,8 +1,8 @@ Composite models · SpectralFitting.jl

Composite models

The model algebra defined by the AbstractSpectralModelKind yields instances of CompositeModel, nested to various degrees. These composite models are designed to make as much information about the spectral model available at compile-time, such that rich and optimized generated functions may be assembled purely from the Julia types (see Why & how).

SpectralFitting.CompositeModelType
CompositeModel{M1,M2,O} <: AbstractSpectralModel
 CompositeModel(left_model, right_model, op::AbstractCompositeOperator)

Type resulting from operations combining any number of AbstractSpectralModel via the model algebra defined from AbstractSpectralModelKind.

Each operation binary operation in the model algebra is encoded in the parametric types of the CompositeModel, where the operation is given by an AbstractCompositeOperator. Composite models adopt the model kind of the right model, i.e. M2, and obey the model algebra accordingly.

Composite models very rarely need to be constructed directly, and are instead obtained by regular model operations.

Example

model = PhotoelectricAbsorption() * (PowerLaw() + BlackBody())
-typeof(model) <: CompositeModel # true
source
+typeof(model) <: CompositeModel # truesource diff --git a/dev/models/models/index.html b/dev/models/models/index.html index 0bac3ea..ddf32d1 100644 --- a/dev/models/models/index.html +++ b/dev/models/models/index.html @@ -19,7 +19,7 @@ 0 │ │ └────────────────────────────────────────┘ 0 20 - E (keV)source
SpectralFitting.BlackBodyType
BlackBody
  • K: Normalisation.

  • kT: Temperature (keV).

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, BlackBody())
                        BlackBody
        ┌────────────────────────────────────────┐
    0.2 │                                        │
@@ -39,7 +39,7 @@
      0 │:                                    '''│
        └────────────────────────────────────────┘
         0                                     20
-                         E (keV)
source
SpectralFitting.GaussianLineType
GaussianLine
  • K: Normalisation.

  • μ: Mean

  • σ: Standard deviation

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, GuassianLine())
                       GaussianLine                
         ┌────────────────────────────────────────┐ 
    0.09 │                                        │ 
@@ -59,7 +59,7 @@
       0 │.......:         :......................│ 
         └────────────────────────────────────────┘ 
          0                                     20  
-                          E (keV)                  
source
SpectralFitting.DeltaLineType
DeltaLine
  • _width

  • K: Normalisation.

  • E: Energy at which the delta function spikes.

Example

energy = collect(range(0.1, 20.0, 100))
+                          E (keV)                  
source
SpectralFitting.DeltaLineType
DeltaLine
  • _width

  • K: Normalisation.

  • E: Energy at which the delta function spikes.

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, DeltaLine())
                        DeltaLine                 
        ┌────────────────────────────────────────┐ 
    0.4 │         .                              │ 
@@ -79,17 +79,17 @@
      0 │.........::.............................│ 
        └────────────────────────────────────────┘ 
         0                                     20  
-                         E (keV)                 
Note

The DeltaLine model is not a true delta function, as this would be extremely difficult to define in a numerical model that needs to be able to propagate gradients. Instead, it is a very narrow GaussianLine model.

source

Multiplicative

Convolutional

SpectralFitting.Log10FluxType
Log10Flux

Used to measure the (log) flux of the models it is applied to. Note that the additive components must have their normalisations frozen for this model to work properly.

  • E_min

  • E_max

  • log10Flux

Example

model = PowerLaw()
+                         E (keV)                 
Note

The DeltaLine model is not a true delta function, as this would be extremely difficult to define in a numerical model that needs to be able to propagate gradients. Instead, it is a very narrow GaussianLine model.

source

Multiplicative

Convolutional

SpectralFitting.Log10FluxType
Log10Flux

Used to measure the (log) flux of the models it is applied to. Note that the additive components must have their normalisations frozen for this model to work properly.

  • E_min

  • E_max

  • log10Flux

Example

model = PowerLaw()
 model.K.frozen = true
 
-flux_model = Log10Flux()(model)
source

Wrappers

SpectralFitting.AutoCacheType
AutoCache

Used to automatically create a cache of another model, to avoid re-evaluating the model if the next parameters are close to the previous parameters. The intended use is for fitting expensive models which.

Example

model = PhotoelectricAbsorption() * AutoCache(PowerLaw())

In the above model, the PowerLaw component will be augmented with the caching behaviour.

source
SpectralFitting.AsConvolutionType
AsConvolution

Turn an additive model into a convolutional model.

Example

convolution_model = AsConvolution(GaussianLine())

The above model will now convolve the GaussianLine model onto whatever it is applied to.

source

Utility

Wrappers

SpectralFitting.AutoCacheType
AutoCache

Used to automatically create a cache of another model, to avoid re-evaluating the model if the next parameters are close to the previous parameters. The intended use is for fitting expensive models which.

Example

model = PhotoelectricAbsorption() * AutoCache(PowerLaw())

In the above model, the PowerLaw component will be augmented with the caching behaviour.

source
SpectralFitting.AsConvolutionType
AsConvolution

Turn an additive model into a convolutional model.

Example

convolution_model = AsConvolution(GaussianLine())

The above model will now convolve the GaussianLine model onto whatever it is applied to.

source

Utility

SpectralFitting.register_model_dataFunction
SpectralFitting.register_model_data(M::Type{<:AbstractSpectralModel}, model_data::ModelDataInfo...)
 SpectralFitting.register_model_data(M::Type{<:AbstractSpectralModel}, remote_and_local::Tuple{String,String}...)
 SpectralFitting.register_model_data(M::Type{<:AbstractSpectralModel}, filenames::String...)
 SpectralFitting.register_model_data(s::Symbol, filenames::String...)

Register filenames as model data associated with the model given by type M or symbol s. This function does not download any files, but rather adds the relevant filenames to a lookup which SpectralFitting.download_model_data consults when invoked, and consequently model data is only downloaded when needed.

Note

It is good practice to use this method immediately after defining a new model with @xspecmodel to register any required datafiles from the HEASoft source code, and therefore keep relevant information together.

Example

# by type
 register_model_data(XS_Laor, "ari.mod")
 # by symbol
-register_model_data(:XS_KyrLine, "KBHline01.fits")
source
SpectralFitting.finite_diff_kernel!Function
finite_diff_kernel!(f::Function, flux, energy)

Calculates the finite difference of the function f over the energy bin between the high and low bin edges, via

\[c_i = f(E_{i,\text{high}}) - f(E_{i,\text{low}}),\]

similar to evaluating the limits of the integral between $E_{i,\text{high}}$ and $E_{i,\text{low}}$.

This utility function is primarily used for Additive models to ensure the flux per bin is normalised for the energy over the bin.

source
SpectralFitting.wrap_model_as_objectiveFunction
wrap_model_as_objective(model::AbstractSpectralModel; ΔE = 1e-1)
-wrap_model_as_objective(M::Type{<:AbstractSpectralModel}; ΔE = 1e-1)

Wrap a spectral model into an objective function for building/optimizing a surrogate model. Returns an anonymous function taking the tuple (E, params...) as the argument, and returning a single flux value.

source

Generating model fingerprints

To generate the unicode plot to add as a fingerprint, we use a simple function:

using SpectralFitting, UnicodePlots
+register_model_data(:XS_KyrLine, "KBHline01.fits")
source
SpectralFitting.finite_diff_kernel!Function
finite_diff_kernel!(f::Function, flux, energy)

Calculates the finite difference of the function f over the energy bin between the high and low bin edges, via

\[c_i = f(E_{i,\text{high}}) - f(E_{i,\text{low}}),\]

similar to evaluating the limits of the integral between $E_{i,\text{high}}$ and $E_{i,\text{low}}$.

This utility function is primarily used for Additive models to ensure the flux per bin is normalised for the energy over the bin.

source
SpectralFitting.wrap_model_as_objectiveFunction
wrap_model_as_objective(model::AbstractSpectralModel; ΔE = 1e-1)
+wrap_model_as_objective(M::Type{<:AbstractSpectralModel}; ΔE = 1e-1)

Wrap a spectral model into an objective function for building/optimizing a surrogate model. Returns an anonymous function taking the tuple (E, params...) as the argument, and returning a single flux value.

source

Generating model fingerprints

To generate the unicode plot to add as a fingerprint, we use a simple function:

using SpectralFitting, UnicodePlots
 
 function plotmodel(energy, model)
     flux = invokemodel(energy, model)
@@ -123,4 +123,4 @@
    0  :...................................... 
      └────────────────────────────────────────┘ 
       0                                     20  
-                       E (keV)                  
+ E (keV) diff --git a/dev/models/surrogate-models/53135381.svg b/dev/models/surrogate-models/60af4c62.svg similarity index 87% rename from dev/models/surrogate-models/53135381.svg rename to dev/models/surrogate-models/60af4c62.svg index 91f9cb4..5af6e03 100644 --- a/dev/models/surrogate-models/53135381.svg +++ b/dev/models/surrogate-models/60af4c62.svg @@ -1,50 +1,50 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/models/surrogate-models/875f9e73.svg b/dev/models/surrogate-models/97da57c2.svg similarity index 86% rename from dev/models/surrogate-models/875f9e73.svg rename to dev/models/surrogate-models/97da57c2.svg index 62a16b9..6c03cde 100644 --- a/dev/models/surrogate-models/875f9e73.svg +++ b/dev/models/surrogate-models/97da57c2.svg @@ -1,48 +1,48 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/models/surrogate-models/77923861.svg b/dev/models/surrogate-models/aa03924b.svg similarity index 98% rename from dev/models/surrogate-models/77923861.svg rename to dev/models/surrogate-models/aa03924b.svg index 8c02b7b..c833c5b 100644 --- a/dev/models/surrogate-models/77923861.svg +++ b/dev/models/surrogate-models/aa03924b.svg @@ -1,62 +1,62 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/dev/models/surrogate-models/3bf28754.svg b/dev/models/surrogate-models/f5ad288b.svg similarity index 98% rename from dev/models/surrogate-models/3bf28754.svg rename to dev/models/surrogate-models/f5ad288b.svg index df4edbf..203b3c2 100644 --- a/dev/models/surrogate-models/3bf28754.svg +++ b/dev/models/surrogate-models/f5ad288b.svg @@ -1,62 +1,62 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - + + + + + + + + + + + diff --git a/dev/models/surrogate-models/index.html b/dev/models/surrogate-models/index.html index 6a1c9ba..b6800de 100644 --- a/dev/models/surrogate-models/index.html +++ b/dev/models/surrogate-models/index.html @@ -9,7 +9,7 @@ surrogate, (FitParam(1.0),), (:ηH,) -)

The lower_bounds and upper_bounds must be tuples in the form (E, params...), where E denotes the bounds on the energy range to train over.

source

To facilitate easy surrogate builds, SpectralFitting exports a number of utility functions.

SpectralFitting.make_surrogate_harnessFunction
make_surrogate_harness(
+)

The lower_bounds and upper_bounds must be tuples in the form (E, params...), where E denotes the bounds on the energy range to train over.

source

To facilitate easy surrogate builds, SpectralFitting exports a number of utility functions.

SpectralFitting.make_surrogate_harnessFunction
make_surrogate_harness(
     model::M,
     lowerbounds::T,
     upperbounds::T;
@@ -18,7 +18,7 @@
     S::Type = RadialBasis,
     sample_type = SobolSample(),
     verbose = false,
-)

Creates and optimizes a surrogate model of type S for model, using wrap_model_as_objective and optimize_accuracy! for optimization_samples iterations. Model is initially seeded with seed_samples points prior to optimization.

Warning

Additive models integrate energies to calculate flux, which surrogate models are currently not capable of. Results for Additive models likely to be inaccurate. This will be patched in a future version.

source
SpectralFitting.optimize_accuracy!Function
optimize_accuracy!(
+)

Creates and optimizes a surrogate model of type S for model, using wrap_model_as_objective and optimize_accuracy! for optimization_samples iterations. Model is initially seeded with seed_samples points prior to optimization.

Warning

Additive models integrate energies to calculate flux, which surrogate models are currently not capable of. Results for Additive models likely to be inaccurate. This will be patched in a future version.

source
SpectralFitting.optimize_accuracy!Function
optimize_accuracy!(
     surr::AbstractSurrogate,
     obj::Function,
     lb,
@@ -27,22 +27,22 @@
     maxiters = 200,
     N_truth = 5000,
     verbose = false,
-)

Improve accuracy (faithfullness) of the surrogate model in recreating the objective function.

Samples a new space of N_truth points between lb and ub, and calculates the objective function obj at each. Finds the point with largest MSE between surrogate and objective, and adds the point to the surrogate pool. Repeats maxiters times, adding maxiters points to surrogate model.

Optionally print to stdout the MSE and iteration count with verbose = true.

Note that upper- and lower-bounds should be in the form (E, params...), where E is a single energy and params are the model parameters.

source

Creating a surrogate for XS_PhotoelectricAbsorption

Before we start, let us discuss a number of benefits the use of surrogate models may bring us:

  • SurrogateSpectralModel permit use of automatic differentiation.
  • Surrogate models may be allocation-free depending on setup, whereas XSPEC wrappers will always have to allocate for type-conversions.
  • Surrogate models may be considerably faster, especially for table models.
  • Surrogate models are shareable (see Sharing surrogate models), and are tunable in size.

XS_PhotoelectricAbsorption is an XSPEC model that is wrapped by a thin C-wrapper into Julia. The implementation of this model is a number of Fortran routines from the late 90s, including a tabulation of ~3000 lines of data that has been copied directly into the Fortran source code.

The performance of this model represents its complexity.

using SpectralFitting, XSPECModels
+)

Improve accuracy (faithfullness) of the surrogate model in recreating the objective function.

Samples a new space of N_truth points between lb and ub, and calculates the objective function obj at each. Finds the point with largest MSE between surrogate and objective, and adds the point to the surrogate pool. Repeats maxiters times, adding maxiters points to surrogate model.

Optionally print to stdout the MSE and iteration count with verbose = true.

Note that upper- and lower-bounds should be in the form (E, params...), where E is a single energy and params are the model parameters.

source

Creating a surrogate for XS_PhotoelectricAbsorption

Before we start, let us discuss a number of benefits the use of surrogate models may bring us:

  • SurrogateSpectralModel permit use of automatic differentiation.
  • Surrogate models may be allocation-free depending on setup, whereas XSPEC wrappers will always have to allocate for type-conversions.
  • Surrogate models may be considerably faster, especially for table models.
  • Surrogate models are shareable (see Sharing surrogate models), and are tunable in size.

XS_PhotoelectricAbsorption is an XSPEC model that is wrapped by a thin C-wrapper into Julia. The implementation of this model is a number of Fortran routines from the late 90s, including a tabulation of ~3000 lines of data that has been copied directly into the Fortran source code.

The performance of this model represents its complexity.

using SpectralFitting, XSPECModels
 
 energy = collect(range(0.1, 20.0, 200))
 model = XS_PhotoelectricAbsorption()
 
 flux = similar(energy)[1:end-1]
199-element Vector{Float64}:
- 6.89874333401666e-310
- 6.89874333446487e-310
- 6.89874333446487e-310
- 6.89874333401666e-310
- 6.89874333446487e-310
- 6.8987433342285e-310
- 6.89874333446487e-310
- 6.89863262016306e-310
- 6.89874637237493e-310
- 6.89874637237493e-310
+ 0.0
+ 0.0
+ 0.0
+ 0.0
+ 0.0
+ 0.0
+ 0.0
+ 0.0
+ 0.0
+ 0.0
  ⋮
  0.0
  0.0
@@ -50,17 +50,17 @@
  0.0
  0.0
  0.0
- 0.10431665886394091
- 0.08792026600988984
- 7.413354821550009e-5

Benchmarking with BenchmarkTools.jl:

using BenchmarkTools
-@benchmark invokemodel!($flux, $energy, $model)
BenchmarkTools.Trial: 4772 samples with 1 evaluation.
- Range (minmax):  1.037 ms 1.513 ms   GC (min … max): 0.00% … 0.00%
- Time  (median):     1.041 ms               GC (median):    0.00%
- Time  (mean ± σ):   1.044 ms ± 11.901 μs   GC (mean ± σ):  0.00% ± 0.00%
+ 0.0
+ 0.0
+ 0.0

Benchmarking with BenchmarkTools.jl:

using BenchmarkTools
+@benchmark invokemodel!($flux, $energy, $model)
BenchmarkTools.Trial: 4757 samples with 1 evaluation.
+ Range (minmax):  1.036 ms 1.670 ms   GC (min … max): 0.00% … 0.00%
+ Time  (median):     1.039 ms               GC (median):    0.00%
+ Time  (mean ± σ):   1.047 ms ± 45.995 μs   GC (mean ± σ):  0.00% ± 0.00%
 
-    ▆█                                                       
-  ▂▆██▅▄▃▂▂▃▄▅▅▄▄▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▁▂▁▂▂▂▂▂▁▂▂▂▂ ▃
-  1.04 ms        Histogram: frequency by time        1.08 ms <
+  ▄█▃▁▅▃  ▁▁ ▁                                             ▁
+  ████████████▇▇▆▅▅▅▆▆▅▅▅▅▅▃▅▄▁▄▃▁▁▃▁▃▁▁▃▃▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▃ █
+  1.04 ms      Histogram: log(frequency) by time     1.15 ms <
 
  Memory estimate: 144 bytes, allocs estimate: 4.

The surrogate we'll construct will have to be tailored a little to the data we wish to fit, as we need to specify the parameter ranges our surrogate should learn. For example, we might be interested in energies between $0.1$ and $20$ keV (expressed in our domain), with equivalent hydrogen column $\eta$H anywhere between $10^{-3}$ and $30$. We specify the parameter bounds using tuples:

lower_bounds = (1e-3,)
 upper_bounds = (30.0,)
Note

The first index is always the energy bounds, and the subsequent indices are the parameters in the same order they are defined in the model structure.

Next, we use make_surrogate_harness to build and optimize a surrogate function for our model. By default, the surrogate uses linear radial basis functions, and seeds the coefficients with a number of seed points. This function then improves the accuracy of the model using optimize_accuracy!, until a maximal number of iterations has been reached.

For illustration purposes, we'll omit the accuracy improving step, and perform this ourselves. We can do this by setting optimization_samples = 0 in the keyword arguments:

using Surrogates
@@ -83,19 +83,19 @@
 model.ηH.value = ηh_test
 f = invokemodel(energy, model)
 
-f̂ = harness.surrogate([ηh_test])
Example block output

Now we'll use optimize_accuracy! to improve the faithfulness of our surrogate. This requires making use of wrap_model_as_objective as a little wrapper around our model:

optimize_accuracy!(harness; maxiters=50)
+f̂ = harness.surrogate([ηh_test])
Example block output

Now we'll use optimize_accuracy! to improve the faithfulness of our surrogate. This requires making use of wrap_model_as_objective as a little wrapper around our model:

optimize_accuracy!(harness; maxiters=50)
 
-length(harness.surrogate.x)
52

We can plot the surrogate model again and see the improvement.

new_f̂ = harness.surrogate([ηh_test])
Example block output

Tight. We can also inspect the memory footprint of our model:

# in bytes
+length(harness.surrogate.x)
52

We can plot the surrogate model again and see the improvement.

new_f̂ = harness.surrogate([ηh_test])
Example block output

Tight. We can also inspect the memory footprint of our model:

# in bytes
 Base.summarysize(harness)
174000

This may be reduced by lowering maxiters in optimize_accuracy! at the cost of decreasing faithfulness. However, compare this to the Fortran tabulated source file in the XSPEC source code, which is approximately 224 Kb. The surrogate model with all it's training data is of the same order.

Using a surrogate spectral model

Now that we have the surrogate model, we use SurrogateSpectralModel to wrap it into an AbstractSpectralModel. The constructor also needs to know the model kind, have a copy of the model parameters, and know which symbols to represent the parameters with.

sm = make_model(harness)
┌ SurrogateSpectralModel
 │      ηH ->  22.9 ± 0.1  ∈ [ 0, Inf ]   FREE

We can now use the familiar API and attempt to benchmark the performance:

@benchmark invokemodel!($flux, $energy, $sm)
BenchmarkTools.Trial: 10000 samples with 7 evaluations.
- Range (minmax):  4.159 μs 2.066 ms   GC (min … max): 0.00% … 88.20%
- Time  (median):     4.334 μs               GC (median):    0.00%
- Time  (mean ± σ):   5.032 μs ± 20.635 μs   GC (mean ± σ):  3.62% ±  0.88%
+ Range (minmax):  4.176 μs 1.489 ms   GC (min … max): 0.00% … 99.30%
+ Time  (median):     4.259 μs               GC (median):    0.00%
+ Time  (mean ± σ):   4.691 μs ± 14.867 μs   GC (mean ± σ):  3.15% ±  0.99%
 
-  ██ ▅▁▂▄▂▆▆▅▄ ▄▃ ▂▂                           ▁▁  ▁       ▂
-  ██▇█████████▇██████▇▇▆▆▅▆▆▆▆▆█▆▃▅▄▁▁▇▅▃▁▃▅▅▆▇█████████▇▇ █
-  4.16 μs      Histogram: log(frequency) by time     8.74 μs <
+  ▆██▃▂         ▁▄▁   ▂▆▆▅▃▂  ▂▄▄▂▁                        ▂
+  ██████▇▅▁▁▃▄▁▄████▆▅███████▆█████▇▆▆▇▆█▇▆▅▄▄▆▅▆▆▄▄▅▄▃▄▄▄ █
+  4.18 μs      Histogram: log(frequency) by time      5.9 μs <
 
  Memory estimate: 1.62 KiB, allocs estimate: 2.

Comparing this to the initial benchmark of XS_PhotoelectricAbsorption, we see about a significant speedup, with no allocations, and this surrogate model is now automatic differentiation ready.

Evaluating the model

p_range = collect(range(1.0, 30.0))
 
@@ -105,11 +105,11 @@
 end
 fluxes_mat = reduce(hcat, fluxes_vecs)
 
-surface(p_range, energy[1:end-1], fluxes_mat, xlabel = "ηH", ylabel = "E", zlabel = "f", title = "Model")
Example block output
s_fluxes_vecs = map(p_range) do p
+surface(p_range, energy[1:end-1], fluxes_mat, xlabel = "ηH", ylabel = "E", zlabel = "f", title = "Model")
Example block output
s_fluxes_vecs = map(p_range) do p
     sm.params[1].value = p
     display(sm)
     f = invokemodel(energy, sm)
 end
 s_fluxes_mat = reduce(hcat, s_fluxes_vecs)
 
-surface(p_range, energy[1:end-1], s_fluxes_mat, xlabel = "ηH", ylabel = "E", zlabel = "f", title = "Surrogate")
Example block output

Sharing surrogate models

To export and import surrogate models, JLD2.jl is recommended.

+surface(p_range, energy[1:end-1], s_fluxes_mat, xlabel = "ηH", ylabel = "E", zlabel = "f", title = "Surrogate")Example block output

Sharing surrogate models

To export and import surrogate models, JLD2.jl is recommended.

diff --git a/dev/models/using-models/index.html b/dev/models/using-models/index.html index 08f51c8..6d0a263 100644 --- a/dev/models/using-models/index.html +++ b/dev/models/using-models/index.html @@ -103,28 +103,28 @@ 0.1999999999999993 0.20000000000000284 0.1999999999999993 - 0.1999999999999993
Note

To add new XSPEC or foreign function models, see Wrapping new XSPEC models.

Model abstraction

All spectral models are a sub-type of AbstractSpectralModel.

SpectralFitting.AbstractSpectralModelType
abstract type AbstractSpectralModel{T,K<:AbstractSpectralModelKind} end

Supertype of all spectral models, tracking the number type T and AbstractSpectralModelKind denoted K.

Implementation

Sub-types must implement the following interface (see the function's documentation for examples):

Usage

The available API for a spectral model is detailed below:

The following query functions exist:

Model reflection is supported by the following functions. These are intended for internal use and are not exported.

The parametric type parameter T is the number type of the model and K defines the AbstractSpectralModelKind.

source
SpectralFitting.invoke!Function
SpectralFitting.invoke!(output, domain, M::Type{<:AbstractSpectralModel}, params...)

Used to define the behaviour of models. Should calculate the output of the model and write in-place into output. The model parameters are passed in the model structure.

Warning

This function should not be called directly. Use invokemodel instead. invoke! is only to define the model, not to use it. Users should always call models using invokemodel or invokemodel! to ensure normalisations and closures are accounted for.

Example

Base.@kwdef struct MyModel{T} <: AbstractSpectralModel{T,Multiplicative}
+ 0.1999999999999993
Note

To add new XSPEC or foreign function models, see Wrapping new XSPEC models.

Model abstraction

All spectral models are a sub-type of AbstractSpectralModel.

SpectralFitting.AbstractSpectralModelType
abstract type AbstractSpectralModel{T,K<:AbstractSpectralModelKind} end

Supertype of all spectral models, tracking the number type T and AbstractSpectralModelKind denoted K.

Implementation

Sub-types must implement the following interface (see the function's documentation for examples):

Usage

The available API for a spectral model is detailed below:

The following query functions exist:

Model reflection is supported by the following functions. These are intended for internal use and are not exported.

The parametric type parameter T is the number type of the model and K defines the AbstractSpectralModelKind.

source
SpectralFitting.invoke!Function
SpectralFitting.invoke!(output, domain, M::Type{<:AbstractSpectralModel}, params...)

Used to define the behaviour of models. Should calculate the output of the model and write in-place into output. The model parameters are passed in the model structure.

Warning

This function should not be called directly. Use invokemodel instead. invoke! is only to define the model, not to use it. Users should always call models using invokemodel or invokemodel! to ensure normalisations and closures are accounted for.

Example

Base.@kwdef struct MyModel{T} <: AbstractSpectralModel{T,Multiplicative}
     p1::T = FitParam(1.0)
     p2::T = FitParam(2.0)
     p3::T = FitParam(3.0)
 end

would have the arguments passed to invoke! as

function SpectralFitting.invoke!(output, domain, model::MyModel)
     # ...
-end
source
SpectralFitting.modelkindFunction
modelkind(M::Type{<:AbstractSpectralModel})
-modelkind(::AbstractSpectralModel)

Return the kind of model given by M: either Additive, Multiplicative, or Convolutional.

source
SpectralFitting.numbertypeFunction
numbertype(::AbstractSpectralModel)

Get the numerical type of the model. This goes through FitParam, so that the number type returned is as close to a primative as possible.

See also paramtype.

Example

numbertype(PowerLaw()) == Float64
source

Model methods

SpectralFitting.invokemodelFunction
invokemodel(domain, model::AbstractSpectralModel)

Invoke the AbstractSpectralModel given by model over the domain domain.

This function will perform any normalisation or post-processing tasks that a specific model kind may require, e.g. multiplying by a normalisation constant for Additive models.

Note

invokemodel allocates the needed output arrays based on the element type of free_params to allow automatic differentation libraries to calculate parameter gradients.

In-place non-allocating variants are the invokemodel! functions.

Example

model = PowerLaw()
+end
source
SpectralFitting.modelkindFunction
modelkind(M::Type{<:AbstractSpectralModel})
+modelkind(::AbstractSpectralModel)

Return the kind of model given by M: either Additive, Multiplicative, or Convolutional.

source
SpectralFitting.numbertypeFunction
numbertype(::AbstractSpectralModel)

Get the numerical type of the model. This goes through FitParam, so that the number type returned is as close to a primative as possible.

See also paramtype.

Example

numbertype(PowerLaw()) == Float64
source

Model methods

SpectralFitting.invokemodelFunction
invokemodel(domain, model::AbstractSpectralModel)

Invoke the AbstractSpectralModel given by model over the domain domain.

This function will perform any normalisation or post-processing tasks that a specific model kind may require, e.g. multiplying by a normalisation constant for Additive models.

Note

invokemodel allocates the needed output arrays based on the element type of free_params to allow automatic differentation libraries to calculate parameter gradients.

In-place non-allocating variants are the invokemodel! functions.

Example

model = PowerLaw()
 domain = collect(range(0.1, 20.0, 100))
 
-invokemodel(domain, model)
source
SpectralFitting.invokemodel!Function
invokemodel!(output, domain, model)
 invokemodel!(output, domain, model, params::AbstractVector)
 invokemodel!(output, domain, model, params::ParameterCache)

In-place variant of invokemodel, calculating the output of an AbstractSpectralModel given by model, optionally overriding the parameters using a ParameterCache or an AbstractVector.

The output may not necessarily be a single vector, and one should use allocate_model_output to allocate the output structure.

Example

model = PowerLaw()
 domain = collect(range(0.1, 20.0, 100))
 output = allocate_model_output(model, domain)
-invokemodel!(output, domain, model)
source

Model algebra

Models exist as three different kinds, defined by an AbstractSpectralModelKind trait.

Model algebra

Models exist as three different kinds, defined by an AbstractSpectralModelKind trait.

SpectralFitting.AdditiveType
Additive <: AbstractSpectralModelKind
-Additive()

Additive models are effectively the sources of photons, and are the principle building blocks of composite models. Every additive model has a normalisation parameter which re-scales the output by a constant factor K.

Note

Defining custom additive models requires special care. See Defining new models.

source
SpectralFitting.MultiplicativeType
Multiplicative <: AbstractSpectralModelKind
-Multiplicative()

Multiplicative models act on Additive models, by element-wise multiplying the output in each domain bin of the additive model by a different factor.

source

Model data availability

Many of the XSPEC implemented models use tabular data, such as FITS, and return results interpolated from these pre-calculated tables. In some cases, these table models have data files that are multiple gigabytes in size, and would be very unwieldy to ship indiscriminantly. SpectralFitting attempts to circumnavigate this bloat by downloading the model data on an ut opus basis.

SpectralFitting.AdditiveType
Additive <: AbstractSpectralModelKind
+Additive()

Additive models are effectively the sources of photons, and are the principle building blocks of composite models. Every additive model has a normalisation parameter which re-scales the output by a constant factor K.

Note

Defining custom additive models requires special care. See Defining new models.

source
SpectralFitting.MultiplicativeType
Multiplicative <: AbstractSpectralModelKind
+Multiplicative()

Multiplicative models act on Additive models, by element-wise multiplying the output in each domain bin of the additive model by a different factor.

source

Model data availability

Many of the XSPEC implemented models use tabular data, such as FITS, and return results interpolated from these pre-calculated tables. In some cases, these table models have data files that are multiple gigabytes in size, and would be very unwieldy to ship indiscriminantly. SpectralFitting attempts to circumnavigate this bloat by downloading the model data on an ut opus basis.

SpectralFitting.download_model_dataFunction
SpectralFitting.download_model_data(model::AbstractSpectralModel; kwargs...)
 SpectralFitting.download_model_data(M::Type{<:AbstractSpectralModel}; kwargs...)
-SpectralFitting.download_model_data(s::Symbol; kwargs...)

Downloads the model data for a model specified either by model, type M, or symbol s. Datafiles associated with a specific model may be registered using SpectralFitting.register_model_data. The download is currently unconfigurable, but permits slight control via a number of keyword arguments:

  • progress::Bool = true

Display a progress bar for the download.

  • model_source_url::String = "http://www.star.bris.ac.uk/fbaker/XSPEC-model-data"

The source URL used to download the model data.

All standard XSPEC spectral model data is currently being hosted on the University of Bristol astrophysics servers, and should be persistently available to anyone.

source

Special care must be taken if new XSPEC models are wrapped to ensure the data is available. For more on this, see Wrapping new XSPEC models.

Model data may also alternatively be copied in by-hand from a HEASoft XSPEC source directory. In this case, the location to copy the data to may be determined via joinpath(SpectralFitting.LibXSPEC_jll.artifact_dir, "spectral", "modelData").

+SpectralFitting.download_model_data(s::Symbol; kwargs...)

Downloads the model data for a model specified either by model, type M, or symbol s. Datafiles associated with a specific model may be registered using SpectralFitting.register_model_data. The download is currently unconfigurable, but permits slight control via a number of keyword arguments:

  • progress::Bool = true

Display a progress bar for the download.

  • model_source_url::String = "http://www.star.bris.ac.uk/fbaker/XSPEC-model-data"

The source URL used to download the model data.

All standard XSPEC spectral model data is currently being hosted on the University of Bristol astrophysics servers, and should be persistently available to anyone.

source

Special care must be taken if new XSPEC models are wrapped to ensure the data is available. For more on this, see Wrapping new XSPEC models.

Model data may also alternatively be copied in by-hand from a HEASoft XSPEC source directory. In this case, the location to copy the data to may be determined via joinpath(SpectralFitting.LibXSPEC_jll.artifact_dir, "spectral", "modelData").

diff --git a/dev/models/xspec-models/index.html b/dev/models/xspec-models/index.html index f9a5816..5cbdb46 100644 --- a/dev/models/xspec-models/index.html +++ b/dev/models/xspec-models/index.html @@ -10,7 +10,7 @@ # constructor has default values function XS_PowerLaw(; K = FitParam(1.0), a = FitParam(1.0)) XS_PowerLaw{typeof(K)}(K, a) -end

We define a new structure XS_PowerLaw with two parameters, but since the model is Additive, only a single parameter (a) is passed to the XSPEC function. The function we bind to this model is :C_powerlaw from the XSPEC C wrappers.

The macro will then generate the following functions

If a callsite was specified, it will also generate:

source

XSPEC models frequently have tabular data dependencies, without which the models fail to invoke (see Model data availability). If the data files are known but not present, the XSPEC models will throw an error with instructions for downloading the missing data. If the data files are unknown, Julia may crash catastrophically. If this is the case, often a single line will be printed with the LibXSPEC error, specifying the name of the missing source file. This can be registered as a data dependency of a model using SpectralFitting.register_model_data.

The first time any XSPEC model is invoked, SpectralFitting checks to see whether requisite data is needed, and whether the data is downloaded. Subsequent calls will hit a lookup cache instead to avoid run-time costs of performing this check.

Additive

XSPECModels.XS_PowerLawType
XS_PowerLaw(K, a)
  • K: Normalisation.

  • a: Photon index.

Example

energy = collect(range(0.1, 20.0, 100))
+end

We define a new structure XS_PowerLaw with two parameters, but since the model is Additive, only a single parameter (a) is passed to the XSPEC function. The function we bind to this model is :C_powerlaw from the XSPEC C wrappers.

The macro will then generate the following functions

If a callsite was specified, it will also generate:

source

XSPEC models frequently have tabular data dependencies, without which the models fail to invoke (see Model data availability). If the data files are known but not present, the XSPEC models will throw an error with instructions for downloading the missing data. If the data files are unknown, Julia may crash catastrophically. If this is the case, often a single line will be printed with the LibXSPEC error, specifying the name of the missing source file. This can be registered as a data dependency of a model using SpectralFitting.register_model_data.

The first time any XSPEC model is invoked, SpectralFitting checks to see whether requisite data is needed, and whether the data is downloaded. Subsequent calls will hit a lookup cache instead to avoid run-time costs of performing this check.

Additive

XSPECModels.XS_PowerLawType
XS_PowerLaw(K, a)
  • K: Normalisation.

  • a: Photon index.

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_PowerLaw())
                      XS_PowerLaw
        ┌────────────────────────────────────────┐
    0.5 │                                        │
@@ -30,7 +30,7 @@
      0 │                                        │
        └────────────────────────────────────────┘
         0                                     20
-                         E (keV)
source
XSPECModels.XS_BlackBodyType
XS_BlackBody(K, T)
  • K: Normalisation.

  • T: Temperature (keV).

Example

energy = collect(range(0.1, 20.0, 100))
+                         E (keV)
source
XSPECModels.XS_BlackBodyType
XS_BlackBody(K, T)
  • K: Normalisation.

  • T: Temperature (keV).

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_BlackBody())
                      XS_BlackBody
        ┌────────────────────────────────────────┐
    0.2 │                                        │
@@ -50,7 +50,7 @@
      0 │'                                    '''│
        └────────────────────────────────────────┘
         0                                     20
-                         E (keV)
source
XSPECModels.XS_BremsStrahlungType
XS_BremsStrahlung(K, T)
  • K: Normalisation.

  • T: Plasma temperature (keV).

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_BremsStrahlung())
                  XS_BremsStrahlung
      ┌────────────────────────────────────────┐
    2 │                                        │
@@ -70,7 +70,7 @@
    0 │  ':....................................│
      └────────────────────────────────────────┘
       0                                     20
-                       E (keV)
source
XSPECModels.XS_GaussianType
XS_Gaussian(K, E, σ)
  • K: Normalisation

  • E: Line wavelength in Angstrom.

  • σ: Line width in Angstrom.

Example

energy = collect(range(4.0, 8.0, 100))
+                       E (keV)
source
XSPECModels.XS_GaussianType
XS_Gaussian(K, E, σ)
  • K: Normalisation

  • E: Line wavelength in Angstrom.

  • σ: Line width in Angstrom.

Example

energy = collect(range(4.0, 8.0, 100))
 invokemodel(energy, XS_Gaussian())
                        XS_Gaussian
         ┌────────────────────────────────────────┐
    0.09 │                                        │
@@ -90,7 +90,7 @@
       0 │.......:         :......................│
         └────────────────────────────────────────┘
          0                                     20
-                          E (keV)
source
XSPECModels.XS_LaorType
XS_Laor(K, lineE, a, inner_r, outer_r, incl)
  • K: Normalisation.

  • lineE: Rest frame line energy (keV).

  • a: Power law dependence of emissitivy. Scales R⁻ᵅ.

  • inner_r: Inner radius of the accretion disk (GM/c).

  • outer_r: Outer radius of the accretion disk (GM/c).

  • θ: Disk inclination angle to line of sight (degrees, 0 is pole on).

Example

energy = collect(range(0.1, 10.0, 100))
+                          E (keV)
source
XSPECModels.XS_LaorType
XS_Laor(K, lineE, a, inner_r, outer_r, incl)
  • K: Normalisation.

  • lineE: Rest frame line energy (keV).

  • a: Power law dependence of emissitivy. Scales R⁻ᵅ.

  • inner_r: Inner radius of the accretion disk (GM/c).

  • outer_r: Outer radius of the accretion disk (GM/c).

  • θ: Disk inclination angle to line of sight (degrees, 0 is pole on).

Example

energy = collect(range(0.1, 10.0, 100))
 invokemodel(energy, XS_Laor())
                          XS_Laor
         ┌────────────────────────────────────────┐
    0.06 │                                        │
@@ -110,7 +110,7 @@
       0 │.......:''                 :............│
         └────────────────────────────────────────┘
          0                                     10
-                          E (keV)
source
XSPECModels.XS_DiskLineType
XS_DiskLine(K, lineE, β, inner_r, outer_r, incl)
  • K: Normalisation.

  • lineE: Rest frame line energy (keV).

  • β: Power law dependence of emissitivy. If < 10, scales Rᵅ.

  • inner_r: Inner radius of the accretion disk (GM/c).

  • outer_r: Outer radius of the accretion disk (GM/c).

  • θ: Disk inclination angle to line of sight (degrees, 0 is pole on).

Example

energy = collect(range(4.0, 8.0, 100))
+                          E (keV)
source
XSPECModels.XS_DiskLineType
XS_DiskLine(K, lineE, β, inner_r, outer_r, incl)
  • K: Normalisation.

  • lineE: Rest frame line energy (keV).

  • β: Power law dependence of emissitivy. If < 10, scales Rᵅ.

  • inner_r: Inner radius of the accretion disk (GM/c).

  • outer_r: Outer radius of the accretion disk (GM/c).

  • θ: Disk inclination angle to line of sight (degrees, 0 is pole on).

Example

energy = collect(range(4.0, 8.0, 100))
 invokemodel(energy, XS_DiskLine())
                        XS_DiskLine
         ┌────────────────────────────────────────┐
    0.09 │                                        │
@@ -130,7 +130,7 @@
       0 │...............:'''           :.........│
         └────────────────────────────────────────┘
          4                                      8
-                          E (keV)
source
XSPECModels.XS_PhotoelectricAbsorptionType
XS_PhotoelectricAbsorption(ηH)
  • ηH: Equivalent hydrogen column (units of 10²² atoms per cm⁻²).

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_PhotoelectricAbsorption())
             XS_PhotoelectricAbsorption
      ┌────────────────────────────────────────┐
    1 │       ...''''''''''''''''''''''''''''''│
@@ -150,7 +150,7 @@
    0 │.:                                      │
      └────────────────────────────────────────┘
       0                                     20
-                       E (keV)
source
XSPECModels.XS_WarmAbsorptionType
XS_WarmAbsorption(ηH, Ew)
  • ηH: Equivalent hydrogen column (units of 10²² atoms per cm⁻²).

  • Ew: Window energy (keV).

Example

energy = collect(range(0.1, 20.0, 100))
+                       E (keV)
source
XSPECModels.XS_WarmAbsorptionType
XS_WarmAbsorption(ηH, Ew)
  • ηH: Equivalent hydrogen column (units of 10²² atoms per cm⁻²).

  • Ew: Window energy (keV).

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_WarmAbsorption())
                    XS_WarmAbsorption
        ┌────────────────────────────────────────┐
      1 │':      ...''':'''''''''''''''''''''''''│
@@ -170,7 +170,7 @@
    0.2 │  :                                     │
        └────────────────────────────────────────┘
         0                                     20
-                         E (keV)
source
XSPECModels.XS_CalculateFluxType
XS_CalculateFlux(E_min, E_max, lg10Flux)
  • E_min: Minimum energy.

  • E_max: Maximum energy.

  • log10Flux: log (base 10) flux in erg / cm^2 / s

source
XSPECModels.XS_KerrDiskType
XS_KerrDisk(K, lineE, index1, index2, break_r, a, θ, inner_r, outer_r)
  • K: Normalisation.

  • lineE: Rest frame line energy (keV).

  • index1: Emissivity index for inner disk.

  • index2: Emissivity index for outer disk.

  • break_r: Break radius seperating inner and outer disk (gᵣ).

  • a: Dimensionless black hole spin.

  • θ: Disk inclination angle to line of sight (degrees).

  • inner_r: Inner radius of the disk in units of rₘₛ.

  • outer_r: Outer radius of the disk in units of rₘₛ.

  • z: Redshift.

Example

energy = collect(range(0.1, 20.0, 100))
+                         E (keV)
source
XSPECModels.XS_CalculateFluxType
XS_CalculateFlux(E_min, E_max, lg10Flux)
  • E_min: Minimum energy.

  • E_max: Maximum energy.

  • log10Flux: log (base 10) flux in erg / cm^2 / s

source
XSPECModels.XS_KerrDiskType
XS_KerrDisk(K, lineE, index1, index2, break_r, a, θ, inner_r, outer_r)
  • K: Normalisation.

  • lineE: Rest frame line energy (keV).

  • index1: Emissivity index for inner disk.

  • index2: Emissivity index for outer disk.

  • break_r: Break radius seperating inner and outer disk (gᵣ).

  • a: Dimensionless black hole spin.

  • θ: Disk inclination angle to line of sight (degrees).

  • inner_r: Inner radius of the disk in units of rₘₛ.

  • outer_r: Outer radius of the disk in units of rₘₛ.

  • z: Redshift.

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_KerrDisk())
                        XS_KerrDisk
         ┌────────────────────────────────────────┐
    0.05 │                                        │
@@ -190,7 +190,7 @@
       0 │.........:'''                    :......│
         └────────────────────────────────────────┘
          0                                      8
-                          E (keV)
source
XSPECModels.XS_KyrLineType
XS_KyrLine(K, a, θ_obs, inner_r, ms_flag, outer_r, lineE, α, β, break_r, z, limb)
  • K: Normalisation.

  • a: Dimensionless black hole spin.

  • θ: Observer inclination (0 is on pole, degrees).

  • inner_r: Inner radius of the disk in units of GM/c²

  • ms_flag: 0: integrate from rᵢₙ. 1: integrate from rₘₛ.

  • outer_r: Outer radius of the disk in units of GM/c²

  • lineE: Rest frame line energy (keV).

  • α

  • β

  • break_r: Break radius seperating inner and outer disk (GM/c²).

  • z: Overall Doppler shift.

  • limb: 0: isotropic emission, 1: Laor's limb darkening, 2: Haard's limb brightening.

Example

energy = collect(range(0.1, 20.0, 100))
+                          E (keV)
source
XSPECModels.XS_KyrLineType
XS_KyrLine(K, a, θ_obs, inner_r, ms_flag, outer_r, lineE, α, β, break_r, z, limb)
  • K: Normalisation.

  • a: Dimensionless black hole spin.

  • θ: Observer inclination (0 is on pole, degrees).

  • inner_r: Inner radius of the disk in units of GM/c²

  • ms_flag: 0: integrate from rᵢₙ. 1: integrate from rₘₛ.

  • outer_r: Outer radius of the disk in units of GM/c²

  • lineE: Rest frame line energy (keV).

  • α

  • β

  • break_r: Break radius seperating inner and outer disk (GM/c²).

  • z: Overall Doppler shift.

  • limb: 0: isotropic emission, 1: Laor's limb darkening, 2: Haard's limb brightening.

Example

energy = collect(range(0.1, 20.0, 100))
 invokemodel(energy, XS_KyrLine())
                        XS_KyrLine
         ┌────────────────────────────────────────┐
    0.05 │                                        │
@@ -210,4 +210,4 @@
       0 │.........:'''                    :......│
         └────────────────────────────────────────┘
          0                                      8
-                          E (keV)
source
+ E (keV)source diff --git a/dev/parameters/46bb1216.svg b/dev/parameters/46bb1216.svg deleted file mode 100644 index 966650f..0000000 --- a/dev/parameters/46bb1216.svg +++ /dev/null @@ -1,1508 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/parameters/56aabc18.svg b/dev/parameters/56aabc18.svg new file mode 100644 index 0000000..5d52335 --- /dev/null +++ b/dev/parameters/56aabc18.svg @@ -0,0 +1,1506 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/parameters/5bf754d5.svg b/dev/parameters/5bf754d5.svg deleted file mode 100644 index af0579b..0000000 --- a/dev/parameters/5bf754d5.svg +++ /dev/null @@ -1,1504 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/parameters/8d56b117.svg b/dev/parameters/8d56b117.svg new file mode 100644 index 0000000..e50d04e --- /dev/null +++ b/dev/parameters/8d56b117.svg @@ -0,0 +1,1502 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/parameters/9a9dbc2d.svg b/dev/parameters/9a9dbc2d.svg new file mode 100644 index 0000000..df3c2aa --- /dev/null +++ b/dev/parameters/9a9dbc2d.svg @@ -0,0 +1,1508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/parameters/aa5285d6.svg b/dev/parameters/aa5285d6.svg deleted file mode 100644 index 02f1d30..0000000 --- a/dev/parameters/aa5285d6.svg +++ /dev/null @@ -1,1508 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dev/parameters/index.html b/dev/parameters/index.html index d7bfa38..52c864b 100644 --- a/dev/parameters/index.html +++ b/dev/parameters/index.html @@ -9,7 +9,7 @@ bind!(prob, :a_1) # bind the normalisation of powerlaws in the 2nd model: -bind!(prob, 2 => :K_1, 2 => :K_2)
Note

Only free parameters can be bound together.

source
Note

Bindings are treated not as specific to the model but specific to the FittingProblem. This is because you may want to use the same model for multiple different datasets, and have slightly different binding requirements for each one (e.g. depending on the instruments you are using). If you do need the same binding applied to two different problems, you can do that with

append!(prob1.bindings, prob2.bindings)

Caution however, this will only make sense if you are using precisely the same model in both problems.

Let's try it out. We'll generate some arbitrary powerlaw spectra with different normalisations and fit them simultaneously.

using SpectralFitting, Plots
+bind!(prob, 2 => :K_1, 2 => :K_2)
Note

Only free parameters can be bound together.

source
Note

Bindings are treated not as specific to the model but specific to the FittingProblem. This is because you may want to use the same model for multiple different datasets, and have slightly different binding requirements for each one (e.g. depending on the instruments you are using). If you do need the same binding applied to two different problems, you can do that with

append!(prob1.bindings, prob2.bindings)

Caution however, this will only make sense if you are using precisely the same model in both problems.

Let's try it out. We'll generate some arbitrary powerlaw spectra with different normalisations and fit them simultaneously.

using SpectralFitting, Plots
 
 energy = collect(range(0.1, 10.0, 100))
 
@@ -21,7 +21,7 @@
 data2 = simulate(energy, model2, var = 1e-3)
 
 plot(data1, xscale = :log10, yscale = :log10)
-plot!(data2, xscale = :log10, yscale = :log10)
Example block output

Now we want to fit a single powerlaw model to both of these spectra simultaneously, but with the powerlaw index fixed to be the same in both models.

model = PowerLaw()
+plot!(data2, xscale = :log10, yscale = :log10)
Example block output

Now we want to fit a single powerlaw model to both of these spectra simultaneously, but with the powerlaw index fixed to be the same in both models.

model = PowerLaw()
 prob = FittingProblem(model => data1, model => data2)
 
 bind!(prob, :a)
@@ -47,11 +47,11 @@
 plot(data1, xscale = :log10, yscale = :log10)
 plot!(data2, xscale = :log10, yscale = :log10)
 plot!(result[1])
-plot!(result[2])
Example block output

Note that these fits are not perfect, because the underlying data have subtly different power law indices, but our fit is required to enforce the models to have the same value. If we release this requirement, the fit will be better, but the models will be entirely independent.

prob = FittingProblem(model => data1, model => data2)
+plot!(result[2])
Example block output

Note that these fits are not perfect, because the underlying data have subtly different power law indices, but our fit is required to enforce the models to have the same value. If we release this requirement, the fit will be better, but the models will be entirely independent.

prob = FittingProblem(model => data1, model => data2)
 
 result = SpectralFitting.fit(prob, LevenbergMarquadt())
 
 plot(data1, xscale = :log10, yscale = :log10)
 plot!(data2, xscale = :log10, yscale = :log10)
 plot!(result[1])
-plot!(result[2])
Example block output +plot!(result[2])Example block output diff --git a/dev/reference/index.html b/dev/reference/index.html index 9c4ccb4..71c0303 100644 --- a/dev/reference/index.html +++ b/dev/reference/index.html @@ -1,5 +1,5 @@ -Reference · SpectralFitting.jl

API reference

General reference

SpectralFitting.Reflection.add_objective_reduction!Method
add_objective_reduction!(ra::CompositeAggregation, op::Symbol)

Reduces the current objective count and applies the reduction operation op to them. For example, if op is :+, and the objective count is 3, then after this function has been called the objective count will be 2 and the reduction expression

@. flux2 = flux2 + flux3

will have been added to the CompositeAggregation.

source
SpectralFitting.Reflection.assemble_objective_unpackMethod
assemble_objective_unpack(N)

Assembles the statements for unpacking the objective cache into a number of views. Assembles the part of the model call that looks like:

objective1 = view(objectives, :, 1), objective2 = ...

for N objectives slices.

source
SpectralFitting.Reflection.make_constructorMethod
make_constructor(model::Type{<:AbstractSpectralModel}, closures::Vector, params::Vector, T::Type)

Create a constructor expression for the model. Should return something similar to

:(PowerLaw{T}(arg1, arg2, arg3)))

unpacking the closures and params vectors in the appropriate places.

source
SpectralFitting.Reflection.CompositeModelInfoType
struct CompositeModelInfo
+Reference · SpectralFitting.jl

API reference

General reference

SpectralFitting.Reflection.add_objective_reduction!Method
add_objective_reduction!(ra::CompositeAggregation, op::Symbol)

Reduces the current objective count and applies the reduction operation op to them. For example, if op is :+, and the objective count is 3, then after this function has been called the objective count will be 2 and the reduction expression

@. flux2 = flux2 + flux3

will have been added to the CompositeAggregation.

source
SpectralFitting.Reflection.assemble_objective_unpackMethod
assemble_objective_unpack(N)

Assembles the statements for unpacking the objective cache into a number of views. Assembles the part of the model call that looks like:

objective1 = view(objectives, :, 1), objective2 = ...

for N objectives slices.

source
SpectralFitting.Reflection.make_constructorMethod
make_constructor(model::Type{<:AbstractSpectralModel}, closures::Vector, params::Vector, T::Type)

Create a constructor expression for the model. Should return something similar to

:(PowerLaw{T}(arg1, arg2, arg3)))

unpacking the closures and params vectors in the appropriate places.

source
SpectralFitting.Reflection.CompositeModelInfoType
struct CompositeModelInfo
     "The parameter symbols of the model with the respective lens to the actual parameter."
     parameter_symbols::Vector{Pair{Symbol,Lens}}
     "Each model assigned to a unique symbol."
@@ -12,7 +12,7 @@
     maximum_objective_cache_count::Int
     "How many objective caches are currently active."
     objective_cache_count::Int
-end

The composite equivalent of ModelInfo, augmented to track the model symbol (a1, m3, etc.), and the model parameters (K_1, a_3, etc.)

source
SpectralFitting.Reflection.ModelInfoType
struct ModelInfo
     "All parameter symbols for the model."
     symbols::Vector{Symbol}
     "Unique symbols generated for the parameter assignment when buildin the function call."
@@ -25,4 +25,4 @@
     lens::Lens
     "The model type itself."
     model::Type
-end

All models are parsed into a ModelInfo struct relative to their parent (in the case of composite models).

The symbols field contains all of the model parameter symbols as they are in the structure, not as they have been generated. Recall when the invocation expressions are generated, we create anonymous paramter names to avoid conflicts. These are the generated_symbols instead.

source
+end

All models are parsed into a ModelInfo struct relative to their parent (in the case of composite models).

The symbols field contains all of the model parameter symbols as they are in the structure, not as they have been generated. Recall when the invocation expressions are generated, we create anonymous paramter names to avoid conflicts. These are the generated_symbols instead.

source
diff --git a/dev/transitioning-from-xspec/index.html b/dev/transitioning-from-xspec/index.html index f2f1496..7c0b0d1 100644 --- a/dev/transitioning-from-xspec/index.html +++ b/dev/transitioning-from-xspec/index.html @@ -1,2 +1,2 @@ -Transitioning from XSPEC · SpectralFitting.jl
+Transitioning from XSPEC · SpectralFitting.jl
diff --git a/dev/walkthrough/b9b3e075.svg b/dev/walkthrough/1d7320ec.svg similarity index 93% rename from dev/walkthrough/b9b3e075.svg rename to dev/walkthrough/1d7320ec.svg index cd73388..b748a6b 100644 --- a/dev/walkthrough/b9b3e075.svg +++ b/dev/walkthrough/1d7320ec.svg @@ -1,204 +1,204 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/6ec77444.svg b/dev/walkthrough/1faf36b5.svg similarity index 67% rename from dev/walkthrough/6ec77444.svg rename to dev/walkthrough/1faf36b5.svg index a120d0f..26a73ca 100644 --- a/dev/walkthrough/6ec77444.svg +++ b/dev/walkthrough/1faf36b5.svg @@ -1,527 +1,527 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/1695b318.svg b/dev/walkthrough/35980b81.svg similarity index 52% rename from dev/walkthrough/1695b318.svg rename to dev/walkthrough/35980b81.svg index 9a50dae..80b7017 100644 --- a/dev/walkthrough/1695b318.svg +++ b/dev/walkthrough/35980b81.svg @@ -1,397 +1,399 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/57ade537.svg b/dev/walkthrough/5932877e.svg similarity index 73% rename from dev/walkthrough/57ade537.svg rename to dev/walkthrough/5932877e.svg index 5041ca3..7eb69b7 100644 --- a/dev/walkthrough/57ade537.svg +++ b/dev/walkthrough/5932877e.svg @@ -1,401 +1,401 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/91d1637c.svg b/dev/walkthrough/7b0761e9.svg similarity index 77% rename from dev/walkthrough/91d1637c.svg rename to dev/walkthrough/7b0761e9.svg index 6a48a6c..22f703d 100644 --- a/dev/walkthrough/91d1637c.svg +++ b/dev/walkthrough/7b0761e9.svg @@ -1,373 +1,373 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/d182fad7.svg b/dev/walkthrough/948c8ca8.svg similarity index 74% rename from dev/walkthrough/d182fad7.svg rename to dev/walkthrough/948c8ca8.svg index a8269a6..9e3e63b 100644 --- a/dev/walkthrough/d182fad7.svg +++ b/dev/walkthrough/948c8ca8.svg @@ -1,521 +1,521 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/a0687720.svg b/dev/walkthrough/a50519cb.svg similarity index 81% rename from dev/walkthrough/a0687720.svg rename to dev/walkthrough/a50519cb.svg index f90b938..92a3598 100644 --- a/dev/walkthrough/a0687720.svg +++ b/dev/walkthrough/a50519cb.svg @@ -1,81 +1,81 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/a8429d8a.svg b/dev/walkthrough/a56548b1.svg similarity index 77% rename from dev/walkthrough/a8429d8a.svg rename to dev/walkthrough/a56548b1.svg index e05a88f..1165ab6 100644 --- a/dev/walkthrough/a8429d8a.svg +++ b/dev/walkthrough/a56548b1.svg @@ -390,10 +390,8 @@ - - - - - - - + + + + + diff --git a/dev/walkthrough/408e2e44.svg b/dev/walkthrough/bd616e2f.svg similarity index 70% rename from dev/walkthrough/408e2e44.svg rename to dev/walkthrough/bd616e2f.svg index 818ef5d..2e88119 100644 --- a/dev/walkthrough/408e2e44.svg +++ b/dev/walkthrough/bd616e2f.svg @@ -1,401 +1,401 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/5f53bde4.svg b/dev/walkthrough/bf6883d5.svg similarity index 69% rename from dev/walkthrough/5f53bde4.svg rename to dev/walkthrough/bf6883d5.svg index a77a569..09f3bf2 100644 --- a/dev/walkthrough/5f53bde4.svg +++ b/dev/walkthrough/bf6883d5.svg @@ -1,529 +1,529 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/84ecabbb.svg b/dev/walkthrough/c13c2afe.svg similarity index 71% rename from dev/walkthrough/84ecabbb.svg rename to dev/walkthrough/c13c2afe.svg index f9c7b2a..25bdf3b 100644 --- a/dev/walkthrough/84ecabbb.svg +++ b/dev/walkthrough/c13c2afe.svg @@ -1,399 +1,399 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/82194c0d.svg b/dev/walkthrough/cd983b3e.svg similarity index 83% rename from dev/walkthrough/82194c0d.svg rename to dev/walkthrough/cd983b3e.svg index d04e697..8b5c254 100644 --- a/dev/walkthrough/82194c0d.svg +++ b/dev/walkthrough/cd983b3e.svg @@ -1,54 +1,54 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/89ad7a24.svg b/dev/walkthrough/f14243d5.svg similarity index 70% rename from dev/walkthrough/89ad7a24.svg rename to dev/walkthrough/f14243d5.svg index 662acbe..9f03b47 100644 --- a/dev/walkthrough/89ad7a24.svg +++ b/dev/walkthrough/f14243d5.svg @@ -1,397 +1,397 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/2b26b4bb.svg b/dev/walkthrough/fafa105f.svg similarity index 64% rename from dev/walkthrough/2b26b4bb.svg rename to dev/walkthrough/fafa105f.svg index 8430291..1800f2d 100644 --- a/dev/walkthrough/2b26b4bb.svg +++ b/dev/walkthrough/fafa105f.svg @@ -1,976 +1,976 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/walkthrough/index.html b/dev/walkthrough/index.html index ac478f4..c1ebd95 100644 --- a/dev/walkthrough/index.html +++ b/dev/walkthrough/index.html @@ -31,9 +31,9 @@ . Response : /home/runner/work/SpectralFitting.jl/SpectralFitting.jl/docs/build/../../ex-datadir/s54405.rsp . Background : nothing . Ancillary : nothing -

We can load and alter any part of a dataset as we do our fitting. For example, if you have multiple different ancillary files at hand, switching them between fits is a one-liner.

To visualize our data, we can use some of the Plots.jl recipes included in SpectralFitting.jl:

plot(data, xlims = (0.5, 70), xscale = :log10)
Example block output

Note that the units are currently not divided by the energy bin widths. We can either do that manually, or use the normalize! to convert whatever units the data is currently in to the defacto standard counts s⁻¹ keV⁻¹ for fitting. Whilst we're at it, we see in the model card that there are 40 bad quality bins still present in our data. We can drop those as well, and plot the data on log-log axes:

normalize!(data)
+

We can load and alter any part of a dataset as we do our fitting. For example, if you have multiple different ancillary files at hand, switching them between fits is a one-liner.

To visualize our data, we can use some of the Plots.jl recipes included in SpectralFitting.jl:

plot(data, xlims = (0.5, 70), xscale = :log10)
Example block output

Note that the units are currently not divided by the energy bin widths. We can either do that manually, or use the normalize! to convert whatever units the data is currently in to the defacto standard counts s⁻¹ keV⁻¹ for fitting. Whilst we're at it, we see in the model card that there are 40 bad quality bins still present in our data. We can drop those as well, and plot the data on log-log axes:

normalize!(data)
 drop_bad_channels!(data)
-plot(data, ylims = (0.001, 2.0), yscale = :log10, xscale = :log10)
Example block output

Note that when there are no negative axes, the scale defaults to log on the plot unless otherwise specified.

Next we want to specify a model to fit to this data. Models that are prefixed with XS_ are models that are linked from the XSPEC model library, provided via LibXSPEC_jll. For a full list of the models, see Models library.

Warning

It is advised to use the Julia implemented models. This allows various calculations to benefit from automatic differentiation, efficient multi-threading, GPU offloading, and various other useful things, see Why & how.

We will start by fitting a photoelectric absorption model that acts on a power law model:

Note

To see information about a model, use the ? in the Julia REPL:

julia> ?PowerLaw
+plot(data, ylims = (0.001, 2.0), yscale = :log10, xscale = :log10)
Example block output

Note that when there are no negative axes, the scale defaults to log on the plot unless otherwise specified.

Next we want to specify a model to fit to this data. Models that are prefixed with XS_ are models that are linked from the XSPEC model library, provided via LibXSPEC_jll. For a full list of the models, see Models library.

Warning

It is advised to use the Julia implemented models. This allows various calculations to benefit from automatic differentiation, efficient multi-threading, GPU offloading, and various other useful things, see Why & how.

We will start by fitting a photoelectric absorption model that acts on a power law model:

Note

To see information about a model, use the ? in the Julia REPL:

julia> ?PowerLaw
 XS_PowerLaw(K, a)
 
     •  K: Normalisation.
@@ -76,7 +76,7 @@
     xscale = :log10,
     yscale = :log10
 )
-plot!(result)
Example block output

Our model does not account for the high energy range well. We can ignore that range for now, and select everything from 0 to 15 keV and refit:

mask_energies!(data, 0, 15)
+plot!(result)
Example block output

Our model does not account for the high energy range well. We can ignore that range for now, and select everything from 0 to 15 keV and refit:

mask_energies!(data, 0, 15)
 result = fit(prob, LevenbergMarquadt())
┌ FittingResult:
 │   Model: CompositeModel[PhotoelectricAbsorption * PowerLaw]
 │   . u     : [21.584, 2.2307, 0.53199]
@@ -87,7 +87,7 @@
     xscale = :log10,
     yscale = :log10
 )
-plot!(result, label = "PowerLaw")
Example block output

The result is not yet baked into our model, and represents just the outcome of the fit. To update the parameters and errors in the model, we can use update_model!

update_model!(model, result)
┌ CompositeModel with 2 model components:
+plot!(result, label = "PowerLaw")
Example block output

The result is not yet baked into our model, and represents just the outcome of the fit. To update the parameters and errors in the model, we can use update_model!

update_model!(model, result)
┌ CompositeModel with 2 model components:
 │      m1 * a1
 │ Model key and parameters:
 │    a1 => PowerLaw
@@ -97,7 +97,7 @@
 │      ηH_1 ->  0.532 ± 0.1  ∈ [ 0, Inf ]   FREE
Note

Since fitting and updating a model is often done in tandem, SpectralFitting.jl has both a fit and fit! method, the latter automatically updates the model parameters after fit.

To estimate the goodness of our fit, we can mimic the goodness command from XSPEC. This will use the simulate function to simulate spectra for a dataset (here determined by the result), and fit the model to the simulated dataset. The fit statistic for each fit is then appended to an array, which we can use to plot a histogram:

spread = goodness(result; N = 1000, seed = 42, exposure_time = data.data.spectrum.exposure_time)
 histogram(spread, ylims = (0, 300), label = "Simulated")
-vline!([result.χ2], label = "Best fit")
Example block output

Note we have set the random number generator seed with seed = 42 to allow our results to be strictly reproduced.

The goodness command will log the percent of simulations with a fit statistic better than the result, but we can equivalently calculate that ourselves:

count(<(result.χ2), spread) * 100 / length(spread)
56.9

Next we want to calculate the flux in an energy range observed by the detector. We can do this with LogFlux or XS_CalculateFlux, as they are both equivalent implementations.

We can modify our model by accessing properties from the model card and writing a new expression:

calc_flux = XS_CalculateFlux(
+vline!([result.χ2], label = "Best fit")
Example block output

Note we have set the random number generator seed with seed = 42 to allow our results to be strictly reproduced.

The goodness command will log the percent of simulations with a fit statistic better than the result, but we can equivalently calculate that ourselves:

count(<(result.χ2), spread) * 100 / length(spread)
56.9

Next we want to calculate the flux in an energy range observed by the detector. We can do this with LogFlux or XS_CalculateFlux, as they are both equivalent implementations.

We can modify our model by accessing properties from the model card and writing a new expression:

calc_flux = XS_CalculateFlux(
     E_min = FitParam(0.2, frozen = true),
     E_max = FitParam(2.0, frozen = true),
     log10Flux = FitParam(-10.3, lower_limit = -100, upper_limit = 100),
@@ -145,7 +145,7 @@
     yscale = :log10
 )
 plot!(flux_result)
-vspan!([flux_model.c1.E_min.value, flux_model.c1.E_max.value], alpha = 0.5)
Example block output

Let's try alternative models to see how they fit the data. First, an absorbed black body:

model2 = PhotoelectricAbsorption() * XS_BlackBody()
┌ CompositeModel with 2 model components:
+vspan!([flux_model.c1.E_min.value, flux_model.c1.E_max.value], alpha = 0.5)
Example block output

Let's try alternative models to see how they fit the data. First, an absorbed black body:

model2 = PhotoelectricAbsorption() * XS_BlackBody()
┌ CompositeModel with 2 model components:
 │      m1 * a1
 │ Model key and parameters:
 │    a1 => XS_BlackBody
@@ -166,14 +166,14 @@
     legend = :bottomleft,
 )
 plot!(dp, result, label = "PowerLaw $(round(result.χ2))")
-plot!(dp, result2, label = "BlackBody $(round(result2.χ2))")
Example block output

Or a bremsstrahlung model:

model3 = PhotoelectricAbsorption() * XS_BremsStrahlung()
+plot!(dp, result2, label = "BlackBody $(round(result2.χ2))")
Example block output

Or a bremsstrahlung model:

model3 = PhotoelectricAbsorption() * XS_BremsStrahlung()
 prob3 = FittingProblem(model3 => data)
 result3 = fit(prob3, LevenbergMarquadt())
┌ FittingResult:
 │   Model: CompositeModel[PhotoelectricAbsorption * XS_BremsStrahlung]
 │   . u     : [13.868, 5.3034, 0.0]
 │   . σᵤ    : [1.3178, 0.70705, 0.19664]
 │   . χ²    : 40.027 
-└ 
plot!(dp, result3, label = "Brems $(round(result3.χ2))")
Example block output

Let's take a look at the residuals of these three models. There are utility methods for this in SpectralFitting.jl, but we can easily just interact with the result directly:

function calc_residuals(result)
+└ 
plot!(dp, result3, label = "Brems $(round(result3.χ2))")
Example block output

Let's take a look at the residuals of these three models. There are utility methods for this in SpectralFitting.jl, but we can easily just interact with the result directly:

function calc_residuals(result)
     # select which result we want (only have one, but for generalisation to multi-model fits)
     r = result[1]
     y = invoke_result(r)
@@ -186,14 +186,14 @@
 plot!(rp,domain, calc_residuals(result), seriestype = :stepmid)
 plot!(rp, domain, calc_residuals(result2), seriestype = :stepmid)
 plot!(rp, domain, calc_residuals(result3), seriestype = :stepmid)
-rp
Example block output

We can compose this figure with our previous one, and change to a linear x scale:

plot(dp, rp, layout = grid(2, 1, heights = [0.7, 0.3]), link = :x, xscale = :linear)
Example block output

We can do all that plotting work in one go with the plotresult recipe:

plotresult(
+rp
Example block output

We can compose this figure with our previous one, and change to a linear x scale:

plot(dp, rp, layout = grid(2, 1, heights = [0.7, 0.3]), link = :x, xscale = :linear)
Example block output

We can do all that plotting work in one go with the plotresult recipe:

plotresult(
     data,
     [result, result2, result3],
     ylims = (0.001, 2.0),
     xscale = :log10,
     yscale = :log10,
     legend = :bottomleft,
-)
Example block output

Let's modify the black body model with a continuum component

bbpl_model = model2.m1 * (PowerLaw() + model2.a1) |> deepcopy
┌ CompositeModel with 3 model components:
+)
Example block output

Let's modify the black body model with a continuum component

bbpl_model = model2.m1 * (PowerLaw() + model2.a1) |> deepcopy
┌ CompositeModel with 3 model components:
 │      m1 * (a2 + a1)
 │ Model key and parameters:
 │    a1 => XS_BlackBody
@@ -231,7 +231,7 @@
     yscale = :log10,
     legend = :bottomleft,
 )
-plot!(bbpl_result)
Example block output

Update the model and fix the black body temperature to 2 keV:

update_model!(bbpl_model, bbpl_result)
+plot!(bbpl_result)
Example block output

Update the model and fix the black body temperature to 2 keV:

update_model!(bbpl_model, bbpl_result)
 
 bbpl_model.T_1.value = 2.0
 bbpl_model.T_1.frozen = true
@@ -254,7 +254,7 @@
 │   . u     : [0.38234, 573.17, 4.8351]
 │   . σᵤ    : [0.034796, 83.183, 0.16012]
 │   . χ²    : 71.708 
-└ 

Overplotting this new result:

plot!(bbpl_result2)
Example block output

MCMC

We can use libraries like Pidgeons.jl or Turing.jl to perform Bayesian inference on our paramters. SpectralFitting.jl is designed with BYOO (Bring Your Own Optimizer) in mind, and so makes it relatively easy to get at the core fitting functions to be used with other packages.

Let's use Turing.jl here, which means we'll also want to use StatsPlots.jl to plot our walker chains.

using StatsPlots
+└ 

Overplotting this new result:

plot!(bbpl_result2)
Example block output

MCMC

We can use libraries like Pidgeons.jl or Turing.jl to perform Bayesian inference on our paramters. SpectralFitting.jl is designed with BYOO (Bring Your Own Optimizer) in mind, and so makes it relatively easy to get at the core fitting functions to be used with other packages.

Let's use Turing.jl here, which means we'll also want to use StatsPlots.jl to plot our walker chains.

using StatsPlots
 using Turing

Turing.jl provides enormous control over the definition of the model, and this is not control SpectralFitting.jl wants to take away from you. Although we will provide utility scripts to do the basics, here we'll show you everything step by step to give you an overview of what you can do.

Let's go back to our first model:

model
┌ CompositeModel with 2 model components:
 │      m1 * a1
 │ Model key and parameters:
@@ -277,13 +277,14 @@
     make_objective_variance(ContiguouslyBinned(), data),
     # _f_objective returns a function used to evaluate and fold the model through the data
     SpectralFitting._f_objective(config),
-)

That's it! We're now ready to sample our model. Since all our models are implemented in Julia, we can use gradient-boosted samplers with automatic differentiation, such as NUTS. We'll walk 5000 itterations, just as a small example:

chain = sample(mm, NUTS(), 5_000)
Chains MCMC chain (5000×15×1 Array{Float64, 3}):
+)
eltype(args) = CompositeModel{PhotoelectricAbsorption{Interpolations.Extrapolation{Float64, 1, Interpolations.GriddedInterpolation{Float64, 1, Vector{Float64}, Interpolations.Gridded{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Vector{Float64}}}, Interpolations.Gridded{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Interpolations.Line{Nothing}}, FitParam{Float64}}, PowerLaw{FitParam{Float64}}, MultiplicationOperator, FitParam{Float64}, Additive}
+eltype(args) = OGIPDataset{Float64, FITSIO.FITSHeader}

That's it! We're now ready to sample our model. Since all our models are implemented in Julia, we can use gradient-boosted samplers with automatic differentiation, such as NUTS. We'll walk 5000 itterations, just as a small example:

chain = sample(mm, NUTS(), 5_000)
Chains MCMC chain (5000×15×1 Array{Float64, 3}):
 
 Iterations        = 1001:1:6000
 Number of chains  = 1
 Samples per chain = 5000
-Wall duration     = 15.93 seconds
-Compute duration  = 15.93 seconds
+Wall duration     = 15.27 seconds
+Compute duration  = 15.27 seconds
 parameters        = K, a, ηH
 internals         = lp, n_steps, is_accept, acceptance_rate, log_density, hamiltonian_energy, hamiltonian_energy_error, max_hamiltonian_energy_error, tree_depth, numerical_error, step_size, nom_step_size
 
@@ -303,4 +304,4 @@
            K   18.5775   19.7203   20.2969   20.8620   21.9507
            a    2.1212    2.1660    2.1895    2.2118    2.2545
           ηH    0.3356    0.4210    0.4690    0.5170    0.6161
-

In the printout we see summary statistics about or model, in this case that it has converged well (rhat close to 1 for all parameters), better estimates of the standard deviation, and various quantiles. We can plot our chains to make sure the caterpillers are healthy and fuzzy, making use of StatsPlots.jl recipes:

plot(chain)
Example block output

Corner plots are currently broken at time of writing.

+

In the printout we see summary statistics about or model, in this case that it has converged well (rhat close to 1 for all parameters), better estimates of the standard deviation, and various quantiles. We can plot our chains to make sure the caterpillers are healthy and fuzzy, making use of StatsPlots.jl recipes:

plot(chain)
Example block output

Corner plots are currently broken at time of writing.

diff --git a/dev/why-and-how/index.html b/dev/why-and-how/index.html index f83a448..8e94b79 100644 --- a/dev/why-and-how/index.html +++ b/dev/why-and-how/index.html @@ -60,4 +60,4 @@ return objective1 end end -end

This generated function also takes care of some other things for us, such as unpacking parameters (optionally unpacking frozen parameters separately), and ensuring any closure are passed to invokemodel if a model needs them (e.g., SurrogateSpectralModel).

This is achieved by moving as much information as possible about the model and its construction to its type, such that all of the invocation and parameter unpacking may be inferred at compile time.

Note

With the addition of more pure-Julia models, non-allocating methods without aggressive pre-allocation are possible, and will be added in the future. Such methods may allow models to add or multiply in-place on the total flux array, instead of relying on later broadcasts.

+end

This generated function also takes care of some other things for us, such as unpacking parameters (optionally unpacking frozen parameters separately), and ensuring any closure are passed to invokemodel if a model needs them (e.g., SurrogateSpectralModel).

This is achieved by moving as much information as possible about the model and its construction to its type, such that all of the invocation and parameter unpacking may be inferred at compile time.

Note

With the addition of more pure-Julia models, non-allocating methods without aggressive pre-allocation are possible, and will be added in the future. Such methods may allow models to add or multiply in-place on the total flux array, instead of relying on later broadcasts.