コード例 #1
0
void UI_AnnotationEditwindow::createButtonClicked()
{
  annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));

  annotation->onset =  onset_daySpinbox->value() * 86400 * TIME_DIMENSION;
  annotation->onset += onset_timeEdit->time().hour() * 3600 * TIME_DIMENSION;
  annotation->onset += onset_timeEdit->time().minute() * 60 * TIME_DIMENSION;
  annotation->onset += onset_timeEdit->time().second() * TIME_DIMENSION;
  annotation->onset += onset_timeEdit->time().msec() * (TIME_DIMENSION / 1000);

  if(posNegTimebox->currentIndex() == 1)
  {
    annotation->onset = -(annotation->onset);
  }

  annotation->onset += mainwindow->edfheaderlist[file_num]->starttime_offset;

  annotation->file_num = file_num;

  if(duration_spinbox->value()>0.0)
  {
    snprintf(annotation->duration, 16, "%f", duration_spinbox->value());
  }
  else
  {
    annotation->duration[0] = 0;
  }

  strncpy(annotation->annotation, annot_descript_lineEdit->text().toUtf8().data(), MAX_ANNOTATION_LEN);

  annotation->annotation[MAX_ANNOTATION_LEN] = 0;

  annotation->modified = 1;

  edfplus_annotation_add_item(&mainwindow->annotationlist[file_num], annotation);

  mainwindow->annotations_edited = 1;

  mainwindow->annotations_dock[file_num]->updateList();

  mainwindow->maincurve->update();
}
コード例 #2
0
ファイル: ecg_export.cpp プロジェクト: pangratz/EDFbrowser
void UI_ECGExport::Export_RR_intervals()
{
  int i,
      len,
      signal_nr,
      type=-1,
      beat_cnt,
      samples_cnt,
      progress_steps,
      datarecords,
      whole_recording=0,
      import_as_annots=0,
      filenum=0;

  char path[MAX_PATH_LENGTH],
       str[2048];

  double *beat_interval_list,
         *buf;

  long long *beat_onset_list,
            datrecs,
            smpls_left,
            l_time=0LL;

  struct signalcompblock *signalcomp;


  FILE *outputfile;

  QList<QListWidgetItem *> selectedlist;

  struct annotationblock *annotation;


  selectedlist = list->selectedItems();

  if(selectedlist.size() < 1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Select a signal first.");
    messagewindow.exec();
    return;
  }

  signal_nr = selectedlist.at(0)->data(Qt::UserRole).toInt();

  if((signal_nr < 0) || (signal_nr >= mainwindow->signalcomps))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Invalid signalcomp number");
    messagewindow.exec();
    return;
  }

  signalcomp = mainwindow->signalcomp[signal_nr];

  if(signalcomp->ecg_filter == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Heart Rate detection is not activated for the selected signal.");
    messagewindow.exec();
    return;
  }

  if(checkBox2->checkState() == Qt::Checked)
  {
    import_as_annots = 1;
  }

  if(checkBox1->checkState() == Qt::Checked)
  {
    whole_recording = 1;

    class FilteredBlockReadClass blockrd;

    buf = blockrd.init_signalcomp(signalcomp, 1, 0);
    if(buf == NULL)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not initialize FilteredBlockReadClass.");
      messagewindow.exec();
      return;
    }

    samples_cnt = blockrd.samples_in_buf();
    if(samples_cnt < 1)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, samples_cnt is < 1.");
      messagewindow.exec();
      return;
    }

    filenum = signalcomp->filenum;

    reset_ecg_filter(signalcomp->ecg_filter);

    datarecords = signalcomp->edfhdr->datarecords;

    QProgressDialog progress("Processing file...", "Abort", 0, datarecords);
    progress.setWindowModality(Qt::WindowModal);
    progress.setMinimumDuration(200);

    progress_steps = datarecords / 100;
    if(progress_steps < 1)
    {
      progress_steps = 1;
    }

    for(i=0; i<signalcomp->edfhdr->datarecords; i++)
    {
      if(!(i%progress_steps))
      {
        progress.setValue(i);

        qApp->processEvents();

        if(progress.wasCanceled() == TRUE)
        {
          return;
        }
      }

      if(blockrd.process_signalcomp(i) != 0)
      {
        progress.reset();
        QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error while reading file.");
        messagewindow.exec();
        return;
      }
    }

    progress.reset();
  }

  beat_cnt = ecg_filter_get_beat_cnt(signalcomp->ecg_filter);

  beat_onset_list = ecg_filter_get_onset_beatlist(signalcomp->ecg_filter);

  beat_interval_list = ecg_filter_get_interval_beatlist(signalcomp->ecg_filter);

  if(beat_cnt < 4)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, not enough beats.");
    messagewindow.exec();
    return;
  }

  if(import_as_annots)
  {
    for(i=0; i<beat_cnt; i++)
    {
      if(whole_recording)
      {
        l_time = 0LL;
      }
      else
      {
        l_time = signalcomp->edfhdr->viewtime;
      }

      if(l_time < 0LL)
      {
        l_time = 0LL;
      }

      datrecs = beat_onset_list[i] / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record;

      smpls_left = beat_onset_list[i] % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record;

      l_time += (datrecs * signalcomp->edfhdr->long_data_record_duration);

      l_time += ((smpls_left * signalcomp->edfhdr->long_data_record_duration) / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record);

      if(!whole_recording)
      {
        l_time += (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime - signalcomp->edfhdr->viewtime);
      }

      annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
      if(annotation == NULL)
      {
        QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation).");
        messagewindow.exec();
        return;
      }
      annotation->onset = l_time;
      strncpy(annotation->annotation, "R-onset", MAX_ANNOTATION_LEN);
      annotation->annotation[MAX_ANNOTATION_LEN] = 0;
      edfplus_annotation_add_item(&mainwindow->annotationlist[filenum], annotation);
    }

    if(mainwindow->annotations_dock[signalcomp->filenum] == NULL)
    {
      mainwindow->annotations_dock[filenum] = new UI_Annotationswindow(filenum, mainwindow);

      mainwindow->addDockWidget(Qt::RightDockWidgetArea, mainwindow->annotations_dock[filenum]->docklist, Qt::Vertical);

      if(!mainwindow->annotationlist[filenum])
      {
        mainwindow->annotations_dock[filenum]->docklist->hide();
      }
    }

    if(mainwindow->annotationlist[filenum])
    {
      mainwindow->annotations_dock[filenum]->docklist->show();

      mainwindow->annotations_edited = 1;

      mainwindow->annotations_dock[filenum]->updateList();

      mainwindow->save_act->setEnabled(TRUE);
    }
  }
  else
  {
    path[0] = 0;
    if(mainwindow->recent_savedir[0]!=0)
    {
      strcpy(path, mainwindow->recent_savedir);
      strcat(path, "/");
    }
    len = strlen(path);
    get_filename_from_path(path + len, signalcomp->edfhdr->filename, MAX_PATH_LENGTH - len);
    remove_extension_from_filename(path);
    strcat(path, "_RR_interval.txt");

    strcpy(path, QFileDialog::getSaveFileName(0, "Export RR-interval to ASCII", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT)").toLocal8Bit().data());

    if(!strcmp(path, ""))
    {
      return;
    }

    get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH);

    outputfile = fopeno(path, "wb");
    if(outputfile==NULL)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not open outputfile for writing.");
      messagewindow.exec();
      return;
    }

    if(radioButton1->isChecked() == TRUE)
    {
      type = 1;
    }

    if(radioButton2->isChecked() == TRUE)
    {
      type = 2;
    }

    if(radioButton3->isChecked() == TRUE)
    {
      type = 3;
    }

    if(type == 1)
    {
      for(i=0; i<beat_cnt; i++)
      {
        fprintf(outputfile, "%.4f\n", beat_interval_list[i]);
      }
    }

    if((type == 2) || (type == 3))
    {
      for(i=0; i<beat_cnt; i++)
      {
        if(whole_recording)
        {
          l_time = 0LL;
        }
        else
        {
          l_time = signalcomp->edfhdr->viewtime;
        }

        if(l_time < 0LL)
        {
          l_time = 0LL;
        }

        datrecs = beat_onset_list[i] / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record;

        smpls_left = beat_onset_list[i] % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record;

        l_time += (datrecs * signalcomp->edfhdr->long_data_record_duration);

        l_time += ((smpls_left * signalcomp->edfhdr->long_data_record_duration) / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record);

        if(!whole_recording)
        {
          l_time += (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime - signalcomp->edfhdr->viewtime);
        }

        if(type == 2)
        {
          fprintf(outputfile, "%.4f\t%.4f\n", ((double)l_time) / TIME_DIMENSION, beat_interval_list[i]);
        }

        if(type == 3)
        {
          fprintf(outputfile, "%.4f\n", ((double)l_time) / TIME_DIMENSION);
        }
      }
    }

    fclose(outputfile);
  }

  myobjectDialog->close();

  if(!import_as_annots)
  {
    sprintf(str, "Done. The R-onsets and/or RR-intervals are exported to:\n\n%s", path);
    QMessageBox messagewindow(QMessageBox::Information, "Ready", str);
    messagewindow.setIconPixmap(QPixmap(":/images/ok.png"));
    messagewindow.exec();
  }

  reset_ecg_filter(signalcomp->ecg_filter);

  mainwindow->setup_viewbuf();
}
コード例 #3
0
void UI_BIOSEMI2BDFPLUSwindow::SelectFileButton()
{
  int i, j, k,
      error,
      hdl_in,
      hdl_out,
      edfsignals,
      status_signal=0,
      status_samples_in_datarecord=0,
      rising_edge,
      set_duration,
      status[24],
      totalSamplesInDatarecord,
      *buf,
      buf_offset[EDFLIB_MAXSIGNALS],
      sf,
      new_sf,
      samplerate_divider;

  char str[2048],
       triggerlabel[24][64],
       outputfilename[MAX_PATH_LENGTH];

  long long datarecords,
            status_sample_duration,
            trigger_cnt,
            progress_steps;

  struct edf_hdr_struct hdr;

  struct annotationblock *annotlist=NULL;

  struct annotationblock *annotation;


  for(i=0; i<16; i++)
  {
    if(!lineEdit1[i]->text().length())
    {
      sprintf(str, "Trigger Input label %i is empty!", i + 1);
      QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
      messagewindow.exec();
      return;
    }
  }

  for(i=0; i<16; i++)
  {
    for(j=0; j<16; j++)
    {
      if(i != j)
      {
        if(!strcmp(lineEdit1[i]->text().toLocal8Bit().data(), lineEdit1[j]->text().toLocal8Bit().data()))
        {
          sprintf(str, "Trigger Input labels %i and %i are the same!", i + 1, j + 1);
          QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
          messagewindow.exec();
          return;
        }
      }
    }
  }

  str[0] = 0;

  strcpy(inputpath, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "BDF files (*.bdf *.BDF)").toLocal8Bit().data());

  if(!strcmp(inputpath, ""))
  {
    return;
  }

  get_directory_from_path(recent_opendir, inputpath, MAX_PATH_LENGTH);

  error = edfopen_file_readonly(inputpath, &hdr, EDFLIB_DO_NOT_READ_ANNOTATIONS);

  if(error < 0)
  {
    error = hdr.filetype;

    switch(error)
    {
      case EDFLIB_MALLOC_ERROR                : strcpy(str, "EDFlib: malloc error.");
                                                break;
      case EDFLIB_NO_SUCH_FILE_OR_DIRECTORY   : strcpy(str, "EDFlib: no such file or directory.");
                                                break;
      case EDFLIB_FILE_CONTAINS_FORMAT_ERRORS : strcpy(str, "EDFlib: file contains format errors.\nOpen the file in EDFbrowser to get more info.");
                                                break;
      case EDFLIB_MAXFILES_REACHED            : strcpy(str, "EDFlib: maximum amount of files reached.");
                                                break;
      case EDFLIB_FILE_READ_ERROR             : strcpy(str, "EDFlib: a file read error occurred.");
                                                break;
      case EDFLIB_FILE_ALREADY_OPENED         : strcpy(str, "EDFlib: file is already opened.");
                                                break;
      case EDFLIB_FILETYPE_ERROR              : strcpy(str, "EDFlib: filetype error.");
                                                break;
      case EDFLIB_FILE_WRITE_ERROR            : strcpy(str, "EDFlib: file write error.");
                                                break;
      case EDFLIB_NUMBER_OF_SIGNALS_INVALID   : strcpy(str, "EDFlib: invalid number of signals.");
                                                break;
      case EDFLIB_FILE_IS_DISCONTINUOUS       : strcpy(str, "EDFlib: file is discontinuous.");
                                                break;
      case EDFLIB_INVALID_READ_ANNOTS_VALUE   : strcpy(str, "EDFlib: invalid read annotations argument.");
                                                break;
      default                                 : strcpy(str, "EDFlib: unknown error.");
    }

    QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
    messagewindow.exec();

    return;
  }

  hdl_in = hdr.handle;

