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

Breaking: refactor #8

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d5f2636
inital lmm_perm
behinger Apr 22, 2024
152b1f6
Moved UnfoldMixedModels also to new extension
behinger Apr 22, 2024
638ba0b
well, it does something now
behinger Apr 22, 2024
67fe653
added lmm clusterperm
behinger Apr 22, 2024
eaa207d
forgot to save this file
behinger Apr 22, 2024
247623a
forgot to save
behinger Apr 22, 2024
409f647
Update UnfoldStatsMixedModelsPermutationsExt.jl
behinger Apr 23, 2024
767e5b1
added an 'abs'
behinger Apr 30, 2024
482a8f7
Merge branch 'lmm_perm' of http://github.com/unfoldtoolbox/UnfoldStat…
behinger Apr 30, 2024
d747591
Update extract_coefs.jl
behinger May 22, 2024
59f0762
upgrade to unfold07
behinger Jun 23, 2024
275e4fb
remove compatability with unfold 0.6
behinger Jun 23, 2024
3b4882c
removed revise requirement
behinger Jun 23, 2024
1594e48
Update Project.toml
behinger Jun 24, 2024
5d4bfbf
Update CI.yml
behinger Jun 24, 2024
096d0fa
fix docs mistake
behinger Jun 24, 2024
cbf097b
Merge branch 'unfold07' of http://github.com/unfoldtoolbox/UnfoldStat…
behinger Jun 24, 2024
d0fb7cc
add statsmodels, update
behinger Jun 24, 2024
2589578
Update CI.yml
behinger Jan 10, 2025
d85d35d
doc fixes
behinger Jan 10, 2025
35b6e7d
major update, might work with unfold0.8?
behinger Jan 23, 2025
6d1f672
compat
behinger Jan 23, 2025
8592f2d
Merge branch 'unfold07' of http://github.com/unfoldtoolbox/UnfoldStat…
behinger Jan 23, 2025
b58a866
fix a lot of bugs for newer unfold versions
behinger Jan 23, 2025
d2670da
fix fix fix everyhtinggit add test
behinger Jan 24, 2025
5c63b45
Merge pull request #7 from unfoldtoolbox/endless_loop
behinger Jan 24, 2025
1bec33b
forgot to rename
behinger Jan 24, 2025
dd44fad
some conflicts with MixedModels.simulate and UnfoldSim.simulate
behinger Jan 24, 2025
0e720cd
Merge branch 'unfold07' of http://github.com/unfoldtoolbox/UnfoldStat…
behinger Jan 24, 2025
4e3331d
finally found the bug
behinger Jan 27, 2025
baf213b
maybe maybe maybe
behinger Jan 27, 2025
0f23a85
mayyybe
behinger Jan 27, 2025
56746f5
Update sim_and_fit.jl
behinger Feb 13, 2025
e7a0a13
Apply suggestions from code review
behinger Feb 13, 2025
8ae7a93
Add docs preview for PRs
jschepers Feb 13, 2025
c12dd91
Fix parantheses and capitalization
jschepers Feb 13, 2025
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
16 changes: 11 additions & 5 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ jobs:
arch:
- x64
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v1
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
Expand All @@ -44,8 +44,8 @@ jobs:
contents: write
statuses: write
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1'
- name: Configure doc environment
Expand All @@ -64,3 +64,9 @@ jobs:
using UnfoldStats
DocMeta.setdocmeta!(UnfoldStats, :DocTestSetup, :(using UnfoldStats); recursive=true)
doctest(UnfoldStats)'
- name: Update UnfoldDocs
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.UNFOLDDOCSPAT }}
repository: unfoldtoolbox/UnfoldDocs
event-type: individual-docs-updated
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/docs/Manifest.toml
/docs/build/
/docs/src/generated
/docs/dev
26 changes: 24 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
name = "UnfoldStats"
uuid = "96fd419a-8306-4ce8-ba5b-cd907cb7647c"
authors = ["Judith Schepers", "Benedikt V. Ehinger"]
version = "1.0.0-DEV"
version = "0.2.0"

[deps]
BSplineKit = "093aae92-e908-43d7-9660-e50ee39d5a0a"
ClusterDepth = "c8d8bbfa-f476-4995-adff-2987f04015d1"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
MixedModels = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316"
MixedModelsPermutations = "647c4018-d7ef-4d03-a0cc-8889a722319e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StatsAPI = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
Unfold = "181c99d8-e21b-4ff3-b70b-c233eddec679"

