Exemple #1
0
        private void btnReadBCI2000_Click(object sender, EventArgs e)
        {
            // clear the output
            txtOutput.Text = "";

            // try to read the file
            Data_BCI2000 info = new Data_BCI2000();

            double[][] samples = null;
            bool       result  = readBCI2000dat(txtInputFile.Text, out info, out samples);

            if (!result)
            {
                return;
            }

            // output
            txtOutput.Text  = info.firstLine + Environment.NewLine + Environment.NewLine;
            txtOutput.Text += "Header length: " + info.headerLen + Environment.NewLine;
            txtOutput.Text += "Source channels: " + info.sourceCh + Environment.NewLine;
            txtOutput.Text += "State vector length: " + info.stateVectorLen + Environment.NewLine;
            txtOutput.Text += Environment.NewLine;
            //txtOutput.Text += "Header: " + Environment.NewLine + data.header;
            txtOutput.Text += "Sample rate: " + info.samplingRate + Environment.NewLine;
            txtOutput.Text += Environment.NewLine;
            txtOutput.Text += "Number of samples: " + info.numSamples + Environment.NewLine + Environment.NewLine;


            string strOutput = "";

            for (int i = 0; i < info.numSamples; i++)
            {
                for (int j = 0; j < info.sourceCh; j++)
                {
                    if (j != 0)
                    {
                        strOutput += "\t";
                    }
                    strOutput += samples[i][j];
                }
                strOutput += Environment.NewLine;
            }

            txtOutput.Text += strOutput;
        }