/////////////////// check file /////////////////////////////////////////////

  if(hdr.filetype == EDFLIB_FILETYPE_BDFPLUS)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Selected file is already a BDF-plus file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  if(hdr.filetype != EDFLIB_FILETYPE_BDF)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Selected file is not a BDF file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  if(hdr.datarecord_duration != EDFLIB_TIME_DIMENSION)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Datarecord duration of inputfile must be 1 second.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  edfsignals = hdr.edfsignals;

  if(edfsignals < 1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "There are no signals in the selected file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  sf = hdr.signalparam[0].smp_in_datarecord;

  for(i=1; i<edfsignals; i++)
  {
    if(hdr.signalparam[i].smp_in_datarecord != sf)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "All signals must have the same samplefrequency.");
      messagewindow.exec();
      edfclose_file(hdl_in);
      return;
    }
  }

  error = 1;

  switch(sf)
  {
    case 16384 : error = 0;
                 break;
    case  8192 : error = 0;
                 break;
    case  4096 : error = 0;
                 break;
    case  2048 : error = 0;
                 break;
    case  1024 : error = 0;
                 break;
    case   512 : error = 0;
                 break;
    case   256 : error = 0;
                 break;
    case   128 : error = 0;
                 break;
    case    64 : error = 0;
                 break;
    case    32 : error = 0;
                 break;
  }

  if(error)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Samplefrequency must be 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64 or 32 Hz.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  for(i=0; i<edfsignals; i++)
  {
    if(!(strcmp(hdr.signalparam[i].label, "Status          ")))
    {
      status_signal = i;

      break;
    }
  }

  if(i == edfsignals)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "There is no Status signal in the selected file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  totalSamplesInDatarecord = 0;

  for(i=0; i<edfsignals; i++)
  {
    buf_offset[i] = totalSamplesInDatarecord;

    if(i == status_signal)
    {
      status_samples_in_datarecord = hdr.signalparam[i].smp_in_datarecord;
    }

    totalSamplesInDatarecord += hdr.signalparam[i].smp_in_datarecord;
  }

  status_sample_duration = EDFLIB_TIME_DIMENSION / (long long)status_samples_in_datarecord;

  for(i=0; i<16; i++)
  {
    strcpy(&triggerlabel[i][0], lineEdit1[i]->text().toUtf8().data());
    triggerlabel[i][16] = 0;
  }

  strcpy(&triggerlabel[16][0], "new epoch");

  if(radioButton1->isChecked() == true)
  {
    rising_edge = 1;

    for(i=0; i<16; i++)
    {
      status[i] = 1;
    }
  }
  else
  {
    rising_edge = 0;

    for(i=0; i<16; i++)
    {
      status[i] = 0;
    }
  }

  if(checkBox1->isChecked() == true)
  {
    set_duration = 1;
  }
  else
  {
    set_duration = 0;
  }

  for(i=16; i<24; i++)
  {
    status[i] = 1;
  }

  strcpy(outputfilename, inputpath);
  remove_extension_from_filename(outputfilename);
  strcat(outputfilename, "_+.bdf");

  outputpath[0] = 0;
  if(recent_savedir[0]!=0)
  {
    strcpy(outputpath, recent_savedir);
    strcat(outputpath, "/");
  }
  strcat(outputpath, outputfilename);

  strcpy(outputpath, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(outputpath), "BDF files (*.bdf *.BDF)").toLocal8Bit().data());

  if(!strcmp(outputpath, ""))
  {
    edfclose_file(hdl_in);
    return;
  }

  get_directory_from_path(recent_savedir, outputpath, MAX_PATH_LENGTH);

  if(mainwindow->file_is_opened(outputpath))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Outputfile is already opened in EDFbrowser.\nClose the file and try again.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  if(!(strcmp(inputpath, outputpath)))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Inputfile and outputfile are the same.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  hdl_out = edfopen_file_writeonly(outputpath, EDFLIB_FILETYPE_BDFPLUS, edfsignals);

  if(hdl_out < 0)
  {
    switch(hdl_out)
    {
      case EDFLIB_MALLOC_ERROR                : strcpy(str, "EDFlib: malloc error.");
                                                break;
      case EDFLIB_NO_SUCH_FILE_OR_DIRECTORY   : strcpy(str, "EDFlib: no such file or directory.");
                                                break;
      case EDFLIB_MAXFILES_REACHED            : strcpy(str, "EDFlib: maximum amount of files reached.");
                                                break;
      case EDFLIB_FILE_READ_ERROR             : strcpy(str, "EDFlib: a file read error occurred.");
                                                break;
      case EDFLIB_FILE_ALREADY_OPENED         : strcpy(str, "EDFlib: file is already opened.");
                                                break;
      case EDFLIB_FILETYPE_ERROR              : strcpy(str, "EDFlib: filetype error.");
                                                break;
      case EDFLIB_FILE_WRITE_ERROR            : strcpy(str, "EDFlib: file write error.");
                                                break;
      case EDFLIB_NUMBER_OF_SIGNALS_INVALID   : strcpy(str, "EDFlib: invalid number of signals.");
                                                break;
      default                                 : strcpy(str, "EDFlib: unknown error.");
    }

    QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
    messagewindow.exec();

    edfclose_file(hdl_in);
    return;
  }

