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

Exporting EDF with 1024 Hz sampling rate throws an error #49

Open
franzfurbass opened this issue Jun 29, 2022 · 3 comments
Open

Exporting EDF with 1024 Hz sampling rate throws an error #49

franzfurbass opened this issue Jun 29, 2022 · 3 comments

Comments

@franzfurbass
Copy link

franzfurbass commented Jun 29, 2022

Ask me on Slack for a private test case!

@franzfurbass
Copy link
Author

The error message is

ERROR: EDFPrecisionError: String representation of value 0.0009765625 is longer than 8 ASCII characters
Stacktrace:
 [1] edf_record_metadata(all_samples::Vector{Samples{Matrix{Float64}, Legolas.Row{Legolas.Schema{Symbol("onda.samples-info"), 1}, NamedTuple{(:kind, :channels, :sample_unit, :sample_resolution_in_unit, :sample_offset_in_unit, :sample_type, :sample_rate), Tuple{String, Vector{String}, String, Float64, Float64, String, Float64}}}}})
   @ OndaEDF ~/.julia/packages/OndaEDF/Z3mAB/src/export_edf.jl:46

@kleinschmidt
Copy link
Member

kleinschmidt commented Jul 8, 2022

I think this is because there's a bit of a mis-match between what happens here: https://github.com/beacon-biosignals/OndaEDF.jl/blob/master/src/export_edf.jl#L31-L53

and what the spec says:

The first 256 bytes of the header record specify the version number of this format, local patient and recording identification, time information about the recording, the number of data records and finally the number of signals (ns) in each data record. Then for each signal another 256 bytes follow in the header record, each specifying the type of signal (e.g. EEG, body temperature, etc.), amplitude calibration and the number of samples in each data record (from which the sampling frequency can be derived since the duration of a data record is also known). In this way, the format allows for different gains and sampling frequencies for each signal. The header record contains 256 + (ns * 256) bytes. Figure 1 shows its detailed format.

The information in the ASCII strings must be left-justified and filled out with spaces. Midnight time is 00:00:00. The duration of each data record is recommended to be a whole number of seconds and its size (number of bytes) is recommended not to exceed 61440. Only if a 1s data record exceeds this size limit, the duration is recommended to be smaller than 1s (e.g. 0.01).

Specifically, we're trying to create one-sample records, with a duration of 1/1024 seconds. Instead, we may need to try to create longer records with more samples, maybe starting with a 1s record and only using fractional record sizes when the record size is too big.

@kleinschmidt
Copy link
Member

Okay, we already ARE doing this check: trying the least-common-multiple of the denominator of the sampling rates of the Samples that get passed in (which is gonna be 1 if they're all integer Hz values), and uses that as the seconds-per-record. then, it computes the byte size of records given that, and if it's too big, it tries something else. If there's a single Samples (with potentially multiple channels), it uses one sample per record; if there are multiple Samples, it uses the greatest common divisor of the numerators of the sample rates to find the smallest record that can still hold an integer number of samples from each Samples; note that these are equivalent in the case where the sample rates are all the same.

We could try an alternative approach that involves finding the prime factors of the numerator instead (or prime factors of the GCD), figure out how much we have to reduce the record size by, and do a greedy thing to find a small integer scale that gets us below the record size constraint...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants