
	/* Reads a gestures_??.txt ground truth file and a machine detected
	** set of rest periods.  Evaluates their overlap.
	*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define	MAX_GESTURES	300

int main(int argc, char *argv[])

{
int		i,j;
FILE		*fpt;
char		GTtype[MAX_GESTURES][16],MDtype[MAX_GESTURES][16];
int		GTstart[MAX_GESTURES],GTend[MAX_GESTURES];
int		MDstart[MAX_GESTURES],MDend[MAX_GESTURES];
int		TotalGT,TotalMD;
unsigned char	*GTlabels,*MDlabels;
int		TP,FP,TN,FN;
int		GTclass[MAX_GESTURES],MDclass[MAX_GESTURES];

if (argc != 3)
  {
  printf("Usage:  evalrest [gt_gestures] [md_rests]\n");
  exit(0);
  }

	/* read ground truth */
if ((fpt=fopen(argv[1],"r")) == NULL)
  {
  printf("Unable to open %s for reading\n",argv[1]);
  exit(0);
  }
TotalGT=0;
while (1)
  {
  i=fscanf(fpt,"%s %d %d",GTtype[TotalGT],
	&(GTstart[TotalGT]),&(GTend[TotalGT]));
  if (i != 3)
    break;
  TotalGT++;
  }
fclose(fpt);
printf("%d total gt\n",TotalGT);

	/* read machine detections */
if ((fpt=fopen(argv[2],"r")) == NULL)
  {
  printf("Unable to open %s for reading\n",argv[2]);
  exit(0);
  }
TotalMD=0;
while (1)
  {
  i=fscanf(fpt,"%s %d %d",MDtype[TotalMD],
	&(MDstart[TotalMD]),&(MDend[TotalMD]));
  if (i != 3)
    break;
  TotalMD++;
  }
fclose(fpt);
printf("%d total md\n",TotalMD);

	/* Evaluate each time index independently.  Create an array for
	** GT and one for MD with each time index labeled, then compare.
	*/
GTlabels=(unsigned char *)calloc(GTend[TotalGT-1],1);
MDlabels=(unsigned char *)calloc(GTend[TotalGT-1],1);
for (i=0; i<TotalGT; i++)
  {
  if (strcmp(GTtype[i],"rest") != 0)
    continue;
  for (j=GTstart[i]; j<=GTend[i]; j++)
    GTlabels[j]=1;
  }
for (i=0; i<TotalMD; i++)
  {
  if (strcmp(MDtype[i],"rest") != 0)
    continue;
  for (j=MDstart[i]; j<=MDend[i]; j++)
    {	/* only evaluate labels within GT span; ignore labels outside */
    if (j >= GTstart[0]  &&  j <= GTend[TotalGT-1])
      MDlabels[j]=1;
    }
  }
TP=FP=FN=TN=0;
for (i=0; i<=GTend[TotalGT-1]; i++)
  {
  if (GTlabels[i] == 1)
    {
    if (MDlabels[i] == 1)
      TP++;
    else
      FN++;
    }
  else
    {
    if (MDlabels[i] == 1)
      FP++;
    else
      TN++;
    }
  }
printf("TP %d TN %d  FP %d FN %d\n",TP,TN,FP,FN);
printf("sens %.2lf  spec %.2lf\n",(double)TP/(double)(TP+FN),
	(double)TN/(double)(TN+FP));

	/* Evaluate each rest segment, both GT and MD.
	** Test for overlap with the opposite to determine TP/FP/FN status.
	** No TN exist for this metric.
	*/
for (i=0; i<TotalGT; i++)
  GTclass[i]=-1;	/* -1 => not matched */
for (i=0; i<TotalMD; i++)
  {
  if (MDend[i] < GTstart[0]  ||  MDstart[i] > GTend[TotalGT-1])
    MDclass[i]=-2;	/* MD segment outside GT labels = never match */
  else
    MDclass[i]=-1;	/* -1 => not matched */
  }
for (i=0; i<TotalGT; i++)
  {
  if (strcmp(GTtype[i],"rest") != 0)
    continue;
  for (j=0; j<TotalMD; j++)
    {
    if (MDclass[j] != -1)
      continue;		/* already matched another GT */
    if ((MDstart[j] >= GTstart[i]  &&  MDend[j] <= GTend[i])  ||
	(MDstart[j] < GTstart[i]  &&
		MDend[j] >= GTstart[i]  &&  MDend[j] <= GTend[i])  ||
	(MDstart[j] >= GTstart[i]  &&  MDstart[j] <= GTend[i]  &&
		MDend[j] >= GTend[i])  ||
	(MDstart[j] <= GTstart[i]  &&  MDend[j] >= GTend[i]) )
      {		/* they overlap - match */
      GTclass[i]=j;
      MDclass[j]=i;
      }
    }
  }

TP=FP=FN=0;
for (i=0; i<TotalGT; i++)
  if (GTclass[i] >= 0)
    TP++;
  else if (strcmp(GTtype[i],"rest") == 0)
    {
    FN++;
    printf("MISSED:  %d %d\n",GTstart[i],GTend[i]);
    }
for (j=0; j<TotalMD; j++)
  if (MDclass[j] == -1)
    FP++;

printf("TP %d  FP %d FN %d\n",TP,FP,FN);
printf("sens %.2lf  ppv %.2lf\n",(double)TP/(double)(TP+FN),
	(double)TP/(double)(TP+FP));

}