/////////////////// copy header /////////////////////////////////////////////

  for(i=0; i<edfsignals; i++)
  {
    edf_set_samplefrequency(hdl_out, i, hdr.signalparam[i].smp_in_datarecord);
    edf_set_physical_maximum(hdl_out, i, hdr.signalparam[i].phys_max);
    edf_set_physical_minimum(hdl_out, i, hdr.signalparam[i].phys_min);
    edf_set_digital_maximum(hdl_out, i, hdr.signalparam[i].dig_max);
    edf_set_digital_minimum(hdl_out, i, hdr.signalparam[i].dig_min);
    edf_set_label(hdl_out, i, hdr.signalparam[i].label);
    edf_set_prefilter(hdl_out, i, hdr.signalparam[i].prefilter);
    edf_set_transducer(hdl_out, i, hdr.signalparam[i].transducer);
    edf_set_physical_dimension(hdl_out, i, hdr.signalparam[i].physdimension);
  }

  edf_set_startdatetime(hdl_out, hdr.startdate_year, hdr.startdate_month, hdr.startdate_day, hdr.starttime_hour, hdr.starttime_minute, hdr.starttime_second);
  edf_set_patientname(hdl_out, hdr.patient);
  edf_set_recording_additional(hdl_out, hdr.recording);

/////////////////// collect triggers /////////////////////////////////////////////

  buf = (int *)malloc(sizeof(int) * status_samples_in_datarecord);
  if(buf == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (buf).");
    messagewindow.exec();
    edfclose_file(hdl_in);
    edfclose_file(hdl_out);
    return;
  }

  QProgressDialog progress("Collecting triggers...", "Abort", 0, (int)hdr.datarecords_in_file);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

  progress_steps = hdr.datarecords_in_file / 100LL;
  if(progress_steps < 1LL)
  {
    progress_steps = 1LL;
  }

  trigger_cnt = 0;

  for(datarecords = 0LL; datarecords < hdr.datarecords_in_file; datarecords++)
  {
    if(trigger_cnt >= ((hdr.datarecords_in_file * 32) - 2))
    {
      break;
    }

    if(trigger_cnt >= 100000)
    {
      break;
    }

    if(!(datarecords % progress_steps))
    {
      progress.setValue((int)datarecords);

      qApp->processEvents();

      if(progress.wasCanceled())
      {
        edfclose_file(hdl_in);
        edfclose_file(hdl_out);
        free(buf);
        edfplus_annotation_delete_list(&annotlist);
        return;
      }
    }

    if(edfread_digital_samples(hdl_in, status_signal, status_samples_in_datarecord, buf) < 0)
    {
      progress.reset();
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred during the collection of triggers.");
      messagewindow.exec();
      edfclose_file(hdl_in);
      edfclose_file(hdl_out);
      free(buf);
      edfplus_annotation_delete_list(&annotlist);
      return;
    }

    for(i=0; i<status_samples_in_datarecord; i++)
    {
      for(j=0; j<17; j++)
      {
        if(((buf[i] & (1 << j)) && !status[j]) || (!(buf[i] & (1 << j)) && status[j]))  // rising or falling edge detected
        {
          if(status[j])  // falling edge detected
          {
            if((!rising_edge) && (j < 16))
            {
              annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
              if(annotation == NULL)
              {
                progress.reset();
                QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (annotation).");
                messagewindow.exec();
                edfclose_file(hdl_in);
                edfclose_file(hdl_out);
                free(buf);
                edfplus_annotation_delete_list(&annotlist);
                return;
              }
              annotation->onset = (datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration);
              annotation->onset += hdr.starttime_subsecond;
              strcpy(annotation->annotation, triggerlabel[j]);
              edfplus_annotation_add_item(&annotlist, annotation);

              trigger_cnt++;
            }
            else
            {
              if(set_duration)
              {
                k = edfplus_annotation_count(&annotlist);
                for(; k>0; k--)
                {
                  annotation = edfplus_annotation_item(&annotlist, k - 1);
                  if(annotation == NULL)
                  {
                    break;
                  }
                  if(!strcmp(annotation->annotation, triggerlabel[j]))
                  {
                    sprintf(str, "%.4f", (double)((datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration) - annotation->onset) / (double)EDFLIB_TIME_DIMENSION);
                    str[15] = 0;
                    strcpy(annotation->duration, str);
                    break;
                  }
                }
              }
            }

            status[j] = 0;
          }
          else  // rising edge detected
          {
            if(rising_edge || (j == 16))
            {
              annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
              if(annotation == NULL)
              {
                progress.reset();
                QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (annotation).");
                messagewindow.exec();
                edfclose_file(hdl_in);
                edfclose_file(hdl_out);
                free(buf);
                edfplus_annotation_delete_list(&annotlist);
                return;
              }
              annotation->onset = (datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration);
              annotation->onset += hdr.starttime_subsecond;
              strcpy(annotation->annotation, triggerlabel[j]);
              edfplus_annotation_add_item(&annotlist, annotation);

              trigger_cnt++;
            }
            else
            {
              if(set_duration)
              {
                k = edfplus_annotation_count(&annotlist);
                for(; k>0; k--)
                {
                  annotation = edfplus_annotation_item(&annotlist, k - 1);
                  if(annotation == NULL)
                  {
                    break;
                  }
                  if(!strcmp(annotation->annotation, triggerlabel[j]))
                  {
                    sprintf(str, "%.4f", (double)((datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration) - annotation->onset) / (double)EDFLIB_TIME_DIMENSION);
                    str[15] = 0;
                    strcpy(annotation->duration, str);
                    break;
                  }
                }
              }
            }

            status[j] = 1;
          }
        }
      }
    }
  }

  edfwrite_annotation_latin1(hdl_out, 0LL, -1LL, "Recording starts");

  j = edfplus_annotation_count(&annotlist);

  for(i=0; i<j; i++)
  {
    annotation = edfplus_annotation_item(&annotlist, i);

    if(annotation->duration[0] == 0)
    {
      edfwrite_annotation_utf8(hdl_out, annotation->onset / 1000LL, -1LL, annotation->annotation);
    }
    else
    {
      edfwrite_annotation_utf8(hdl_out, annotation->onset / 1000LL, (long long)(atof(annotation->duration) * 10000.0), annotation->annotation);
    }
  }

  free(buf);

  edfwrite_annotation_latin1(hdl_out, hdr.datarecords_in_file * 10000LL, -1LL, "Recording ends");

