EVAL_ST Tool 1.0.0
(142,468 bytes)
/* ************************************************************************************* */
/* */
/* 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 <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <arpa/inet.h>
#include <string.h>
#include <math.h>
#if (motif) /* MOTIF SECTION - includes */
#include <Xm/Xm.h>
#include <Xm/BulletinB.h>
#include <Xm/CascadeB.h>
#include <Xm/CascadeBG.h>
#include <Xm/DialogSP.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>
#include <Xm/MainW.h>
#include <Xm/MenuShell.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/ScrollBar.h>
#include <Xm/ScrolledW.h>
#include <Xm/SelectioB.h>
#include <Xm/SeparatoG.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/ToggleB.h>
#include <Xm/ToggleBG.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Shell.h>
#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<j) && (name[i]!='.'))
{
n2[i]=name[i];
i++;
}
n2[i]='\0';
if (nam2!=NULL) free(nam2);
nam2=(char *) malloc(sizeof(char)*(strlen(n2))+4);
strcpy(nam2,n2);
return(nam2);
}
/* Opens header file for the record */
long Open_Header(char *record)
{
FILE *hea;
char FName[NAME_LEN],rec[NAME_LEN];
int leads,freq,n;
long Duration;
sprintf(FName,"%s.hea",record);
hea=fopen(FName,"rt");
if (Test(hea,FName)==-1) return (-1);
fscanf(hea,"%s %d %d %ld",rec,&leads,&freq,&Duration);
fclose(hea);
return (Duration*4); /* Length of the record in milliseconds */
}
/* Tests if the file was successfully opened for reading */
int Test(fp,filename)
FILE *fp;
char filename[NAME_LEN];
{
char message[NAME_LEN];
#if (motif) /* MOTIF SECTION - dialog for input files */
XmString message_string;
Arg args[2];
if ( fp == NULL )
{
sprintf( message, " Can't open file %s",GetName(filename));
message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[0], XmNmessageString, message_string);
XtSetValues(fbb, args, 1);
XtManageChild(fbb);
return(-1);
}
else
return(0);
#else /* END OF MOTIF SECTION */
if ( fp == NULL )
{
fprintf(stderr,"Can't open file %s\n",GetName(filename));
return (-1);
}
else return (0);
#endif
}
/* Tests if the file was successfully opened for writing */
int Test_out(fp,filename)
FILE *fp;
char filename[NAME_LEN];
{
char message[NAME_LEN];
#if (motif) /* MOTIF SECTION - dialog for output files */
XmString message_string;
Arg args[2];
if ( fp == NULL )
{
sprintf( message, " Error writing file %s",GetName(filename));
message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[0], XmNmessageString, message_string);
XtSetValues(fbb, args, 1);
XtManageChild(fbb);
return(-1);
}
else
return(0);
#else /* END OF MOTIF SECTION */
if ( fp == NULL )
{
fprintf(stderr,"Error writing file %s\n",GetName(filename));
return (-1);
}
else return (0);
#endif
}
/* Calculates the ST segment deviation measurement statistics */
void st_deviation(dat_1,diff)
char dat_1[NAME_LEN];
int diff;
{
FILE *fp,*fo,*fw,*fra,*frt;
char dat_3[NAME_LEN], dat_4[NAME_LEN],dat[NAME_LEN];
char filename_00[NAME_LEN], filename_11[NAME_LEN], path0[NAME_LEN], path1[NAME_LEN];
char filename_01[NAME_LEN], filename_0[NAME_LEN], filename_1[NAME_LEN], filename_0t[NAME_LEN], filename_1t[NAME_LEN];
episode ra_epi[MAXEPI],rt_epi[MAXEPI];
double difftab[MAXIMAL], anntab[MAXIMAL], meatab[MAXIMAL];
int i,j ,read,l;
times cl;
fp = fopen(dat_1,"r");
if ( Test(fp,dat_1) == -1 )
return;
i = 0;
j = 0;
initial(difftab);
nrebe=0;
while (((read=fscanf(fp,"%s",filename_00)) == 1 ) && ( i < MAXREC ))
{
strcpy(path0,path);
strcpy(path1,path);
strcpy(filename_0, strcat(path0,filename_00));
strcpy(filename_1, strcat(path1,filename_00));
REC_COUNT++;
strcpy(path0,path);
strcpy(path1,path);
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);
return;
}
DUR_TOT+=(double)DUR_REC;
REC_TOT++;
sprintf(filename_0,"%s.ref",filename_0t);
sprintf(filename_1,"%s.dev",filename_1t);
sprintf(filename_0R,"%s.ref",filename_00);
sprintf(filename_0P,"%s.dev",filename_00);
init_episode(&rt_epi);
init_episode(&ra_epi);
fra = fopen(filename_1,"r");
if ( Test(fra,filename_1) == -1 )
{
fclose(fp);
return;
}
fill_array(fra,&ra_epi); /* Algorithm episodes */
fclose(fra);
frt = fopen(filename_0,"r");
if ( Test(frt,filename_0) == -1 )
{
fclose(fp);
return;
}
fill_array(frt,&rt_epi); /* Reference episodes */
fclose(frt);
str_delete(filename_0,0,strlen(filename_0) - 6);
str_delete(filename_1,0,strlen(filename_1) - 6);
write_episode_report(fw,diff,filename_00,rt_epi,ra_epi,0,
&j,difftab,anntab,meatab);
write_episode_report(fw,diff,filename_00,rt_epi,ra_epi,1,
&j,difftab,anntab,meatab);
write_episode_report(fw,diff,filename_00,rt_epi,ra_epi,2,
&j,difftab,anntab,meatab);
i++;
}
extepi = j;
mvalue = mean(difftab,j);
stand_dev = st_variance(difftab,j,mvalue);
corr = corr_coefficient(anntab,meatab,j);
k = 0.0;
n1 = linear_regression(anntab,meatab,j,&k);
phund = p100(difftab,100,j);
enfive = e95(difftab,j);
fclose(fp);
dev_valid=1;
strcpy(writeX,"");
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;l<nrebe;l++)
{
sprintf(dat," %4d %8s %d ",webe[l].episode,webe[l].rec,webe[l].lead);
strcat(writeX,dat);
convert_time(FACTOR*webe[l].time,&cl);
sprintf(dat,"%2d:%02d:%02d ",cl.hour,cl.min,cl.sec);
strcat(writeX,dat);
sprintf(dat," %4d",webe[l].meas);
strcat(writeX,dat);
sprintf(dat," %6d",webe[l].annot);
strcat(writeX,dat);
sprintf(dat," %6.0f",webe[l].diff);
strcat(writeX,dat);
sprintf(dat," %8.2f\n",webe[l].percent);
strcat(writeX,dat);
}
}
/* Writes sensitivity and positive predictivity performances to the buffer */
void Xwrite_statistics(ref,alg)
record ref,alg;
{
char dat[NAME_LEN];
if ( diff == IMPORTANT )
{
if ( ref.se == -1.0 )
sprintf(dat,"IE Sensitivity = undefined ");
else
sprintf(dat,"IE Sensitivity = %9.2lf ",ref.se );
strcat(writeX,dat);
if ( alg.se == -1.0 )
sprintf(dat,"IE PositPredict = undefined \n");
else
sprintf(dat,"IE PositPredict = %9.2lf \n",alg.se );
strcat(writeX,dat);
if ( ref.ish_dur == -1.0 )
sprintf(dat,"ID Sensitivity = undefined ");
else
sprintf(dat,"ID Sensitivity = %9.2lf ",ref.ish_dur);
strcat(writeX,dat);
if ( alg.ish_dur == -1.0 )
sprintf(dat,"ID PositPredict = undefined \n");
else
sprintf(dat,"ID PositPredict = %9.2lf\n",alg.ish_dur);
strcat(writeX,dat);
}
else
{
if ( ref.se == -1.0 )
sprintf(dat,"SE Sensitivity = undefined ");
else
sprintf(dat,"SE Sensitivity = %9.2lf ",ref.se );
strcat(writeX,dat);
if ( alg.se == -1.0 )
sprintf(dat,"SE PositPredict = undefined \n");
else
sprintf(dat,"SE PositPredict = %9.2lf \n",alg.se );
strcat(writeX,dat);
if ( ref.ish_dur == -1.0 )
sprintf(dat,"SD Sensitivity = undefined ");
else
sprintf(dat,"SD Sensitivity = %9.2lf ",ref.ish_dur);
strcat(writeX,dat);
if ( alg.ish_dur == -1.0 )
sprintf(dat,"SD PositPredict = undefined \n");
else
sprintf(dat,"SD PositPredict = %9.2lf\n",alg.ish_dur);
strcat(writeX,dat);
}
}
/* Writes sensitivity and positive predictivity matrices to the buffer */
void Xwrite_matrix(ref,alg,diff)
record ref,alg;
int diff;
{
char dat[NAME_LEN];
sprintf(dat,"Episodes : annotated : %4d ",ref.num_epi);
strcat(writeX,dat);
sprintf(dat,"detected : %4d\n",alg.num_epi);
strcat(writeX,dat);
if ( diff == IMPORTANT )
sprintf(dat,"Percent of ischemia : %7.3lf ",ref.percent);
else
sprintf(dat,"Percent of ST changes: %7.3lf ",ref.percent);
strcat(writeX,dat);
sprintf(dat," detected : %7.3lf %\n\n",alg.percent);
strcat(writeX,dat);
sprintf(dat,"Sensitivity matrix : Positive predictivity matrix :\n");
strcat(writeX,dat);
if ( diff == IMPORTANT )
{
sprintf(dat," Ischemic HR related Not epis");
strcat(writeX,dat);
sprintf(dat," Ischemic HR related Not epis\n");
strcat(writeX,dat);
sprintf(dat,"Ischemic I %4d I %4d I %4d I ",ref.a,ref.b,ref.c);
strcat(writeX,dat);
sprintf(dat,"Ischemic I %4d I %4d I - I\n",alg.a,alg.d);
strcat(writeX,dat);
sprintf(dat,"HR relatedI %4d I %4d I %4d I ",ref.d,ref.e,ref.f);
strcat(writeX,dat);
sprintf(dat,"HR relatedI %4d I %4d I - I\n",alg.b,alg.e);
strcat(writeX,dat);
sprintf(dat,"Not epis I - I - I - I ");
strcat(writeX,dat);
sprintf(dat,"Not epis I %4d I %4d I - I\n\n",alg.c,alg.f);
strcat(writeX,dat);
}
else
{
sprintf(dat," ST chang Not epis ");
strcat(writeX,dat);
sprintf(dat," ST chang Not epis\n");
strcat(writeX,dat);
sprintf(dat,"ST chang I %4d I %4d I ",ref.a+ref.d+ref.b+ref.e,ref.c+ref.f);
strcat(writeX,dat);
sprintf(dat,"ST chang I %4d I - I\n",alg.a+alg.b+alg.d+alg.e);
strcat(writeX,dat);
sprintf(dat,"Not epis I - I - I ");
strcat(writeX,dat);
sprintf(dat,"Not epis I %4d I - I\n\n",alg.c+alg.f);
strcat(writeX,dat);
}
sprintf(dat,"Sensitivity : true positives :%4d ",ref.tp);
strcat(writeX,dat);
sprintf(dat,"false negatives :%4d\n",ref.fn);
strcat(writeX,dat);
sprintf(dat,"Pos.Predictivity : true positives :%4d ",alg.tp);
strcat(writeX,dat);
sprintf(dat,"false positives :%4d\n",alg.fn);
strcat(writeX,dat);
}
/* Writes the reference/algorithm episode statistics to the buffer */
void Xwr_episode(ref,d,i)
episode ref;
int i;
{
int j;
times cl;
char string[LEN_SHORTER], dat[NAME_LEN];
if ( d == 0 )
strcpy(string,"Reference");
else
strcpy(string,"Algorithm");
sprintf(dat,"\n%s episode number : %4d",string,i+1);
strcat(writeX,dat);
convert_time(FACTOR*ref.onset,&cl);
sprintf(dat,"\nOnset : %2d:%02d:%02d ",cl.hour,cl.min,cl.sec);
strcat(writeX,dat);
convert_time(FACTOR*ref.offset,&cl);
sprintf(dat," Offset : %2d:%02d:%02d \n",cl.hour,cl.min,cl.sec);
strcat(writeX,dat);
for ( j = 0; j < ref.num_ext; j++ )
{
convert_time(FACTOR*ref.ext_pos[j],&cl);
sprintf(dat,"Position of extrema : %2d:%02d:%02d ",cl.hour,cl.min,cl.sec);
strcat(writeX,dat);
sprintf(dat,"Value of extrema : %4ld [uV]\n",ref.ext_val[j]);
strcat(writeX,dat);
}
if ( diff == IMPORTANT )
{
switch ( ref.status )
{
case 0 : sprintf(dat,"Status : ischemic episode ");
break;
case -1 : sprintf(dat,"Status : heart-rate related episode ");
break;
case 3 : sprintf(dat,"Status : missed episode ");
break;
};
strcat(writeX,dat);
}
else
{
switch ( ref.status )
{
case 0 : sprintf(dat,"Status : ST segment episode ");
break;
case -1 : sprintf(dat,"Status : ST segment episode ");
break;
case 3 : sprintf(dat,"Status : missed episode ");
break;
};
strcat(writeX,dat);
}
if ( diff == IMPORTANT )
{
switch ( ref.tip )
{
case 0 : sprintf(dat," Type: ischemic episode\n");
break;
case -1 : sprintf(dat," Type: heart-rate related episode\n");
break;
};
strcat(writeX,dat);
}
else
{
sprintf(dat," Type: ST segment episode\n");
strcat(writeX,dat);
}
switch ( ref.match )
{
case 0 : sprintf(dat,"Match: overlaps at least one extrema\n");
strcat(writeX,dat);
break;
case 1 : sprintf(dat,"Match : overlaps >= 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;l<nrebe;l++)
{
sprintf(dat," %4d %8s %d ",webe[l].episode,webe[l].rec,webe[l].lead);
strcat(writeX,dat);
convert_time(FACTOR*webe[l].time,&cl);
sprintf(dat,"%2d:%02d:%02d ",cl.hour,cl.min,cl.sec);
strcat(writeX,dat);
sprintf(dat," %4d",webe[l].meas);
strcat(writeX,dat);
sprintf(dat," %6d",webe[l].annot);
strcat(writeX,dat);
sprintf(dat," %6.0f",webe[l].diff);
strcat(writeX,dat);
sprintf(dat," %8.2f\n",webe[l].percent);
strcat(writeX,dat);
}
}
#if (motif) /* MOTIF SECTION - callback functions */
/* Clears the pixmap and copies it to the drawing area */
void ClearScreen()
{
XFillRectangle (XtDisplay (workarea), pixmap, wall_gc, 0, 0, W_WIDTH, W_HEIGHT);
XCopyArea (XtDisplay(workarea), pixmap, XtWindow(workarea),
wall_gc, 0, 0, W_WIDTH, W_HEIGHT, 0, 0);
}
/* Copies the pixmap to the drawing area */
void PaintScreen()
{
XCopyArea (XtDisplay(workarea), pixmap, XtWindow(workarea),
wall_gc, 0, 0, W_WIDTH, W_HEIGHT, 0, 0);
}
/* In case of EXPOSE event redraws drawing area */
void CBDraw (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
XmDrawingAreaCallbackStruct *cbs =
(XmDrawingAreaCallbackStruct *) call_data;
XCopyArea (cbs->event->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;i<tot_rec;i++)
{
if ((i+1)%5==0)
sprintf(eval_mess,"%s: %s \n",evaluated[i].rec,evaluated[i].is?"Y":"N");
else
sprintf(eval_mess,"%s: %s ",evaluated[i].rec,evaluated[i].is?"Y":"N");
strcat(recs_mess,eval_mess);
}
sprintf(eval_mess,"\n\nST segment changes\n");
strcat(recs_mess,eval_mess);
for (i=0;i<tot_rec;i++)
{
if ((i+1)%5==0)
sprintf(eval_mess,"%s: %s \n",evaluated[i].rec,evaluated[i].st?"Y":"N");
else
sprintf(eval_mess,"%s: %s ",evaluated[i].rec,evaluated[i].st?"Y":"N");
strcat(recs_mess,eval_mess);
}
pos = XmTextGetLastPosition (text_stt);
XmTextReplace (text_stt, pos, pos, recs_mess);
XmTextSetCursorPosition(text_stt,0);
}
/* Creates and manages the Help dialog */
void CBHelp (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
int n;
Arg args[24];
XFontStruct *newfont;
XmFontList newfontlist;
static Widget text_hlp;
Widget hw;
Widget button;
char fname[NAME_LEN];
XmString title_string;
if (!dialog_hlp)
{
n = 0;
XtSetArg (args[n], XmNtitle, " Help "); n++;
XtSetArg (args[n], XmNallowShellResize, True); n++;
dialog_hlp = (Widget) XmCreateBulletinBoardDialog
( toplevel, "Hlp_shell", args, n);
newfont = XLoadQueryFont (XtDisplay(dialog_hlp), "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, 83); 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_hlp = (Widget) XmCreateScrolledText(dialog_hlp, "Raw_text", args, n);
}
sprintf(fname,"%s.hlp",hname);
ReadTextFromFile (text_hlp,fname);
XmTextSetCursorPosition(text_hlp,0);
XtManageChild(text_hlp);
XtManageChild(dialog_hlp);
}
/* Selection of the "Ischemic/Heart rate related changes" mode */
void CBIshemic (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
int n;
Arg args[10];
char message[LEN_SHORTER];
XmString message_string,title_string;
if ( filevalid == 1 )
{
diff = IMPORTANT;
bootvalid = 0;
extremavalid = 0;
rawvalid = 0;
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, " Select evaluation project ");
message_string = XmStringCreateLtoR (message, XmSTRING_DEFAULT_CHARSET);
n = 0;
XtSetArg (args[n], XmNmessageString, message_string); n++;
title_string = XmStringCreateLtoR ("Mode selection", XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNdialogTitle, title_string); n++;
XtSetValues (mb, args, n);
XtManageChild (mb);
}
}
/* Selection of the "ST segment changes" mode */
void CBSt (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
int n;
Arg args[10];
char message[LEN_SHORTER];
XmString message_string,title_string;
if ( filevalid == 1 )
{
diff = NO_MATTER;
bootvalid = 0;
extremavalid = 0;
rawvalid = 0;
sprintf(message,"Evaluation: %s Evaluation mode: ST segment changes",RemoveDot(file_name));
ModeString = XmStringCreateLtoR (message,XmSTRING_DEFAULT_CHARSET);
XtVaSetValues(mess_w, XmNlabelString, ModeString, NULL);
}
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 ("Mode selection", XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNdialogTitle, title_string); n++;
XtSetValues (mb, args, n);
XtManageChild (mb);
}
}
/* Unmanages the "Select evaluation project" dialog */
void CBMode_message (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
XtUnmanageChild(mb);
}
/* Unmanages the Evaluate dialog */
void CBEvaluate_message (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
XtUnmanageChild(eb);
}
/* Unmanages dialog for file read/write error */
void CBFile_message (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
XtUnmanageChild(fbb);
}
/* Evaluation of a single record */
void CBRead_record(w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
XmSelectionBoxCallbackStruct *cs =
(XmSelectionBoxCallbackStruct *) call_data;
char *text[NAME_LEN];
char dat_1[NAME_LEN], dat_2[NAME_LEN], dat_3[NAME_LEN], dat_4[NAME_LEN],dat[NAME_LEN];
char ref[NAME_LEN], alg[NAME_LEN], ave[NAME_LEN], name[NAME_LEN], tString[NAME_LEN];
char buf[LEN_SHORTER],rc_name1[NAME_LEN],rc_name2[NAME_LEN],rc_name3[NAME_LEN];
int Y,n,i;
char message[LEN_SHORTER];
XmString message_string,title_string;
Arg args[10];
FILE *fs,*in;
XFontStruct *newfont;
XmFontList newfontlist;
static Widget text_ebe;
XmTextPosition pos=0;
int rlen;
ClearScreen();
XmStringGetLtoR (cs->value, 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;i<tot_rec;i++)
if (strcmp(evaluated[i].rec,name)==0)
{
if (diff == IMPORTANT) evaluated[i].is=1;
if (diff == NO_MATTER) evaluated[i].st=1;
}
if (!dialog_ebe)
{
n = 0;
XtSetArg (args[n], XmNtitle, " Episode by episode report "); n++;
XtSetArg (args[n], XmNallowShellResize, True); n++;
dialog_ebe = (Widget) XmCreateBulletinBoardDialog
( toplevel, "Ebe_shell", args, n);
newfont = XLoadQueryFont (XtDisplay(dialog_ebe), "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, 83); 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_ebe = (Widget) XmCreateScrolledText(dialog_ebe, "Ebe_text", args, n);
}
n=0;
sprintf(tString,"Episode by episode report, record: %s",name);
XtSetArg (args[n], XmNdialogTitle, XmStringCreateLtoR(tString, XmSTRING_DEFAULT_CHARSET)); n++;
XtSetValues (dialog_ebe, args, n);
XmTextSetString(text_ebe,writeX);
XmTextSetCursorPosition(text_ebe,0);
XtManageChild(text_ebe);
XtManageChild(dialog_ebe);
if (dialog_stt) EStats();
sprintf(dat_4,"%s%s.%s",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st",rec_name);
fs = fopen(dat_4,"w");
if (Test_out(fs,dat_4)==-1) ;
else
{
fprintf(fs,"%s",writeX);
fclose(fs);
}
}
/* Select a single record */
void CBSingle (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
Widget cbs, textW;
XmString title_string;
int n;
Arg args[10];
char message[LEN_SHORTER],FstRec[NAME_LEN], name[NAME_LEN];
XmString message_string;
XmString label_string,name_string;
FILE *in;
if ( filevalid == 1 )
{
n = 0;
title_string = XmStringCreateLtoR ("Single record", XmSTRING_DEFAULT_CHARSET);
label_string = XmStringCreateLtoR ("Record:",XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNdialogTitle, title_string); n++;
XtSetArg (args[n], XmNselectionLabelString, label_string); n++;
cbs = XmCreatePromptDialog (w, "cbs", args, n);
XtUnmanageChild (XmSelectionBoxGetChild (cbs, XmDIALOG_HELP_BUTTON));
if ( bw == 0 )
{
n=0;
name_string = XmStringCreateLocalized(name);
XtSetArg (args[n], XmNforeground, XBlackPixel(XtDisplay (cbs), XtWindow (cbs)));n++;
XtSetArg (args[n], XmNselectionLabelString, label_string); n++;
XtSetValues (cbs, args, n);
XtSetValues (XmSelectionBoxGetChild (cbs, XmDIALOG_TEXT), args, n);
textW = XmSelectionBoxGetChild (cbs,XmDIALOG_TEXT);
}
XtAddCallback (cbs, XmNokCallback, CBRead_record, NULL);
XtManageChild(cbs);
}
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 ("Single record", XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNdialogTitle, title_string); n++;
XtSetValues (mb, args, n);
XtManageChild(mb);
}
}
/* Evaluation of the entire database selected */
void CBAll (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
char buf[NAME_LEN], dat_1[NAME_LEN], dat_4[NAME_LEN], dat_3[NAME_LEN];
int dist1, dist2, dist, n,i;
char message[LEN_SHORTER] ,w1_name[NAME_LEN];
XmString message_string,title_string;
Arg args[10];
FILE *fw, *fs;
static Widget text_raw;
XFontStruct *newfont;
XmFontList newfontlist;
XmTextPosition pos=0;
dist1 = dist2 = dist = 0;
ClearScreen();
if ( filevalid == 1 )
{
rawvalid = 1;
all_records(dat1, diff);
if (all_valid==0) return;
else all_valid=0;
if ( diff == IMPORTANT ) rawi=1;
if ( diff == NO_MATTER ) raws=1;
dist = 80;
dist1 = 140;
dist2 = 170;
if ( diff == IMPORTANT )
{
Draw_matrix_3x3(20/*60*/,20+dist,340/*285*/,120,"Sensitivity (Se)");
Draw_matrix_3x3(400,20+dist,340/*285*/,120,"Pos. pred. (+P)");
Draw_Se_matrix_3x3( 20/*60*/, 20+dist, 340/*285*/, 120, allref);
Draw_P_matrix_3x3( 400, 20+dist, 340/*285*/, 120, allalg);
}
else
{
Draw_matrix_2x2(60,20+dist,285,120,"Sensitivity (Se)");
Draw_matrix_2x2(400,20+dist,285,120,"Pos. pred. (+P)");
Draw_Se_matrix_2x2( 60, 20+dist, 285, 120, allref);
Draw_P_matrix_2x2( 400, 20+dist, 285, 120, allalg);
}
if ( diff == IMPORTANT )
{
sprintf(buf,"Episodes: annotated: %6d,", allref.num_epi);
Draw_text_font(buf, 60, 170+dist1, "8x13");
sprintf(buf,"detected: %6d,", allalg.num_epi);
Draw_text(buf, 400, 170+dist1);
sprintf(buf,"Per.of ischemia: annotated: %6.2lf,", allref.percent);
Draw_text(buf, 60, 190+dist1);
sprintf(buf,"detected: %6.2lf,", allalg.percent);
Draw_text(buf, 400, 190+dist1);
sprintf(buf,"IE Se [%%] = %6.2lf [g], %6.2lf [a]",
allref.se,allref.ase);
Draw_text_font(buf, 60, 240+dist2, "8x13");
sprintf(buf,"ID Se [%%] = %6.2lf [g], %6.2lf [a]",
allref.ish_dur, allref.aish_dur);
Draw_text(buf, 60, 260+dist2);
sprintf(buf,"IE +P [%%] = %6.2lf [g], %6.2lf [a]",
allalg.se, allalg.ase);
Draw_text(buf, 400, 240+dist2);
sprintf(buf,"ID +P [%%] = %6.2lf [g], %6.2lf [a]",
allalg.ish_dur, allalg.aish_dur);
Draw_text(buf, 400, 260+dist2);
}
else
{
sprintf(buf,"Episodes: annotated: %6d,", allref.num_epi);
Draw_text_font(buf, 60, 170+dist1, "8x13");
sprintf(buf,"detected: %6d,", allalg.num_epi);
Draw_text(buf, 400, 170+dist1);
sprintf(buf,"Per.of ST changes: annotated: %6.2lf,", allref.percent);
Draw_text(buf, 60, 190+dist1);
sprintf(buf,"detected: %6.2lf,", allalg.percent);
Draw_text(buf, 400, 190+dist1);
sprintf(buf,"SE Se [%%] = %6.2lf [g], %6.2lf [a]",
allref.se,allref.ase);
Draw_text_font(buf, 60, 240+dist2, "8x13");
sprintf(buf,"SD Se [%%] = %6.2lf [g], %6.2lf [a]",
allref.ish_dur, allref.aish_dur);
Draw_text(buf, 60, 260+dist2);
sprintf(buf,"SE +P [%%] = %6.2lf [g], %6.2lf [a]",
allalg.se, allalg.ase);
Draw_text(buf, 400, 240+dist2);
sprintf(buf,"SD +P [%%] = %6.2lf [g], %6.2lf [a]",
allalg.ish_dur, allalg.aish_dur);
Draw_text(buf, 400, 260+dist2);
}
PaintScreen();
if (!dialog_raw)
{
n = 0;
XtSetArg (args[n], XmNtitle, " Record by record statistics "); n++;
XtSetArg (args[n], XmNallowShellResize, True); n++;
dialog_raw = (Widget) XmCreateBulletinBoardDialog
( toplevel, "Raw_shell", args, n);
newfont = XLoadQueryFont (XtDisplay(dialog_raw), "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, 83); 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_raw = (Widget) XmCreateScrolledText(dialog_raw, "Raw_text", args, n);
}
if (dialog_stt) EStats();
write_rbr();
XmTextSetString(text_raw,writeX);
XmTextSetCursorPosition(text_raw,0);
XtManageChild(text_raw);
XtManageChild(dialog_raw);
sprintf(w1_name,"%s%s.raw",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st");
write_raw(w1_name,diff);
write_rbr_file();
}
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 ("Raw statistics", XmSTRING_DEFAULT_CHARSET);
XtSetArg (args[n], XmNdialogTitle, title_string); n++;
XtSetValues (mb, args, n);
XtManageChild(mb);
}
}
/* Examining ST segment deviation measurements */
void CBExamine (Widget w, XtPointer client_data, XtPointer call_data)
{
int num;
XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *) call_data;
if (( cbs->event->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', "Ctrl<Key>O", XmStringCreateLocalized ("Ctrl+O"),
XmVaPUSHBUTTON, save, 'E', "Ctrl<Key>E", XmStringCreateLocalized ("Ctrl+E"),
XmVaSEPARATOR,
XmVaPUSHBUTTON, quit, 'Q', "Ctrl<Key>Q", 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', "Ctrl<Key>I", XmStringCreateLocalized ("Ctrl+I"),
XmVaPUSHBUTTON, segment, 'S', "Ctrl<Key>S", 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', "Ctrl<Key>R", XmStringCreateLocalized ("Ctrl+R"),
NULL);
XmStringFree(single);
raw = XmStringCreateLocalized("Evaluate");
extrema = XmStringCreateLocalized("Extrema");
XmVaCreateSimplePulldownMenu (menubar, "mode_menu", 3, statistics_cb,
XmVaPUSHBUTTON, raw, 'E', "Ctrl<Key>A", XmStringCreateLocalized ("Ctrl+A"),
XmVaPUSHBUTTON, extrema, 'x', "Ctrl<Key>X", 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', "Ctrl<Key>N", XmStringCreateLocalized ("Ctrl+N"),
XmVaPUSHBUTTON, evaluate, 'E', "Ctrl<Key>B", XmStringCreateLocalized ("Ctrl+B"),
NULL);
freeze = XmStringCreateLocalized("Compare");
differences = XmStringCreateLocalized("Differences");
XmVaCreateSimplePulldownMenu (menubar, "summary_menu", 5, summary_cb,
XmVaPUSHBUTTON, freeze, 'C', "Ctrl<Key>C", XmStringCreateLocalized ("Ctrl+C"),
XmVaPUSHBUTTON, differences, 'D', "Ctrl<Key>D", XmStringCreateLocalized ("Ctrl+D"),
NULL);
XmStringFree(freeze);
XmStringFree(differences);
help = XmStringCreateLocalized("Help");
XmVaCreateSimplePulldownMenu (menubar, "help_menu", 6, help_cb,
XmVaPUSHBUTTON, help, 'H', "Ctrl<Key>H", 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<MAXREC;i++)
{
recref[i].se=-1.0;
recalg[i].se=-1.0;
recref[i].ish_dur=-1.0;
recalg[i].ish_dur=-1.0;
}
}
/* Initializes values of the table of records */
void init_record(avrec)
record avrec[MAXREC];
{
int i;
for ( i = 0; i < MAXREC; i++ )
in_record(&avrec[i]);
}
/* Converts the index [samples] to the time [h:m:s:ms] */
void convert_time(number,time)
long number;
times *time;
{
long new;
time -> 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<MAXI; j++ )
{
if (( epi -> 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<REC_COUNT;i++)
{
sprintf(buf,"\nRecord: %s\n",evaluated[i].rec);
strcat(writeX,buf);
Xwrite_matrix(recref[i],recalg[i],diff);
Xwrite_statistics(recref[i],recalg[i]);
}
}
/* Writes record-by-record statistics, too */
int write_rbr_file()
{
char dat_3[NAME_LEN];
FILE *fs;
sprintf(dat_3,"%s%s.rbr",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st");
fs = fopen(dat_3,"w");
if (Test_out(fs,dat_3)!=-1)
{
fprintf(fs,"%s",writeX);
fclose(fs);
return(0);
}
return (-1);
}
/* Writes bootstrap statistics to file */
int write_boot1(char fname[NAME_LEN],int diff, long trials1)
{
FILE *fa;
fa = fopen(fname,"w");
if (Test_out(fa,fname)==-1) return (-1);
fprintf(fa,"%s",writeX);
fclose(fa);
return (0);
}
/* Writes episode-by-episode statistics */
int write_ebe()
{
char dat_3[NAME_LEN];
FILE *fw;
sprintf(dat_3,"%s%s.ebe",RemoveDot(alg_name),diff==IMPORTANT?"_ih":"_st");
fw = fopen(dat_3,"w");
if (Test_out(fw,dat_3)!=-1)
{
fprintf(fw,"%s",writeX);
fclose (fw);
}
return (0);
}
/* ************************************************************************************* */
/* Main program */
main(argc,argv)
int argc;
char *argv[];
{
#if (motif) /* MOTIF SECTION - main program */
sprintf(hname,"%s",argv[0]);
toplevel = XtAppInitialize(&app_context, "EVAL_ST", NULL,
0, &argc, argv, fallback_resources, NULL, 0);
display=XtDisplay(toplevel);
CreateApplication(toplevel);
InitDraw();
XtRealizeWidget(toplevel);
XtAppMainLoop(app_context);
#else /* END OF MOTIF SECTION */
char *s,*t,*t1;
char w1_name[NAME_LEN],w2_name[NAME_LEN],pname[NAME_LEN],buf[LEN_SHORTER];
int i;
FILE *help;
struct stat stat_val;
strcpy(path,"");
strcpy(pname,argv[0]);
if (argc>=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 <database>_<algorithm>.evl <record> -[i|s] \n",pname);
fprintf(stderr,"Usage: %s -a <database>_<algorithm>.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 <database>_<algorithm>.evl <record> -[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 <project>.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 <database>_<algorithm>.evl <record> -[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 <database>_<algorithm>.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 <project>.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 <database>_<algorithm>.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 <database>_<algorithm>.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname);
break;
}}
break;
default : fprintf(stderr,"Usage: %s -a <database>_<algorithm> -[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 <project>.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 <database>_<algorithm>.evl <record> -[i|s] \n",pname);
fprintf(stderr,"Usage: %s -a <database>_<algorithm>.evl -[i|s] [-e|-b [NR_TRIALS]]\n",pname);
argc = 0;
}
break;
}
#endif
}
/* ************************************************************************************* */