# Writing an .edf File using EDF.jl

**URL:** https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666
**Category:** General Usage
**Tags:** question, package
**Created:** [May 3, 2025, 3:58pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666 "2025-05-03T15:58:19Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![vh94](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vh94/32/209232_2.png) [@vh94](https://discourse.julialang.org/u/vh94)
#### Post date: [May 3, 2025, 3:58pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/1 "2025-05-03T15:58:19Z")

</div>

Hi, I am trying to create a .edf file using the `EDF.jl` package , but i run into issues during File creation; I get a Method Error in calling EDF.File

```julia
ERROR: MethodError: no method matching EDF.File(::IOStream, ::EDF.FileHeade
r, ::Vector{EDF.Signal{Int16}})
Closest candidates are:
  EDF.File(::I, ::EDF.FileHeader, ::Array{Union{EDF
Signal{T}}, 1}) where {T<:Union{Int16, EDF.Int24}, 

```

I tried to be as type cautious as possible by initializing explicitly an Array , but to no avail  
the File method insists i pass the wrong type.  
Minimum Reproducible Examle:

```julia
using EDF
using Dates

# some random example data
data_matrix = round.(rand(0.0:400.0,15,9000))

## Header Creation 
header = EDF.FileHeader(
    "0.0", # EDF version (0.0 for EDF+)
    "Simulation01", # Patient ID
    "Recording001", # Recording ID
    now(), # t0
    true, #contiguous
    1, # num of records 
    9000.0 # Duration
)

## Signals
signal_labels = string.(collect('A':'Z')[1:15])
signals = Array{EDF.Signal{Int16},1}(undef,15)

for (i,label) in enumerate(signal_labels)
    signal_header = EDF.SignalHeader(
        label,                          
        "EEG",                         
        "V",                            
        Float32(-100.0f0),                        
        Float32(100.0f0),                        
        Float32(-32768.0f0),                   
        Float32(32767.0f0),                      
        "No filter",                    
        Int32(9000)                     
    )
    signal = EDF.Signal{Int16}(signal_header,data_matrix[i,:] )
    push!(signals,signal)
end

print(typeof(signals)) # should be fine?!
Vector{EDF.Signal{Int16}} # (alias for Array{EDF.Signal{Int16}, 1})

output_file = "example_data.edf"
io = open(output_file, "w")

edf_file = EDF.File(io, header, signals)
## Method error!!

EDF.write(io, edf_file)
close(io)

```

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [May 3, 2025, 8:34pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/2 "2025-05-03T20:34:55Z")

</div>

here the issue is actually that EDF.jl wants a more flexible type than `Vector{EDF.Signal{Int16}}`. You can use

```julia
signals = collect(Union{EDF.AnnotationsSignal, eltype(signals)}, signals)

```

to change the type post-hoc, or initialize it as

```julia
signals = Array{Union{EDF.AnnotationsSignal, EDF.Signal{Int16}},1}(undef,15)

```

This is not very ergonomic from EDF.jl but the MethodError is trying to tell you the type isn’t what it expects and that it needs that union:

```julia
julia> edf_file = EDF.File(io, header, signals)
ERROR: MethodError: no method matching EDF.File(::IOStream, ::EDF.FileHeader, ::Vector{EDF.Signal{Int16}})
The type `EDF.File` exists, but no method is defined for this combination of argument types when trying to construct it.

Closest candidates are:
  EDF.File(::I, ::EDF.FileHeader, ::Array{Union{EDF.AnnotationsSignal, EDF.Signal{T}}, 1}) where {T<:Union{Int16, EDF.Int24}, I<:IO}
   @ EDF ~/.julia/packages/EDF/ueatx/src/types.jl:266
  EDF.File(::IO)
   @ EDF ~/.julia/packages/EDF/ueatx/src/read.jl:204

Stacktrace:
 [1] top-level scope
   @ REPL[13]:1

```

One other note is that you can use the do-block form of `open` to automatically close the file even in the case of exceptions:

```julia
open(output_file, "w") do io
    edf_file = EDF.File(io, header, signals)
    EDF.write(io, edf_file)
end

```

---

<div class="post-metadata">

### Author: ![vh94](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vh94/32/209232_2.png) [@vh94](https://discourse.julialang.org/u/vh94)
#### Post date: [May 4, 2025, 11:53am UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/3 "2025-05-04T11:53:52Z")

</div>

Thank you so much, you resolved the issue!;  
Just as a follow-up question out of curiosity:  
about the usage of `Union` in type declarations: I assumed that the `Union{}` type refers to an “either-or” type situation; the Julia documentation states:

> Declaring a function argument or a field as `Union{T, Nothing}` allows setting it either to a value of type `T`, or to `nothing` to indicate that there is no value

am i understanding this wrong? Whats going on? Anyways thanks again for the help!

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [May 4, 2025, 12:12pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/4 "2025-05-04T12:12:37Z")

</div>

That’s right, what is tricky here is that when a [parametric type](https://docs.julialang.org/en/v1/manual/types/#Parametric-Types) has a union in the type parameter. A `Vector{Union{EDF.AnnotationsSignal, EDF.Signal{Int16}}` is a vector whose _elements_ can be either a `EDF.AnnotationsSignal` or a `EDF.Signal{Int16}`. This is different from `Union{Vector{EDF.AnnotationsSignal}, Vector{EDF.Signal{Int16}}}` which is either a vector of all `EDF.AnnotationSignal`’s or all `EDF.Signal{Int16}`'s.

So `Vector{Union{A,B}}` is fundamentally a different thing, because the container itself has properties about what it can hold, it’s not “either As or Bs” encoded at the type level. A Vector of unions is actually a _concrete type_, meaning it can be instantiated: we can construct a value with that exact type.

I filed [provide EDF.File constructor which relaxes constraints on signals · Issue #95 · beacon-biosignals/EDF.jl · GitHub](https://github.com/beacon-biosignals/EDF.jl/issues/95) based on this post FYI

---

<div class="post-metadata">

### Author: ![palday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palday/32/12640_2.png) [@palday](https://discourse.julialang.org/u/palday)
#### Post date: [May 8, 2025, 3:14pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/5 "2025-05-08T15:14:12Z")

</div>

A fix has been released as part of [EDF.jl 0.8.1](https://github.com/beacon-biosignals/EDF.jl/releases/tag/v0.8.1).

---

<div class="post-metadata">

### Author: ![mpeters2](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpeters2/32/202247_2.png) [@mpeters2](https://discourse.julialang.org/u/mpeters2)
#### Post date: [May 8, 2025, 5:34pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/6 "2025-05-08T17:34:44Z")

</div>

Huh, I always thought EDF was the Eyelink data format (“Eyelink data file”?). I wonder if they are one and the same, or if they just happen to share a name?

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [May 8, 2025, 11:31pm UTC](https://discourse.julialang.org/t/writing-an-edf-file-using-edf-jl/128666/7 "2025-05-08T23:31:09Z")

</div>

> [@mpeters2](#):
>
> Eyelink data file

I’ve never heard of this format, but MNE says they are different:

> The Eyelink Data Format (EDF), should not be confused with the European Data Format, the common EEG data format that also uses the .edf extension.

> **[Importing Data from Eyetracking devices — MNE 1.9.0 documentation](https://mne.tools/stable/auto_tutorials/io/70_reading_eyetracking_data.html)**
