Unfold.jl
# [](https://github.com/unfoldtoolbox/Unfold.jl) [](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/stable/) [](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/dev/) [](https://github.com/unfoldtoolbox/Unfold.jl/actions/workflows/Test.yml?query=branch%3Amain) [](https://github.com/unfoldtoolbox/Unfold.jl/actions/workflows/Lint.yml?query=branch%3Amain) [](https://github.com/unfoldtoolbox/Unfold.jl/actions/workflows/Docs.yml?query=branch%3Amain) [](https://codecov.io/gh/unfoldtoolbox/Unfold.jl) [](https://doi.org/10.5281/zenodo.5759066) [](CODE_OF_CONDUCT.md) [](#contributors) |Estimation|Visualisation|Simulation|BIDS pipeline|Decoding|Statistics|MixedModelling| |---|---|---|---|---|---|---| |<a href="https://github.com/unfoldtoolbox/Unfold.jl/tree/main"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/10183650/277623787-757575d0-aeb9-4d94-a5f8-832f13dcd2dd.png" alt="Unfold.jl Logo"></a>|<a href="https://github.com/unfoldtoolbox/UnfoldMakie.jl"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/10183650/277623793-37af35a0-c99c-4374-827b-40fc37de7c2b.png" alt="UnfoldMakie.jl Logo"></a>|<a href="https://github.com/unfoldtoolbox/UnfoldSim.jl"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/10183650/277623795-328a4ccd-8860-4b13-9fb6-64d3df9e2091.png" alt="UnfoldSim.jl Logo"></a>|<a href="https://github.com/unfoldtoolbox/UnfoldBIDS.jl"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/10183650/277622460-2956ca20-9c48-4066-9e50-c5d25c50f0d1.png" alt="UnfoldBIDS.jl Logo"></a>|<a href="https://github.com/unfoldtoolbox/UnfoldDecode.jl"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/10183650/277622487-802002c0-a1f2-4236-9123-562684d39dcf.png" alt="UnfoldDecode.jl Logo"></a>|<a href="https://github.com/unfoldtoolbox/UnfoldStats.jl"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/10183650/277623799-4c8f2b5a-ea84-4ee3-82f9-01ef05b4f4c6.png" alt="UnfoldStats.jl Logo"></a>|<a href="https://github.com/unfoldtoolbox/UnfoldMixedModels.jl"><img src="https://github.com/user-attachments/assets/ffb2bba6-3a30-48b7-9849-7d4e7195b297" alt="UnfoldMixedModels.jl logo"></a>| Package (-family) to perform linear / GAM / hierarchical / deconvolution regression on biological signals. This kind of modelling is also known as encoding modeling, linear deconvolution, Temporal Response Functions (TRFs), linear system identification, and probably under other names. fMRI models with HRF-basis functions and pupil-dilation bases are also supported. ## Getting started ### πPython User? We clearly recommend Julia π - but [Python users can use juliacall/Unfold directly from python!](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/dev/generated/HowTo/juliacall_unfold/) ### Julia installation <details> <summary>Click to expand</summary> The recommended way to install julia is [juliaup](https://github.com/JuliaLang/juliaup). It allows you to, e.g., easily update Julia at a later point, but also test out alpha/beta versions etc. TL:DR; If you dont want to read the explicit instructions, just copy the following command #### Windows AppStore -> JuliaUp, or `winget install julia -s msstore` in CMD #### Mac & Linux `curl -fsSL https://install.julialang.org | sh` in any shell </details> ### Unfold.jl installation ```julia using Pkg Pkg.add("Unfold") ``` ## Usage Please check out [the documentation](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/dev) for extensive tutorials, explanations and more! ### Tipp on Docs You can read the docs online: [](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/stable) - or use the `?fit`, `?effects` julia-REPL feature. To filter docs, use e.g. `?fit(::UnfoldModel)` Here is a quick overview on what to expect. ### What you need ```julia using Unfold events::DataFrame # formula with or without random effects f = @formula 0~1+condA fLMM = @formula 0~1+condA+(1|subject) + (1|item) # in case of [overlap-correction] we need continuous data plus per-eventtype one basisfunction (typically firbasis) data::Array{Float64,2} basis = firbasis(Ο=(-0.3,0.5),srate=250) # for "timeexpansion" / deconvolution # in case of [mass univariate] we need to epoch the data into trials, and a accompanying time vector epochs::Array{Float64,3} # channel x time x epochs (n-epochs == nrows(events)) times = range(0,length=size(epochs,3),step=1/sampling_rate) ``` To fit any of the models, Unfold.jl offers a unified syntax: |Overlap-Correction|Mixed Modelling|julia syntax| |:---:|:---:|---| |||`fit(UnfoldModel,[Any=>(f,times)),evts,data_epoch]`| |x||`fit(UnfoldModel,[Any=>(f,basis)),evts,data]`| ||x|`fit(UnfoldModel,[Any=>(fLMM,times)),evts,data_epoch]`| |x|x|`fit(UnfoldModel,[Any=>(fLMM,basis)),evts,data]`| ## Comparison to Unfold (matlab) <details> <summary>Click to expand</summary> The matlab version is still maintained, but active development happens in Julia. | Feature | Unfold | Unfold.jl | | --- | --- | --- | | overlap correction | x | x | | non-linear splines | x | x | | speed | | β‘ 2-100x | | GPU support | | π | | plotting tools | x | [UnfoldMakie.jl](https://unfoldtoolbox.github.io/UnfoldDocs/UnfoldMakie.jl/) | | Interactive plotting | | ERPExplorer.jl | | simulation tools | x | [UnfoldSim.jl](https://unfoldtoolbox.github.io/UnfoldDocs/UnfoldSim.jl) | | BIDS support | x | [UnfoldBIDS.jl](https://unfoldtoolbox.github.io/UnfoldDocs/UnfoldBIDS.jl)) | | tutorials | x | x | | unittests | x | x | | Alternative bases e.g. HRF (fMRI) | | x | | Duration modelling (e.g. Hassal style) | | x | | mix different basisfunctions | | x | | different timewindows per event | | x | | linear mixed models | | x | | decoding | | [UnfoldDecode.jl](https://unfoldtoolbox.github.io/UnfoldDocs/UnfoldDecode.jl) | | outlier-robust fits | | [many options (but slower)](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/dev/HowTo/custom_solvers/#Robust-Solvers) | | πPython support | | [via juliacall](https://unfoldtoolbox.github.io/UnfoldDocs/Unfold.jl/dev/generated/HowTo/juliacall_unfold/) | </details> ## Contributions Contributions are very welcome. These could be typos, bugreports, feature-requests, speed-optimization, new solvers, better code, better documentation. ### How-to Contribute You are very welcome to raise issues and start pull requests! ### Adding Documentation 1. We recommend to write a Literate.jl document and place it in `docs/literate/FOLDER/FILENAME.jl` with `FOLDER` being `HowTo`, `Explanation`, `Tutorial` or `Reference` ([recommended reading on the 4 categories](https://documentation.divio.com/)). 2. Literate.jl converts the `.jl` file to a `.md` automatically and places it in `docs/src/generated/FOLDER/FILENAME.md`. 3. Edit [make.jl](https://github.com/unfoldtoolbox/Unfold.jl/blob/main/docs/make.jl) with a reference to `docs/src/generated/FOLDER/FILENAME.md`. ## Contributors <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tbody> <tr> <td align="center" valign="top" width="14.28%"><a href="https://github.com/jschepers"><img src="https://avatars.githubusercontent.com/u/22366977?v=4?s=100" width="100px;" alt="Judith Schepers"/><br /><sub><b>Judith Schepers</b></sub></a><br /><a href="#bug-jschepers" title="Bug reports">π</a> <a href="#code-jschepers" title="Code">π»</a> <a href="#doc-jschepers" title="Documentation">π</a> <a href="#tutorial-jschepers" title="Tutorials">β </a> <a href="#ideas-jschepers" title="Ideas, Planning, & Feedback">π€</a> <a href="#test-jschepers" title="Tests">β οΈ</a></td> <td align="center" valign="top" width="14.28%"><a href="http://www.benediktehinger.de"><img src="https://avatars.githubusercontent.com/u/10183650?v=4?s=100" width="100px;" alt="Benedikt Ehinger"/><br /><sub><b>Benedikt Ehinger</b></sub></a><br /><a href="#bug-behinger" title="Bug reports">π</a> <a href="#code-behinger" title="Code">π»</a> <a href="#doc-behinger" title="Documentation">π</a> <a href="#tutorial-behinger" title="Tutorials">β </a> <a href="#ideas-behinger" title="Ideas, Planning, & Feedback">π€</a> <a href="#test-behinger" title="Tests">β οΈ</a> <a href="#infra-behinger" title="Infrastructure (Hosting, Build-Tools, etc)">π</a> <a href="#test-behinger" title="Tests">β οΈ</a> <a href="#maintenance-behinger" title="Maintenance">π§</a> <a href="#review-behinger" title="Reviewed Pull Requests">π</a> <a href="#question-behinger" title="Answering Questions">π¬</a></td> <td align="center" valign="top" width="14.28%"><a href="https://reneskukies.de/"><img src="https://avatars.githubusercontent.com/u/57703446?v=4?s=100" width="100px;" alt="RenΓ© Skukies"/><br /><sub><b>RenΓ© Skukies</b></sub></a><br /><a href="#bug-ReneSkukies" title="Bug reports">π</a> <a href="#doc-ReneSkukies" title="Documentation">π</a> <a href="#tutorial-ReneSkukies" title="Tutorials">β </a> <a href="#code-ReneSkukies" title="Code">π»</a> <a href="#ideas-ReneSkukies" title="Ideas, Planning, & Feedback">π€</a></td> <td align="center" valign="top" width="14.28%"><a href="https://reboreexplore.github.io/"><img src="https://avatars.githubusercontent.com/u/43548330?v=4?s=100" width="100px;" alt="Manpa Barman"/><br /><sub><b>Manpa Barman</b></sub></a><br /><a href="#infra-ReboreExplore" title="Infrastructure (Hosting, Build-Tools, etc)">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://www.phillipalday.com"><img src="https://avatars.githubusercontent.com/u/1677783?v=4?s=100" width="100px;" alt="Phillip Alday"/><br /><sub><b>Phillip Alday</b></sub></a><br /><a href="#code-palday" title="Code">π»</a> <a href="#infra-palday" title="Infrastructure (Hosting, Build-Tools, etc)">π</a></td> <td align="center" valign="top" width="14.28%"><a href="http://davekleinschmidt.com"><img src="https://avatars.githubusercontent.com/u/135920?v=4?s=100" width="100px;" alt="Dave Kleinschmidt"/><br /><sub><b>Dave Kleinschmidt</b></sub></a><br /><a href="#doc-kleinschmidt" title="Documentation">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/ssaket"><img src="https://avatars.githubusercontent.com/u/27828189?v=4?s=100" width="100px;" alt="Saket Saurabh"/><br /><sub><b>Saket Saurabh</b></sub></a><br /><a href="#bug-ssaket" title="Bug reports">π</a></td> </tr> <tr> <td align="center" valign="top" width="14.28%"><a href="https://github.com/suddha-bpn"><img src="https://avatars.githubusercontent.com/u/7974144?v=4?s=100" width="100px;" alt="suddha-bpn"/><br /><sub><b>suddha-bpn</b></sub></a><br /><a href="#bug-suddha-bpn" title="Bug reports">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/vladdez"><img src="https://avatars.githubusercontent.com/u/33777074?v=4?s=100" width="100px;" alt="Vladimir Mikheev"/><br /><sub><b>Vladimir Mikheev</b></sub></a><br /><a href="#bug-vladdez" title="Bug reports">π</a> <a href="#doc-vladdez" title="Documentation">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/carmenamme"><img src="https://avatars.githubusercontent.com/u/100191854?v=4?s=100" width="100px;" alt="carmenamme"/><br /><sub><b>carmenamme</b></sub></a><br /><a href="#doc-carmenamme" title="Documentation">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/maxvanmigem"><img src="https://avatars.githubusercontent.com/u/115144441?v=4?s=100" width="100px;" alt="Maximilien Van Migem"/><br /><sub><b>Maximilien Van Migem</b></sub></a><br /><a href="#bug-maxvanmigem" title="Bug reports">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/Till223"><img src="https://avatars.githubusercontent.com/u/29772145?v=4?s=100" width="100px;" alt="Till PrΓΆlΓ"/><br /><sub><b>Till PrΓΆlΓ</b></sub></a><br /><a href="#doc-Till223" title="Documentation">π</a> <a href="#bug-Till223" title="Bug reports">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/LeonvonHaugwitz"><img src="https://avatars.githubusercontent.com/u/44725676?v=4?s=100" width="100px;" alt="Leon von Haugwitz"/><br /><sub><b>Leon von Haugwitz</b></sub></a><br /><a href="#bug-LeonvonHaugwitz" title="Bug reports">π</a></td> <td align="center" valign="top" width="14.28%"><a href="https://github.com/jordandeakin"><img src="https://avatars.githubusercontent.com/u/48567988?v=4?s=100" width="100px;" alt="Jordan Deakin"/><br /><sub><b>Jordan Deakin</b></sub></a><br /><a href="#bug-jordandeakin" title="Bug reports">π</a></td> </tr> <tr> <td align="center" valign="top" width="14.28%"><a href="https://github.com/CherryClementine"><img src="https://avatars.githubusercontent.com/u/156665249?v=4?s=100" width="100px;" alt="Sanaz "/><br /><sub><b>Sanaz </b></sub></a><br /><a href="#doc-CherryClementine" title="Documentation">π</a></td> </tr> </tbody> </table> <!-- markdownlint-restore --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END --> This project follows the [all-contributors](https://allcontributors.org/specification) specification. Contributions of any kind welcome! ## Citation For now, please cite [](https://doi.org/10.5281/zenodo.5759066) and/or [Ehinger & Dimigen](https://peerj.com/articles/7838/) ## Acknowledgements This work was initially supported by the Center for Interdisciplinary Research, Bielefeld (ZiF) Cooperation Group "Statistical models for psychological and linguistic data". Funded by Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) under GermanyΒ΄s Excellence Strategy β EXC 2075 β 390740016