Main functionalities

  • Preparation of empirical data: both the data domain and empirical values (with associated uncertainties) should be wrapped into Domain (or CartesianDomain) and Measures objects respectively. Such objects are created by simply passing AbstractVector{<: Real} to their respective constructors, e.g.:

    using GModelFit
    dom  = Domain([0.1, 1.1, 2.1, 3.1, 4.1])
    data = Measures(dom, [6.29, 7.27, 10.41, 18.67, 25.3],
                          [1.1,  1.1,   1.1,   1.2, 1.2])
  • Component creation: a component is a structure inheriting GModelFit.AbstractComponent and hosting one or more fields with type GModelFit.Parameter. It is created by simply invoking its constructor, e.g.:

    using GModelFit
    
    # Create a stand-alone component (i.e. a component used outisde a model)
    comp = GModelFit.Gaussian(1, 0, 1) # numbers represent the parameter values
    
    # A stand-alone component can be evaluated on a user provided domain as follows:
    comp(Domain(-4:0.1:4))
    
    # Evaluate the component providing custom parameter values:
    comp(Domain(-4:0.1:4), center=0.1, sigma=1.3)

    The list of available components is available in Built-in components.

    Note: a component with dependencies can't be evaluated as a stand-alone since it requires the corresponding dependencies to be available in a model.

  • Model definition and manipulation: a Model object is essentially a dictionary of components with Symbol keys. The keys(), haskey() and iterate() methods defined for the Model object provide the usual functionalities as for any dictionary. . A model object can be created and manipulated as follows:

    using GModelFit
    
    # Create an empty model
    model = Model()
    
    # Add a two Gaussian components, and a third one representing their sum
    model[:comp1] = GModelFit.Gaussian(1, 3, 1)
    model[:comp2] = GModelFit.Gaussian(0.5, 4, 0.3)
    model[:sum] = @fd (comp1, comp2) -> comp1 .+ comp2
    
    # Modify a parameter value:
    model[:comp1].center.val = 5
    
    # Evaluate the model on a user defined domain
    dom = Domain(0:0.1:10)
    model(dom)
    
    # Evaluate the model, but retrieve the outcome of the :comp2 component
    model(dom, :comp2)
  • Mock data: the GModelFit.mock() function allows to generate mock data set(s) using a (multi-)model as ground truth, and add a random noise to simulate the measurement process. An example using the previously defined model and domain is as follows:

    data = GModelFit.mock(Measures, model, dom)

    This functionality is used in the examples of the next sections to generate the mock datasets.

  • Fitting: the main functions to fit a model (represented by a Model object) to an empirical dataset (represented by a Measures object) are fit and fit!. The latter provide the same functionality as the former with the only difference that upon return the Model object will have their parameters set to the best fit values. In both cases the Model object will be evaluated on the same domain associated with the Measures object. An overview of the fit workflow is as follows:

    The following code shows how to fit the previously generated mock data set to the above model:

    bestfit, stats = fit(model, data)
    (Components:
    ───────────┬─────────────┬───────┬─────────────┬───────────┬───────────┬───────────┬─────────╮
     Component  Type         #Free  Eval. count  Min        Max        Mean       NaN/Inf 
    ├───────────┼─────────────┼───────┼─────────────┼───────────┼───────────┼───────────┼─────────┤
     sum        FComp               158          4.025e-07     0.8991     0.1444  0       
     ├─╴comp1   Gaussian_1D  3      88           4.025e-07     0.3873    0.09398  0       
     └─╴comp2   Gaussian_1D  3      78           1.283e-93     0.7005    0.05044  0       
    ╰───────────┴─────────────┴───────┴─────────────┴───────────┴───────────┴───────────┴─────────╯
    
    Parameters:
    ───────────┬─────────────┬────────┬──────────┬───────────┬───────────┬────────┬───────╮
     Component  Type         Param.  Range     Value      Uncert.    Actual  Patch 
    ├───────────┼─────────────┼────────┼──────────┼───────────┼───────────┼────────┼───────┤
     comp1      Gaussian_1D  norm    0:Inf        0.9492    0.07232                
                             center  -Inf:Inf       5.13    0.09001                
                             sigma   0:Inf        0.9773    0.06464                
    ├───────────┼─────────────┼────────┼──────────┼───────────┼───────────┼────────┼───────┤
     comp2      Gaussian_1D  norm    0:Inf        0.5095    0.05394                
                             center  -Inf:Inf      4.005    0.01508                
                             sigma   0:Inf        0.2901    0.02094                
    ╰───────────┴─────────────┴────────┴──────────┴───────────┴───────────┴────────┴───────╯
    , Fit results: #data: 101, #free pars: 6, red. fit stat.:      1.141, Status: OK      
    )

    The fit function returns a tuple with:

    To perform a Multi-dataset fitting simply pass a Vector{Model} and a Vector{Measures to the fit function.

  • Serialization: a few structures (such as GModelFit.ModelSnapshot, GModelFit.FitStats and Measures{N}) can be serialized, i.e. stored in a file, and later de-serialized in a separata Julia session. This is useful when the best fit model and associated informations must be saved for a later use, without the need to re-run the fitting. The best fit model, fit statistics and mock dataset used above can be serialized with:

    GModelFit.serialize("my_snapshot.json", bestfit, stats, data)

    In a separate Julia session, you can obtain a copy of exactly the same data with

    using GModelFit
    (bestit, stats, data) = GModelFit.deserialize("my_snapshot.json")