// file: $(NEDC_NFC)/class/cpp/Wfdb/wfdb_01.cc // // This file contains header-related and I/O-related methods. // // Revision History: // // 20240409 (JP): initial version // // local include files // #include "Wfdb.h" //***************************************************************************** // // public methods: load methods // //***************************************************************************** // method: load_db_tnmg // // arguments: // char* fname: the filename of the csv file containing the data // // return: a boolean value indicating status // bool Wfdb::load_db_tnmg(const char* fname_a) { // declare local variables // char buf[Itgl::MAX_LSTR_LENGTH]; // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: loading database [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, (char*)fname_a); } // open the database file // FILE* fp = fopen(fname_a, "r"); if (fp == (FILE*)NULL) { fprintf(stdout, "Error: %s (line: %d) %s: %s (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, "error opening database", fname_a); return false; } // load the first line of labels // if (fgets(buf, Itgl::MAX_LSTR_LENGTH, fp) == (char*)NULL) { fprintf(stdout, "Error: %s (line: %d) %s: error reading db header\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); return false; } // parse the line and compute the number of channels // long nl; char* labels[MAX_NUM_CLASSES]; edf_d.parse_line(nl, labels, buf, Itgl::COMMA); num_classes_d = nl - MD_SIZE; // assign all the header labels // strcpy(lbl_id_exam_d, labels[0]); strcpy(lbl_id_patient_d, labels[1]); strcpy(lbl_age_d, labels[2]); strcpy(lbl_sex_d, labels[3]); strcpy(lbl_date_exam_d, labels[ANN_OFFSET + num_classes_d]); // assign the header channel labels // for (long i = 0; i < num_classes_d; i++) { strcpy(labels_d[i], labels[ANN_OFFSET + i]); } // clean up memory // edf_d.cleanup(labels, nl); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: done loading header\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); } // save the file position because we will return to this point // long pos = ftell(fp); // count the number of entries in the file and capture the max exam id: // we cannot assume the exams are ordered in any way // num_patients_d = (long)0; long max_exam_id = (long)0; while (fgets(buf, Itgl::MAX_LSTR_LENGTH, fp) != (char*)NULL) { // increment the patient count // num_patients_d++; // parse the string for the first number, which is the exam id // long val; sscanf(buf, "%ld,", &val); // save the maximum // max_exam_id = Itgl::max(max_exam_id, val); } // increment by one so we can allocate enough space for an array // that goes from [0, max_exam_id]. max_exam_id++; // rewind the file pointer to the beginning of the data // fseek(fp, pos, SEEK_SET); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: loading patient records\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); } // create space for the database // id_exam_d = new long[max_exam_id]; id_patient_d = new long[max_exam_id]; age_d = new long[max_exam_id]; sex_d = new char*[max_exam_id]; annotations_d = new long*[max_exam_id]; date_exam_d = new char*[max_exam_id]; // set the exam id array values to "-1" because some exams will be missing. // you might consider this a poor man's dictionary or hash table. // for (long i = 0; i < max_exam_id; i++) { id_exam_d[i] = (long)-1; } // collect all the patient records // for (long i = 0; i < num_patients_d; i++) { // read the data // fgets(buf, Itgl::MAX_LSTR_LENGTH, fp); // parse the line // edf_d.parse_line(nl, labels, buf, Itgl::COMMA); // use id_exam as the index // long indx = atoi(labels[0]); // assign the values // id_exam_d[indx] = atoi(labels[0]); id_patient_d[indx] = atoi(labels[1]); age_d[indx] = atoi(labels[2]); sex_d[indx] = new char[strlen(labels[3]) + 1]; strcpy(sex_d[indx], labels[3]); // grab the annotation values as integers // long k = 0; annotations_d[indx] = new long[num_classes_d]; for (long j = 0; j < num_classes_d; j++) { annotations_d[indx][k] = atoi(labels[ANN_OFFSET + k]); k++; } // grab the exam date // date_exam_d[indx] = new char[strlen(labels[ANN_OFFSET + k]) + 1]; strcpy(date_exam_d[indx], labels[ANN_OFFSET + k]); // clean up memory // edf_d.cleanup(labels, nl); } // close the text file // fclose(fp); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: done loading the databse\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); } // exit gracefully // return true; } //***************************************************************************** // // public methods: load headers and data, print header and data // //***************************************************************************** // method: load_header_tnmg // // arguments: // char* fn_hea: the filename for the header file containing metadata // // return: a boolean value indicating status // // This method loads data using the .hea file. // bool Wfdb::load_header_tnmg(const char* fn_hea_a) { // declare local variables // char tstr[Itgl::MAX_SSTR_LENGTH]; char* ptr; long num_len; // create space for the labels // long nl = (long)0; char* labels[MAX_NUM_CLASSES]; memset(labels, (int)0, MAX_NUM_CLASSES * sizeof(char*)); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: loading header data [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, (char*)fn_hea_a); } // open the header file // FILE* fp = fopen(fn_hea_a, "r"); if (fp == (FILE*)NULL) { fprintf(stdout, "Error: %s (line: %d) %s: %s (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, "error opening header file", fn_hea_a); return false; } // grab and parse the first line // char buf[Itgl::MAX_LSTR_LENGTH]; fgets(buf, Itgl::MAX_LSTR_LENGTH, fp); edf_d.parse_line(nl, labels, buf, Itgl::SPACE); // parse the exam id // the basename is of the form TNMGXXXXXX_N*.dat // we need to extract the number. // strcpy(hdr_fname_d, labels[0]); ptr = strstr(labels[0], Itgl::UNDERSCORE); num_len = ptr - labels[0] - 4; memcpy(tstr, labels[0] + 4, num_len); tstr[num_len] = (char)NULL; hdr_id_exam_d = atoi(tstr); // copy the rest of the stuff // hdr_num_channels_d = atoi(labels[1]); hdr_sample_frequency_d = atof(labels[2]); hdr_num_samples_per_channel_d = atoi(labels[3]); if (nl > 4) { strcpy(hdr_start_time_d, labels[4]); } else { strcpy(hdr_start_time_d, "00:00:00"); } if (nl > 5) { strcpy(hdr_exam_date_d, labels[5]); } else { strcpy(hdr_exam_date_d, "00/00/0000"); } // clean up memory // edf_d.cleanup(labels, MAX_NUM_CLASSES); // grab the channel data // for (long i = 0; i < hdr_num_channels_d; i++) { // read and parse a line // fgets(buf, Itgl::MAX_LSTR_LENGTH, fp); edf_d.parse_line(nl, labels, buf, Itgl::SPACE); // parse the patient_id: // the basename is of the form TNMGXXXXXX_N*.dat // we need to extract the number. // strcpy(hdr_fnames_d[i], labels[0]); ptr = strstr(labels[0], Itgl::UNDERSCORE); num_len = ptr - labels[0] - 4; memcpy(tstr, labels[0] + 4, num_len); tstr[num_len] = (char)NULL; hdr_fid_exam_d[i] = atoi(tstr); // grab the gain and the units // ptr = strstr(labels[2], Itgl::OPENPAREN); memcpy(tstr, labels[2], ptr - labels[2]); tstr[ptr - labels[2]] = (char)NULL; hdr_adc_gain_d[i] = atof(tstr); strcpy(hdr_units_d[i], EDF_UNITS); // grab the remaining stuff: numeric data + channel label // hdr_adc_nbits_d[i] = atoi(labels[1]); hdr_adc_resolution_d[i] = atoi(labels[3]); hdr_adc_offset_d[i] = atof(labels[4]); hdr_initial_value_d[i] = atoi(labels[5]); hdr_checksum_d[i] = atoi(labels[6]); hdr_block_size_d[i] = atoi(labels[7]); strcpy(hdr_channel_label_d[i], labels[8]); // clean up memory // edf_d.cleanup(labels, MAX_NUM_CLASSES); } // close the hea file // fclose(fp); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: done loading metadata [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, fn_hea_a); } // exit gracefully // return true; } // method: load_data_tnmg // // arguments: // char* fn_dat: the filename containing the signal data // // return: a boolean value indicating status // // This method loads data using the .hea file. // bool Wfdb::load_data_tnmg(const char* fn_dat_a) { // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: loading data [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, (char*)fn_dat_a); } // open the data file // FILE* fp = fopen(fn_dat_a, "r"); if (fp == (FILE*)NULL) { fprintf(stdout, "Error: %s (line: %d) %s: %s (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, "error opening file list", fn_dat_a); return false; } // check the dimensions // if ((hdr_num_channels_d > MAX_NUM_CHANNELS) || (hdr_num_samples_per_channel_d > MAX_NSAMPS_PER_CHAN)) { fprintf(stdout, "Error: %s (line: %d) %s: %s [%ld %ld] [%ld %ld]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, "max dimensions exceeded", hdr_num_channels_d, MAX_NUM_CHANNELS, hdr_num_samples_per_channel_d, MAX_NSAMPS_PER_CHAN); return false; } // read the data file as 16-bit binary values // long total_num_samples = hdr_num_channels_d * hdr_num_samples_per_channel_d; short int bufs[total_num_samples]; long num_read = 0; if ((num_read = fread(bufs, sizeof(short int), total_num_samples, fp)) != total_num_samples) { fprintf(stdout, "Error: %s (line: %d) %s: %s (%ld %ld)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, "error reading data", total_num_samples, num_read); fclose(fp); return false; } // resize the signal matrix // sig_d.resize(hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { sig_d[i].resize(hdr_num_samples_per_channel_d); } // convert the data to a matrix: note that the .dat data is interleaved // by sample (the first num_channels samples are written, followed // by the second sample, ...) // long k = (long)0; for (long i = 0; i < hdr_num_samples_per_channel_d; i++) { for (long j = 0; j < hdr_num_channels_d; j++) { sig_d[j][i] = (double)bufs[k++]; } } // close the text file // fclose(fp); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d)%s: done loading signal data [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, fn_dat_a); } // exit gracefully // return true; } //***************************************************************************** // // public methods: print methods // //***************************************************************************** // method: print_db_tnmg // // arguments: // char* id: a string to print to identify the data // FILE* fp: output file pointer where print is directed // // return: a boolean value indicating status // bool Wfdb::print_db_tnmg(const char* id_a, FILE* fp_a) { // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: printing db [%s] ", __FILE__, __LINE__, __PRETTY_FUNCTION__, id_a); } // print the header metadata // fprintf(stdout, "headings:\n"); fprintf(stdout, " num_patients = %ld\n", num_patients_d); fprintf(stdout, " num_classes = %ld\n", num_classes_d); fprintf(stdout, " exam_id = %s\n", lbl_id_exam_d); fprintf(stdout, " patient_id = %s\n", lbl_id_patient_d); fprintf(stdout, " age = %s\n", lbl_age_d); fprintf(stdout, " sex = %s\n", lbl_sex_d); fprintf(stdout, " date_exam = %s\n", lbl_date_exam_d); fprintf(stdout, "\n"); fprintf(stdout, "classes:\n"); for (long i = 0; i < num_classes_d; i++) { fprintf(stdout, " labels[%3ld] = %s\n", i, labels_d[i]); } fprintf(stdout, "\n"); // print data // fprintf(stdout, "data:\n"); for (long i = 0; i < MAX_DEBUG_OUTPUT; i++) { if (id_exam_d[i] > (long)0) { fprintf(stdout, " %ld, %ld, %ld, %s %s:", id_exam_d[i], id_patient_d[i], age_d[i], sex_d[i], date_exam_d[i]); for (long j = 0; j < num_classes_d; j++) { fprintf(stdout, " %ld", annotations_d[i][j]); } fprintf(stdout, "\n"); } } fprintf(stdout, "\n"); // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: done printing db [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, id_a); } // exit gracefully // return true; } // method: print_header_tnmg // // arguments: // char* id: a string to print to identify the data // FILE* fp: output file pointer where print is directed // // return: a boolean value indicating status // bool Wfdb::print_header_tnmg(const char* id_a, FILE* fp_a) { // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: printing header [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, id_a); } // print the header metadata // fprintf(stdout, "hea file metadata: %s\n", id_a); fprintf(stdout, " fname = %s\n", hdr_fname_d); fprintf(stdout, " exam_id = %ld\n", hdr_id_exam_d); fprintf(stdout, " num channels = %ld\n",hdr_num_channels_d); fprintf(stdout, " sample frequency = %f\n",hdr_sample_frequency_d); fprintf(stdout, " num samples per channel = %ld\n", hdr_num_samples_per_channel_d); fprintf(stdout, " start_time = %s\n", hdr_start_time_d); fprintf(stdout, " exam_date = %s\n", hdr_exam_date_d); // print the channel data // fprintf(stdout, "hea file channel data: %s\n", id_a); for (long i = 0; i < hdr_num_channels_d; i++) { fprintf(stdout, " channel %ld:\n", i); fprintf(stdout, " fname = %s\n", hdr_fnames_d[i]); fprintf(stdout, " id_exam = %ld\n", hdr_fid_exam_d[i]); fprintf(stdout, " adc_nbits = %ld\n", hdr_adc_nbits_d[i]); fprintf(stdout, " adc_gain = %.4f\n", hdr_adc_gain_d[i]); fprintf(stdout, " units = %s\n", hdr_units_d[i]); fprintf(stdout, " adc_resolution = %ld\n", hdr_adc_resolution_d[i]); fprintf(stdout, " adc_offset = %0.4f\n", hdr_adc_offset_d[i]); fprintf(stdout, " initial value = %ld\n", hdr_initial_value_d[i]); fprintf(stdout, " checksum = %ld\n", hdr_checksum_d[i]); fprintf(stdout, " blocksize = %ld\n", hdr_block_size_d[i]); fprintf(stdout, " channel_label = %s\n", hdr_channel_label_d[i]); } // exit gracefully // return true; } // method: print_data_tnmg // // arguments: // char* id: a string to print to identify the data // FILE* fp: output file pointer where print is directed // // return: a boolean value indicating status // bool Wfdb::print_data_tnmg(const char* id_a, FILE* fp_a) { // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: printing data [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, id_a); } // print the signal data // fprintf(fp_a, "signal data: %s\n", id_a); for (long i = 0; i < hdr_num_channels_d; i++) { fprintf(fp_a, " channel %ld:\n", i); for (long j = 0; j < MAX_DEBUG_OUTPUT; j++) { fprintf(fp_a, " sig[%4ld][%4ld] = %7.0f\n", i, j, sig_d[i][j]); } } // display debug message // if (dbgl_d > Dbgl::BRIEF) { fprintf(fp_a, "%s (line: %d) %s: done printing data [%s] ", __FILE__, __LINE__, __PRETTY_FUNCTION__, id_a); } // exit gracefully // return true; } //***************************************************************************** // // public methods: check id methods // //***************************************************************************** // method: check_ids // // arguments: // char* iname: the input header filename // FILE* fp: output file pointer where print is directed // // return: a long value containing the exam id (or -1 if not found) // long Wfdb::check_ids(const char* iname_a) { // read the header file // if (load_header_tnmg(iname_a) == false) { fprintf(stdout, "Error: %s (line: %d) %s: error loading header\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); } if (dbgl_d > Dbgl::BRIEF) { print_header_tnmg("hea"); } // find the patient record in the annotation data // long indx = hdr_id_exam_d; if (id_exam_d[indx] >= 0) { return id_exam_d[indx]; } // exit gracefully // return (long)-1; } // method: get_annotation // // arguments: // long id_a: the input id // // return: a pointer to the annotation, or a NULL if it doesn't exist // long* Wfdb::get_annotation(const long id_a) { // return the annotation if it exists // if (id_exam_d[id_a] >= 0) { return annotations_d[id_a]; } // exit (un)gracefully // return (long*)NULL; } //***************************************************************************** // // public methods: make edf methods // //***************************************************************************** // method: make_edf // // arguments: // char* oname: the output edf filename // char* iname: the input dat filename // // return: a boolean value indicating status // bool Wfdb::make_edf(const char* oname_a, const char* iname_a) { // look for a header file in the same directory as the input // char hfname[Itgl::MAX_LSTR_LENGTH]; edf_d.create_filename(hfname, iname_a, Itgl::EMPTY, EXT_HEA, Itgl::EMPTY, false); if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: header filename = [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, hfname); } // load the header file // if (load_header_tnmg(hfname) == false) { fprintf(stdout, "Error: %s (line: %d) %s: error loading header [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, hfname); } if (dbgl_d > Dbgl::NONE) { print_header_tnmg("header"); } // load the signal data // if (load_data_tnmg(iname_a) == false) { fprintf(stdout, "Error: %s (line: %d) %s: error loading data [%s]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, iname_a); } if (dbgl_d > Dbgl::NONE) { print_data_tnmg("data"); } // find the patient record in the annotation data // long indx = hdr_id_exam_d; if (id_exam_d[indx] < 0) { fprintf(stdout, "Error: %s (line: %d) %s: %s [%s,%ld,%ld]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, "patient not found", iname_a, indx, id_patient_d[indx]); return false; } //--------------------------------------------------------------------------- // // create a header: this is a bit tedious as we have to populate a // number of fields. // //--------------------------------------------------------------------------- if (dbgl_d > Dbgl::NONE) { fprintf(stdout, "creating header...\n"); } // (1) version // edf_d.set_hdr_version(Edf::EDF_VERS); // (2) local patient information (lpti) // char tmp_string[Itgl::MAX_SSTR_LENGTH + 1]; char odate1[Itgl::MAX_SSTR_LENGTH + 1]; char odate2[Itgl::MAX_SSTR_LENGTH + 1]; sprintf(tmp_string, "%ld", id_patient_d[indx]); edf_d.set_hdr_lpti_patient_id(tmp_string); edf_d.set_hdr_lpti_gender(sex_d[indx]); edf_d.set_hdr_lpti_dob(EDF_BLANK); edf_d.set_hdr_lpti_full_name(EDF_BLANK); sprintf(tmp_string, "%ld", age_d[indx]); edf_d.set_hdr_lpti_age(tmp_string); // (3) local recording information (lrci) // edf_d.set_hdr_lrci_start_date_label("Startdate"); convert_date(odate1, odate2, hdr_exam_date_d); edf_d.set_hdr_lrci_start_date(odate1); sprintf(tmp_string, "%ld", hdr_id_exam_d); edf_d.set_hdr_lrci_eeg_id(tmp_string); edf_d.set_hdr_lrci_tech(Itgl::EMPTY); edf_d.set_hdr_lrci_machine(Itgl::EMPTY); // (4) general header information (ghdi) // sprintf(tmp_string, "%s", odate2); edf_d.set_hdr_ghdi_start_date(tmp_string); convert_time(tmp_string, hdr_start_time_d); edf_d.set_hdr_ghdi_start_time(tmp_string); long hsize = EDF_HSIZE + hdr_num_channels_d * EDF_HSIZE; edf_d.set_hdr_ghdi_hsize(hsize); edf_d.set_hdr_ghdi_file_type(EDF_BLANK); edf_d.set_hdr_ghdi_reserved(EDF_BLANK); // set the number of records: // do this by setting the record size to 1 sec and computing // the number of records // long rec_size = Itgl::gcd(hdr_num_samples_per_channel_d, (long)round(hdr_sample_frequency_d)); float dur_rec = rec_size / hdr_sample_frequency_d; long num_recs = hdr_num_samples_per_channel_d / rec_size; edf_d.set_hdr_ghdi_dur_rec(dur_rec); edf_d.set_hdr_ghdi_num_recs(num_recs); edf_d.set_hdr_ghdi_nsig_rec(hdr_num_channels_d); if (dbgl_d > Dbgl::BRIEF) { fprintf(stdout, "%s (line: %d) %s: [%ld %f %f] [%ld %ld]\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, hdr_num_samples_per_channel_d, hdr_sample_frequency_d, dur_rec, rec_size, num_recs); } // (5a) channel-specific data: labels // char* labels[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { labels[i] = new char[strlen(hdr_channel_label_d[i]) + 1]; strcpy(labels[i], hdr_channel_label_d[i]); } edf_d.set_hdr_chan_labels(labels, hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { delete [] labels[i]; } // (5b) channel-specific data: trans_types // char* ttypes[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { ttypes[i] = new char[strlen(Itgl::EMPTY) + 1]; strcpy(ttypes[i], Itgl::EMPTY); } edf_d.set_hdr_chan_trans_types(ttypes, hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { delete [] ttypes[i]; } // (5c) channel-specific data: phys_dim // char* physd[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { physd[i] = new char[strlen(hdr_units_d[i]) + 1]; strcpy(physd[i], hdr_units_d[i]); } edf_d.set_hdr_chan_phys_dim(physd, hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { delete [] physd[i]; } // (5d) channel-specific data: phys_min and phys_max // // To match the physical voltage values used by various open // source software, we have to set phys_min and phys_max as follows: // // phys_max = 32767.0 / adc_gain // phys_min = -phys_max // dig_max = 32767.0 // dig_min = -dig_max // // This allows the floating-point values in the Edf file to match // the floating-point values from the cardiology software (wfdb). // double physm[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { physm[i] = (float)EDF_DMAX / hdr_adc_gain_d[i]; } edf_d.set_hdr_chan_phys_max(physm, hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { physm[i] = -1.0 * physm[i]; } edf_d.set_hdr_chan_phys_min(physm, hdr_num_channels_d); // (5e) channel-specific data: dig_min and dig_max // long digm[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { digm[i] = EDF_DMAX; } edf_d.set_hdr_chan_dig_max(digm, hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { digm[i] = (long)-1 * digm[i]; } edf_d.set_hdr_chan_dig_min(digm, hdr_num_channels_d); // (5f) channel-specific data: prefilt // char* prefilt[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { prefilt[i] = new char[strlen(Itgl::EMPTY) + 1]; strcpy(prefilt[i], Itgl::EMPTY); } edf_d.set_hdr_chan_prefilt(prefilt, hdr_num_channels_d); for (long i = 0; i < hdr_num_channels_d; i++) { delete [] prefilt[i]; } // (5g) channel-specific data: rec_size // long recsz[hdr_num_channels_d]; for (long i = 0; i < hdr_num_channels_d; i++) { recsz[i] = rec_size; } edf_d.set_hdr_chan_rec_size(recsz, hdr_num_channels_d); if (dbgl_d > Dbgl::NONE) { fprintf(stdout, "done creating header...\n"); } //--------------------------------------------------------------------------- // // write the file // //--------------------------------------------------------------------------- if (dbgl_d > Dbgl::NONE) { fprintf(stdout, "writing the edf file...\n"); } // write the edf file: note that we write it as an unscaled signal // if (!edf_d.write_edf(sig_d, oname_a, false)) { fprintf(stdout, "Error: %s (line: %d) %s: error writing data\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); exit(EXIT_FAILURE); } if (dbgl_d > Dbgl::NONE) { fprintf(stdout, "done writing the edf file...\n"); } // exit gracefully // return true; } // // end of file