Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement JOSS doc suggestions #101

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
85f037b
Improve documentation especially quickstart, home and power analysis
jschepers Jul 10, 2024
2c65a7f
adapted the order of reference overviews and adapted titles
jschepers Jul 18, 2024
ee9e00a
Updated quickstart page
jschepers Jul 22, 2024
ac0d3bd
minor changes
jschepers Jul 22, 2024
373e535
fixed docstrings for predef_eeg and predef_2x2
jschepers Jul 23, 2024
b073526
added draft of design types reference page
jschepers Jul 23, 2024
89c09a1
Update quickstart.jl
behinger Jul 24, 2024
1e2694f
Add UnfoldSim logo to the documentation
jschepers Jul 24, 2024
9ab04aa
Finished experimental design reference page
jschepers Jul 24, 2024
5671e2e
Replace logo file
jschepers Jul 25, 2024
10c77a3
Update logo file
jschepers Jul 25, 2024
ea25ddc
Delete docs/src/assets/logo.svg
jschepers Jul 25, 2024
e0c2310
Add logo as png file
jschepers Jul 25, 2024
34ce887
Added intro paragraph for Simulate ERP tutorial
jschepers Jul 30, 2024
b5a60bf
Improved docstrings for single- and multi-subject design
jschepers Jul 30, 2024
b81b605
Fixed simulate docstring
jschepers Jul 30, 2024
369faff
Added cross references in docstrings
jschepers Jul 31, 2024
541cf67
Added intro sentences, matched titles and sidebar, reordered pages an…
jschepers Jul 31, 2024
f449083
Update noise.jl
behinger Jul 26, 2024
fe00ec2
Update src/noise.jl
behinger Jul 26, 2024
f93a3c1
Update src/noise.jl
behinger Jul 26, 2024
aca3fd2
Update src/noise.jl
jschepers Jul 31, 2024
e868a14
add empty line for formatting reasons
jschepers Jul 31, 2024
43dd57c
Update docs/literate/reference/noisetypes.jl
jschepers Aug 1, 2024
68ce722
Update docs/literate/reference/overview.jl
jschepers Aug 1, 2024
2dfd44b
Update docs/literate/reference/overview.jl
jschepers Aug 1, 2024
2c34e5e
Update docs/literate/reference/noisetypes.jl
jschepers Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ data, events = simulate(
PinkNoise(),
);
```
All components (design, components, onsets, noise) can be easily modified and you can simply plugin your own!
All simulation ingredients (design, components, onsets, noise) can be easily modified and you can simply plugin your own!

## Contributions
Contributions of any kind are very welcome. Please have a look at [CONTRIBUTING.md](https://github.com/unfoldtoolbox/UnfoldSim.jl/blob/main/CONTRIBUTING.md) for guidance on contributing to UnfoldSim.jl.
Expand Down
18 changes: 15 additions & 3 deletions docs/literate/HowTo/multichannel.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# # Generate multi channel data

# Here you will learn how to simulate EEG data for multiple channels/electrodes.
# The idea is to specify a signal on source level and then use a head model or a manual projection matrix to project the source signal to a number of electrodes.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
## Load required packages
using UnfoldSim
using UnfoldMakie
using CairoMakie
using DataFrames
using Random

# ```@raw html
# </details >
# ```

# ## Specifying a design

Expand All @@ -17,7 +29,7 @@ c2 = LinearModelComponent(; basis = p300(), formula = @formula(0 ~ 1), β = [1])


# ## The multichannel component
# next similar to the nested design above, we can nest the component in a `MultichannelComponent`. We could either provide the projection marix manually, e.g.:
# Next, similar to the nested design above, we can nest the component in a `MultichannelComponent`. We could either provide the projection matrix manually, e.g.:
mc = UnfoldSim.MultichannelComponent(c, [1, 2, -1, 3, 5, 2.3, 1])

