OpenVIBE EDF File Reader based on codes provided by TEMPO

Come here to discuss about OpenViBE in general!
Post Reply
ThinkEEG
Posts: 4
Joined: Tue Jan 04, 2011 12:18 am

OpenVIBE EDF File Reader based on codes provided by TEMPO

Post by ThinkEEG »

We have tested Tempo using its EDF file reader.

http://code.google.com/p/tempo/


The EDF file reader in Tempo is simpler than BioSig Library. After looking through the sample data ("sample.edf" http://code.google.com/p/tempo/source/browse/#hg%2Fdata) and the EDF reader codes "Input.cpp"http://code.google.com/p/tempo/source/b ... 423da2d763

I wonder if it is possible to write a OpenVIBE Reader that can read the binary "sample.edf".

Here are the supporting argument for the effort

(1)
There are many publications that uses Tempo to generate figures. To do that, the authors must have prepared many EDF files compatible with the Tempo. If there is a OpenVIBE EDF reader compatible with that of Tempo, the same files can be used to generate many more interesting diagrams offered by OpenVIBE.

(2)
Currently, the Research Edition and above of Emotiv allows saving of raw EEG data in EDF format for playback and distribution. I can not say right now how compatible is the Emotiv EDF format until further testing. Having an OpenVIBE EDF reader that is also compatible with the Emotiv EDF file format will motivate more users to combine Emotiv headset and OpenVIBE for BCI research.

I would like to hear from others if the simplified EDF format used in Tempo is a good starting point to prepare OpenVIBE towards having a EDF file reader eventually.


Below is an extract from the Input.cpp file that read the sample.edf.

Questions:
based on the available readers in OpenVIBE, which of them is more "Compatible" as a template to evaluate the feasibility to incorporate the code below into a OpenVIBE Edf reader.

Thanks.

(FYI, I have downloaded 0.9 openVIBE source, it is straight forwards to generate VS2008 projects and compile, good work).

Code: Select all


      /* Open file with sampled values. */
        std::ifstream stream(name.c_str(), std::ios::binary);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);

        char buffer[81];
        int i, j;

        /* Read and check version string. */
        stream.read(buffer, 8);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[8] = 0;
        if (buffer != VERSION)
                throw Exception(Exception::INVALID_INPUT_FILE);

        /* Read patient information. */
        stream.read(buffer, 80);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[80] = 0;
        for (i = 79; i >= 0 && buffer[i] == ' '; i--)
                buffer[i] = 0;
        patient = buffer;

        /* Read recording information. */
        stream.read(buffer, 80);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[80] = 0;
        for (i = 79; i >= 0 && buffer[i] == ' '; i--)
                buffer[i] = 0;
        recording = buffer;

        /* Read start date of recording. */
        stream.read(buffer, 8);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[8] = 0;
        for (i = 7; i >= 0 && buffer[i] == ' '; i--)
                buffer[i] = 0;
        std::istringstream date(buffer);
        date >> day;
        date.get();
        date >> month;
        date.get();
        date >> year;
        if (!date)
                throw Exception(Exception::INVALID_INPUT_FILE);

        /* Read start time of recording. */
        stream.read(buffer, 8);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[8] = 0;
        for (i = 7; i >= 0 && buffer[i] == ' '; i--)
                buffer[i] = 0;
        std::istringstream time(buffer);
        time >> hour;
        time.get();
        time >> minute;
        time.get();
        time >> second;
        if (!time)
                throw Exception(Exception::INVALID_INPUT_FILE);
        
        /* Read number of bytes in input file header. */
        stream.read(buffer, 8);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[8] = 0;
        offset = std::atoi(buffer);

        /* Read first reserved block. */
        stream.read(buffer, 44);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);

         /* Read number of data records. */
        stream.read(buffer, 8);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[8] = 0;
        data = std::atoi(buffer);

        /* Read data record duration. */
        stream.read(buffer, 8);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[8] = 0;
        duration = std::atoi(buffer);

        /* Read number of signals in input file. */
        stream.read(buffer, 4);
        if (!stream)
                throw Exception(Exception::INVALID_INPUT_FILE);
        buffer[4] = 0;
        count = std::atoi(buffer);

        /* Create signal objects. */
        for (i = 0; i < count; i++) {
                /* Read signal label. */
                stream.read(buffer, 16);
                if (!stream)
                        throw Exception(Exception::INVALID_INPUT_FILE);
                buffer[16] = 0;
                for (j = 15; j >= 0 && buffer[j] == ' '; j--)
                        buffer[j] = 0;

                const std::vector<std::string> &names = sensors.getNames();
                const std::vector<Vector> &positions = sensors.getPositions();
                /* Compare signal label with all known sensor
                   names... */
                for (j = 0; j < (int) names.size(); j++)
                        /* ...and if match found, create signal object
                           and read signal information from file, then
                           remember signal object and position of
                           corresponding sensor.  */
                        if (names[j] == buffer) {
                                signals.push_back(Signal(name, i));
                                points.push_back(positions[j]);
                                break;
                        }
        }