/////////////////// choose datarecord duration /////////////////////////////////////////////

  samplerate_divider = 1;

  i = edfplus_annotation_count(&annotlist);

  edfplus_annotation_delete_list(&annotlist);

  annotlist = NULL;

  if(i % 2)
  {
    i++;
  }

  i += 2;

  while(i > hdr.datarecords_in_file)
  {
    samplerate_divider *= 2;

    i /= 2;

    if(samplerate_divider == 32)
    {
      break;
    }
  }

  if(samplerate_divider > 1)
  {
    for(i=0; i<edfsignals; i++)
    {
      edf_set_samplefrequency(hdl_out, i, hdr.signalparam[i].smp_in_datarecord / samplerate_divider);
    }

    if(edf_set_datarecord_duration(hdl_out, 100000 / samplerate_divider) == -1)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_datarecord_duration() returned an error.");
      messagewindow.exec();
      edfclose_file(hdl_in);
      edfclose_file(hdl_out);
      return;
    }
  }

  new_sf = sf / samplerate_divider;

/////////////////// start conversion /////////////////////////////////////////////

  buf = (int *)malloc(sizeof(int) * totalSamplesInDatarecord);
  if(buf == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (buf).");
    messagewindow.exec();
    edfclose_file(hdl_in);
    edfclose_file(hdl_out);
    return;
  }

  edfrewind(hdl_in, status_signal);

  progress.setLabelText("Converting...");
  progress.setValue(0);

  for(datarecords = 0LL; datarecords < hdr.datarecords_in_file; datarecords++)
  {
    if(!(datarecords % progress_steps))
    {
      progress.setValue((int)datarecords);

      qApp->processEvents();

      if(progress.wasCanceled())
      {
        edfclose_file(hdl_in);
        edfclose_file(hdl_out);
        free(buf);
        return;
      }
    }

    for(i=0; i<edfsignals; i++)
    {
      if(edfread_digital_samples(hdl_in, i, hdr.signalparam[i].smp_in_datarecord, buf + buf_offset[i]) < 0)
      {
        progress.reset();
        QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred during the conversion.");
        messagewindow.exec();
        edfclose_file(hdl_in);
        edfclose_file(hdl_out);
        free(buf);
        return;
      }
    }

    for(j=0; j<samplerate_divider; j++)
    {
      for(i=0; i<edfsignals; i++)
      {
        if(edfwrite_digital_samples(hdl_out, buf + buf_offset[i] + (j * new_sf)) < 0)
        {
          progress.reset();
          QMessageBox messagewindow(QMessageBox::Critical, "Error", "A write error occurred during the conversion.");
          messagewindow.exec();
          edfclose_file(hdl_in);
          edfclose_file(hdl_out);
          free(buf);
          return;
        }
      }
    }
  }

  QApplication::setOverrideCursor(Qt::WaitCursor);

  edfclose_file(hdl_in);
  edfclose_file(hdl_out);
  free(buf);

  QApplication::restoreOverrideCursor();

  progress.reset();