# or maybe more convenient: use the pair-syntax: Headmodel=>Label which makes use of a headmodel (HaRTmuT is currently easily available in UnfoldSim)
Expand All @@ -26,7 +38,7 @@ mc = UnfoldSim.MultichannelComponent(c, hart => "Left Postcentral Gyrus")
mc2 = UnfoldSim.MultichannelComponent(c2, hart => "Right Occipital Pole")

# !!! hint
# You could also specify a noise-specific component which is applied prior to projection & summing with other components
# You could also specify a noise-specific component which is applied prior to projection & summing with other components.
#
# finally we need to define the onsets of the signal
onset = UniformOnset(; width = 20, offset = 4);
Expand Down
18 changes: 14 additions & 4 deletions docs/literate/HowTo/newComponent.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
# # New component: Duration + Shift
# # Define a new component (with variable duration and shift)

# We want a new component that changes its duration and shift depending on a column in the event-design. This is somewhat already implemented in the HRF + Pupil bases
# We want a new component that changes its duration and shift depending on a column in the event design. This is somewhat already implemented in the HRF + Pupil bases.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
using UnfoldSim
using Unfold
using Random
using DSP
using CairoMakie, UnfoldMakie

sfreq = 100;
# ```@raw html
# </details >
# ```

# ## Design
# Let's generate a design with two columns, shift + duration
Expand All @@ -19,7 +28,8 @@ design = UnfoldSim.SingleSubjectDesign(;
)


# We also need a new AbstractComponent
# ## Implement a new AbstractComponent
# We also need a new `AbstractComponent`
struct TimeVaryingComponent <: AbstractComponent
basisfunction::Any
maxlength::Any
Expand Down Expand Up @@ -51,7 +61,7 @@ function basis_shiftduration(evts, maxlength)
end
end


