예제 #1
0
        static private List <ECGAnnotation> loadCustomAnnotations(String signalFileName, int channel)
        {
            if (!File.Exists(signalFileName))
            {
                return(new List <ECGAnnotation>());
            }
            FileStream           fileStream   = new FileStream(signalFileName, FileMode.Open);
            StreamReader         streamReader = new StreamReader(fileStream);
            String               line         = streamReader.ReadLine();
            List <ECGAnnotation> annotations  = new List <ECGAnnotation>();

            while (line != null)
            {
                List <String> list = line.Split(' ').ToList();
                if (list[1] == channel.ToString())
                {
                    List <String> help       = list.GetRange(3, list.Count - 3);
                    ECGAnnotation annotation = new ECGAnnotation()
                    {
                        Type      = (ANNOTATION_TYPE)Enum.Parse(typeof(ANNOTATION_TYPE), list[0].ToString()),
                        TimeIndex = Convert.ToDouble(list[2]),
                        Text      = String.Join(" ", help)
                    };
                    annotations.Add(annotation);
                }

                // read next line
                line = streamReader.ReadLine();
            }
            streamReader.Close();
            return(annotations);
        }
예제 #2
0
 private void OnAnnotationInsertRequested(ECGAnnotation annotation)
 {
     if (annotationInsertRequested != null)
     {
         annotationInsertRequested(annotation);
     }
 }
예제 #3
0
 private void OnAnnotationDeletionRequested(ECGAnnotation annotation)
 {
     if (annotationDeletionRequested != null)
     {
         annotationDeletionRequested(annotation);
     }
 }
예제 #4
0
        private void Insert_Button_Click(object sender, RoutedEventArgs e)
        {
            ANNOTATION_TYPE selectedType = (ANNOTATION_TYPE)cb_annotationType.SelectedItem;
            String          content      = "";

            if (selectedType == ANNOTATION_TYPE.PHYSIONET_STANDARD)
            {
                content = cb_standard_content.SelectedItem as String;
            }
            else
            {
                content = tb_content.Text;
            }

            String[] timestampStrings = tb_timestamp.Text.Split(':');

            if (content.Length == 0)
            {
                MessageBox.Show("There must be some annotation content?");
            }
            else if (timestampStrings.Length == 0 || timestampStrings.Length > 3)
            {
                MessageBox.Show("Timestamp must be specified correctly ([mm]:[ss]:msec)!");
            }
            else
            {
                try
                {
                    double[] timestampNumbers = timestampStrings.Select(timestampstring =>
                    {
                        return(Double.Parse(timestampstring));
                    }).Reverse().ToArray();

                    // first milliseconds (divide by 1000)
                    timestampNumbers[0] = timestampNumbers[0] / 1000;
                    // second should be seconds, no division or multiplication neccessary
                    // thrid should be minutes, multiply by 60
                    if (timestampNumbers.Length > 2)
                    {
                        timestampNumbers[2] = timestampNumbers[2] * 60;
                    }

                    // now sum for total seconds
                    double timeIndex = 0;
                    for (int i = 0; i < timestampNumbers.Length; i++)
                    {
                        timeIndex += timestampNumbers[i];
                    }

                    ECGAnnotation annot = new ECGAnnotation()
                    {
                        Text      = content,
                        Type      = selectedType,
                        TimeIndex = timeIndex
                    };

                    if (annot.Type == ANNOTATION_TYPE.PHYSIONET_STANDARD)
                    {
                        // set the MIT annotation specific values
                        annot.Code = ECGAnnotation.getCodeFromStandardAnnotationText(annot.Text);
                        annot.Aux  = "";
                    }

                    MessageBox.Show("Insertion successful!");
                    OnAnnotationInsertRequested(annot);
                }
                catch (Exception)
                {
                    MessageBox.Show("Incorrect timestamp format!");
                }
            }
        }