ThinkEEG
Posts: 4
Joined: Tue Jan 04, 2011 12:18 am

Re: OpenVIBE EDF File Reader based on codes provided by TEMP

Post by ThinkEEG »

Both the Emotiv EDF and the Tempo EDF binary files can be converted into asci (CSV) format using the utility program (http://www.teuniz.net/edf2ascii/index.html)
EDFConvert.jpg
EDFConvert.jpg (13.58 KiB) Viewed 8228 times
The complete "sample_signals.txt"

Code: Select all

Signal,Label,Transducer,Units,Min,Max,Dmin,Dmax,PreFilter,Smp/Rec,Reserved
1,EEG Fp1         ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
2,EEG Fp2         ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
3,EEG T3          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
4,EEG T4          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
5,EEG T5          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
6,EEG T6          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
7,EEG F7          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
8,EEG F8          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
9,EEG F3          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
10,EEG F4          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
11,EEG C3          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
12,EEG C4          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
13,EEG P3          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
14,EEG P4          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
15,EEG O1          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                
16,EEG O2          ,AgAgCl electrode                                                                ,uV      ,-682.000000,682.000000,-2046,2046,n/a                                                                             ,256,                                

The first 5 lines of the "sample_data.txt"

Code: Select all

Time,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
0.000000,5.333333,6.333333,4.666667,7.333333,0.000000,4.666667,3.000000,12.000000,0.333333,-0.333333,-4.666667,4.666667,-11.666667,-3.000000,-5.333333,-18.333333
0.003906,7.000000,11.000000,3.666667,10.666667,-5.000000,6.000000,7.666667,17.666667,2.000000,4.666667,-4.666667,8.333333,-12.333333,-0.666667,-15.000000,-20.000000
0.007812,7.333333,14.000000,2.000000,10.666667,-8.333333,6.333333,9.333333,19.333333,4.000000,7.333333,-3.666667,11.000000,-11.333333,1.333333,-22.000000,-21.000000
0.011719,6.666667,12.333333,0.333333,9.666667,-10.000000,6.333333,9.666667,16.000000,5.666667,8.333333,-1.666667,12.000000,-8.666667,3.666667,-26.333333,-21.333333

Please suggest a possible template codes in openvibe that could help me to understand how to write a reader that can import the two files into OpenVIBE as well as Openvibe scene that I can combine the two imported file and proceed with the analysis.

Thank you.

yrenard
Site Admin
Posts: 645
Joined: Fri Sep 01, 2006 3:39 pm
Contact:

Re: OpenVIBE EDF File Reader based on codes provided by TEMP

Post by yrenard »

Dear ThinkEEG,

technically, there is no reason why you could not build an EDF file reader. If you have time for this and want to contribute this, then feel free :)

By the way, we have a CSV file writer currently available and a CSV file reader almost ready in a branch. Did you try to use the EDF to ASCII program you pointed out in order to do the conversion to a format that is already supported ?

Yann

Post Reply