#ifdef Q_WS_WIN
  snprintf(str, 2048, "Done. Converted %I64d input trigger events to BDF+ annotations.\n"
                      "\nBDF+ file is located at %s", trigger_cnt, outputpath);
#else
  snprintf(str, 2048, "Done. Converted %lli input trigger events to BDF+ annotations.\n"
                      "\nBDF+ file is located at %s", trigger_cnt, outputpath);
#endif

  QMessageBox messagewindow(QMessageBox::Information, "Ready", str);
  messagewindow.setIconPixmap(QPixmap(":/images/ok.png"));
  messagewindow.exec();
}
コード例 #4
0
void UI_ZScoreWindow::get_annotationsButtonClicked()
{
  int i,
      awake = 1,
      filenum,
      marker_start,
      marker_end;

  struct annotationblock *annotation;


  if((epoch_cntr < 2) || (zscore_pages < 1))
  {
    return;
  }

  marker_start = curve1->getMarker1Position() * zscore_pages;
  if(marker_start < 0)
  {
    marker_start = 0;
  }

  marker_end = curve1->getMarker2Position() * zscore_pages;
  if(marker_end > zscore_pages)
  {
    marker_end = zscore_pages;
  }

  filenum = mainwindow->signalcomp[signalnr]->edfhdr->file_num;

  for(i=0; i<marker_end; i++)
  {
    if(zscore_sleepstage_buf[i] != awake)
    {
      awake = zscore_sleepstage_buf[i];

      if(i >= marker_start)
      {
        annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
        if(annotation == NULL)
        {
          QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation).");
          messagewindow.exec();
          return;
        }
        annotation->onset = i * zscore_page_len * 2LL * TIME_DIMENSION;
        if(awake)
        {
          strcpy(annotation->annotation, "Wake");
        }
        else
        {
          strcpy(annotation->annotation, "Sleep");
        }
        edfplus_annotation_add_item(&mainwindow->annotationlist[filenum], annotation);
      }
    }
  }

  if(mainwindow->annotations_dock[filenum] == NULL)
  {
    mainwindow->annotations_dock[filenum] = new UI_Annotationswindow(filenum, mainwindow);

    mainwindow->addDockWidget(Qt::RightDockWidgetArea, mainwindow->annotations_dock[filenum]->docklist, Qt::Vertical);

    if(!mainwindow->annotationlist[filenum])
    {
      mainwindow->annotations_dock[filenum]->docklist->hide();
    }
  }

  if(mainwindow->annotationlist[filenum])
  {
    mainwindow->annotations_dock[filenum]->docklist->show();

    mainwindow->annotations_edited = 1;

    mainwindow->annotations_dock[filenum]->updateList();

    mainwindow->save_act->setEnabled(true);
  }

   mainwindow->maincurve->update();
}