/* ************************************************************************************* */ /* */ /* eval_st.c and geval_st.c */ /* */ /* F. Jager, A. Udovc and A. Smrdel 5 September 1997 */ /* Last revised: 12 September 2004 */ /* */ /* EVAL_ST (Tool to EVALuate performance of transient ST segment episode detection */ /* algorithms with graphic user interface), Version 2.0 */ /* */ /* -------------------------------------------------------------------------------- */ /* */ /* Copyright (C) 1997 Franc Jager, Ales Udovc and Ales Smrdel */ /* */ /* This program is free software; you can redistribute it and/or modify it under */ /* the terms of the GNU General Public License as published by the Free Software */ /* Foundation; either version 2 of the License, or (at your option) any later */ /* version. */ /* */ /* This program is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS */ /* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License along with */ /* this program; if not, write to the Free Software Foundation, Inc., 59 Temple */ /* Place - Suite 330, Boston, MA 02111-1307, USA. */ /* */ /* You may contact the author by e-mail (franc.jager@fri.uni-lj.si) or postal */ /* mail (Faculty of Computer and Information Science, Trzaska 25, 1000 Ljubljana, */ /* Slovenia). For updates to this software, please visit http://mimi.fri.uni-lj.si */ /* and PhysioNet http://www.physionet.org/ */ /* */ /* ************************************************************************************* */ /* MOTIF SECTIONS realizes graphic user interface */ #define motif 0 /* 1 - Motif graphic environment code included for compiling */ /* 0 - Graphic user interface not included -> Command line input */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if (motif) /* MOTIF SECTION - includes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /* END OF MOTIF SECTION */ #define ISHEMIC 0 /* Ischemic ST episode */ #define NON_ISHEMIC -1 /* Non-ischemic heart-rate related ST episode */ #define MAXEPI 1000 /* Maximum number of episodes in a record */ #define OVER_EX 0 /* Episode overlaps extrema */ #define OVER_HF 1 /* Episode overlaps one half of defining episode */ #define MISSED 3 /* Episode is missed */ #define OVER_BOTH 2 /* Episode fit both criteria */ #define NO_MATTER 5 /* Ischemic and non-ischemic episodes are equal */ #define IMPORTANT 6 /* Differentiate between ischemia and non-ischemia */ #define MAXEX 10 /* Maximum number of extrema */ #define YES 1 /* Success */ #define NO 0 /* Not success */ #define MAXREC 200 /* Maximum number of records */ #define FACTOR 4 /* Time multiplication factor */ #define MAXIMAL 50000 /* Maximum number of all episodes */ #define EXACT 1000 /* Dimension of arrays for bootstrap results */ #define NUMRES 9 /* Number of aggregate statistics */ #define NAME_LEN 224 /* Maximum file name length */ #define LEN_SHORTER 192 #define MAXI 32767 #if (motif) /* MOTIF SECTION - constants */ #define W_WIDTH 750 /* Width of main window widget */ #define W_HEIGHT 675 /* Height of main window widget */ #define NSTEP 10 /* Step during drawing of graph */ #define YSTEP 11 /* Step in y-axis during drawing of graph */ #define XSTEP 20 /* Step in x-axis during drawing of graph */ #endif /* END OF MOTIF SECTION */ int Test(); int Test_out(); int Single(); void fill_array(); void in_episode(); void in_record(); void init_record(); void convert_time(); long minimum(); long maximum(); long matching(); int overlap(); void determine_status(); void initial(); void fill_record(); double sensitivity(); double ish_duration(); double gross_statistic(); double average_statistic(); double gross_duration(); double average_duration(); double mean(); double st_variance(); double linear_regression(); double p100(); double max_el(); double e95(); double corr_coefficient(); void str_delete(); void write_matrix(); void write_gross_stat(); void write_episode_report(); void choose_base(); void copy_array(); void ini(); void init_episode(); void count_res(); double confidence_limits(); double minmax(); void store_result(); void write_parameter(); void all_records(); void st_deviation(); void bootstrap(); void fill_ep_lead(); int write_single(); int write_raw(); int write_rbr(); int write_rbr_file(); int write_boot1(); #if (motif) /* MOTIF SECTION - function prototypes */ void CreateApplication(); void InitDraw(); void CBDraw(); void CBConst_1(); void CBConst_2(); void CBSet_const_1(); void CBCancel_const_1(); void CBFile(); void CBFile_select(); void CBFile_cancel(); void CBHelp(); void CBIshemic(); void CBSt(); void CBMode_message(); void CBEvaluate_message(); void CBAll(); void CBExtrema(); void CBExamine(); void CBBoot(); void CBSingle(); void CBRead_record(); void CBFile_message(); void CBDraw1(); void CBFreeze(); void CBDifferences(); void Draw_graph(); void Draw_extrema_results(); void Draw_reg_line(); void EStats(); #endif /* END OF MOTIF SECTION */ typedef struct { int x; int y; int ann; int meas; int diff; double percent; char name[10]; int number; int lead; } coor; typedef struct { int hour; int min; int sec; int msec; } times; typedef struct { long episode; char rec[10]; int lead; long time; int meas; int annot; double diff; double percent; } ebe_out; typedef struct { long onset; /* Beginning of episode */ int num_ext; /* Number of extrema */ long ext_pos[20]; /* Array of positions of ST level extrema */ long ext_val[20]; /* Array of values of ST level extrema */ int ext_lead[20]; /* Array of leads of extrema */ long offset; /* End of episode */ int status; /* Status of episode after the matching test */ int tip; /* Type of episode: ischemic or non-ischemic heart-rate related */ int match; /* Type of match */ long overlp; /* Duration of episode overlap */ } episode; typedef struct { char rec[LEN_SHORTER]; int st; int is; } opn_rec; typedef struct { int num_epi; /* Number of episodes in record */ int a; /* Ischemic - ischemic */ int b; /* Ischemic - non-ischemic */ int c; /* Ischemic - missed */ int d; /* Non-ischemic - ischemic */ int e; /* Non-ischemic - non-ischemic */ int f; /* Non-ischemic - missed */ int tp; /* True positive events */ int fn; /* False negatives or False positives */ double se; /* Sensitivity - positive predictivity */ double duration; /* Ischemia duration */ double overlap; /* Overlap */ double ish_dur; /* Total duration of ischemia */ double percent; /* Percent of ischemia */ double ase; /* Average sensitivity */ double aish_dur; /* Average duration of ischemia */ } record; int REC_COUNT=0; int MAXR=0; ebe_out webe[10000]; long nrebe=0; opn_rec evaluated[MAXREC]; int tot_rec=0; episode epialg [MAXEPI]; /* Algorithm episodes */ episode epiref [MAXEPI]; /* Reference episodes */ episode ep_lead0 [MAXEPI]; /* Reference episodes, lead 0 */ episode ep_lead1 [MAXEPI]; /* Reference episodes, lead 1 */ episode ep_lead2 [MAXEPI]; /* Reference episodes, lead 2 */ record recref[MAXREC]; /* Reference records */ record recalg[MAXREC]; /* Algorithm records */ coor st_tab[MAXIMAL]; /* ST level measurements */ record allref,allalg; /* Overall statistics */ double hist_gse[100]; /* Histogram, gross sensitivity */ double hist_gpn[100]; /* Histogram, gross posit. predictivity */ double hist_ase[100]; /* Histogram, average sensitivity */ double hist_apn[100]; /* Histogram, average posit. predictivity */ double hist_gdurse[100]; /* Histogram, gross duration sensitivity */ double hist_adurse[100]; /* Histogram, average duration sensitivity */ double hist_gdurpn[100]; /* Histogram, gross duration positive predictivity */ double hist_adurpn[100]; /* Histogram, average duration positive predictivity */ double gsensr[NUMRES]; /* Confidence intervals */ double gpredr[NUMRES]; /* for bootstrap statistics */ double asensr[NUMRES]; double apredr[NUMRES]; double gdurser[NUMRES]; double adurser[NUMRES]; double gdurpr[NUMRES]; double adurpr[NUMRES]; int extepi; /* Number of episodes */ double mvalue; /* Mean value of ST level deviations */ double stand_dev; /* Standard deviation of ST level deviations */ double corr; /* Correlation coefficient */ double k; /* Coefficient of regression line */ double n1; /* Intersection of regression line at x=0 */ double phund; /* Percentage of measurements, p100 */ double enfive; /* Value of error which 95% of measurements do not exceed */ int diff = NO_MATTER; /* Mode */ long int trials1 = 10000; /* Number of bootstrap trials */ char dat1[NAME_LEN]; /* File name of reference record */ char dat2[NAME_LEN]; /* File name of algorithm record */ char path[NAME_LEN]; /* File path */ char rec_name[NAME_LEN]; char alg_name[NAME_LEN]; char ref_name[NAME_LEN]; char file_name[NAME_LEN]; char hname[NAME_LEN]; char namealg[NAME_LEN]; char *nam1; char *nam2; int all_valid=0; int dev_valid=0; char writeX[250000]; /* 85 * 200 * 14 */ int bootvalid = 0; int extremavalid = 0; int rawvalid = 0; long DUR_REC=0; double DUR_TOT=0; long REC_TOT=0; int examine_valid=0; char filename_0P[NAME_LEN], filename_0R[NAME_LEN],recName[NAME_LEN]; #if (motif) /* MOTIF SECTION - widgets, variables */ int filevalid = 0; /* File indicator */ int boti=0,bots=0; int rawi=0,raws=0; int exti=0,exts=0; Display *display; XtAppContext app_context; Widget toplevel; /* Application shell */ GC empty_gc; GC wall_gc; Font font; Widget workarea, sb; /* Workarea and FileSelectionBox */ Widget dialog_bts,dialog_raw,dialog_stt,dialog_ext,dialog_ebe,dialog_hlp,dialog_smr; Widget text_stt; Widget cb1; Widget mb, eb, fbb; /* Message windows */ int bw = 0; XmString ModeString; Widget mess_w; Pixmap pixmap; int numfreeze = 0; /* Counter of freeze windows */ int cur = 1; /* Index of current text compare window */ #endif /* END OF MOTIF SECTION */ /* ************************************************************************************* */ /* Functions */ /* Extracts the record name from the string */ char *GetName(char name[NAME_LEN]) { char n2[NAME_LEN],n3[NAME_LEN]; int i,j; j=strlen(name); while ((j>0) && (name[j]!='/')) j--; if (nam1!=NULL) free(nam1); nam1=(char *) malloc(sizeof(char)*(strlen(name)-j+4)); if (j==0) strcpy(nam1,name); else strcpy(nam1,&name[j+1]); return (nam1); } /* Extracts the database and the algorithm name from the string */ char *RemoveDot(char name[NAME_LEN]) { char n2[NAME_LEN],n3[NAME_LEN]; int i,j; j=strlen(name); i=0; while ((i 0) sprintf(dat,"Linear regression : %4.3lf M + %4.3lf [uV] \n", k, n1); else sprintf(dat,"Linear regression : %4.3lf M %4.3lf [uV]\n", k, n1); strcat(writeX,dat); sprintf(dat,"p100 = %4.3lf [%%] ", phund); strcat(writeX,dat); sprintf(dat,"e95 = %4.3lf [uV]\n\n",enfive); strcat(writeX,dat); sprintf(dat,"Episode by episode report\n"); strcat(writeX,dat); sprintf(dat,"Episode Record Lead Time [h:m:s] "); strcat(writeX,dat); sprintf(dat," Measured [uV] Annotated [uV] Difference [uV] "); strcat(writeX,dat); sprintf(dat,"Diff/Annotated [%%]\n"); strcat(writeX,dat); for (l=0;l= 50 %% of true episode\n"); strcat(writeX,dat); break; case 2 : sprintf(dat,"Match : overlaps >= 50 %% of true episode and extrema\n"); strcat(writeX,dat); break; case 3 : sprintf(dat,"Match : missed episode\n"); strcat(writeX,dat); break; }; convert_time(FACTOR*ref.overlp,&cl); sprintf(dat,"Overlap time : %2d:%02d:%02d ", cl.hour,cl.min,cl.sec); strcat(writeX,dat); sprintf(dat," Number of extrema : %4d\n",ref.num_ext ); strcat(writeX,dat); } /* Calls the function for writing episode statistics for each episode */ void Xwrite_episodes(refi,d) episode refi[MAXEPI]; int d; { int i; for ( i = 0; refi[i].offset > 0; i++ ) Xwr_episode(refi[i],d,i); } /* Writes bootstrap statistics to the buffer */ void Xwrite_parameter(i) int i; { char dat[NAME_LEN]; if ( diff == IMPORTANT ) { sprintf(dat,"IE Sensitivity = %6.2lf %% [g] %6.2lf %% [a] ",gsensr[i],asensr[i]); strcat(writeX,dat); sprintf(dat,"IE PositPredict = %6.2lf %% [g] %6.2lf %% [a]\n",gpredr[i],apredr[i]); strcat(writeX,dat); sprintf(dat,"ID Sensitivity = %6.2lf %% [g] %6.2lf %% [a] ",gdurser[i],adurser[i]); strcat(writeX,dat); sprintf(dat,"ID PositPredict = %6.2lf %% [g] %6.2lf %% [a]\n",gdurpr[i],adurpr[i]); strcat(writeX,dat); } else { sprintf(dat,"SE Sensitivity = %6.2lf %% [g] %6.2lf %% [a] ",gsensr[i],asensr[i]); strcat(writeX,dat); sprintf(dat,"SE PositPredict = %6.2lf %% [g] %6.2lf %% [a]\n",gpredr[i],apredr[i]); strcat(writeX,dat); sprintf(dat,"SD Sensitivity = %6.2lf %% [g] %6.2lf %% [a] ",gdurser[i],adurser[i]); strcat(writeX,dat); sprintf(dat,"SD PositPredict = %6.2lf %% [g] %6.2lf %% [a]\n",gdurpr[i],adurpr[i]); strcat(writeX,dat); } } /* Writes bootstrap statistics to the buffer, too */ void Xwrite_boot() { char dat[NAME_LEN]; sprintf(dat,"Bootstrap method Number of trials : %6ld\n",trials1); strcpy(writeX,dat); if ( diff == IMPORTANT ) sprintf(dat,"Ischemic and Heart-rate related episodes are differentiated\n\n"); else sprintf(dat,"Ischemic and Heart-rate related episodes are considered as episodes of single type\n\n"); strcat(writeX,dat); sprintf(dat," 5 %% confidence limits :\n"); strcat(writeX,dat); Xwrite_parameter(0); sprintf(dat,"\n16 %% confidence limits :\n"); strcat(writeX,dat); Xwrite_parameter(1); sprintf(dat,"\n84 %% confidence limits :\n"); strcat(writeX,dat); Xwrite_parameter(2); sprintf(dat,"\n95 %% confidence limits :\n"); strcat(writeX,dat); Xwrite_parameter(3); sprintf(dat,"\nMinimum statistic :\n"); strcat(writeX,dat); Xwrite_parameter(5); sprintf(dat,"\nMaximum statistic :\n"); strcat(writeX,dat); Xwrite_parameter(4); sprintf(dat,"\nMedian :\n"); strcat(writeX,dat); Xwrite_parameter(6); sprintf(dat,"\nMean :\n"); strcat(writeX,dat); Xwrite_parameter(7); sprintf(dat,"\nMean - 5%% confidence limits :\n"); strcat(writeX,dat); Xwrite_parameter(8); } /* Writes the ST segment deviation measurement statistics to the buffer */ void Xwrite_extrema() { char dat[NAME_LEN]; int l; times cl; sprintf(dat,"Extrema statistics\n"); strcat(writeX,dat); if ( diff == IMPORTANT ) sprintf(dat,"Ischemic and Heart-rate related episodes are differentiated\n\n"); else sprintf(dat,"Ischemic and Heart-rate related episodes are considered as episodes of single type\n\n"); strcat(writeX,dat); sprintf(dat,"Summary statistics\n"); strcat(writeX,dat); sprintf(dat,"Mean = %4.3lf [uV] ",mvalue); strcat(writeX,dat); sprintf(dat,"Standard deviation = %4.3lf [uV]\n",stand_dev); strcat(writeX,dat); sprintf(dat,"Correlation coefficient = %4.3lf ",corr); strcat(writeX,dat); if (n1 > 0) sprintf(dat,"Linear regression : %4.3lf M + %4.3lf [uV] \n", k, n1); else sprintf(dat,"Linear regression : %4.3lf M %4.3lf [uV]\n", k, n1); strcat(writeX,dat); sprintf(dat,"p100 = %4.3lf [%%] ", phund); strcat(writeX,dat); sprintf(dat,"e95 = %4.3lf [uV]\n\n",enfive); strcat(writeX,dat); sprintf(dat,"Episode by episode report\n"); strcat(writeX,dat); sprintf(dat,"Episode Record Lead Time [h:m:s] "); strcat(writeX,dat); sprintf(dat," Measured [uV] Annotated [uV] Difference [uV] "); strcat(writeX,dat); sprintf(dat,"Diff/Annotated [%%]\n"); strcat(writeX,dat); for (l=0;levent->xexpose.display, pixmap, cbs->window, empty_gc, 0, 0, W_WIDTH, W_HEIGHT, 0, 0); } /* Draws a line in the drawing area, defined with two points */ void Draw_line (x1, y1, x2, y2) int x1, y1, x2, y2; { XDrawLine (XtDisplay (workarea), pixmap, empty_gc, x1, y1, x2, y2); } /* Draws a rectangle in the drawing area, defined with two points */ void Draw_rectangle(x, y, width, height) int x, y; unsigned int width, height; { XDrawRectangle (XtDisplay (workarea), pixmap, empty_gc, x, y, width, height); } /* Writes a string in the drawing area*/ void Draw_text (string, x, y ) char string[NAME_LEN]; int x, y; { XDrawString (XtDisplay (workarea), pixmap, empty_gc, x, y, string, strlen(string)); } /* Writes a string using specified font in the drawing area*/ void Draw_text_font (string, x, y, shape ) char string[NAME_LEN]; int x, y; char shape[LEN_SHORTER]; { font = XLoadFont (XtDisplay (workarea), shape); XSetFont (XtDisplay (workarea), empty_gc, font); XDrawString (XtDisplay (workarea), pixmap, empty_gc, x, y, string, strlen(string)); } /* Draws a 3x3 matrix in the drawing area */ void Draw_matrix_3x3 ( x, y, sizex, sizey, string ) int x, y; int sizex, sizey; char string[LEN_SHORTER]; { int i,x1,x2,x3,x4,x5; int ytab[6]; x1 = 0.15 * sizex + x; x2 = 0.4 * sizex + x; x3 = 0.6 * sizex + x; x4 = 0.8 * sizex + x; x5 = sizex + x; for (i = 1; i <= 5; i++) ytab[i] = y + i * ( sizey / 5 ); Draw_text_font ("Algorithm", x3, ytab[1]-5, "8x13bold"); Draw_text ("matrix", x+(x2-x)/2-20, ytab[2] - 5); Draw_text (string, x+(x2-x)/2-3-58, ytab[1]); Draw_text_font (" Ref.", x+3, ytab[4]-5,"6x13bold"); Draw_line (x, y, x5, y); Draw_line (x2, ytab[1], x5, ytab[1]); Draw_line (x, ytab[2], x5, ytab[2]); Draw_line (x1, ytab[3], x5, ytab[3]); Draw_line (x1, ytab[4], x5, ytab[4]); Draw_line (x, ytab[5], x5, ytab[5]); Draw_line (x, y, x, ytab[5]); Draw_line (x1, ytab[2], x1, ytab[5]); Draw_line (x2, y, x2, ytab[5]); Draw_line (x3, ytab[1], x3, ytab[5]); Draw_line (x4, ytab[1], x4, ytab[5]); Draw_line (x5, y, x5 , ytab[5]); Draw_text_font ("Ischemic", x2+(x3-x2)/2-5-15, ytab[2]-5, "6x13"); Draw_text ("HR related", x3+(x4-x3)/2-21-10, ytab[2]-5); Draw_text ("Not epis", x4+(x5-x4)/2-21, ytab[2]-5); Draw_text ("Ischemic", x1+(x2-x1)/2-5-15, ytab[3]-5); Draw_text ("HR related", x1+(x2-x1)/2-21-10, ytab[4]-5); Draw_text ("Not epis", x1+(x2-x1)/2-21, ytab[5]-5); } /* Draws a 2x2 matrix in the drawing area */ void Draw_matrix_2x2 ( x, y, sizex, sizey, string ) int x, y; int sizex, sizey; char string[LEN_SHORTER]; { int i,x1,x2,x3,x4; int ytab[5]; x1 = (int) (0.18 * sizex + x); x2 = (int) (0.5 * sizex + x); x3 = (int) (0.75 * sizex + x); x4 = (int) (sizex + x ); for (i = 1; i <= 4; i++) ytab[i] = y + i * ( sizey / 4 ); Draw_text_font ("Algorithm", x2+(x4-x2)/2-19-10, ytab[1]-5, "8x13bold"); Draw_text ("matrix", x+(x2-x)/2-20, ytab[2] - 10); Draw_text (string, x+(x2-x)/2-3-60, ytab[1]-5); Draw_text_font (" Ref.", x+5, ytab[3]+5,"6x13bold");/*fg-18*/ Draw_line (x, y, x4, y); Draw_line (x2, ytab[1], x4, ytab[1]); Draw_line (x, ytab[2], x4, ytab[2]); Draw_line (x1, ytab[3], x4, ytab[3]); Draw_line (x, ytab[4], x4, ytab[4]); Draw_line (x, y, x, ytab[4]); Draw_line (x1, ytab[2], x1, ytab[4]); Draw_line (x2, y, x2, ytab[4]); Draw_line (x3, ytab[1], x3, ytab[4]); Draw_line (x4, y, x4 , ytab[4]); Draw_text_font ("ST changes", x2+5, ytab[2]-5, "6x13"); Draw_text ("Not epis", x3+14, ytab[2]-5); Draw_text ("ST changes", x1+10, ytab[3]-5); Draw_text ("Not epis", x1+17, ytab[4]-5); } /* Writes a 3x3 sensitivity matrix values in the drawing area */ void Draw_Se_matrix_3x3 ( x, y, sizex, sizey, rec) int x, y, sizex, sizey; record rec; { char buf[LEN_SHORTER]; int i, x2; int ytab[6]; x2 = 0.4 * sizex + x; for (i = 1; i <= 5; i++) ytab[i] = y + i * ( sizey / 5 ); sprintf(buf, " %3d %3d %3d", rec.a, rec.b, rec.c); Draw_text_font(buf, x2, ytab[3]-5, "8x13"); sprintf(buf, " %3d %3d %3d", rec.d, rec.e, rec.f); Draw_text(buf, x2, ytab[4]-5); sprintf(buf, " - - -"); Draw_text(buf, x2, ytab[5]-5); } /* Writes a 3x3 positive predictivity matrix values in the drawing area */ void Draw_P_matrix_3x3 ( x, y, sizex, sizey, rec) int x, y, sizex, sizey; record rec; { char buf[LEN_SHORTER]; int i, x2; int ytab[6]; x2 = 0.4 * sizex + x; for (i = 1; i <= 5; i++) ytab[i] = y + i * ( sizey / 5 ); sprintf(buf, " %3d %3d -", rec.a, rec.d); Draw_text_font(buf, x2, ytab[3]-5, "8x13"); sprintf(buf, " %3d %3d -", rec.b, rec.e); Draw_text(buf, x2, ytab[4]-5); sprintf(buf, " %3d %3d -", rec.c, rec.f); Draw_text(buf, x2, ytab[5]-5); } /* Writes a 2x2 sensitivity matrix values in the drawing area */ void Draw_Se_matrix_2x2 ( x, y, sizex, sizey, rec) int x, y, sizex, sizey; record rec; { char buf[LEN_SHORTER]; int i, x2; int ytab[5]; x2 = 0.5 * sizex + x; for (i = 1; i <= 4; i++) ytab[i] = y + i * ( sizey / 4 ); sprintf(buf, " %3d %3d", rec.a+rec.b+rec.d+rec.e, rec.c+rec.f); Draw_text_font(buf, x2, ytab[3]-5, "8x13"); sprintf(buf, " - -"); Draw_text(buf, x2, ytab[4]-5); } /* Writes a 2x2 positive predictivity matrix values in the drawing area */ void Draw_P_matrix_2x2 ( x, y, sizex, sizey, rec) int x, y, sizex, sizey; record rec; { char buf[LEN_SHORTER]; int i, x2; int ytab[5]; x2 = 0.5 * sizex + x; for (i = 1; i <= 4; i++) ytab[i] = y + i * ( sizey / 4 ); sprintf(buf, " %3d -", rec.a+rec.b+rec.d+rec.e); Draw_text_font(buf, x2, ytab[3]-5, "8x13"); sprintf(buf, " %3d -", rec.c + rec.f); Draw_text(buf, x2, ytab[4]-5); } /* Draws frame of the ST segment deviation measurements graph in the drawing area */ void Draw_frame_graph ( x, y) int x, y; { int i,dist; char buf[LEN_SHORTER]; dist = -1000; Draw_line(x, y, x+44*NSTEP, y); for ( i = 0; i < 45; i++) { if ( i%2 == 0 ) Draw_line(x+i*NSTEP, y, x+i*NSTEP, y+10); else Draw_line(x+i*NSTEP, y, x+i*NSTEP, y+5); if ( i%4 == 0 ) { sprintf(buf, "%5d", dist); if ( dist == 0 ) Draw_text_font(buf, x+i*NSTEP-25, y+30, "6x13"); else Draw_text_font(buf, x+i*NSTEP-20, y+30, "6x13"); } dist += 50; } Draw_line( x, y, x, y-44*NSTEP); dist = -1000; for ( i = 0; i < 45; i++) { if ( i%2 == 0 ) Draw_line(x, y-i*NSTEP, x-10, y-i*NSTEP); else Draw_line(x, y-i*NSTEP, x-5, y-i*NSTEP); if ( i%4 == 0 ) { sprintf(buf, "%5d", dist); Draw_text(buf, x-5*NSTEP, y-i*NSTEP+5); } dist += 50; } Draw_text("Algorithm measurements [uV]", x+25*NSTEP, y+5*NSTEP-7); Draw_text("Reference measurements [uV]", x-5*NSTEP, y-46*NSTEP); Draw_text_font("ST segment deviation measurements", x+6*NSTEP, y-49*NSTEP, "8x13bold");/*fg-16*/ Draw_line(x+18*NSTEP, y, x+18*NSTEP, y-44*NSTEP); Draw_line(x+20*NSTEP, y, x+20*NSTEP, y-44*NSTEP); Draw_line(x+22*NSTEP, y, x+22*NSTEP, y-44*NSTEP); Draw_line(x, y-18*NSTEP, x+44*NSTEP, y-18*NSTEP); Draw_line(x, y-20*NSTEP, x+44*NSTEP, y-20*NSTEP); Draw_line(x, y-22*NSTEP, x+44*NSTEP, y-22*NSTEP); } /* Draws a cross at point x,y in the drawing area */ void Draw_vector( x, y) int x, y; { Draw_line( x-2, y-2, x+2, y+2); Draw_line( x-2, y+2, x+2, y-2); } /* Draws the ST segment deviation measurements graph in the drawing area */ void Draw_graph( x, y) int x, y; { int i, relx, rely; double factor; relx = x + 20 * NSTEP; /* Coordinate x */ rely = y - 20 * NSTEP; /* Coordinate y */ factor = NSTEP / 50.0; /* Ratio between 1uV and number of pixels */ for ( i = 1; i <= extepi; i++) { Draw_vector(( relx + (int)( st_tab[i].meas * factor)), ( rely - (int)( st_tab[i].ann * factor))); st_tab[i].x = relx + (int)( st_tab[i].meas * factor); st_tab[i].y = rely - (int)( st_tab[i].ann * factor); } } /* Writes the ST segment deviation measurements statistics in the drawing area */ void Draw_extrema_results( x, y) int x, y; { char buf[LEN_SHORTER]; sprintf(buf,"Num. of epis. = %6d ",extepi); Draw_text_font(buf, x, y - 20, "6x13bold"); sprintf(buf,"Mean [uV] = %6.2lf ",mvalue); Draw_text(buf, x + 240, y - 20 ); sprintf(buf,"St. dev. [uV] = %6.2lf ",stand_dev); Draw_text(buf, x, y-3); sprintf(buf,"Corr. coef. = %6.2lf",corr); Draw_text(buf, x + 240, y-3); if (n1 > 0) { sprintf(buf,"Ref. [uV] = %6.2lf Meas. + %4.2lf", k, n1); Draw_text(buf, x, y + 40-9); } else { n1 = -1 * n1; sprintf(buf,"Ref. [uV] = %6.2lf Meas. - %4.2lf", k, n1); Draw_text(buf, x, y + 40-9); n1 = -1 * n1; } sprintf(buf,"p(100uV) [%%] = %6.2lf ", phund); Draw_text(buf, x, y + 20-6); sprintf(buf,"e(95%) [uV] = %6.2lf ",enfive); Draw_text(buf, x + 240, y + 20-6); } /* Draws the regression line of the ST segment deviation measurements in the drawing area */ void Draw_reg_line(x, y ) int x, y; { int x1, x2; double y1, y2, factor; int relx, rely; relx = 20 * NSTEP + x; /* Coordinate system */ rely = y - 20 * NSTEP; x1 = -1000; /* T1(x1,y1) the first point */ y1 = k * x1 + n1; x2 = 1200; /* T2(x2,y2) the second point of regression line */ y2 = k * x2 + n1; factor = NSTEP / 50.0; /* Ratio between 1uV and number of pixels */ Draw_line(( relx + (int)( x1 * factor)), ( rely - (int)( y1 * factor)), ( relx + (int)( x2 * factor)), ( rely - (int)( y2 * factor))); } /* Writes the information of the selected ST segment deviation measurement in the drawing area */ void Draw_wished( x, y, tab) int x, y; coor tab; { char buf[LEN_SHORTER]; XFillRectangle (XtDisplay(workarea),pixmap,wall_gc,x,y-15,580,45); sprintf(buf, "record: %s", tab.name); Draw_text_font(buf, x, y, "6x13"); sprintf(buf, "annotated [uV]: %6d ", tab.ann); Draw_text(buf, x + 240, y); sprintf(buf, "lead: %3d", tab.lead); Draw_text(buf, x, y + 15 ); sprintf(buf, "number:%3d", tab.number); Draw_text(buf, x, y + 30 ); sprintf(buf, "measured [uV]: %6d ", tab.meas); Draw_text(buf, x + 240, y + 15); sprintf(buf, "difference [uV]: %6d ", tab.diff); Draw_text(buf, x + 240, y + 30); } /* Draws the coordinate axis for the bootstrap histograms in the drawing area */ void Draw_boot_axe( x, y, sizex, sizey) int x, y, sizex, sizey; { int i, x1, y1, oznx; float ozny; char buf[LEN_SHORTER]; x1 = x + sizex/5; y1 = y - sizey/8; Draw_line( x1, y1, x1+10*XSTEP, y1); Draw_line( x1, y1, x1, y1-10*YSTEP); ozny = 0.0; for ( i = 0; i <= 10; i++ ) { Draw_line( x1, y1-i*YSTEP, x1-2, y1-i*YSTEP); if ( i%2 == 0 ) { sprintf(buf, "%4.2f", ozny); Draw_text_font( buf, x1-30, y1-i*YSTEP+4, "6x10"); } ozny += 0.02; } Draw_text("probability", x1-40, y1-12*YSTEP+4+10); oznx = 0; for ( i = 0; i <= 10; i++ ) { Draw_line( x1+i*XSTEP, y1, x1+i*XSTEP, y1+2); if ( i%2 == 0 ) { sprintf(buf, "%3d", oznx); Draw_text(buf, x1+i*XSTEP-12, y1+15); } oznx += 10; } } /* Draws the bootstrap histograms in the drawing area */ void Draw_boot_hist( x, y, sizex, sizey, hist) int x, y, sizex, sizey; double hist[100]; { int i, x1, x2, y1; x1 = x + sizex/5; y1 = y - sizey/8; x2 = x1; for ( i = 0; i < 100; i++) { Draw_rectangle( x2, y1 - (int)( 550 * hist[i]), 2, (int)(550 * hist[i])); x2 += 2; } } /* Draws the frame for the bootstrap histograms in the drawing area */ void Draw_boot_frame( x, y, sizex, sizey) int x, y, sizex, sizey; { int x2, y2; int size_axe_x, size_axe_y; x2 = x + sizex / 2; y2 = y - (sizey - 20) / 2; size_axe_x = sizex / 2 - 30; size_axe_y = sizey / 2 - 5; Draw_line( x, y, x + sizex, y); Draw_line( x, y, x, y - sizey); Draw_line( x, y - sizey, x + sizex, y - sizey); Draw_line( x + sizex, y, x + sizex, y - sizey); Draw_line( x, y - sizey + 20, x + sizex, y - sizey + 20); Draw_line( x, y - sizey + 18, x + sizex, y - sizey + 18); Draw_line( x, y2 + 1, x + sizex, y2 + 1); Draw_line( x, y2 - 1, x + sizex, y2 - 1); Draw_line( x2 - 1, y, x2 - 1, y - sizey + 18); Draw_line( x2 + 1, y, x2 + 1, y - sizey + 18); Draw_boot_axe( x, y, size_axe_x, size_axe_y); Draw_boot_axe( x2, y, size_axe_x, size_axe_y); Draw_boot_axe( x, y2, size_axe_x, size_axe_y); Draw_boot_axe( x2, y2, size_axe_x, size_axe_y); } /* Draws the ST episode detection Se/+P bootstrap histograms and writes confidence limits in the drawing area */ void Draw_hist1( x, y, sizex, sizey) int x, y, sizex, sizey; { int x2, y2; int size_axe_x, size_axe_y; char buf[100]; x2 = x + sizex / 2; y2 = y - (sizey - 20) / 2; size_axe_x = sizex / 2 - 30; size_axe_y = sizey / 2 - 5; if ( diff == IMPORTANT ) { Draw_boot_hist( x, y, size_axe_x, size_axe_y, hist_ase); Draw_text_font("Average IE Se [%] ", x + sizex/4 - 18, y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", asensr[0]); Draw_text_font(buf, x + sizex/4 - 18, y2 + 30,"6x10"); Draw_boot_hist( x2, y, size_axe_x, size_axe_y, hist_apn); Draw_text_font("Average IE +P [%]", x2 + sizex/4 - 18, y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", apredr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y2 + 30,"6x10"); Draw_boot_hist( x, y2, size_axe_x, size_axe_y, hist_gse); Draw_text_font(" Gross IE Se [%]", x + sizex/4 - 18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gsensr[0]); Draw_text_font(buf, x + sizex/4 - 18, y - sizey + 50,"6x10"); Draw_boot_hist( x2, y2, size_axe_x, size_axe_y, hist_gpn); Draw_text_font( " Gross IE +P [%]", x2 + sizex/4 -18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gpredr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y - sizey + 50,"6x10"); Draw_text_font( "Ischemic episode performance distributions", x2 - 168, y - sizey + 15, "8x13bold"); } else { Draw_boot_hist( x, y, size_axe_x, size_axe_y, hist_ase); Draw_text_font("Average SE Se [%] ", x + sizex/4 - 18, y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", asensr[0]); Draw_text_font(buf, x + sizex/4 - 18, y2 + 30,"6x10"); Draw_boot_hist( x2, y, size_axe_x, size_axe_y, hist_apn); Draw_text_font("Average SE +P [%]", x2 + sizex/4 - 18, y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", apredr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y2 + 30,"6x10"); Draw_boot_hist( x, y2, size_axe_x, size_axe_y, hist_gse); Draw_text_font(" Gross SE Se [%]", x + sizex/4 - 18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gsensr[0]); Draw_text_font(buf, x + sizex/4 - 18, y - sizey + 50,"6x10"); Draw_boot_hist( x2, y2, size_axe_x, size_axe_y, hist_gpn); Draw_text_font( " Gross SE +P [%]", x2 + sizex/4 -18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gpredr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y - sizey + 50,"6x10"); Draw_text_font( "ST segment episode performance distributions", x2 - 168, y - sizey + 15, "8x13bold"); } } /* Draws the ST duration detection Se/+P bootstrap histograms and writes confidence limits in the drawing area */ void Draw_hist2( x, y, sizex, sizey) int x, y, sizex, sizey; { int x2, y2; int size_axe_x, size_axe_y; char buf[LEN_SHORTER]; x2 = x + sizex / 2; y2 = y - (sizey - 20) / 2; size_axe_x = sizex / 2 - 30; size_axe_y = sizey / 2 - 5; if ( diff == IMPORTANT ) { Draw_boot_hist( x, y, size_axe_x, size_axe_y, hist_adurse); Draw_text_font(" Average ID Se [%]", x + sizex/4 - 18, y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", adurser[0]); Draw_text_font(buf, x + sizex/4 - 18, y2 + 30,"6x10"); Draw_boot_hist( x2, y, size_axe_x, size_axe_y, hist_adurpn); Draw_text_font(" Average ID +P [%]", x2 + sizex/4 - 18,y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", adurpr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y2 + 30, "6x10"); Draw_boot_hist( x, y2, size_axe_x, size_axe_y, hist_gdurse); Draw_text_font(" Gross ID Se [%]", x + sizex/4 - 18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gdurser[0]); Draw_text_font(buf, x + sizex/4 - 18, y - sizey + 50, "6x10"); Draw_boot_hist( x2, y2, size_axe_x, size_axe_y, hist_gdurpn); Draw_text_font(" Gross ID +P [%]", x2 + sizex/4 - 18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gdurpr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y - sizey + 50, "6x10"); Draw_text_font( "Ischemic duration performance distributions", x2 - 168, y - sizey + 15, "8x13bold"); } else { Draw_boot_hist( x, y, size_axe_x, size_axe_y, hist_adurse); Draw_text_font(" Average SD Se [%]", x + sizex/4 - 18, y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", adurser[0]); Draw_text_font(buf, x + sizex/4 - 18, y2 + 30,"6x10"); Draw_boot_hist( x2, y, size_axe_x, size_axe_y, hist_adurpn); Draw_text_font(" Average SD +P [%]", x2 + sizex/4 - 18,y2 + 15,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", adurpr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y2 + 30, "6x10"); Draw_boot_hist( x, y2, size_axe_x, size_axe_y, hist_gdurse); Draw_text_font(" Gross SD Se [%]", x + sizex/4 - 18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gdurser[0]); Draw_text_font(buf, x + sizex/4 - 18, y - sizey + 50, "6x10"); Draw_boot_hist( x2, y2, size_axe_x, size_axe_y, hist_gdurpn); Draw_text_font(" Gross SD +P [%]", x2 + sizex/4 - 18, y - sizey + 35,"8x13bold"); sprintf(buf, " (5 %% conf.lim. %6.2lf)", gdurpr[0]); Draw_text_font(buf, x2 + sizex/4 - 18, y - sizey + 50, "6x10"); Draw_text_font( "ST segment duration performance distributions", x2 - 168, y - sizey + 15, "8x13bold"); } } /* Draws a time scale for ST episode representation in the drawing area */ void Draw_single_frame(x, y, sizex, n) int x, y, sizex, n; { int i, time, dist, time_scale, lnt; char buf[LEN_SHORTER]; int scl_cst=12; lnt=0; scl_cst=12; if (DUR_REC<= 7200000) {time_scale=10;lnt=1;} else if (DUR_REC<= 43200000) time_scale= 1; else if (DUR_REC<= 86400000) {time_scale=2;} else if (DUR_REC<= 93600000) {time_scale=2;scl_cst=13;} else if (DUR_REC<=129600000) time_scale=3; else if (DUR_REC<=172800000) time_scale=4; else time_scale=8; dist = sizex / scl_cst; time = 0; Draw_line(x, y, x + scl_cst * dist, y); for ( i = 0; i <= scl_cst; i++) { Draw_line(x + i * dist, y - 1, x + i * dist, y + 1); if ( n == 1 ) { sprintf(buf, "%3d", (int)time); Draw_text_font(buf, x + i * dist - 15, y + 15, "6x10"); } time+=time_scale; } if ( n == 1 ) if ( lnt == 1 ) Draw_text("[min]", x + sizex, y + 15); else Draw_text("[hour]", x + sizex, y + 15); } /* Draws reference and algorithm episodes in the drawing area */ void Draw_single_graph(x, y, sizex, dir, class, epi) int x, y, sizex, dir, class; episode epi[MAXEPI]; { int i, j, width; long int x1, x2, x3; double z1, z2, z3; double dur_rec; if (DUR_REC<=7200000) dur_rec=7200000; else if (DUR_REC<= 43200000) dur_rec=7200000; else if (DUR_REC<= 86400000) dur_rec=86400000; else if (DUR_REC<= 93600000) dur_rec=93600000; else if (DUR_REC<=129600000) dur_rec=129600000; else if (DUR_REC<=172800000) dur_rec=172800000; else dur_rec=2*172800000; if ( dir > 0 ) width = dir; else width = -1 * dir; for ( i = 0; epi[i].offset > 0; i++ ) { z1 = (double) (FACTOR * epi[i].onset) / dur_rec; z2 = (double) (FACTOR * epi[i].offset) / dur_rec; x1 = x + (int) ( sizex * z1); x2 = x + (int) ( sizex * z2); if ( class == 0 ) if (( epi[i].ext_val[0] < 0 ) && ( dir > 0 )) dir = -1 * dir; if ( dir > 0 ) if ( epi[i].tip == ISHEMIC ) Draw_rectangle( x1, y - dir, x2 - x1, width); else Draw_rectangle( x1, y - dir - 4, x2 - x1, width + 4); else if ( epi[i].tip == ISHEMIC ) Draw_rectangle( x1, y, x2 - x1, width); else Draw_rectangle( x1, y, x2 - x1, width + 4 ); for ( j = 0; j < epi[i].num_ext; j++ ) { z3 = (double) (FACTOR * epi[i].ext_pos[j]) / dur_rec; x3 = x + (int) ( sizex * z3 ); if ( epi[i].tip == ISHEMIC ) Draw_line( x3, y, x3, y - dir); else if ( dir > 0 ) Draw_line( x3, y, x3, y - dir - 4); else Draw_line( x3, y, x3, y - dir + 4); } } } /* Reads text from a file into a text widget */ void ReadTextFromFile (w, filename) Widget w; char filename[NAME_LEN]; { FILE *fp; char *file_contents; struct stat stat_val; long file_length; if (stat(filename, &stat_val) == 0) { file_length = stat_val.st_size; if ((fp=fopen(filename,"r"))!=NULL) { file_contents = XtMalloc((unsigned)file_length+1); *file_contents = '\0'; fread(file_contents, sizeof(char), file_length, fp); file_contents[file_length]='\0'; fclose(fp); XmTextSetString(w, file_contents); XtFree(file_contents); XmTextSetCursorPosition(w,0); } else XmTextSetString(w, "No eval_st.hlp file"); } else XmTextSetString(w, "No eval_st.hlp file"); } /* Manages the widget for selecting the number of bootstrap trials */ void CBConst_1(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XtManageChild (cb1); } /* Reads selected number of bootstrap trials */ void CBSet_const_1(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XmSelectionBoxCallbackStruct *cs = (XmSelectionBoxCallbackStruct *) call_data; char *text[32]; double step; XmStringGetLtoR (cs->value, XmSTRING_DEFAULT_CHARSET, text); sscanf (*text, "%lf", &step); if ((strlen (*text) == 0) || ( step < 0 )) trials1 = 10000; else { trials1 = (long) (step + 0.5); bootvalid = 0; } XtUnmanageChild (cb1); } /* Unmanages the widget for selection of the number of bootstrap trials */ void CBCancel_const_1(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XtUnmanageChild(cb1); } /* Manages the FileSelection widget */ void CBFile(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XtManageChild(sb); } /* Unmanages the FileSelection widget */ void CBFile_cancel(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XtUnmanageChild(sb); } /* Reads the name of the selected file and initializes data structures */ void CBFile_select(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XmFileSelectionBoxCallbackStruct *cs = (XmFileSelectionBoxCallbackStruct *) call_data; char *text[NAME_LEN]; char name[NAME_LEN]; char pom[NAME_LEN],recs[NAME_LEN]; int n,i; Arg args[10]; char message[LEN_SHORTER]; XmString message_string,title_string; FILE *in; filevalid = 0; XmStringGetLtoR (cs->value, XmSTRING_DEFAULT_CHARSET, text); XtUnmanageChild( sb ); strcpy(dat1, *text); filevalid = 1; bootvalid = 0; rawvalid = 0; extremavalid = 0; examine_valid = 0; sprintf(alg_name,"%s",dat1); sprintf(dat2,"%s",dat1); sprintf(file_name,"%s",GetName(dat1)); if ( diff == IMPORTANT ) { sprintf(message,"Evaluation: %s Evaluation mode: Ischemic/Heart-rate related changes",RemoveDot(file_name)); ModeString = XmStringCreateLtoR (message,XmSTRING_DEFAULT_CHARSET); XtVaSetValues(mess_w, XmNlabelString, ModeString, NULL); } else { sprintf(message,"Evaluation: %s Evaluation mode: ST segment changes",RemoveDot(file_name)); ModeString = XmStringCreateLtoR (message,XmSTRING_DEFAULT_CHARSET); XtVaSetValues(mess_w, XmNlabelString, ModeString, NULL); } rawi=raws=exti=exts=boti=bots=0; tot_rec=0; numfreeze=0; in=fopen(alg_name,"rt"); if ((Test(in,alg_name)==-1)) { } else { while (fscanf(in,"%s",recs)>0) { strcpy(evaluated[tot_rec].rec,GetName(recs)); evaluated[tot_rec].is=0; evaluated[tot_rec].st=0; tot_rec++; } fclose(in); } if (dialog_stt) EStats(); /* Select your own permanent windows */ if (dialog_ebe) XtUnmanageChild(dialog_ebe); if (dialog_ext) XtUnmanageChild(dialog_ext); if (dialog_raw) XtUnmanageChild(dialog_raw); if (dialog_bts) XtUnmanageChild(dialog_bts); /* if (dialog_smr) XtUnmanageChild(dialog_smr); */ if (dialog_hlp) XtUnmanageChild(dialog_hlp); } /* Creates and manages a dialog for statistics of evaluations performed */ void CBEStats(w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { int n; Arg args[24]; XFontStruct *newfont; XmFontList newfontlist; if (!dialog_stt) { n = 0; XtSetArg (args[n], XmNtitle, " Evaluations performed "); n++; XtSetArg (args[n], XmNallowShellResize, True); n++; dialog_stt = (Widget) XmCreateBulletinBoardDialog ( toplevel, "Stt_shell", args, n); newfont = XLoadQueryFont (XtDisplay(dialog_stt), "6x13"); newfontlist = XmFontListCreate (newfont, XmFONTLIST_DEFAULT_TAG); n = 0; XtSetArg (args[n], XmNx, 10); n++; XtSetArg (args[n], XmNy, 0); n++; XtSetArg (args[n], XmNcolumns, 55); n++; XtSetArg (args[n], XmNrows, 52); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg (args[n], XmNfontList, newfontlist); n++; XtSetArg (args[n], XmNcursorPositionVisible, False); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNforeground, 0); n++; text_stt = (Widget) XmCreateScrolledText(dialog_stt, "Stt_text", args, n); } EStats(); XtManageChild(text_stt); XtManageChild(dialog_stt); } /* Writes the statistics of performed evaluations to the dialog */ void EStats() { int i; char eval_mess[NAME_LEN]; char recs_mess[MAXREC*16]; XmTextPosition pos=0; XmTextSetString (text_stt, ""); sprintf (eval_mess,"Evaluations performed\n\n"); pos = XmTextGetLastPosition (text_stt); XmTextReplace (text_stt, pos, pos, eval_mess); sprintf(eval_mess,"Evaluation: %s \n\n",RemoveDot(file_name)); pos = XmTextGetLastPosition (text_stt); XmTextReplace (text_stt, pos, pos, eval_mess); sprintf(eval_mess,"Ischemic/Heart-rate related changes\n"); pos = XmTextGetLastPosition (text_stt); XmTextReplace (text_stt, pos, pos, eval_mess); sprintf(eval_mess,"Aggregate: %s Extrema: %s Bootstrap: %s \n\n",rawi?"Y":"N",exti?"Y":"N",boti?"Y":"N"); pos = XmTextGetLastPosition (text_stt); XmTextReplace (text_stt, pos, pos, eval_mess); sprintf(eval_mess,"ST segment changes\n"); pos = XmTextGetLastPosition (text_stt); XmTextReplace (text_stt, pos, pos, eval_mess); sprintf(eval_mess,"Aggregate: %s Extrema: %s Bootstrap: %s \n\n",raws?"Y":"N",exts?"Y":"N",bots?"Y":"N"); pos = XmTextGetLastPosition (text_stt); XmTextReplace (text_stt, pos, pos, eval_mess); strcpy(recs_mess,""); sprintf(recs_mess,"Ischemic/Heart-rate related changes\n"); for (i=0;ivalue, XmSTRING_DEFAULT_CHARSET, text); rlen=strlen(*text); strcpy(dat_1,path); strcpy(dat_2,path); strcpy(dat_3,path); in=fopen(alg_name,"rt"); if (Test(in,alg_name)==-1) { return; } fscanf(in,"%s",rc_name2); strcpy(rc_name1,GetName(rc_name2)); strcpy(rc_name2,rc_name1); while ((strcmp(rc_name2,*text)!=0) && (!feof(in))) { fscanf(in,"%s",rc_name3); strcpy(rc_name2,GetName(rc_name3)); } fclose(in); if ((strcmp(rc_name2,*text)!=0)&&(rlen==0)) strcpy(*text,rc_name1); else if ((strcmp(rc_name2,*text)!=0)&&(rlen!=0)) { sprintf( message, " Can't open file %s",GetName(*text)); message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET); XtSetArg (args[0], XmNmessageString, message_string); XtSetValues(fbb, args, 1); XtManageChild(fbb); return; } strcpy(name,*text); strcpy(rec_name,*text); if ( Single(dat_1,*text,diff) == -1 ) return; if ( diff == IMPORTANT ) { Draw_matrix_3x3(20/*65*/,30,340/*285*/,120,"Sensitivity (Se)"); Draw_matrix_3x3(400,30,340/*285*/,120,"Pos. pred. (+P)"); Draw_Se_matrix_3x3( 20/*65*/, 30, 340/*285*/, 120, allref); Draw_P_matrix_3x3( 400, 30, 340/*285*/, 120, allalg); } else { Draw_matrix_2x2(65, 30,285,120,"Sensitivity (Se)"); Draw_matrix_2x2(400, 30,285,120,"Pos. pred. (+P)"); Draw_Se_matrix_2x2( 65, 30, 285, 120, allref); Draw_P_matrix_2x2( 400, 30, 285, 120, allalg); } if ( diff == IMPORTANT ) { sprintf(buf,"Episodes: annotated:%6d,", allref.num_epi); Draw_text_font(buf, 65, 190, "8x13"); sprintf(buf,"detected: %6d,", allalg.num_epi); Draw_text(buf, 400, 190); sprintf(buf,"Per.of ischemia: annotated:%6.2lf,", allref.percent); Draw_text(buf, 65, 210); sprintf(buf,"detected: %6.2lf,", allalg.percent); Draw_text(buf, 400, 210); if ( allref.se == -1.0 ) sprintf(buf,"IE Se [%%] = undefined "); else sprintf(buf,"IE Se [%%] = %6.2lf ",allref.se ); Draw_text(buf,65,240); if ( allref.ish_dur == -1.0 ) sprintf(buf,"ID Se [%%] = undefined "); else sprintf(buf,"ID Se [%%] = %6.2lf",allref.ish_dur); Draw_text(buf,65,260); if ( allalg.se == -1.0 ) sprintf(buf,"IE +P [%%] = undefined "); else sprintf(buf,"IE +P [%%] = %6.2lf ",allalg.se ); Draw_text(buf,400,240); if ( allalg.ish_dur == -1.0 ) sprintf(buf,"ID +P [%%] = undefined "); else sprintf(buf,"ID +P [%%] = %6.2lf",allalg.ish_dur); Draw_text(buf,400,260); } else { sprintf(buf,"Episodes: annotated:%6d,", allref.num_epi); Draw_text_font(buf, 65, 190, "8x13"); sprintf(buf,"detected: %6d,", allalg.num_epi); Draw_text(buf, 400, 190); sprintf(buf,"Per.of ST changes: annotated:%6.2lf,", allref.percent); Draw_text(buf, 65, 210); sprintf(buf,"detected: %6.2lf,", allalg.percent); Draw_text(buf, 400, 210); if ( allref.se == -1.0 ) sprintf(buf,"SE Se [%%] = undefined "); else sprintf(buf,"SE Se [%%] = %6.2lf ",allref.se ); Draw_text(buf,65,240); if ( allref.ish_dur == -1.0 ) sprintf(buf,"SD Se [%%] = undefined "); else sprintf(buf,"SD Se [%%] = %6.2lf",allref.ish_dur); Draw_text(buf,65,260); if ( allalg.se == -1.0 ) sprintf(buf,"SE +P [%%] = undefined "); else sprintf(buf,"SE +P [%%] = %6.2lf ",allalg.se ); Draw_text(buf,400,240); if ( allalg.ish_dur == -1.0 ) sprintf(buf,"SD +P [%%] = undefined "); else sprintf(buf,"SD +P [%%] = %6.2lf",allalg.ish_dur); Draw_text(buf,400,260); } PaintScreen(); sprintf(buf,"Record: %s", name); Draw_text_font(buf,25,310,"6x13"); Draw_text_font("Lead 0",25,340,"6x13"); Draw_single_frame(65,340,620,0); Draw_single_graph(65,340,620,5,0,ep_lead0); Draw_text_font("Lead 1",25,370,"6x13"); Draw_single_frame(65,370,620,0); Draw_single_graph(65,370,620,5,0,ep_lead1); Draw_text_font("Lead 2",25,400,"6x13"); Draw_single_frame(65,400,620,0); Draw_single_graph(65,400,620,5,0,ep_lead2); Draw_text_font("Alg",25,425,"8x13"); Draw_single_frame(65,430,620,0); Draw_single_graph(65,430,620,5,1,epialg); Draw_text_font("Ref",25,445,"8x13"); Draw_single_graph(65,430,620,-5,1,epiref); Draw_single_frame(65,475,620,1); for (i=0;ievent->xany.type == ButtonPress ) && (cbs->event->xbutton.button == 1) && (examine_valid==1)) { num = find_pixel(cbs->event->xbutton.x, cbs->event->xbutton.y, st_tab); Draw_wished(180, 640, st_tab[num]); } else if ((cbs->event->xany.type == KeyPress ) && (examine_valid == 1)) { num = find_pixel(cbs->event->xbutton.x, cbs->event->xbutton.y, st_tab); Draw_wished(180, 640, st_tab[num]); } PaintScreen(); } /* Evaluation of ST segment deviation measurements */ void CBExtrema (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { int done = 0; int num, n; char message[LEN_SHORTER], dat_4[NAME_LEN]; XmString message_string,title_string; Arg args[10]; static Widget text_ext; XFontStruct *newfont; XmFontList newfontlist; ClearScreen(); if ( filevalid == 1 ) { st_deviation( dat1, diff); if (dev_valid==0) return; else dev_valid=0; XSelectInput (XtDisplay(workarea), XtWindow(workarea), ButtonPressMask | LeaveWindowMask | ExposureMask ); extremavalid = 1; examine_valid = 1; Draw_frame_graph(150, 510); Draw_graph (150, 510); Draw_extrema_results(150, 590); Draw_reg_line(150, 510); PaintScreen(); if ( diff == IMPORTANT ) exti=1; if ( diff == NO_MATTER ) exts=1; if (!dialog_ext) { n = 0; XtSetArg (args[n], XmNtitle, " Extrema statistics "); n++; XtSetArg (args[n], XmNallowShellResize, True); n++; dialog_ext = (Widget) XmCreateBulletinBoardDialog ( toplevel, "Ext_shell", args, n); newfont = XLoadQueryFont (XtDisplay(dialog_ext), "6x13"); newfontlist = XmFontListCreate (newfont, XmFONTLIST_DEFAULT_TAG); n = 0; XtSetArg (args[n], XmNx, 10); n++; XtSetArg (args[n], XmNy, 0); n++; XtSetArg (args[n], XmNcolumns, 109); n++; XtSetArg (args[n], XmNrows, 52); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg (args[n], XmNfontList, newfontlist); n++; XtSetArg (args[n], XmNcursorPositionVisible, False); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNforeground, 0); n++; text_ext = (Widget) XmCreateScrolledText(dialog_ext, "ext_text", args, n); } if (dialog_stt) EStats(); XmTextSetString(text_ext,writeX); XmTextSetCursorPosition(text_ext,0); XtManageChild(text_ext); XtManageChild(dialog_ext); write_ebe(); } else { sprintf (message, " Select evaluation project "); message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg (args[n], XmNmessageString, message_string); n++; title_string = XmStringCreateLtoR ("Extrema", XmSTRING_DEFAULT_CHARSET); XtSetArg (args[n], XmNdialogTitle, title_string); n++; XtSetValues (mb, args, n); XtManageChild(mb); } } /* Bootstrap method */ void CBBoot (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { int i, n; char message[LEN_SHORTER],dat_3[NAME_LEN]; XmString message_string,title_string; Arg args[10]; XFontStruct *newfont; XmFontList newfontlist; FILE *fa; static Widget text_bts; ClearScreen(); if ( filevalid == 1 ) { all_records(dat1, diff); if (all_valid==0) return; else all_valid=0; bootstrap(diff,trials1); strcpy(writeX,""); Xwrite_boot(text_bts); if ( diff == IMPORTANT ) boti=1; if ( diff == NO_MATTER ) bots=1; if (dialog_stt) EStats(); Draw_boot_frame(90,330,540,320); Draw_hist1(90,330,540,320); Draw_boot_frame(90,660,540,320); Draw_hist2(90,660,540,320); PaintScreen(); bootvalid = 1; examine_valid=0; if (!dialog_bts) { n = 0; XtSetArg (args[n], XmNtitle, " Bootstrap method "); n++; XtSetArg (args[n], XmNallowShellResize, True); n++; dialog_bts = (Widget) XmCreateBulletinBoardDialog ( toplevel, "Bootstrap_shell", args, n); newfont = XLoadQueryFont (XtDisplay(dialog_bts), "6x13"); newfontlist = XmFontListCreate (newfont, XmFONTLIST_DEFAULT_TAG); n = 0; XtSetArg (args[n], XmNx, 10); n++; XtSetArg (args[n], XmNy, 0); n++; XtSetArg (args[n], XmNcolumns, 94); n++; XtSetArg (args[n], XmNrows, 52); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg (args[n], XmNfontList, newfontlist); n++; XtSetArg (args[n], XmNcursorPositionVisible, False); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNforeground, 0); n++; text_bts = (Widget) XmCreateScrolledText(dialog_bts, "Bootstrap_text", args, n); } XmTextSetString(text_bts,writeX); XmTextSetCursorPosition(text_bts,0); XtManageChild(text_bts); XtManageChild(dialog_bts); sprintf(dat_3,"%s%s.bts",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_boot1(dat_3,diff,10000); } else { sprintf (message, " Select evaluation project "); message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg (args[n], XmNmessageString, message_string); n++; title_string = XmStringCreateLtoR ("Bootstrap", XmSTRING_DEFAULT_CHARSET); XtSetArg (args[n], XmNdialogTitle, title_string); n++; XtSetValues (mb, args, n); XtManageChild(mb); } } /* Comparing results of different algorithms/databases */ void CBFreeze (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { FILE *fp; char namealg[NAME_LEN], dat_1[NAME_LEN],dat[NAME_LEN]; char namecri[NAME_LEN]; char message[LEN_SHORTER]; XmString message_string,title_string; Arg args[10]; int n; XFontStruct *newfont; XmFontList newfontlist; static Widget text_smr1,text_smr2,text_smr3; if ( filevalid == 1 ) { strcpy(namealg,dat2); str_delete(namealg, 0, strlen(dat2) - 3); if ( diff == IMPORTANT ) strcpy(namecri,"Ischemic"); else strcpy(namecri,"ST Changes"); if (!dialog_smr) { title_string = XmStringCreateLtoR ("Comparison of algorithms ", XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg (args[n], XmNtitle, "Comparison of algorithms"); n++; XtSetArg (args[n], XmNallowShellResize, True); n++; dialog_smr = (Widget) XmCreateBulletinBoardDialog ( toplevel, "Smr_shell", args, n); newfont = XLoadQueryFont (XtDisplay(dialog_smr), "6x13"); newfontlist = XmFontListCreate (newfont, XmFONTLIST_DEFAULT_TAG); n = 0; XtSetArg (args[n], XmNx, 10); n++; XtSetArg (args[n], XmNy, 0); n++; XtSetArg (args[n], XmNcolumns, 46); n++; XtSetArg (args[n], XmNrows, 12); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg (args[n], XmNcursorPositionVisible, False); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNfontList, newfontlist); n++; XtSetArg (args[n], XmNforeground, 0); n++; text_smr1 = (Widget) XmCreateText(dialog_smr, "text_smr1", args, n); n = 0; XtSetArg (args[n], XmNx, 10); n++; XtSetArg (args[n], XmNy, 195); n++; XtSetArg (args[n], XmNcolumns, 46); n++; XtSetArg (args[n], XmNrows, 12); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg (args[n], XmNcursorPositionVisible, False); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNfontList, newfontlist); n++; XtSetArg (args[n], XmNforeground,0 ); n++; text_smr2 = (Widget) XmCreateText(dialog_smr, "text_smr2", args, n); n = 0; XtSetArg (args[n], XmNx, 10); n++; XtSetArg (args[n], XmNy, 380); n++; XtSetArg (args[n], XmNcolumns, 46); n++; XtSetArg (args[n], XmNrows, 12); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; XtSetArg (args[n], XmNcursorPositionVisible, False); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNfontList, newfontlist); n++; XtSetArg (args[n], XmNforeground, 0); n++; text_smr3 = (Widget) XmCreateText(dialog_smr, "text_smr3", args, n); n=0; XtSetArg (args[n],XmNforeground, XBlackPixel (XtDisplay (dialog_smr), XtWindow (dialog_smr))); XtSetValues (text_smr1 , args, 1); XtSetValues (text_smr2 , args, 1); XtSetValues (text_smr3 , args, 1); } strcpy(writeX,""); if (diff == IMPORTANT ) sprintf(dat,"Evaluation: %s \nEvaluation mode: \nIschemic/Heart-rate related changes\n",RemoveDot(file_name)); else sprintf(dat,"Evaluation: %s \nEvaluation mode: \nST segment changes\n",RemoveDot(file_name)); strcat(writeX,dat); if ( rawvalid == 1 ) { if (diff == IMPORTANT) { sprintf(dat, "Raw statistics:\n"); strcat(writeX,dat); sprintf(dat, "IE Se [%%] = %6.2lf [a] IE +P [%%] = %6.2lf [a]\n", allref.ase, allalg.ase); strcat(writeX,dat); sprintf(dat, "ID Se [%%] = %6.2lf [a] ID +P [%%] = %6.2lf [a]\n",allref.aish_dur, allalg.aish_dur); strcat(writeX,dat); } else { sprintf(dat, "Raw statistics:\n"); strcat(writeX,dat); sprintf(dat, "SE Se [%%] = %6.2lf [a] SE +P [%%] = %6.2lf [a]\n",allref.ase, allalg.ase); strcat(writeX,dat); sprintf(dat, "SD Se [%%] = %6.2lf [a] SD +P [%%] = %6.2lf [a]\n",allref.aish_dur, allalg.aish_dur); strcat(writeX,dat); } } if ( bootvalid == 1 ) { if (diff == IMPORTANT) { sprintf(dat,"5 %% confidence limits: \n"); strcat(writeX,dat); sprintf(dat, "IE Se [%%] = %6.2lf [a] IE +P [%%] = %6.2lf [a]\n",asensr[0], apredr[0]); strcat(writeX,dat); sprintf(dat, "ID Se [%%] = %6.2lf [a] ID +P [%%] = %6.2lf [a]\n",adurser[0], adurpr[0]); strcat(writeX,dat); } else { sprintf(dat,"5 %% confidence limits: \n"); strcat(writeX,dat); sprintf(dat, "SE Se [%%] = %6.2lf [a] SE +P [%%] = %6.2lf [a]\n",asensr[0], apredr[0]); strcat(writeX,dat); sprintf(dat, "SD Se [%%] = %6.2lf [a] SD +P [%%] = %6.2lf [a]\n",adurser[0], adurpr[0]); strcat(writeX,dat); } } if ( extremavalid == 1 ) { sprintf(dat, "ST measurements:\n"); strcat(writeX,dat); sprintf(dat, "Mean [uV] = %6.2lf St.dev [uV] = %6.2lf\n", mvalue, stand_dev); strcat(writeX,dat); sprintf(dat, "p(100 uV) [%%] = %6.2lf e(95 %%) [uV] = %6.2lf\n", phund, enfive); strcat(writeX,dat); } switch (cur) { case 1: XmTextSetString(text_smr1,writeX); XmProcessTraversal(text_smr1,XmTRAVERSE_CURRENT); cur = 2; break; case 2: XmTextSetString(text_smr2,writeX); XmProcessTraversal(text_smr2,XmTRAVERSE_CURRENT); cur = 3; break; case 3: XmTextSetString(text_smr3,writeX); XmProcessTraversal(text_smr3,XmTRAVERSE_CURRENT); cur = 1; break; } XtManageChild(text_smr1); XtManageChild(text_smr2); XtManageChild(text_smr3); XtManageChild(dialog_smr); sprintf(dat_1,"%s%s.smr%03d",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st",numfreeze); fp = fopen(dat_1, "w"); if (Test_out(fp,dat_1)!=-1) { fprintf(fp,"%s",writeX); fclose(fp); } numfreeze++; if (numfreeze>=1000) numfreeze=0; } else { sprintf (message, " Select evaluation project "); message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg (args[n], XmNmessageString, message_string); n++; title_string = XmStringCreateLtoR ("Compare", XmSTRING_DEFAULT_CHARSET); XtSetArg (args[n], XmNdialogTitle, title_string); n++; XtSetValues (mb, args, n); XtManageChild(mb); } } /* Comparing the performance of the algorithms */ void CBDifferences (w, client_data, call_data) Widget w; caddr_t client_data; caddr_t call_data; { XtManageChild(eb); } String fallback_resources[] = { "*title: EVAL_ST Evaluation of transient ST segment episode detectors", "*User.set: True", "*Auto.set: True", "*workarea.width: 750", "*workarea.height: 675", "*XmScale.minimum: 100", "*XmScale.maximum: 16000", "*geometry: 761x737", "*allowShellResize: True", NULL }; /* File menu */ void file_cb(Widget widget, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 0) CBFile(widget,client_data,call_data); else if (item_no == 1) CBEStats(widget,client_data,call_data); if (item_no == 2) exit (0); } /* Evaluation_mode menu */ void mode_cb(Widget widget, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 0) CBIshemic(widget,client_data,call_data); else if (item_no == 1) CBSt(widget,client_data,call_data); } /* Aggregate_statistics menu */ void statistics_cb(Widget widget, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 0) CBAll(widget,client_data,call_data); else if (item_no == 1) CBExtrema(widget,client_data,call_data); } /* Single_record menu */ void single_cb(Widget w, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; XmString message_string, label_string; CBSingle(toplevel,client_data,call_data); } /* Bootstrap menu */ void bootstrap_cb(Widget widget, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 0) CBConst_1(widget,client_data,call_data); else if (item_no == 1) CBBoot(widget,client_data,call_data); } /* Summary menu */ void summary_cb(Widget widget, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 0) CBFreeze(widget,client_data,call_data); else if (item_no == 1) CBDifferences(widget,client_data,call_data); } /* Help menu */ void help_cb(Widget widget, XtPointer client_data, XtPointer call_data) { int item_no = (int) client_data; if (item_no == 0) CBHelp(widget,client_data,call_data); } /* Creates the graphic user interface */ void CreateApplication (parent) Widget parent; { Widget mainwindow, menubar; Widget menubarBtn[9]; Widget pulldowns[5]; Widget buttons0[2]; Widget buttons1[3]; Widget buttons2[2]; Widget buttons3[2]; Widget buttons4[2]; Widget fpulldown, fbut[3],button; XmString title_string; XmString message_string; XSetWindowAttributes attributes; unsigned long valuemask; XSetWindowAttributes xswa; Arg args[20]; int n; char message[LEN_SHORTER]; XFontStruct *newfont; XmFontList newfontlist; unsigned long i; XmString file, mode, statistics, single, bootstrap, summary, help, label_string; XmString open,save,quit,ischr,segment,raw,extrema,trials,evaluate,freeze,differences; Widget widget,main_w,rowcol; XGCValues gcv; main_w = XtVaCreateManagedWidget ("main_window", xmMainWindowWidgetClass, parent, XmNscrollBarDisplayPolicy, XmAS_NEEDED, XmNscrollingPolicy, XmAUTOMATIC, NULL); file = XmStringCreateLocalized ("File"); mode = XmStringCreateLocalized ("Evaluation_mode"); statistics = XmStringCreateLocalized ("Aggregate_statistics"); single = XmStringCreateLocalized ("Single_record"); bootstrap = XmStringCreateLocalized ("Bootstrap"); summary = XmStringCreateLocalized ("Summary"); help = XmStringCreateLocalized ("Help"); menubar = XmVaCreateSimpleMenuBar (main_w, "menubar", XmVaCASCADEBUTTON, file, 'F', XmVaCASCADEBUTTON, mode, 'E', XmVaCASCADEBUTTON, single, 'S', XmVaCASCADEBUTTON, statistics, 'A', XmVaCASCADEBUTTON, bootstrap, 'B', XmVaCASCADEBUTTON, summary, 'm', XmVaCASCADEBUTTON, help, 'H', NULL); if (widget = XtNameToWidget (menubar, "button_6")) XtVaSetValues (menubar, XmNmenuHelpWidget, widget, NULL); XmStringFree(file); XmStringFree(mode); XmStringFree(statistics); XmStringFree(single); XmStringFree(bootstrap); XmStringFree(summary); XmStringFree(help); open = XmStringCreateLocalized ("Open"); save = XmStringCreateLocalized ("Examine"); quit = XmStringCreateLocalized ("Quit"); XmVaCreateSimplePulldownMenu (menubar, "file_menu", 0, file_cb, XmVaPUSHBUTTON, open, 'O', "CtrlO", XmStringCreateLocalized ("Ctrl+O"), XmVaPUSHBUTTON, save, 'E', "CtrlE", XmStringCreateLocalized ("Ctrl+E"), XmVaSEPARATOR, XmVaPUSHBUTTON, quit, 'Q', "CtrlQ", XmStringCreateLocalized ("Ctrl+Q"), NULL); XmStringFree(open); XmStringFree(save); XmStringFree(quit); ischr = XmStringCreateLocalized ("Ischemic/Heart-rate related changes"); segment = XmStringCreateLocalized("ST segment changes"); XmVaCreateSimplePulldownMenu (menubar, "mode_menu", 1, mode_cb, XmVaPUSHBUTTON, ischr, 'I', "CtrlI", XmStringCreateLocalized ("Ctrl+I"), XmVaPUSHBUTTON, segment, 'S', "CtrlS", XmStringCreateLocalized ("Ctrl+S"), NULL); XmStringFree(ischr); XmStringFree(segment); XmStringFree(trials); XmStringFree(evaluate); single = XmStringCreateLocalized("Record"); XmVaCreateSimplePulldownMenu (menubar, "single_menu", 2, single_cb, XmVaPUSHBUTTON, single, 'R', "CtrlR", XmStringCreateLocalized ("Ctrl+R"), NULL); XmStringFree(single); raw = XmStringCreateLocalized("Evaluate"); extrema = XmStringCreateLocalized("Extrema"); XmVaCreateSimplePulldownMenu (menubar, "mode_menu", 3, statistics_cb, XmVaPUSHBUTTON, raw, 'E', "CtrlA", XmStringCreateLocalized ("Ctrl+A"), XmVaPUSHBUTTON, extrema, 'x', "CtrlX", XmStringCreateLocalized ("Ctrl+X"), NULL); XmStringFree(raw); XmStringFree(extrema); trials = XmStringCreateLocalized("Number_of_bootstrap_trials"); evaluate = XmStringCreateLocalized("Evaluate"); XmVaCreateSimplePulldownMenu (menubar, "bootstrap_menu", 4, bootstrap_cb, XmVaPUSHBUTTON, trials, 'N', "CtrlN", XmStringCreateLocalized ("Ctrl+N"), XmVaPUSHBUTTON, evaluate, 'E', "CtrlB", XmStringCreateLocalized ("Ctrl+B"), NULL); freeze = XmStringCreateLocalized("Compare"); differences = XmStringCreateLocalized("Differences"); XmVaCreateSimplePulldownMenu (menubar, "summary_menu", 5, summary_cb, XmVaPUSHBUTTON, freeze, 'C', "CtrlC", XmStringCreateLocalized ("Ctrl+C"), XmVaPUSHBUTTON, differences, 'D', "CtrlD", XmStringCreateLocalized ("Ctrl+D"), NULL); XmStringFree(freeze); XmStringFree(differences); help = XmStringCreateLocalized("Help"); XmVaCreateSimplePulldownMenu (menubar, "help_menu", 6, help_cb, XmVaPUSHBUTTON, help, 'H', "CtrlH", XmStringCreateLocalized ("Ctrl+H"), NULL); XmStringFree(help); XtManageChild(menubar); /* Creates workarea in the MainWindow */ rowcol = XtVaCreateWidget ("rowcolumn", xmRowColumnWidgetClass, main_w, XmNorientation, XmVERTICAL, NULL); mess_w = XtVaCreateManagedWidget ("Evaluation: Evaluation mode: ST segment changes", xmLabelWidgetClass, rowcol, XmNalignment, XmALIGNMENT_BEGINNING, NULL); n = 0; XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++; XtSetArg (args[n], XmNmarginWidth, 0); n++; workarea = (Widget) XmCreateDrawingArea (/*main_w*/rowcol, "workarea", args, n); XtAddCallback (workarea, XmNexposeCallback, CBDraw, NULL); XtAddCallback (workarea, XmNinputCallback, CBExamine, NULL); pixmap = XCreatePixmap (XtDisplay (workarea), RootWindowOfScreen (XtScreen (workarea)), W_WIDTH, W_HEIGHT, DefaultDepthOfScreen (XtScreen (workarea))); n=0; XtSetArg (args[n],XmNbackground, XWhitePixel (XtDisplay (workarea), XtWindow (workarea)));n++; XtSetValues (workarea , args, n); XtManageChild (workarea); XtManageChild (rowcol); XmMainWindowSetAreas (main_w, menubar, NULL, NULL, NULL, /*workarea*/rowcol); title_string = XmStringCreateLtoR (" Selecting evaluation project ", XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg (args[n], XmNdialogTitle, title_string); n++; sb = (Widget) XmCreateFileSelectionDialog (parent, "files", args, n); XtUnmanageChild ((Widget) XmFileSelectionBoxGetChild (sb, XmDIALOG_HELP_BUTTON)); if ( bw == 0 ) { XtSetArg (args[0], XmNforeground, XBlackPixel(XtDisplay (sb), XtWindow(sb))); XtSetValues (sb, args, 1); XtSetValues ((Widget) XmFileSelectionBoxGetChild (sb, XmDIALOG_DIR_LIST), args, 1); XtSetValues ((Widget) XmFileSelectionBoxGetChild (sb, XmDIALOG_FILTER_TEXT), args, 1); XtSetValues ((Widget) XmFileSelectionBoxGetChild (sb, XmDIALOG_LIST), args, 1); XtSetValues ((Widget) XmFileSelectionBoxGetChild (sb, XmDIALOG_TEXT), args, 1); } XmTextFieldSetString((Widget) XmFileSelectionBoxGetChild (sb, XmDIALOG_FILTER_TEXT),"*.evl"); XmFileSelectionDoSearch(sb,XmStringCreateLocalized("*.evl")); XtAddCallback (sb, XmNokCallback, CBFile_select, NULL ); XtAddCallback (sb, XmNcancelCallback, CBFile_cancel, NULL ); n = 0; title_string = XmStringCreateLtoR ("Bootstrap trials", XmSTRING_DEFAULT_CHARSET); label_string = XmStringCreateLtoR ("Number of bootstrap trials:",XmSTRING_DEFAULT_CHARSET); XtSetArg (args[n], XmNdialogTitle, title_string); n++; XtSetArg (args[n], XmNselectionLabelString, label_string); n++; cb1 = XmCreatePromptDialog (parent, "cb1", args, n); XtUnmanageChild (XmSelectionBoxGetChild (cb1, XmDIALOG_HELP_BUTTON)); if ( bw == 0 ) { XtSetArg (args[0], XmNforeground, 0); XtSetValues (cb1, args, 1); XtSetValues (XmSelectionBoxGetChild (cb1, XmDIALOG_TEXT), args, 1); n=0; XtSetArg (args[n],XmNforeground, XBlackPixel (XtDisplay (cb1), XtWindow (cb1))); XtSetValues (cb1 , args, 1); XtSetValues (XmSelectionBoxGetChild (cb1, XmDIALOG_TEXT), args, 1); } XtAddCallback (cb1, XmNokCallback, CBSet_const_1, NULL); XtAddCallback (cb1, XmNcancelCallback, CBCancel_const_1, NULL); sprintf (message, " Select evaluation project "); message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET); n = 0; title_string = XmStringCreateLtoR ("Evaluation", XmSTRING_DEFAULT_CHARSET); XtSetArg (args[n], XmNdialogTitle, title_string); n++; XtSetArg (args[n], XmNmessageString, message_string); n++; mb = XmCreateMessageDialog (parent, "", args, n); XtUnmanageChild (XmMessageBoxGetChild ( mb, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild (XmMessageBoxGetChild ( mb, XmDIALOG_HELP_BUTTON)); if ( bw == 0 ) { XtSetArg (args[0], XmNforeground, 0); XtSetValues (mb, args, 1); } XtAddCallback (mb, XmNokCallback, CBMode_message, NULL); n = 0; XtSetArg (args[n], XmNdialogTitle, title_string); n++; fbb = XmCreateMessageDialog (parent, "fbb", args, n); XtUnmanageChild (XmMessageBoxGetChild ( fbb, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild (XmMessageBoxGetChild ( fbb, XmDIALOG_HELP_BUTTON)); if ( bw == 0 ) { XtSetArg (args[0], XmNforeground, 0); XtSetValues (fbb, args, 1); } XtAddCallback (fbb, XmNokCallback, CBFile_message, NULL); sprintf (message, " Not implemented yet "); message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET); n = 0; XtSetArg (args[n], XmNdialogTitle, XmStringCreateLtoR("Differences",XmSTRING_DEFAULT_CHARSET)); n++; XtSetArg (args[n], XmNmessageString, message_string); n++; eb = XmCreateMessageDialog (parent, "eb", args, n); XtUnmanageChild (XmMessageBoxGetChild ( eb, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild (XmMessageBoxGetChild ( eb, XmDIALOG_HELP_BUTTON)); if ( bw == 0 ) { XtSetArg (args[0], XmNforeground, 0); XtSetValues (eb, args, 1); } XtAddCallback (eb, XmNokCallback, CBEvaluate_message, NULL); return; } /* Initialization of the drawing area and creation of graphic context */ void InitDraw() { XGCValues val,gcv; wall_gc=DefaultGC(XtDisplay (workarea), DefaultScreen(XtDisplay(workarea))); val.foreground = 0 /*1*/; val.background = 1 /*0*/; val.function = GXcopy; wall_gc = XtGetGC(workarea, GCForeground | GCBackground | GCFunction, &val); XSetBackground(XtDisplay(workarea), wall_gc, WhitePixel(XtDisplay(workarea), DefaultScreen(XtDisplay(workarea)))); XSetForeground(XtDisplay(workarea), wall_gc, WhitePixel(XtDisplay(workarea), DefaultScreen(XtDisplay(workarea)))); empty_gc=DefaultGC(XtDisplay (workarea), DefaultScreen(XtDisplay(workarea))); val.foreground = 1 /*0*/; val.background = 0 /*0*/; empty_gc = XtGetGC(workarea, GCForeground | GCBackground | GCFunction, &val); XSetBackground(XtDisplay(workarea), empty_gc, WhitePixel(XtDisplay(workarea), DefaultScreen(XtDisplay(workarea)))); XSetForeground(XtDisplay(workarea), empty_gc, BlackPixel(XtDisplay(workarea), DefaultScreen(XtDisplay(workarea)))); XFillRectangle (XtDisplay (workarea), pixmap, wall_gc, 0, 0, W_WIDTH, W_HEIGHT); XtVaSetValues (workarea, XmNuserData, wall_gc, NULL); } #endif /* END OF MOTIF SECTION */ /* Reads the episodes from the file, combines the episodes, and fills the array */ void fill_array(fp,epi1) FILE *fp; episode epi1[MAXEPI]; { int i,j,k; long time; int event; long extrem; int lead; i = -1; k = 0; while ( feof(fp) == 0 ) { fscanf(fp,"%ld%d%ld%d",&time,&event,&extrem,&lead); switch(event) { case -1 : if (( i>-1 ) && ( diff == NO_MATTER ) && ( time==epi1[i].offset )) { k++; } else { k++; if ( k == 1 ) { i++; epi1[i].onset = time; /* Beginning */ j = 0; if (diff == IMPORTANT) if ( extrem == -1 ) /* Episode type */ epi1[i].tip = NON_ISHEMIC; else epi1[i].tip = ISHEMIC; else epi1[i].tip = ISHEMIC; epi1[i].num_ext = 0; } } break; case -2 : epi1[i].ext_pos[j] = time; /* Position of the extrema */ epi1[i].ext_val[j] = extrem; /* Value of the extrema */ epi1[i].ext_lead[j] = lead; /* Lead */ j++; epi1[i].num_ext = j; /* Number of extrema */ break; case -3 : k--; if ( k == 0 ) { epi1[i].offset = time; /* End of episode */ } break; } } } /* Reads the episodes from the file and fills the array for each lead */ void fill_ep_lead(fp,epi0,epi1,epi2) FILE *fp; episode epi0[MAXEPI], epi1[MAXEPI], epi2[MAXEPI]; { int i,j,k,l,m, n; long time; int event; long extrem; int lead; i = -1; k = -1; m=-1; while ( feof(fp) == 0 ) { fscanf(fp,"%ld%d%ld%d",&time,&event,&extrem,&lead); switch(event) { case -1 : if ( lead == 0 ) { i++; epi0[i].onset = time; j = 0; if ( extrem == 0 ) epi0[i].tip = ISHEMIC; else epi0[i].tip = NON_ISHEMIC; } else if (lead==1) { k++; epi1[k].onset = time; l = 0; if ( extrem == 0 ) epi1[k].tip = ISHEMIC; else epi1[k].tip = NON_ISHEMIC; } else { m++; epi2[m].onset = time; n = 0; if ( extrem==0 ) epi2[m].tip = ISHEMIC; else epi2[m].tip = NON_ISHEMIC; } break; case -2 : if ( lead == 0 ) { epi0[i].ext_pos[j] = time; epi0[i].ext_val[j] = extrem; epi0[i].ext_lead[j] = lead; j++; epi0[i].num_ext = j; } else if ( lead==1 ) { epi1[k].ext_pos[l] = time; epi1[k].ext_val[l] = extrem; epi1[k].ext_lead[l] = lead; l++; epi1[k].num_ext = l; } else { epi2[m].ext_pos[n] = time; epi2[m].ext_val[n] = extrem; epi2[m].ext_lead[n] = lead; n++; epi2[m].num_ext = n; } break; case -3 : if ( lead == 0 ) epi0[i].offset = time; else if ( lead==1 ) epi1[k].offset = time; else epi2[m].offset = time; break; } } } /* Initializes the data structure for the episode */ void in_episode(epi) episode *epi; { int j; epi -> onset = 0; epi -> offset = 0; epi -> num_ext = MAXEX; for ( j = 0; j < epi -> num_ext; j++ ) { epi -> ext_pos[j] = 0; epi -> ext_val[j] = 0; epi -> ext_lead[j] = 0; } epi -> status = 4; /* Neutral */ epi -> tip = 1; /* Neutral */ epi -> match = -1; /* No matching */ epi -> overlp = 0; } /* Initializes the array for the episodes */ void init_episode(epi) episode epi[MAXEPI]; { int i; for ( i = 0; i < MAXEPI; i++ ) in_episode(&epi[i]); } /* Initializes the data arrays for the records */ void in_record(rec) record *rec; { rec -> num_epi = 0; rec -> a = 0; rec -> b = 0; rec -> c = 0; rec -> d = 0; rec -> e = 0; rec -> f = 0; rec -> tp = 0; rec -> fn = 0; rec -> se = 0.0; rec -> duration = 0.0; rec -> ish_dur = 0.0; rec -> overlap = 0.0; rec -> percent = 0.0; rec -> ase = 0.0; rec -> aish_dur = 0.0; } /* Initializes the structures for the records */ void Init_Structs() { int i; for (i=0;i msec = number % 1000; new = number / 1000; time -> sec = new % 60; number = new / 60; time -> min = number % 60; time -> hour = number / 60; } /* Returns the minimum of two numbers */ long minimum(a,b) long a,b; { return (( a > b ) ? b : a ); } /* Returns the maximum of two numbers */ long maximum(a,b) long a,b; { return ((a > b ) ? a : b ); } /* Returns the duration of the overlapping interval of two episodes */ long matching(ref,alg) episode ref,alg; { long bover,eover; bover = maximum ( ref.onset, alg.onset ); eover = minimum ( ref.offset, alg.offset ); return( eover - bover) ; } /* Checks if the episode is sufficiently overlapped with another episode */ int overlap(epi,algtab,typofep) episode *epi; episode algtab[MAXEPI]; int typofep; { long durepi; long durover; long durcur; int i,j; durover = 0; durepi = epi -> offset - epi -> onset; for ( i = 0; algtab[i].offset > 0; i++ ) /* We consider only episodes of correct type */ if (( algtab[i].tip == typofep ) || ( typofep == NO_MATTER )) { durcur = matching(*epi,algtab[i] ); if ( durcur > 0 ) /* Matching ? */ { durover += durcur; /* Check for all extrema of the episode */ for ( j = 0; epi -> ext_pos[j] < algtab[i].offset && j ext_pos[j] >= algtab[i].onset ) && ( epi -> ext_pos[j] <= algtab[i].offset )) /* Episode overlaps at least one extrema of defining episode */ epi -> match = OVER_EX; } } } if ( 2 * durover >= durepi ) /* Overlaps at least one half of defining episode */ epi -> match = ( epi -> match == OVER_EX ) ? OVER_BOTH : OVER_HF; /* Determine the type of overlapping */ if ( epi -> match != -1 ) /* Episode was detected */ epi -> overlp = durover; if ( epi -> overlp > 0 ) { if ( typofep != NO_MATTER ) if ( epi -> tip == NON_ISHEMIC || typofep == NON_ISHEMIC ) epi -> overlp = 0; return (YES); } else return (NO); } /* Determines status of the episode - ISCHEMIC, NON_ISCHEMIC, MISSED */ void determine_status(epitab1,epitab2,typeofep) episode epitab1[MAXEPI]; episode epitab2[MAXEPI]; int typeofep; { int i,overlap(); for( i = 0; epitab1[i].offset > 0; i++ ) if ( typeofep == IMPORTANT ) if ( overlap(&epitab1[i],epitab2,ISHEMIC) ) epitab1[i].status = ISHEMIC; else if ( overlap(&epitab1[i],epitab2,NON_ISHEMIC)) epitab1[i].status = NON_ISHEMIC; else epitab1[i].status = MISSED; else if ( overlap(&epitab1[i],epitab2,NO_MATTER )) epitab1[i].status = ISHEMIC; else epitab1[i].status = MISSED; } /* Initializes values of the elements in the table */ void initial(tab) double tab[MAXIMAL]; { int i; for (i = 0; i <= MAXIMAL; i++) tab[i] = 0.0; } /* Determines parameters of the record according to the type of episodes and their status after the matching test */ void fill_record(epitab,el_rec) episode epitab[MAXEPI]; record *el_rec; { int i; for ( i = 0; epitab[i].offset > 0; i++ ) if ( epitab[i].tip == ISHEMIC ) switch ( epitab[i].status ) { case ISHEMIC : ( el_rec -> a ) ++; break; case NON_ISHEMIC : ( el_rec -> b ) ++; break; case MISSED : ( el_rec -> c ) ++; } else switch ( epitab[i].status ) { case ISHEMIC : ( el_rec -> d ) ++; break; case NON_ISHEMIC : ( el_rec -> e ) ++; break; case MISSED : ( el_rec -> f ) ++; }; } /* Calculates sensitivity or positive predictivity for the record */ double sensitivity(rec,diff) record *rec; int diff ;{ double tps,fns; if ( diff == NO_MATTER ) { tps = rec -> a + rec -> b + rec -> d + rec -> e; fns = rec -> c + rec -> f; } else { tps = rec -> a; fns = rec -> b + rec -> c; }; rec -> tp = tps; rec -> fn = fns; if (( tps + fns ) == 0.0 ) return(-1.0); else return( 100 * ( tps / (tps + fns ))); } /* Calculates ischemic duration */ double ish_duration(epi,rec,typeofep) episode epi[MAXEPI]; record *rec; int typeofep; { double durepi,durboth; int i,j; j = 0; durepi = 0.0; /* Overall ischemia */ durboth = 0.0; /* Overlapping ischemia */ for( i = 0; epi[i].offset > 0; i++) if ( typeofep == NO_MATTER ) /* Type does not matter */ { durepi += ( epi[i].offset - epi[i].onset ); durboth += epi[i].overlp; rec -> num_epi = i + 1; /* Number of episodes */ } else if ( epi[i].tip == ISHEMIC ) /* Consider ischemic episodes only */ { durepi += ( epi[i].offset - epi[i].onset ); durboth += epi[i].overlp; j++; rec -> num_epi = j; }; rec -> duration = durepi; rec -> overlap = durboth; /* Total overlap */ rec -> percent = 100 * FACTOR * ( rec -> duration / DUR_REC ); if ( durepi == 0.0 ) return( -1.0); /* Undefined */ else return(100 * (durboth/durepi)); } /* Calculates gross episode detection statistics */ double gross_statistic(auxref,rec,diff) record auxref[MAXREC]; record *rec; int diff; { int i; double tps,fn; tps = 0.0; fn = 0.0; for ( i = 0; i < MAXR; i++ ) { rec -> a += auxref[i].a; rec -> b += auxref[i].b; rec -> c += auxref[i].c; rec -> d += auxref[i].d; rec -> e += auxref[i].e; rec -> f += auxref[i].f; rec -> num_epi += auxref[i].num_epi; rec -> duration += auxref[i].duration; } if ( diff == IMPORTANT ) { tps = rec -> a; fn = rec -> b + rec -> c; } else { tps = rec -> a + rec -> b + rec -> d + rec -> e; fn = rec -> c + rec -> f; } rec -> tp = tps; rec -> fn = fn; rec -> percent = ( 100 * FACTOR * ( rec -> duration / ((double)DUR_TOT ))); if ( tps + fn == 0.0 ) return (-1.0); else return(100 * ( tps / ( tps + fn ))); } /* Calculates average episode detection statistics */ double average_statistic(auxref) record auxref[MAXREC]; { int i; double pvc,j; j = 0.0; pvc = 0.0; for ( i = 0; i < MAXR; i++ ) if ( auxref[i].se != -1.00 ) { pvc += auxref[i].se; j++; } if ( j == 0 ) return(-1.00); else return( pvc / j); } /* Calculates gross deviant duration detection statistics */ double gross_duration(rec) record rec[MAXREC]; { int i; double dur,durboth; dur = durboth = 0.0; for ( i = 0; i < MAXR; i++) { dur += rec[i].duration; durboth += rec[i].overlap; } if ( dur == 0.0 ) return(-1.0); else return(100 * (durboth/dur)); } /* Calculates average deviant duration detection statistics */ double average_duration(rec) record rec[MAXREC]; { int i; double tps,j; tps = 0.0; j = 0.0; for ( i = 0; i < MAXR; i++ ) if ( rec[i].ish_dur != -1.0 ) { tps += rec[i].ish_dur; j++; } if ( j == 0.0 ) return(-1.0); else return(tps/j); } /* Calculates mean value */ double mean(tab,size) double tab[MAXIMAL]; int size; { int i; double sum; sum = 0.0; for (i = 1; i <= size; i++) sum += tab[i]; return(sum/size); } /* Calculates standard deviation value */ double st_variance(difftab,size,mean) double difftab[MAXIMAL]; int size; double mean; { int i; double variance; variance = 0.0; for(i = 1; i <= size; i++) variance += (( difftab[i] - mean ) * ( difftab[i] - mean )); variance /= ( size - 1 ); return(sqrt((double)variance)); } /* Calculates correlation coefficient */ double corr_coefficient(tab1,tab2,size) double tab1[MAXIMAL], tab2[MAXIMAL]; int size; { double mean1, mean2, prod, prod1, prod2; int i; mean1 = mean(tab1,size); mean2 = mean(tab2,size); prod = prod1 = prod2 = 0.0; for ( i = 1; i <= size; i++) { prod += (( tab1[i] - mean1 ) * ( tab2[i] - mean2 )); prod1 += (( tab1[i] - mean1 ) * ( tab1[i] - mean1 )); prod2 += (( tab2[i] - mean2 ) * ( tab2[i] - mean2 )); } prod1 = sqrt(prod1); prod2 = sqrt(prod2); return(prod / ( prod1 * prod2 )); } /* Calculates coefficients of the regression line */ double linear_regression(tabx,tabz,size,a1) double tabx[MAXIMAL], tabz[MAXIMAL], *a1; int size; { int i; double prodxz, prodx, prodz, prodz2; prodxz = prodx = prodz = prodz2 = 0.0; for ( i = 1; i <= size; i++ ) { prodxz += ( tabx[i] * tabz[i] ); prodx += tabx[i]; prodz += tabz[i]; prodz2 += ( tabz[i] * tabz[i] ); } *a1 = ((prodxz - prodx * prodz / size) / (prodz2 - prodz * prodz / size)); return(prodx / size - (*a1) * prodz / size); } /* Calculates percentage of measurements that exceeds the boundary */ double p100(tab,bound,size) double tab[MAXIMAL]; int bound,size; { int i; double j; j = 0.0; for ( i = 1; i <= size; i++ ) if ( abs(tab[i]) >= bound ) j++; return (100 * j / size); } /* Returns maximal element of the table */ double max_el(tab,size) double tab[MAXIMAL]; int size; { double max; int i; max = 0.0; for(i = 1; i <= size; i++) if ( tab[i] >= max ) max = tab[i]; return(max); } /* Calculates the value which 95% of measurements do not exceed */ double e95(tab,size) double tab[MAXIMAL]; int size; { int low,high,mid; double pro; low = 0; high = max_el(tab,size); while ( low <= high ) { mid = ( low + high ) / 2; if ( pro = p100(tab,mid,size) > 5.00 ) low = mid + 1; else if ( pro < 5.00 ) high = mid - 1; else return(mid); } return(low); } /* Deletes no_char characters from the selected character in forward direction */ void str_delete(string,start,no_char) char *string; int start, no_char; { int index1, index2; index1 = index2 = 0; index2 = start + no_char; for (index1 = start; string[index1] = string[index2]; index1++) index2++; } /* writes sensitivity and positive predictivity matrix to the file */ void write_matrix(fs,ref,alg,diff) record ref,alg; FILE *fs; int diff; { fprintf(fs,"Episodes : annotated : %4d ",ref.num_epi); fprintf(fs,"detected : %4d\n",alg.num_epi); if ( diff == IMPORTANT ) fprintf(fs,"Percent of ischemia : %7.3lf ",ref.percent); else fprintf(fs,"Percent of ST changes: %7.3lf ",ref.percent); fprintf(fs," detected : %7.3lf %\n\n",alg.percent); fprintf(fs,"Sensitivity matrix : Positive predictivity matrix :\n"); if ( diff == IMPORTANT ) { fprintf(fs," Ischemic HR related Not epis"); fprintf(fs," Ischemic HR related Not epis\n"); fprintf(fs,"Ischemic I %4d I %4d I %4d I ",ref.a,ref.b,ref.c); fprintf(fs,"Ischemic I %4d I %4d I - I\n",alg.a,alg.d); fprintf(fs,"HR relatedI %4d I %4d I %4d I ",ref.d,ref.e,ref.f); fprintf(fs,"HR relatedI %4d I %4d I - I\n",alg.b,alg.e); fprintf(fs,"Not epis I - I - I - I "); fprintf(fs,"Not epis I %4d I %4d I - I\n\n",alg.c,alg.f); } else { fprintf(fs," ST chang Not epis "); fprintf(fs," ST chang Not epis\n"); fprintf(fs,"ST chang I %4d I %4d I ",ref.a+ref.d+ref.b+ref.e,ref.c+ref.f); fprintf(fs,"ST chang I %4d I - I\n",alg.a+alg.b+alg.d+alg.e); fprintf(fs,"Not epis I - I - I "); fprintf(fs,"Not epis I %4d I - I\n\n",alg.c+alg.f); } fprintf(fs,"Sensitivity : true positives :%4d ",ref.tp); fprintf(fs,"false negatives :%4d\n",ref.fn); fprintf(fs,"Pos.Predictivity : true positives :%4d ",alg.tp); fprintf(fs,"false positives :%4d\n",alg.fn); } /* Calculates gross statistics */ void write_gross_stat(diff) int diff; { FILE *fw; in_record(&allref); in_record(&allalg); allref.se = gross_statistic(recref,&allref,diff); allalg.se = gross_statistic(recalg,&allalg,diff); allref.ase = average_statistic(recref); allalg.ase = average_statistic(recalg); allref.ish_dur = gross_duration(recref); allalg.ish_dur = gross_duration(recalg); allref.aish_dur = average_duration(recref); allalg.aish_dur = average_duration(recalg); } /* Computes episode by episode report */ void write_episode_report(dat,diff,str,tab1,tab2,lead,num,difftab,atab,mtab) FILE *dat; char str[NAME_LEN]; episode tab1[MAXEPI], tab2[MAXEPI]; int lead, diff, *num; double difftab[MAXIMAL],atab[MAXIMAL],mtab[MAXIMAL]; { times cl; char str1[NAME_LEN]; int i, j, old; float percent; double diffave; int zap = 1; strcpy(str1,str); for(i = 0; tab1[i].offset > 0; i++) if (( tab1[i].tip == ISHEMIC ) || ( diff == NO_MATTER )) for(j = 0; tab1[i].ext_pos[j] > 0; j++) if ( tab1[i].ext_lead[j] == lead ) { old = *num; (*num)++; convert_time(FACTOR*tab1[i].ext_pos[j],&cl); diffave = -1 * ( tab1[i].ext_val[j] - tab2[i].ext_val[j] ); st_tab[*num].diff = diffave; st_tab[*num].ann = tab1[i].ext_val[j]; st_tab[*num].meas = tab2[i].ext_val[j]; st_tab[*num].percent = 100 * ( diffave / tab1[i].ext_val[j] ); webe[nrebe].episode=*num; strcpy(webe[nrebe].rec,GetName(str1)); webe[nrebe].lead=lead; webe[nrebe].time=tab1[i].ext_pos[j]; webe[nrebe].meas=tab2[i].ext_val[j]; webe[nrebe].annot=tab1[i].ext_val[j]; webe[nrebe].diff=diffave; webe[nrebe].percent=100 * ( diffave / tab1[i].ext_val[j] ); nrebe++; strcpy(st_tab[*num].name,GetName(str)); st_tab[*num].lead = lead; if ( old > 1 ) if (st_tab[*num].lead == st_tab[old].lead) zap++; else zap = 1; st_tab[*num].number = zap; difftab[*num] = diffave; atab[*num] = tab1[i].ext_val[j]; mtab[*num] = tab2[i].ext_val[j]; percent = 100 * ( diffave / tab1[i].ext_val[j] ); } } /* Randomly selects records for the new database */ void choose_base(tab) int tab[MAXREC]; { int i; for ( i = 0; i < MAXR; i++ ) tab[i] = random() % MAXR; } /* Returns set of records of the new database */ void copy_array(base,old,new) int base[MAXREC]; record old[MAXREC], new[MAXREC]; { int i,j; for ( i = 0; i < MAXR; i++ ) { j = base[i]; new[i] = old[j]; } } /* Initializes an integer table */ void ini(tab) int tab[EXACT]; { int i; for ( i = 0; i < EXACT; i++) tab[i] = 0; } /* Counts results of the bootstrap method */ void count_res(res,tab) double res; int tab[EXACT]; { int i; double l; l = 10.0 * res; i = l >= 0 ? l + 0.5 : l - 0.5; tab[i]++; } /* Calculates confidence limits */ double confidence_limits(limit,tab,trials) double limit; int tab[EXACT]; long trials; { long i, suma; double bound; bound = limit * trials; suma = 0; for ( i = 0; suma <= bound; i++) suma += tab[i]; return((i-1)/10.0); } /* Returns maximum and minimum statistics */ double minmax(tab,min) int tab[EXACT]; double *min; { long i,j; double max; *min = 0; for ( i = 0; *min == 0; i++) if ( tab[i] > 0 ) *min = i / 10.0; for ( j = i; j < EXACT; j++) if ( tab[j] > 0 ) max = j; return(max/10.0); } /* Calculates histogram of the bootstrap method */ void make_hist(tab,num,hist) int tab[EXACT]; long num; double hist[100]; { int i, j, k; double suma; k = 0; for ( j = 0; j < 100; j++) { suma = 0.0; for ( i = 0; i < 10; i++) suma += tab[k+i]; hist[j] = suma / num; k += 10; } } /* Calculates confidence limits, minimal, maximal, median and mean results, and difference between the mean and the 5% confidence limits */ void store_result(tab,trials,tab1) int tab[EXACT]; long trials; double tab1[NUMRES]; { double min; tab1[0] = confidence_limits(0.05,tab,trials); tab1[1] = confidence_limits(0.16,tab,trials); tab1[2] = confidence_limits(0.84,tab,trials); tab1[3] = confidence_limits(0.95,tab,trials); tab1[4] = minmax(tab,&min); tab1[5] = min; tab1[6] = ( min + tab1[4] ) / 2; tab1[7] = confidence_limits(0.5,tab,trials); tab1[8] = tab1[7] - tab1[0]; } /* Performs evaluation on single record */ int Single(dat_1, dat_2, diff) char dat_1[NAME_LEN], dat_2[NAME_LEN]; int diff; { char dat[NAME_LEN], number[NAME_LEN], temp[NAME_LEN], header[NAME_LEN], rec_head[NAME_LEN]; FILE *fref, *falg, *fw; int i, j=0; char file_ref[NAME_LEN],file_alg[NAME_LEN],file_cmr[NAME_LEN],temp_name[NAME_LEN]; in_record(&allref); in_record(&allalg); fref=fopen(alg_name,"rt"); sprintf(rec_head,"%s",dat_2); if (Test(fref,alg_name)==-1) return (-1); while (!feof(fref)) { fscanf(fref,"%s\n",temp_name); if (strstr(temp_name,dat_2)!=NULL) sprintf(rec_head,"%s",temp_name); } fclose(fref); init_episode(&epiref); init_episode(&epialg); init_episode(ep_lead0); init_episode(ep_lead1); init_episode(ep_lead2); sprintf(header,"%s%s",path,rec_head); strcpy(number,dat_2); sprintf(file_ref,"%s.ref",header); sprintf(file_alg,"%s.alg",header); sprintf(file_cmr,"%s.cmr",header); sprintf(header,"%s%s",path,rec_head); if ((DUR_REC=Open_Header(header))<0) return (-1); fref = fopen(file_cmr,"r"); if ( Test(fref,file_cmr) == -1 ) { return(-1); } fill_array(fref,&epiref); fclose(fref); fref = fopen(file_ref,"r"); if ( Test(fref,file_ref) == -1 ) { return(-1); } fref = fopen(file_ref,"r"); fill_ep_lead(fref,ep_lead0,ep_lead1,ep_lead2); fclose(fref); falg = fopen(file_alg,"r"); if ( Test(falg,file_alg) == -1 ) { return(-1); } fill_array(falg,&epialg); fclose(falg); determine_status(&epiref,epialg,diff); determine_status(&epialg,epiref,diff); fill_record(epiref,&allref); fill_record(epialg,&allalg); allref.se = sensitivity(&allref,diff); allalg.se = sensitivity(&allalg,diff); allref.ish_dur = ish_duration(epiref,&allref,diff); allalg.ish_dur = ish_duration(epialg,&allalg,diff); examine_valid=0; strcpy(writeX,""); sprintf(dat,"Episode by episode report, record: %s\n",GetName(rec_head)); strcat(writeX,dat); if (diff == IMPORTANT ) sprintf(dat,"Evaluation: %s Evaluation mode: Ischemic/Heart-rate related changes",RemoveDot(file_name)); else sprintf(dat,"Evaluation: %s Evaluation mode: ST segment changes\n",RemoveDot(file_name)); strcat(writeX,dat); sprintf(dat,"\n"); strcat(writeX,dat); Xwrite_matrix(allref,allalg,diff); Xwrite_statistics(allref,allalg); Xwrite_episodes(epiref,0); Xwrite_episodes(epialg,1); } /* Performs evaluation on entire database */ void all_records(dat_1,diff) char dat_1[NAME_LEN]; int diff; { FILE *fp,*fo,*fs,*fref,*falg,*fa; char dat_3[NAME_LEN],filename_01[NAME_LEN], filename_0[NAME_LEN], filename_1[NAME_LEN]; char filename_0t[NAME_LEN], filename_1t[NAME_LEN]; char filename_00[NAME_LEN], filename_11[NAME_LEN], path0[NAME_LEN], path1[NAME_LEN]; char filename_C[NAME_LEN],recName1[NAME_LEN],recName2[NAME_LEN]; char dummystr[NAME_LEN]; int i , read; REC_COUNT=0; DUR_TOT=0; REC_TOT=0; fp = fopen(dat_1,"r"); if ( Test(fp,dat_1) == -1) return; init_record(&recref); init_record(&recalg); i = 0; Init_Structs(); MAXR=0; while (((read=fscanf(fp,"%s",filename_00))==1) && ( i < MAXREC )) /*( feof(fp) == NULL )*/ { strcpy(path0,path); strcpy(path1,path); strcpy(recName,filename_00); strcpy(filename_0t, strcat(path0,filename_00)); strcpy(filename_1t, strcat(path1,filename_00)); init_episode(&epiref); init_episode(&epialg); if ((DUR_REC=Open_Header(filename_0t))==-1) /* !!! */ { fclose(fp); strcpy(writeX,""); return; } else { REC_COUNT++; MAXR++; DUR_TOT+=(double)DUR_REC; REC_TOT++; sprintf(filename_0,"%s.ref",filename_0t); sprintf(filename_1,"%s.alg",filename_1t); sprintf(filename_C,"%s.cmr",filename_0t); fref = fopen(filename_C,"r"); if ( Test(fref,filename_C) == -1 ) { fclose(fp); strcpy(writeX,""); return; } fill_array(fref,&epiref); fclose(fref); falg = fopen(filename_1,"r"); if ( Test(falg,filename_1) == -1 ) { fclose(fp); strcpy(writeX,""); return; } fill_array(falg,&epialg); fclose(falg); determine_status(&epiref,epialg,diff); determine_status(&epialg,epiref,diff); fill_record(epiref,&recref[i]); fill_record(epialg,&recalg[i]); recref[i].se = sensitivity(&recref[i],diff); recalg[i].se = sensitivity(&recalg[i],diff); recref[i].ish_dur = ish_duration(epiref,&recref[i],diff); recalg[i].ish_dur = ish_duration(epialg,&recalg[i],diff); if (i>=tot_rec) { strcpy(evaluated[i].rec,GetName(recName)); tot_rec++; } i++; } } fclose(fp); all_valid=1; write_gross_stat(diff); examine_valid=0; } /* Performs bootstrap evaluation */ void bootstrap(diff,trials) int diff; long trials; { int newbase[MAXREC]; int gsens[EXACT], gpred[EXACT], asens[EXACT], apred[EXACT]; int gdurse[EXACT], adurse[EXACT], gdurp[EXACT], adurp[EXACT]; record trialref[MAXREC], trialalg[MAXREC]; record rec; double griese, griepp, aviese, aviepp, gridse, gridpp, avidse, avidpp; long i; ini(gsens); ini(gpred); ini(asens); ini(apred); ini(gdurse); ini(adurse); ini(gdurp); ini(adurp); srand(1); for ( i = 0; i < trials; i++ ) { choose_base(newbase); copy_array(newbase,recref,trialref); copy_array(newbase,recalg,trialalg); in_record(&rec); griese = gross_statistic(trialref,&rec,diff); count_res(griese,gsens); in_record(&rec); griepp = gross_statistic(trialalg,&rec,diff); count_res(griepp,gpred); aviese = average_statistic(trialref); count_res(aviese,asens); aviepp = average_statistic(trialalg); count_res(aviepp,apred); gridse = gross_duration(trialref); count_res(gridse,gdurse); gridpp = gross_duration(trialalg); count_res(gridpp,gdurp); avidse = average_duration(trialref); count_res(avidse,adurse); avidpp = average_duration(trialalg); count_res(avidpp,adurp); } store_result(gsens,trials,&gsensr); store_result(gpred,trials,&gpredr); store_result(asens,trials,&asensr); store_result(apred,trials,&apredr); store_result(gdurse,trials,&gdurser); store_result(gdurp,trials,&gdurpr); store_result(adurse,trials,&adurser); store_result(adurp,trials,&adurpr); make_hist(gsens,trials,&hist_gse); make_hist(gpred,trials,&hist_gpn); make_hist(asens,trials,&hist_ase); make_hist(apred,trials,&hist_apn); make_hist(gdurse,trials,&hist_gdurse); make_hist(gdurp,trials,&hist_gdurpn); make_hist(adurse,trials,&hist_adurse); make_hist(adurp,trials,&hist_adurpn); } /* Returns Euclidean distance between two points */ long evklid_dist ( x1, y1, x2, y2 ) int x1, y1, x2, y2; { long z1, z2; if ( x2 > x1 ) z1 = (x2 - x1) * (x2 - x1); else z1 = (x1 - x2) * (x1 - x2); if ( y2 > y1 ) z2 = (y2 - y1) * (y2 - y1); else z2 = (y1 - y2) * (y1 - y2); return(z1 + z2); } /* Returns the episode which is the nearest to the specified point */ int find_pixel( x, y, tab) int x, y; coor tab[MAXIMAL]; { int i, epi; long min, a; min = 1000000; for (i = 1; i <= extepi; i++) { if (( a = evklid_dist(x, y, tab[i].x, tab[i].y)) < min ) { min = a; epi = i; } } return(epi); } /* Writes statistics for a single record */ int write_single(char fname[NAME_LEN],char rname[NAME_LEN],int diff) { FILE *fs; char dat_4[NAME_LEN]; sprintf(dat_4,"%s%s.%s",fname,diff==IMPORTANT?"_ih":"_st",rname); fs = fopen(dat_4,"w"); if (Test_out(fs,dat_4)==-1) return (-1); fprintf(fs,"%s",writeX); return (0); } /* Writes raw statistics */ int write_raw(char fname[NAME_LEN],int diff) { FILE *fw; fw = fopen(fname, "w"); if (Test_out(fw,fname)==-1) return (-1); else { fprintf(fw,"Raw statistics\n"); if ( diff == IMPORTANT ) { fprintf(fw, "Ischemic and Heart-rate related episodes are differentiated\n\n"); write_matrix(fw,allref,allalg,diff); fprintf(fw,"IE Sensitivity = %6.2lf [g] %6.2lf [a] ",allref.se,allref.ase); fprintf(fw,"IE PositPredict = %6.2lf [g] %6.2lf [a]\n",allalg.se,allalg.ase); fprintf(fw,"ID Sensitivity = %6.2lf [g] %6.2lf [a] ", allref.ish_dur,allref.aish_dur); fprintf(fw,"ID PositPredict = %6.2lf [g] %6.2lf [a]\n\n",allalg.ish_dur,allalg.aish_dur); } else { fprintf(fw, "Ischemic and Heart-rate related episodes are considered as episodes of single type\n\n"); write_matrix(fw,allref,allalg,diff); fprintf(fw,"SE Sensitivity = %6.2lf [g] %6.2lf [a] ",allref.se,allref.ase); fprintf(fw,"SE PositPredict = %6.2lf [g] %6.2lf [a]\n",allalg.se,allalg.ase); fprintf(fw,"SD Sensitivity = %6.2lf [g] %6.2lf [a] ",allref.ish_dur,allref.aish_dur); fprintf(fw,"SD PositPredict = %6.2lf [g] %6.2lf [a]\n\n",allalg.ish_dur,allalg.aish_dur); } fclose(fw); } return (0); } /* Writes record-by-record statistics */ int write_rbr() { int i; char buf[LEN_SHORTER]; strcpy(writeX,""); sprintf(buf,"Record by record statistics\n"); strcat(writeX,buf); if ( diff == IMPORTANT ) sprintf(buf,"Ischemic and Heart-rate related episodes are differentiated\n"); else sprintf(buf,"Ischemic and Heart-rate related episodes are considered as episodes of single type\n"); strcat(writeX,buf); for (i=0;i=2) { if (memcmp(argv[1],"-h",2)==0) { if ((help=fopen("eval_st.hlp","rt"))==NULL) { fprintf(stderr,"No eval_st.hlp file\n"); } else { while (!feof(help)) { fgets(buf, sizeof(char)*LEN_SHORTER, help); if (!feof(help)) fprintf(stderr,"%s",buf); } fclose(help); } return; } } if (argc<4) { fprintf(stderr,"Usage: %s -h \n",pname); fprintf(stderr,"Usage: %s -r _.evl -[i|s] \n",pname); fprintf(stderr,"Usage: %s -a _.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname); return; } if ((*++argv)[0] == '-') for (s = argv[0] + 1; *s != '\0';s++) switch (*s) { case 'r' : if (argc<5) { fprintf(stderr,"Usage: %s -r _.evl -[i|s] \n",pname); return; } if (stat(argv[1], &stat_val) == 0) if ((stat_val.st_mode & S_IFMT )== S_IFDIR) { fprintf(stderr,"Enter project file .evl\n"); return ; } sprintf(alg_name,"%s",argv[1]); sprintf(file_name,"%s",argv[1]); sprintf(ref_name,"%s",argv[2]); if (*(argv + 3)[0] == '-' ) for (t = (argv+3)[0] + 1; *t != '\0'; t++) switch (*t) { case 'i' : { diff = IMPORTANT; Single(alg_name,ref_name,IMPORTANT); write_single(RemoveDot(alg_name),ref_name,IMPORTANT); } break; case 's' : { diff = NO_MATTER; Single(alg_name,ref_name,NO_MATTER); write_single(RemoveDot(alg_name),ref_name,NO_MATTER); } break; default : fprintf(stderr,"Usage: %s -r _.evl -[i|s] \n",pname); break; } else { diff = IMPORTANT; Single(alg_name,ref_name,IMPORTANT); write_single(RemoveDot(alg_name),ref_name,NO_MATTER); } break; case 'a' : if (argc<4) { fprintf(stderr,"Usage: %s -a _.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname); return; } if (stat(argv[1], &stat_val) == 0) if ((stat_val.st_mode & S_IFMT )== S_IFDIR) { fprintf(stderr,"Enter project file .evl\n"); return ; } sprintf(alg_name,"%s",argv[1]); sprintf(file_name,"%s",argv[1]); if (*(argv + 2)[0] == '-' ) for (t = (argv+2)[0] + 1; *t != '\0'; t++) switch (*t) { case 'i' : diff = IMPORTANT; if (argc==4) { sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); all_records(*(argv + 1),IMPORTANT); if (all_valid==0) return; write_rbr(); write_raw(w1_name,IMPORTANT); write_rbr_file(); } else if (*(argv + 3)[0] == '-' ) for (t1 = (argv+3)[0] + 1; *t1 != '\0'; t1++) switch(*t1) { case 'e' : { all_records(alg_name,IMPORTANT); if (all_valid==0) return; write_rbr(); write_rbr_file(); st_deviation(alg_name,IMPORTANT); if (dev_valid==0) return; write_ebe(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); sprintf(w2_name,"%s%s.ext",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,IMPORTANT); } break; case 'b' : if ( argc == 6 ) { all_records(alg_name,IMPORTANT); if (all_valid==0) return; write_rbr(); write_rbr_file(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,IMPORTANT); bootstrap(IMPORTANT,atol(argv[4])); sprintf(w2_name,"%s%s.bts",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); Xwrite_boot(); write_boot1(w2_name,IMPORTANT,10000); } else { all_records(alg_name,IMPORTANT); if (all_valid==0) return; write_rbr(); write_rbr_file(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,IMPORTANT); bootstrap(IMPORTANT,10000); sprintf(w2_name,"%s%s.bts",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); Xwrite_boot(); write_boot1(w2_name,IMPORTANT,10000); } break; default : fprintf(stderr,"Usage: %s -a _.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname); break; } break; case 's' : diff = NO_MATTER; if (argc==4) { sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); all_records(alg_name,NO_MATTER); if (all_valid==0) return; write_rbr(); write_rbr_file(); write_raw(w1_name,NO_MATTER); } else if (*(argv + 3)[0] == '-' ) { for (t1 = (argv+3)[0] + 1; *t1 != '\0'; t1++) switch(*t1) { case 'e' : { all_records(alg_name,NO_MATTER); if (all_valid==0) return; write_rbr(); write_rbr_file(); st_deviation(alg_name,NO_MATTER); if (dev_valid==0) return; write_ebe(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); sprintf(w2_name,"%s%s.ext",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,NO_MATTER); } break; case 'b' : if ( argc == 6 ) { all_records(alg_name,NO_MATTER); if (all_valid==0) return; write_rbr(); write_rbr_file(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,NO_MATTER); bootstrap(NO_MATTER,atol(argv[4])); sprintf(w2_name,"%s%s.bts",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); Xwrite_boot(); write_boot1(w2_name,NO_MATTER,atol(argv[4])); } else { all_records(alg_name,NO_MATTER); if (all_valid==0) return; write_rbr(); write_rbr_file(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,NO_MATTER); bootstrap(NO_MATTER,10000); sprintf(w2_name,"%s%s.bts",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); Xwrite_boot(); write_boot1(w2_name,NO_MATTER,10000); } break; default:fprintf(stderr,"Usage: %s -a _.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname); break; }} break; default : fprintf(stderr,"Usage: %s -a _ -[i|s] [-e|-b [NR_TRIALS]]\n",pname); break; } else { if (stat(argv[1], &stat_val) == 0) if ((stat_val.st_mode & S_IFMT )== S_IFDIR) { fprintf(stderr,"Enter project file .evl\n"); return ; } sprintf(alg_name,"%s",alg_name); sprintf(file_name,"%s",alg_name); diff = IMPORTANT; all_records(alg_name,IMPORTANT); if (all_valid==0) return; write_rbr(); write_rbr_file(); sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st"); write_raw(w1_name,IMPORTANT); } break; break; default : { fprintf(stderr,"Usage: %s -h \n",pname); fprintf(stderr,"Usage: %s -r _.evl -[i|s] \n",pname); fprintf(stderr,"Usage: %s -a _.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname); argc = 0; } break; } #endif } /* ************************************************************************************* */