https://github.com/venryx/node-edf
NodeJS library for reading and writing EDF files. (WIP)
https://github.com/venryx/node-edf
Last synced: 11 months ago
JSON representation
NodeJS library for reading and writing EDF files. (WIP)
- Host: GitHub
- URL: https://github.com/venryx/node-edf
- Owner: Venryx
- License: mit
- Created: 2020-12-05T01:36:39.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-12-05T18:53:17.000Z (over 5 years ago)
- Last Synced: 2025-08-16T09:43:33.207Z (11 months ago)
- Language: JavaScript
- Size: 40 KB
- Stars: 2
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Node EDF
NodeJS library for reading and writing EDF files.
Note: Only EDF writing/serializing is implemented atm. For EDF reading/parsing, consider:
* https://github.com/Pixpipe/edfdecoder
* https://github.com/jusjusjus/edfjs
* https://github.com/Pixpipe/edfdecoder
* https://github.com/korob93/edf-node
### Installation
```
npm install node-edf --save-exact
```
The `--save-exact` flag is recommended (to disable version-extending), since this package uses [Explicit Versioning](https://medium.com/sapioit/why-having-3-numbers-in-the-version-name-is-bad-92fc1f6bc73c) (`Release.Breaking.FeatureOrFix`) rather than SemVer (`Breaking.Feature.Fix`).
For `FeatureOrFix` version-extending (recommended for libraries), prepend "`~`" in `package.json`. (for `Breaking`, prepend "`^`")
### Usage
```
import {EDFPackage, WriteEDFHeader, WriteEDFPackage, AppendChunk, ChannelInfo, Chunk} from "node-edf";
import paths from "path";
function ExportNightEEGData(sessionFolderName: string, exportChannelsInOneFile = true) {
const path = GetSessionFolderPath(sessionFolderName); // project-specific
console.log(`Starting export of session: ${sessionFolderName}`);
// project-specific
const sessionInfo = JSON.parse(ReadFileTextSync_Safe(paths.join(path, "SessionInfo.json")) ?? `{}`)
const data = {
Forehead_Left: new Float32Array(GetEEGSamples("EEG_Forehead_Left.json")),
Forehead_Right: new Float32Array(GetEEGSamples("EEG_Forehead_Right.json")),
Ear_Left: new Float32Array(GetEEGSamples("EEG_Ear_Left.json")),
Ear_Right: new Float32Array(GetEEGSamples("EEG_Ear_Right.json")),
};
if (exportChannelsInOneFile) {
const exportFolder = GetSessionSubPath(sessionFolderName, "Export_SleepApp"); // project-specific
fs.mkdirSync(exportFolder, {recursive: true}); // marked recursive, just so doesn't error if folder already exists
const pack = new EDFPackage({
patientID: "User_Unknown",
recordingID: `Folder_${sessionFolderName}`,
startTime: sessionInfo.startTime,
chunkDuration: 30, // 30 seconds per chunk
channelInfos: [
CreateChannelInfo({name: "Forehead_Left"}),
CreateChannelInfo({name: "Forehead_Right"}),
CreateChannelInfo({name: "Ear_Left"}),
CreateChannelInfo({name: "Ear_Right"}),
],
chunks: [],
});
const stream = fs.createWriteStream(paths.join(exportFolder, "EEGData.edf"));
//WriteEDFHeader(pack, stream);
const samplesPerChunk = pack.channelInfos[0].sampleCountPerChunk;
for (let chunkI = 0; ; chunkI++) {
const sampleStartI = chunkI * samplesPerChunk;
const sampleEndI = sampleStartI + samplesPerChunk;
if (sampleEndI >= data.Ear_Left.length) break;
const channelSamples = [] as number[][];
for (const channel of pack.channelInfos) {
const samplesForThisChannel = [] as number[];
for (let i = sampleStartI; i < sampleEndI; i++) {
samplesForThisChannel.push(data[channel.name][i]);
}
channelSamples.push(samplesForThisChannel);
}
const chunk = new Chunk({
channelSamples,
});
pack.chunks.push(chunk);
//AppendChunk(chunk, stream, pack.channelInfos);
console.log(`Wrote chunk ${chunkI}.`);
}
WriteEDFPackage(pack, stream);
stream.close();
} else {
// channel-per-file exporting example not yet written
}
}
function CreateChannelInfo(data: Partial) {
const data_final = Object.assign(
{
type: "MuseS",
dimensions: "unknown",
physicalMin: -32768,
physicalMax: 32767,
digitalMin: -1000,
digitalMax: 1000,
prefilteringInfo: "unknown",
sampleCountPerChunk: 256 * 30,
},
data,
);
return new ChannelInfo(data_final);
}
```