[weakdeps]
ClusterDepth = "c8d8bbfa-f476-4995-adff-2987f04015d1"
MixedModelsPermutations = "647c4018-d7ef-4d03-a0cc-8889a722319e"
UnfoldMixedModels = "019ae9e0-8363-565c-86e5-97a5a2fe84f4"

[extensions]
UnfoldStatsMixedModelsExt = ["UnfoldMixedModels"]
UnfoldStatsMixedModelsPermutationsExt = ["UnfoldMixedModels", "ClusterDepth", "MixedModelsPermutations"]

[compat]
julia = "1"
BSplineKit = "0.16,0.17"
ClusterDepth = "0.2"
MixedModelsPermutations = "0.2"
StatsAPI = "1"
StatsModels = "0.7"
Unfold = "0.8"
UnfoldMixedModels = "0.1"
julia = "1.9,1.10,1.11"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
40 changes: 21 additions & 19 deletions benchmark/sim_and_fit.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using UnfoldSim
using Unfold
using Unfold, UnfoldMixedModels
using StableRNGs
using DataFrames

Expand Down Expand Up @@ -51,7 +51,7 @@ function sim_and_fit(
data, events = simulate_data(sim_type, simulation, return_epoched, seed)

# Create event dict containing basis function(s)/times and formula(s) for all events
event_dict = create_event_dict(sim_type, model_type, simulation)
event_dict = create_event_vector(sim_type, model_type, simulation)

# Fit an Unfold model for each subject
subject_list = unique(events.subject)
Expand Down Expand Up @@ -81,30 +81,32 @@ simulate_data(sim_type::T, simulation, return_epoched, seed) where {T} =
function simulate_data(::SingleEventType, simulation, return_epoched, seed)

# Simulate data
data, events = simulate(StableRNG(seed), simulation; return_epoched = return_epoched)
data, events =
UnfoldSim.simulate(StableRNG(seed), simulation; return_epoched = return_epoched)

return data, events
end

function simulate_data(::MultipleEventTypes, simulation, return_epoched, seed)

# Simulate data
data, events = simulate(StableRNG(seed), simulation; return_epoched = return_epoched)
data, events =
UnfoldSim.simulate(StableRNG(seed), simulation; return_epoched = return_epoched)

# Add an event column to the events df and assign each event to an event type
events[!, :event] = repeat(["stim", "fix"], size(events, 1) ÷ 2)

return data, events
end

create_event_dict(sim_type::T, model_type, simulation) where {T} = create_event_dict(
create_event_vector(sim_type::T, model_type, simulation) where {T} = create_event_vector(
EventStyle(T),
PredictorStyle(T),
model_type::Type{<:UnfoldModel},
simulation,
)

function create_event_dict(
function create_event_vector(
::MultipleEventTypes,
::ManyPredictors,
model_type::Type{<:UnfoldModel},
Expand All @@ -117,8 +119,8 @@ function create_event_dict(
t_stim = times
t_fix = times
else # UnfoldLinearModelContinuousTime
t_stim = firbasis(τ = (-0.1, 1.5), sfreq = 100, name = "stimulus")
t_fix = firbasis(τ = (-0.1, 1), sfreq = 100, name = "fixation")
t_stim = firbasis(τ = (-0.1, 1.5), sfreq = 100, name = "stim")
t_fix = firbasis(τ = (-0.1, 1), sfreq = 100, name = "fix")
end

# Define formula(s)
Expand All @@ -131,7 +133,7 @@ function create_event_dict(
return event_dict
end

function create_event_dict(
function create_event_vector(
::MultipleEventTypes,
::OnlySplines,
model_type::Type{<:UnfoldModel},
Expand All @@ -144,21 +146,21 @@ function create_event_dict(
t_stim = times
t_fix = times
else # UnfoldLinearModelContinuousTime
t_stim = firbasis(τ = (-0.1, 1.5), sfreq = 100, name = "stimulus")
t_fix = firbasis(τ = (-0.1, 1), sfreq = 100, name = "fixation")
t_stim = firbasis(τ = (-0.1, 1.5), sfreq = 100, name = "stim")
t_fix = firbasis(τ = (-0.1, 1), sfreq = 100, name = "fix")
end

# Define formula(s)
f_stim = @formula 0 ~ 1
f_fix = @formula 0 ~ 1 + spl(continuous, 4)

# Combine basis function(s)/times and formula(s) with the corresponding event
event_dict = Dict("stim" => (f_stim, t_stim), "fix" => (f_fix, t_fix))
event_vec = ["stim" => (f_stim, t_stim), "fix" => (f_fix, t_fix)]

return event_dict
return event_vec
end

function create_event_dict(
function create_event_vector(
::SingleEventType,
::ManyPredictors,
model_type::Type{<:UnfoldModel},
Expand All @@ -176,12 +178,12 @@ function create_event_dict(
f = @formula 0 ~ 1 + spl(continuous, 4) + continuous + condition * pet

# Combine basis function(s)/times and formula(s) with the corresponding event
event_dict = Dict(Any => (f, t))
event_vec = [Any => (f, t)]

return event_dict
return event_vec
end

function create_event_dict(
function create_event_vector(
::SingleEventType,
::OnlySplines,
model_type::Type{<:UnfoldModel},
Expand All @@ -199,9 +201,9 @@ function create_event_dict(
f = @formula 0 ~ 1 + spl(continuous, 4)

# Combine basis function(s)/times and formula(s) with the corresponding event
event_dict = Dict(Any => (f, t))
event_vec = [Any => (f, t)]

return event_dict
return event_vec
end

get_conditions(sim_type::T) where {T} = get_conditions(PredictorStyle(T))
Expand Down
5 changes: 5 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Chain = "8be319e6-bccf-4806-a6f7-6fae938471bc"
ClusterDepth = "c8d8bbfa-f476-4995-adff-2987f04015d1"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
HypothesisTests = "09f84164-cd44-5f33-b23f-e6b0d136a0d5"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
LiveServer = "16fef848-5104-11e9-1b77-fb7a48bbb589"
MixedModelsPermutations = "647c4018-d7ef-4d03-a0cc-8889a722319e"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
Unfold = "181c99d8-e21b-4ff3-b70b-c233eddec679"
UnfoldMakie = "69a5ce3b-64fb-4f22-ae69-36dd4416af2a"
UnfoldMixedModels = "019ae9e0-8363-565c-86e5-97a5a2fe84f4"
UnfoldSim = "ed8ae6d2-84d3-44c6-ab46-0baf21700804"
UnfoldStats = "96fd419a-8306-4ce8-ba5b-cd907cb7647c"
82 changes: 82 additions & 0 deletions docs/literate/tutorial/lmm_clusterdepth.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# !!! important
# This functionality is not tested. While it returns reasonable results, we haven't written any unit-tests, nor tested the type-1 error probability yet
# get some data
using UnfoldSim
using UnfoldMixedModels

using MixedModelsPermutations, ClusterDepth # both necessary to activate correct extension!
using UnfoldStats
using StatsModels
using Random

srate = 25
design = MultiSubjectDesign(;
n_subjects = 30,
n_items = 40,
items_between = Dict(:stimtype => ["car", "face"]),
)
#both_within = Dict(:condition=>["scrambled","intact"]))
contrasts = Dict(:stimtype => DummyCoding())
p1 = MixedModelComponent(;
basis = UnfoldSim.p100(; sfreq = srate),
formula = @formula(dv ~ 1 + (1 | subject) + (1 | item)),
β = [5.0],
σs = Dict(:subject => [0.0], :item => [0.0]),
contrasts = contrasts,
);

n1 = MixedModelComponent(;
basis = UnfoldSim.n170(; sfreq = srate),
formula = @formula(dv ~ 1 + stimtype + (1 + stimtype | subject) + (1 | item)),
β = [1.0, 4], # n170-basis is negative
σs = Dict(:subject => [2.0, 0.25], :item => [0.25]),
contrasts = contrasts,
);

p3 = MixedModelComponent(;
basis = UnfoldSim.p300(; sfreq = srate),
formula = @formula(dv ~ 1 + (1 | subject) + (1 + stimtype | item)),
β = [4.0],
σs = Dict(:subject => [1.0], :item => [0.5, 2]),
contrasts = contrasts,
);



data_e, events = UnfoldSim.simulate(
design,
[p1, n1, p3],
UniformOnset(srate * 2, 10),
PinkNoise(; noiselevel = 1);
return_epoched = true,
) # 18
times = range(-0.1, 0.5, length = size(data_e, 1))
data_e = reshape(data_e, 1, size(data_e, 1), :)
#events.latency .+= repeat(range(0,length=size(data,2),step=size(data,1)),inner=size(events[events.subject.=="S01",:],1))



# # Fit LMM
m = fit(
UnfoldModel,
[
Any => (
@formula(0 ~ 1 + stimtype + (1 + stimtype | item) + (1 + stimtype | subject)),
times,
),
],
events,
data_e,
);


# # Cluster Permute :)
coefficient = 2
pvalue(
MersenneTwister(1),
m,
data_e,
coefficient;
n_permutations = 10,
clusterforming_threshold = 1.8,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[JuliaFormatter] reported by reviewdog 🐶

Suggested change
)
)

Loading
Loading