예제 #5
0
        static private void saveStandardAnnotations(ECG ecg, String atrFileName)
        {
            int sampleTime = 0;
            int num        = 0;
            int chan       = 0;

            FileStream   fs                 = new FileStream(atrFileName + ".atr", FileMode.Create);
            BinaryWriter writer             = new BinaryWriter(fs);
            byte         buf                = Convert.ToByte(0x0);
            byte         nul                = Convert.ToByte(0x0);
            int          previousSampleTime = 0;

            ecg.Annotations = ecg.Annotations.OrderBy(an => an.TimeIndex).ToList();

            for (int i = 0; i < ecg.Annotations.Count; i++)
            {
                ECGAnnotation annotation = ecg.Annotations.ElementAt(i);
                if (annotation.Type == ANNOTATION_TYPE.PHYSIONET_STANDARD)
                {
                    sampleTime         = Convert.ToInt32(annotation.TimeIndex * Frequency) - previousSampleTime;
                    previousSampleTime = Convert.ToInt32(annotation.TimeIndex * Frequency);

                    buf = Convert.ToByte(sampleTime & 0xFF);
                    writer.Write(buf);
                    buf = Convert.ToByte(Convert.ToByte((annotation.Code << 2) & 0xFF) | (Convert.ToByte((sampleTime >> 8) & 0xFF) & 0x3));
                    writer.Write(buf);

                    if (annotation.Aux != null && annotation.Aux.Length > 0)
                    {
                        buf = Convert.ToByte((annotation.Aux.Length + 1) & 0xFF);
                        writer.Write(buf);
                        buf = Convert.ToByte(Convert.ToByte((63 << 2) & 0xFF) | (Convert.ToByte(((annotation.Aux.Length + 1) >> 8) & 0xFF) & 0x3));
                        writer.Write(buf);

                        // write down AUX
                        for (int j = 0; j < annotation.Aux.Length; j++)
                        {
                            writer.Write(Convert.ToByte(annotation.Aux[j] & 0xFF));
                        }

                        writer.Write(nul); // string termination...

                        if (annotation.Aux.Length + 1 % 2 != 0)
                        {
                            writer.Write(nul);
                        }
                    }

                    if (annotation.SubTyp != 0)
                    {
                        // write down SUB
                        buf = Convert.ToByte(annotation.SubTyp & 0xFF);
                        writer.Write(buf);
                        buf = Convert.ToByte(Convert.ToByte((61 << 2) & 0xFF) | (Convert.ToByte((annotation.SubTyp >> 8) & 0xFF) & 0x3));
                        writer.Write(buf);
                    }

                    if ((ecg.Channel - 1) != chan)
                    {
                        chan = (ecg.Channel - 1);
                        // write down new CHAN

                        buf = Convert.ToByte(chan & 0xFF);
                        writer.Write(buf);
                        buf = Convert.ToByte(Convert.ToByte((62 << 2) & 0xFF) | (Convert.ToByte((chan >> 8) & 0xFF) & 0x3));
                        writer.Write(buf);
                    }

                    if (annotation.Num != num)
                    {
                        num = annotation.Num;
                        // write down new NUM

                        buf = Convert.ToByte(annotation.Num & 0xFF);
                        writer.Write(buf);
                        buf = Convert.ToByte(Convert.ToByte((60 << 2) & 0xFF) | (Convert.ToByte((annotation.Num >> 8) & 0xFF) & 0x3));
                        writer.Write(buf);
                    }
                }
            }

            // write EOF
            writer.Write(nul);
            writer.Write(nul);
            writer.Close();
        }
예제 #6
0
        static private List <ECGAnnotation> loadStandardAnnotations(String atrFileName, int channelToLoad = 1)
        {
            List <ECGAnnotation> standardAnnotations = new List <ECGAnnotation>();

            byte[]        bytes              = File.ReadAllBytes(atrFileName);
            int           sampleTime         = 0;
            int           num                = 0;
            int           subtyp             = 0;
            int           chan               = 0;
            bool          increaseSampleTime = true;
            ECGAnnotation annotation         = null;
            String        aux                = "";

            for (int i = 0; i < bytes.Length; i += 2)
            {
                aux                = "";
                subtyp             = 0;
                increaseSampleTime = true;

                int A = bytes[i + 1] >> 2;
                int I = (((bytes[i + 1] & 0x3) << 8) | bytes[i]);

                switch (A)
                {
                // SKIP
                case 59:
                    if (I == 0)
                    {
                        // if I is 0, we should skip the next 4 bytes
                        i += 4;
                    }
                    else
                    {
                        // otherwise we have to skip next I bytes
                        i += I;
                    }
                    increaseSampleTime = false;
                    break;

                // NUM
                case 60:
                    num                = I;
                    annotation.Num     = num;
                    increaseSampleTime = false;
                    break;

                // SUB
                case 61:
                    subtyp             = I;
                    annotation.SubTyp  = subtyp;
                    increaseSampleTime = false;
                    break;

                // CHAN
                case 62:
                    chan               = I;
                    annotation.Chan    = chan;
                    increaseSampleTime = false;
                    break;

                // AUX
                case 63:
                    for (int j = 0; j < I; j++)
                    {
                        // next I bytes are the aux string letters.
                        // since we are reading two bytes at a time in main for loop, the aux string starts at (i+1)+1 position hence the: i+2+offset formula
                        char c = Convert.ToChar(bytes[i + 2 + j]);
                        if (c == '\0')
                        {
                            continue;
                        }
                        aux += c;
                    }

                    // if I is odd, there is a null byte pad appended to make the byte count even, but the null byte is not included in the byte count represented by I
                    i += I + (I % 2 == 0 ? 0 : 1);

                    annotation.Aux     = aux;
                    increaseSampleTime = false;
                    break;

                // EOF
                case 0:
                    if (I == 0)
                    {
                        return(standardAnnotations);
                    }
                    break;
                }

                if (increaseSampleTime)
                {
                    sampleTime += I;

                    annotation           = new ECGAnnotation();
                    annotation.Type      = ANNOTATION_TYPE.PHYSIONET_STANDARD;
                    annotation.TimeIndex = sampleTime * (1.0 / Frequency);
                    annotation.Text      = ECGAnnotation.getStandardAnnotationTextFromCode(A);
                    annotation.Code      = A;
                    annotation.Aux       = aux;
                    annotation.Chan      = chan;
                    annotation.Num       = num;
                    annotation.SubTyp    = subtyp;

                    if (annotation.Chan == (channelToLoad - 1))
                    {
                        standardAnnotations.Add(annotation);
                    }
                }
                else
                {
                    if (aux.Length > 0)
                    {
                        annotation.Text += " " + aux;
                    }
                }
            }

            return(standardAnnotations);
        }
예제 #7
0
 void annotationInsertWindow_annotationInsertRequested(ECGAnnotation annotation)
 {
     signal.Annotations.Add(annotation);
     ecgView.refresh();
 }
예제 #8
0
 void annotationDeleteWindow_annotationDeletionRequested(ECGAnnotation annotation)
 {
     signal.Annotations.Remove(annotation);
     ecgView.refresh();
 }