# ## Simulate data with the new component type
erp = UnfoldSim.simulate(
MersenneTwister(1),
TimeVaryingComponent(basis_shiftduration, 50),
Expand Down
23 changes: 17 additions & 6 deletions docs/literate/HowTo/newDesign.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
# # Define a new (imbalanced) design

# A design specifies how much data is generated, and how the event-table(s)
# should be generated. Already implemented examples are `MultiSubjectDesign` and `SingleSubjectDesign`.

# We need 3 things for a new design: a `struct<:AbstractDesign`, a `size` and a `generate` function.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
using UnfoldSim
using StableRNGs
using DataFrames
using Parameters
# ## Define a new Design
# A design specifies how much data is generated, and how the event-table(s)
# should be generated. Already implemented examples are `MultiSubjectDesign` and `SingleSubjectDesign`
#
# We need 3 things for a new design: a `struct<:AbstractDesign`, a `size` and a `generate` function
#
# ```@raw html
# </details>
# <br />
# ```

# #### 1) `type`
# We need a `ImbalanceSubjectDesign` struct. You are free to implement it as you wish, as long as the other two functions are implemented
#
Expand Down
10 changes: 10 additions & 0 deletions docs/literate/HowTo/predefinedData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@

# Let's say you want to use the events data frame (containing the levels of the experimental variables and the event onsets (latencies)) from a previous study in your simulation.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
## Load required packages
using UnfoldSim
using DataFrames
using Random
using CairoMakie # for plotting
# ```@raw html
# </details >
# <br />
# ```

# From a previous study, we (somehow, e.g. by using [pyMNE.jl](https://unfoldtoolbox.github.io/Unfold.jl/dev/HowTo/pymne/)) imported an event data frame like this:
my_events = DataFrame(:condition => [:A, :B, :B, :A, :A], :latency => [7, 13, 22, 35, 41])
Expand Down
6 changes: 2 additions & 4 deletions docs/literate/HowTo/repeatTrials.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using UnfoldSim


# ## Repeating Design entries
# # [Get multiple trials with identical subject/item combinations](@id howto_repeat_design)
# Sometimes we want to repeat a design, that is, have multiple trials with identical values, but it is not always straight forward to implement.
# For instance, there is no way to easily modify `MultiSubjectDesign` to have multiple identical subject/item combinations,
# without doing awkward repetitions of condition-levels or something.

# If you struggle with this problem `RepeatDesign` is an easy tool for you:
using UnfoldSim

designOnce = MultiSubjectDesign(;
n_items = 2,
Expand Down
23 changes: 16 additions & 7 deletions docs/literate/reference/basistypes.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
using UnfoldSim
using CairoMakie
using DSP
using StableRNGs

# ## Basistypes
# # Overview: Basis function (component) types
# There are several basis types directly implemented. They can be easily used for the `components`.
#
# !!! note
# You can use any arbitrary shape defined by yourself! We often make use of `hanning(50)` from the DSP.jl package.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
## Load required packages
using UnfoldSim
using CairoMakie
using DSP
using StableRNGs
# ```@raw html
# </details >
# ```

# ## EEG
# By default, the EEG bases assume a sampling rate of 100, which can easily be changed by e.g. p100(;sfreq=300)
# By default, the EEG bases assume a sampling rate of 100, which can easily be changed by e.g. p100(; sfreq=300)
f = Figure()
ax = f[1, 1] = Axis(f)
for b in [p100, n170, p300, n400]
Expand Down
107 changes: 107 additions & 0 deletions docs/literate/reference/designtypes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# # Overview: Experimental design types

# The experimental design specifies the experimental conditions and other variables that are supposed to have an influence on the simulated data.
# Currently, there are three types of designs implemented: `SingleSubjectDesign`, `MultiSubjectDesign` and `RepeatDesign`.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
## Load required packages
using UnfoldSim
using Random
# ```@raw html
# </details >
# ```

# ## Single-subject designs
# As the name suggests, the `SingleSubjectDesign` type can be used to specify the experimental design for a single subject. Using the `conditions` arguments,
# the user can specify all relevant conditions or predictors and their levels or value range.

# The current implementation assumes a full factorial design (also called fully crossed design)
# in which each level of a factor occurs with each level of the other factors. Moreover, in the current implementation, there is exactly one instance of each of these factor combinations.

# Example:
design_single = SingleSubjectDesign(;
conditions = Dict(
:stimulus_type => ["natural", "artificial"],
:contrast_level => range(0, 1, length = 3),
),
);

# In order to inspect the design, we can use the `generate_events` function to create an event table based on the design we specified.
generate_events(design_single)

# To change the order of the trials e.g. to sort or shuffle them, one can use the `event_order_function` argument.
# Example: Randomize the order of trials
design_single_shuffled = SingleSubjectDesign(;
conditions = Dict(
:stimulus_type => ["natural", "artificial"],
:contrast_level => range(0, 1, length = 3),
),
event_order_function = x -> shuffle(MersenneTwister(42), x),
);
# ```@raw html
# <details>
# <summary>Click to expand event table </summary>
# ```
generate_events(design_single_shuffled)
# ```@raw html
# </details >
# ```

# ## Multi-subject designs
# The `MultiSubjectDesign` type can be used to simulate data for an experiment with multiple subjects. Internally, it uses the [MixedModelsSim.jl package](https://github.com/RePsychLing/MixedModelsSim.jl).
# One needs to specify the number of subjects `n_subjects` and the number of items `n_items` i.e. stimuli.
# In addition, one needs to decide for every experimental factor whether it should be between- or within-subject (and item).

# !!! note
# For factors that are not listed in `items_between` it is assumed that they vary within-item (accordingly for `subjects_between`).

design_multi = MultiSubjectDesign(
n_subjects = 6,
n_items = 4,
items_between = Dict(:colour => ["red", "blue"]),
subjects_between = Dict(:age_group => ["young", "old"]),
both_within = Dict(:luminance => range(0, 1, length = 3)),
);

# ```@raw html
# <details>
# <summary>Click to expand event table </summary>
# ```
generate_events(design_multi)
# ```@raw html
# </details >
# <br />
# ```

# As with the `SingleSubjectDesign` one can use the `event_order_function` argument to determine the order of events/trials.

# !!! important
# The number of subjects/items has to be a divisor of the number of factor level combinations, i.e. it is assumed that the design is balanced
# which means that there is an equal number of observations for all possible factor level combinations.

# ## Repeat designs
# The `RepeatDesign` type is a functionality to encapsulate single- or multi-subject designs. It allows to repeat a generated event table multiple times.
# In other words, the `RepeatDesign` type allows to have multiple instances of the same item/subject/factor level combination.

# Example:
# Assume, we have the following single-subject design from above:
# ```@raw html
# <details>
# <summary>Click to expand event table </summary>
# ```
generate_events(design_single)
# ```@raw html
# </details >
# <br />
# ```


# But instead of having only one instance of the factor combinations e.g. `stimulus_type`: `natural` and `contrast_level`: `0`, we will repeat the design three times such that there are three occurrences of each combination.
design_repeated = RepeatDesign(design_single, 3);
generate_events(design_repeated)

# [Here](@ref howto_repeat_design) one can find another example of how to repeat design entries for multi-subject designs.
10 changes: 8 additions & 2 deletions docs/literate/reference/noisetypes.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# # Overview: Noise types

# There are different types of noise signals which differ in their power spectra.
# If you are not familiar with different types/colors of noise yet, have a look at this [source](https://en.wikipedia.org/wiki/Colors_of_noise).
jschepers marked this conversation as resolved.
Show resolved Hide resolved

# There are several noise types directly implemented in UnfoldSim.jl. Here is a comparison:


using UnfoldSim
using CairoMakie
using DSP
using StableRNGs
import StatsBase.autocor
# ## What's the noise?
# There are several noise-types directly implemented. Here is a comparison:

f = Figure()
ax_sig =
Expand Down
16 changes: 8 additions & 8 deletions docs/literate/reference/onsettypes.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# # Onset types
# # Overview: Onset types
# The onset types determine the distances between event onsets in the continuous EEG signal. The distances are sampled from a certain probability distribution.
# Currently, there are two types of onset distributions implemented: `UniformOnset` and `LogNormalOnset`.

# ## Setup
# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```

## Load required packages
using UnfoldSim
using CairoMakie
using Random
Expand Down Expand Up @@ -58,11 +58,11 @@ let # hide
design, # hide
) # hide

hist!(
ax,
distances,
bins = range(0, 100, step = 1),
label = "($width, $offset)",
hist!( # hide
ax, # hide
distances, # hide
bins = range(0, 100, step = 1), # hide
label = "($width, $offset)", # hide
) # hide

if label == "offset" && offset != 0 # hide
Expand Down
10 changes: 10 additions & 0 deletions docs/literate/reference/overview.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
# # Overview of functionality
# UnfoldSim has many modules, here we try to collect them to provide you with an overview.
jschepers marked this conversation as resolved.
Show resolved Hide resolved

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
## Load required packages
using UnfoldSim
using InteractiveUtils
# ```@raw html
# </details>
# ```

# ## Design
# Designs define the experimental design. They can be nested, e.g. `RepeatDesign(SingleSubjectDesign,10)` would repeat the generated design-dataframe 10x.
Expand Down
15 changes: 14 additions & 1 deletion docs/literate/tutorials/multisubject.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
# # Multi-subject simulation

# In this tutorial, you will learn how to simulate data for multiple subjects. In particular, you will learn how to specify fixed and random effects and what their influence on the simulated data looks like.

# ### Setup
# ```@raw html
# <details>
# <summary>Click to expand</summary>
# ```
## Load required packages
using UnfoldSim
using Unfold
using CairoMakie
using UnfoldMakie
using DataFrames
# ```@raw html
# </details >
# <br />
# ```

# # Multi-subject simulation
# Similar to the single subject case, multi-subject simulation depends on:
# - `Design` (typically a `MultiSubjectDesign`)
# - `Components` (typically a `MixedModelComponent`)
Expand Down
Loading
Loading