Exemple #2
0
        private bool readBCI2000dat(string filename, out Data_BCI2000 info, out double[][] samples)
        {
            FileStream   dataStream = null;
            StreamReader dataReader = null;

            // check if the file exists
            if (!File.Exists(filename))
            {
                MessageBox.Show("Could not find input file", "File error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                info    = null;
                samples = null;
                return(false);
            }

            try {
                // open file stream
                dataStream = new FileStream(filename, FileMode.Open);

                // open reader
                //dataReader = new System.IO.StreamReader(filestream, System.Text.Encoding.UTF8, true, 128);
                dataReader = new System.IO.StreamReader(dataStream);
            } catch (Exception) {
                // message
                MessageBox.Show("Could not create filestream to data file '" + filename + "' for reading");
                info    = null;
                samples = null;
                return(false);
            }

            // create a new bci2000 data object
            info = new Data_BCI2000();

            // retrieve the first line
            info.firstLine = dataReader.ReadLine();

            // retrieve HeaderLen
            string fieldName        = "HeaderLen=";
            int    fieldValueLength = 6;
            int    pos = info.firstLine.IndexOf(fieldName);

            if (pos == -1 || info.firstLine.Length < pos + fieldName.Length + fieldValueLength)
            {
                MessageBox.Show("Could not retrieve " + fieldName + ", aborting");
                info    = null;
                samples = null;
                return(false);
            }
            bool result = Int32.TryParse(info.firstLine.Substring(pos + fieldName.Length, fieldValueLength), out info.headerLen);

            if (!result)
            {
                MessageBox.Show("Could not retrieve " + fieldName + ", aborting");
                info    = null;
                samples = null;
                return(false);
            }

            // retrieve SourceCh
            fieldName        = "SourceCh=";
            fieldValueLength = 2;
            pos = info.firstLine.IndexOf(fieldName);
            if (pos == -1 || info.firstLine.Length < pos + fieldName.Length + fieldValueLength)
            {
                MessageBox.Show("Could not retrieve " + fieldName + ", aborting");
                info    = null;
                samples = null;
                return(false);
            }
            result = Int32.TryParse(info.firstLine.Substring(pos + fieldName.Length, fieldValueLength), out info.sourceCh);
            if (!result)
            {
                MessageBox.Show("Could not retrieve " + fieldName + ", aborting");
                info    = null;
                samples = null;
                return(false);
            }

            // retrieve StatevectorLen
            fieldName = "StatevectorLen=";
            //fieldValueLength = 3;
            pos = info.firstLine.IndexOf(fieldName);
            fieldValueLength = Math.Min(3, info.firstLine.Length - (pos + fieldName.Length));               // adjusted: fieldValueLength is variable: so it is either three, or in case the string is shorter, the remainder of the string: either 1 or 2
            if (pos == -1 || info.firstLine.Length < pos + fieldName.Length + fieldValueLength)
            {
                MessageBox.Show("Could not retrieve " + fieldName + ", aborting");
                info    = null;
                samples = null;
                return(false);
            }
            result = Int32.TryParse(info.firstLine.Substring(pos + fieldName.Length, fieldValueLength), out info.stateVectorLen);
            if (!result)
            {
                MessageBox.Show("Could not retrieve " + fieldName + ", aborting");
                info    = null;
                samples = null;
                return(false);
            }

            // retrieve entire header
            char[] buffer = new char[info.headerLen];
            dataStream.Position = 0;
            dataReader.DiscardBufferedData();
            dataReader.ReadBlock(buffer, 0, info.headerLen);
            info.header = new string(buffer);

            // retrieve the sample rate from the header
            if (!getDoubleParameterFromHeader(info.header, "SamplingRate", out info.samplingRate))
            {
                MessageBox.Show("Could not retrieve sample rate from header, aborting");
                info    = null;
                samples = null;
                return(false);
            }

            // set the dataStream position to the start of the data (needed, readblock before messed it up)
            dataStream.Position = info.headerLen;

            // set
            int mDataSize = 2;      // each sample in BCI2000 is stored as an int16 (2 bytes)

            // calculate the number of samples
            info.numSamples = (int)(dataStream.Length - info.headerLen) / (mDataSize * info.sourceCh + info.stateVectorLen);

            // init matrix for all samples values
            samples = new double[info.numSamples][];

            // retrieve the data
            for (int i = 0; i < info.numSamples; i++)
            {
                // init the row of samples
                samples[i] = new double[info.sourceCh];

                // read the samples
                byte[] channels = new byte[mDataSize * info.sourceCh];
                dataStream.Read(channels, 0, mDataSize * info.sourceCh);

                // convert each channel
                for (int j = 0; j < info.sourceCh; j++)
                {
                    samples[i][j] = BitConverter.ToInt16(channels, j * mDataSize);
                }

                // read the state vector data
                byte[] stateVector = new byte[info.stateVectorLen];
                dataStream.Read(stateVector, 0, info.stateVectorLen);

                // TODO: interpret state vector
            }

            // close the datastream
            if (dataStream != null)
            {
                dataStream.Close();
            }
            dataReader = null;
            dataStream = null;

            // return success
            return(true);
        }
Exemple #3
0
        private void btnConvertBCIToPalmtree_Click(object sender, EventArgs e)
        {
            // clear the output
            txtOutput.Text = "";

            // try to read the file
            Data_BCI2000 info = new Data_BCI2000();

            double[][] samples = null;
            bool       result  = readBCI2000dat(txtInputFile.Text, out info, out samples);

            // open file dialog to save dat file
            SaveFileDialog dlgSaveDatFile = new SaveFileDialog();

            dlgSaveDatFile.Filter           = "Data files (*.dat)|*.dat|Data files (*.src)|*.src|All files (*.*)|*.*";
            dlgSaveDatFile.RestoreDirectory = true;            // restores current directory to the previously selected directory, potentially beneficial if other code relies on the currently set directory

            // check if ok has been clicked on the dialog
            if (dlgSaveDatFile.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            FileStream dataStream = null;

            try {
                // create filestream: create file if it does not exists, allow to write, do not share with other processes and use buffer of 8192 bytes (roughly 1000 samples)
                dataStream = new FileStream(dlgSaveDatFile.FileName, FileMode.Create, FileAccess.Write, FileShare.None, 8192);
            } catch (Exception exc) {
                MessageBox.Show("Unable to create data file at " + dlgSaveDatFile.FileName + " (" + exc.ToString() + ")");
                return;
            }

            // generate stream names for the header (bci2000 does not have these)
            string[] streamNames = new string[info.sourceCh];
            for (int i = 0; i < streamNames.Length; i++)
            {
                streamNames[i] = "Ch" + (i + 1);
            }

            // create header
            DataHeader header = new DataHeader();

            header.version            = 1;
            header.code               = "dat";
            header.columnNames        = streamNames;
            header.numPlaybackStreams = streamNames.Length;
            header.sampleRate         = info.samplingRate;

            // write header
            if (dataStream != null)
            {
                DataWriter.writeBinaryHeader(dataStream, header);
            }

            // write data
            uint dataSampleCounter = 0;

            byte[] dataElapsedTimeBinary = BitConverter.GetBytes((1000.0 / header.sampleRate));
            for (int i = 0; i < info.numSamples; i++)
            {
                // transform variables that will be stored in .dat to binary arrays (except for dataStreamValues array which is copied directly)
                byte[] dataSampleCounterBinary = BitConverter.GetBytes(dataSampleCounter);

                // transfer the values for output
                double[] dataStreamValues = new double[info.sourceCh];
                for (int j = 0; j < info.sourceCh; j++)
                {
                    dataStreamValues[j] = samples[i][j];
                }

                // create new array to hold all bytes
                int    l1        = dataSampleCounterBinary.Length;
                int    l2        = dataElapsedTimeBinary.Length;
                int    l3        = dataStreamValues.Length * sizeof(double);
                byte[] streamOut = new byte[l1 + l2 + l3];

                // blockcopy all bytes to this array
                Buffer.BlockCopy(dataSampleCounterBinary, 0, streamOut, 0, l1);
                Buffer.BlockCopy(dataElapsedTimeBinary, 0, streamOut, l1, l2);
                Buffer.BlockCopy(dataStreamValues, 0, streamOut, l1 + l2, l3);

                // write data to file
                if (dataStream != null)
                {
                    dataStream.Write(streamOut, 0, streamOut.Length);
                }

                // increase sample counter
                dataSampleCounter++;
            }

            // set output text
            txtOutput.Text = "Done";

            // clear
            dataStream.Close();
            dataStream = null;
        }