[ANN] NeuroJ.jl

Hi,

This is the first public release, I’m kinda nervous and excited :slight_smile:

NeuroJ.jl is a Julia package for analyzing of EEG data. Future versions will also process MEG and NIRS data and use MRI data for source localization techniques. Also, various methods for modelling non-invasive brain stimulation protocols (tDCS/tACS/tRNS/tPCS/TMS) will be included.

The stable version (currently 0.26.0) will be released on a monthly basis.

Any feedback, remarks, bug reports, feature requests, pull requests, documentation improvements are highly welcomed.

Regards,
Adam

7 Likes

Hi Adam - this is great to see! Nice work. There are a couple of others that have been working in a similar vein, but I’m not sure if any efforts are planning to be quite so comprehensive.

A couple of possibly trivial non-code points I thought I’d mention, in case you were unfamiliar:

  1. Regarding the name - is the ‘J’ of NeuroJ for “julia”? If so, this is generally discouraged (see point 2 in the package naming guidelines). Because of the .jl suffix, Neuro.jl would make it clear this is a julia package, for example.
  2. It looks like you’re using date-based versioning, but the julia ecosystem, particularly Pkg, expects SemVer, so it you use this kind of versioning, it will be hard for the ecosystem to reason about version compatibility.

Neither of these points really matter unless / until you intend to register the package in the general registry, but I thought I’d mention them.

3 Likes

Additionally, the section in your readme about installing the packages manually is a red herring. Packages may release new versions and incompatibilities may emerge.

Tell users to activate the Project.toml in a clean environment instead.

1 Like

I was going to open an issue for this, but having some issues making a codeberg account. I noticed in your readme that you have functions like eeg_keep_epoch(), presumably as a way to distinguish from something like mri_keep_epoch(). I’d encourage you to take advantage of julia dispatch instead. That is, you can define keep_epoch() methods for your different types, and let julia do the work chosing based on which type is passed.

For example:

julia> abstract type BrainScan end

julia> struct EEG <: BrainScan
           # fields...
       end

julia> struct MRI <: BrainScan
           # ... fields
       end

julia> keep_epoch(x::BrainScan) = "keep_epoch not defined for $(typeof(x))" # fallback
keep_epoch (generic function with 1 method)

julia> keep_epoch(x::EEG) = "Hi, I'm keeping an epoch for EEG"
keep_epoch (generic function with 2 methods)

julia> keep_epoch(x::MRI) = "Do MRIs have epochs? I don't know"
keep_epoch (generic function with 3 methods)

julia> e = EEG(); m = MRI();

julia> keep_epoch(e)
"Hi, I'm keeping an epoch for EEG"

julia> keep_epoch(m)
"Do MRIs have epochs? I don't know"
1 Like

Hi Kevin!
Thanks for the input.
I’ve change the versioning scheme to SymVer.
I’ll consider changing the name, but there already exists Julia Neuro and this might be confusing.
Regards, Adam

Hi Peter!
Thanks, I’ll deal with it tomorrow.
Regards, Adam

Kevin, I’m using multiple dispatch in many places, mostly in the low level functions. The purpose of eeg_ functions is to make clear distinction from low level functions. Also, for named arguments multiple dispatch does not work.