// file: $(NEDC_NFC)/util/cpp/nedc_cardio_make_edf/nedc_cardio_make_edf_edf.h // // Revision History: // // 20240305 (JP): initial version // // make sure definitions are only made once // #ifndef NEDC_CARDIO_MAKE_EDF #define NEDC_CARDIO_MAKE_EDF // system include files: // // local include files // #include #include // define the help and usage messages // #define NEDC_USAGE \ "$NEDC_NFC/util/cpp/nedc_cardio_make_edf/nedc_cardio_make_edf.usage" #define NEDC_HELP \ "$NEDC_NFC/util/cpp/nedc_cardio_make_edf/nedc_cardio_make_edf.help" // define the program options: // note that you cannot separate them by spaces // #define ARG_DB_NAME "db" #define ARG_DB "db,d" #define ARG_OEXT_NAME "ext" #define ARG_OEXT "ext,e" #define ARG_ODIR_NAME "odir" #define ARG_ODIR "odir,o" #define ARG_RDIR_NAME "rdir" #define ARG_RDIR "rdir,r" // define default parameter file // #define DEF_DB_FILE "$ISIP/data/tnmg_code/v1.0.0/DOCS/annotations.csv" #define DEF_OUTPUT_FILE_EXTENSION "edf" // declare the file extension for a header file // #define EXT_HEA (char*)"hea" // declare important constants // #define SSTR_LENGTH (long)29 // length of a short string #define EDF_HSIZE (long)256 // header block size (fixed) #define EDF_RECSIZE (long)22 // record size #define EDF_BLANK (char*)"X" // blank field value #define EDF_UNITS (char*)"mV" // voltage scale #define EDF_DMAX (long)32767 // Edf digital max #define MAX_NUM_CHANNELS (long)19 // max num signal channels #define MAX_NUM_SAMPLES_PER_CHANNEL (long)9999 // max num samples per channel #define MAX_NUM_CLASSES (long)9 // max num classes #define MAX_NUM_LABELS (long)49 // max number of labels #define MAX_DEBUG_OUTPUT (long)10 // max number to print // define information to locate annotations // #define ANN_OFFSET (long)4 // location of annotations #define MD_SIZE (long)5 // size of non-annotations // DB: a structure to hold the database of patient information // typedef struct dbr { long id_exam; long id_patient; long age; char sex[SSTR_LENGTH]; long annotations[MAX_NUM_CLASSES]; char date_exam[SSTR_LENGTH]; } DBR; typedef struct db { long num_patients; long num_classes; char lbl_id_exam[SSTR_LENGTH]; char lbl_id_patient[SSTR_LENGTH]; char lbl_age[SSTR_LENGTH]; char lbl_sex[SSTR_LENGTH]; char* labels[MAX_NUM_CLASSES]; char lbl_date_exam[SSTR_LENGTH]; DBR* records; } DB; // CDATA: a structure to hold the per-channel information in the .txt file // typedef struct cdata { char fname[Itgl::MAX_LSTR_LENGTH]; long id_exam; long adc_nbits; float adc_gain; char units[SSTR_LENGTH]; long adc_resolution; float adc_offset; long initial_value; long checksum; long block_size; char channel_label[SSTR_LENGTH]; } CDATA; // FData: a structure that encapsulates all the information in the *.hea file. // // Note: to make this easier for our novice C++ programmers, we are using // fixed data allocations. This can be easily changed to dynamic memory // allocation. // typedef struct fdata { // declare space for the metadata // long id_exam; long id_patient; long age; char sex[SSTR_LENGTH]; char exam_date[SSTR_LENGTH]; char start_time[SSTR_LENGTH]; long num_channels; float sample_frequency; long num_samples_per_channel; // declare space for the per-channel metadata // CDATA data[MAX_NUM_CHANNELS]; // declare space for the signal data // VVectorDouble sig; } FDATA; // define the main function that processes a single file // bool nedc_cardio_make_edf(const char* oname, const char* iname, DB& db, FILE* fp = stdout); // define TNMG-specific functions // bool load_db_tnmg(DB& db, const char* fname); bool load_data_tnmg(FDATA& d, const char* fname_hea, const char* fname_dat); bool print_db_tnmg(DB& db, FILE* fp, const char* id = (char*)NULL); bool print_data_tnmg(FDATA d, FILE* fp, const char* id = (char*)NULL); // define general purpose functions // bool convert_date(char* odate1, char* odate2, char* idate); bool convert_time(char* otime, char* itime); // end of include file // #endif