[2143f9]: / HRV.src / plt_rrs

Download this file

593 lines (527 with data), 13.9 kB

#! /bin/sh

# plt_rrs		Joe Mietus		Oct 7 2008

# plt_rrs

USAGE="$0 [options] -R rrfile | record annotator [start [end]]
	Plot RR intervals or RR interval heart rates
	options :
	  [-P 2|4|8|16|24|32] : plot 2, 4, 8, 16, 24 or 32 hours per page
                               (default: scale page length to data length)
	  [-R rrfile] : RR interval file : time (sec), interval
	  [-N] : plot NN intervals instead of RR intervals
	  [-H] : plot RR/NN interval heart rate
	  [-F \"filt hwin\"] : filter intervals, plot filtered data
	  [-f \"filt hwin\"] : filter intervals
	  [-p] : plot points
	  [-I c|h|m] : input time format: hh::mm:ss, hours, minutes (default: seconds)
          [-m] : RR intervals in msec
	  [-y \"ymin ymax\"] : y axis limits
	  [-o] : output postscript
"

DATA=Intervals
YLABEL="RR (sec)"

while getopts P:R:NHF:f:pI:my:o c
do
    case $c in
	P) PAGELEN=$OPTARG ;;
	R) RRFILE=$OPTARG ;;
	N) NFLAG='-a N -r'
	   YLABEL="NN (sec)" ;;
	H) HRFLAG=1
	   DATA="Interval Heart Rate"
	   YLABEL="HR (bpm)" ;;
	F) FILT=$OPTARG
	   PLTFILT=1 ;;
	f) FILT=$OPTARG ;;
	p) PPLT=1 ;;
        I) TIME=$OPTARG ;;
	m) MFLAG=1 ;;
	y) YLIMS=$OPTARG ;;
	o) PS=-ps ;;
	\?) echo "$USAGE"
	    exit 1;;
    esac
done

shift `expr $OPTIND - 1`

if test "$RRFILE"
then
    if test ! -r "$RRFILE"
    then
	echo "$0 : Can't open $RRFILE"
	exit 1
    fi

    FORM=`head -1 $RRFILE |
          awk 'NF>3 {printf "bad"}
               NF==3 || NF==2 || NF==1  \
                   {if($1~/[0-9:.]+/) \
                       {{if($1~/[^0-9:.]+/) printf "bad"}; printf "N1 "}
                       else printf "A1 "}
               NF==3 || NF==2 \
                   {if($2~/[0-9:.]+/) \
                       {{if($2~/[^0-9:.]+/) printf "bad"}; printf "N2 "}
                       else printf "A2 "}
               NF==3 \
                   {if($3~/[0-9\.]+/) \
                       {{if($3~/[^0-9:.]+/) printf "bad"}; printf "N3 "}
                       else printf "A3 "}
               {printf "\n"}'` >/dev/null
    NF=`echo $FORM | wc -w`
    F1=`echo $FORM | awk '{print $1}'`
    F2=`echo $FORM | awk '{print $2}'`
    F3=`echo $FORM | awk '{print $3}'`
    if test $NF -eq 3 -a "$F1" = N1 -a "$F2" = N2 -a "$F3" = A3
    then :
    elif test $NF -eq 2 -a "$F1" = N1 -a "$F2" = N2
    then
        NOANN=1
    elif test $NF -eq 2 -a "$F1" = N1 -a "$F2" = A2
    then
        TFLAG=1
    elif test $NF -eq 1 -a "$F1" = N1
    then
        NOANN=1
        TFLAG=1
    else
        echo "$RRFILE : bad input format"
        exit 1
    fi
    if test "$NOANN"
    then
        echo "$0 : No beat labels"
        unset NFLAG
    fi
else
    if test $# -lt 2
    then
	echo "$USAGE"
	exit 1
    fi
    REC=$1
    ANN=$2
    if test ! "`wfdbwhich $REC.$ANN 2>/dev/null`"
    then
	echo "$0 : can't read annotator $ANN for record $REC"
	exit 1
    fi
    shift 2
fi

START=$1
END=$2

if test "$PS"
then
    PTERM=lw
    export PTERM
else
    xpltwin -g 720x940
fi

if test ! "$START" -o "$START" = "-"
then
    START=00:00:00
fi
STARTSEC=`seconds $START`
if test "$STARTSEC" -eq -1
then
    echo "$0 : bad start time : $START"
    exit 1
fi
START=`hours $STARTSEC`

if test "$END"
then
    ENDSEC=`seconds $END`
    if test $STARTSEC -gt $ENDSEC
    then
	echo "$0: start time greater than end time"
	exit 1
    fi
fi

if test "$PAGELEN" != 2 -a "$PAGELEN" != 4 -a "$PAGELEN" != 8 -a \
        "$PAGELEN" != 16 -a "$PAGELEN" != 24 -a "$PAGELEN" != 32
then PAGELEN=s
fi

if test ! "$YLIMS"
then
    if test "$HRFLAG"
    then YLIMS="0 150"
    else YLIMS="0 2.0"
    fi
elif test `echo $YLIMS | wc -w` -ne 2
then
    echo "$0 : [-y \"ymin ymax\"]"
    exit 1
fi


(
if test "$RRFILE"
then
    cat $RRFILE |
    (
    if test "$TFLAG"
    then awk '{T+=$1}; {printf "%.3f %s\n", T, $0}'
    else cat
    fi
    ) |
    (
    if test "$MFLAG" -a "$TFLAG"
    then awk '{$1/=1000; $2/=1000; print}'
    elif test "$MFLAG"
    then awk '{$2/=1000; print}'
    else cat
    fi
    ) |
    (
    if test "$TIME" = c
    then
        sed 's/[0-9:.][0-9:.]* /&: /' |
        awk -F: 'NF==2 {print $1, $2}
                 NF==3 {print $1*60+$2, $3}
                 NF==4 {print $1*3600+$2*60+$3, $4}'
    elif test "$TIME" = h
    then
        awk '{$1*=3600; print}'
    elif test "$TIME" = m
    then
        awk '{$1*=60; print}'
    else
        cat
    fi
    ) |
    (
    if test "$END"
    then
	awk "\$1 >= $STARTSEC && \$1 <= $ENDSEC && \$2!=0 {print}
	     \$1 > $ENDSEC {exit}"
    else
	awk "\$1 >= $STARTSEC && \$2!=0 {print}"
    fi
    ) |
    (
    if test "$NFLAG"
    then
	awk '{RCNT++}
	     LAST=="N" && $3=="N" {print; NCNT++}
	     {LAST = $3}
	     END {printf "NN : RR = %d : %d = %.3f\n", \
	          NCNT, RCNT, NCNT/RCNT > "foo.n0"}'
    else
	cat
    fi
    )
else
    rrlist $ANN $REC -f $START ${END:+-t} $END $NFLAG -s 2>foo.n0
fi
) | awk "{print \$1, \$2}" |
(
if test "$HRFLAG"
then awk '{$2 = 60/$2; print}'
else cat
fi
) |
(
if test "$FILT"
then filt $FILT -p foo.exc -n 2>foo.n1
else cat
fi
) |
awk '{print $1/3600, $2}' >foo.dat


if test $PAGELEN = s
then
    DATSTART=`head -1 foo.dat | awk '{print $1}'`
    DATEND=`tail -1 foo.dat | awk '{print $1}'`
    PAGELEN=`echo $DATSTART $DATEND |
              awk '{LEN=$2-$1}
                   LEN<=2 {print 2; exit}
                   LEN<=4 {print 4; exit}
                   LEN<=4 {print 4; exit}
                   LEN<=8 {print 8; exit}
                   LEN<=16 {print 16; exit}
                   LEN<=24 {print 24; exit}
                   LEN<=32 {print 32; exit}'`
fi

LINELEN=`echo "scale=2; $PAGELEN / 8" | bc`
if test $PAGELEN -eq 2
then
    XTIC=`echo "1 / 60" | bc -l`
    XMIN0=`echo $START |
    sed 's/^.:..$/0&/
         s/^..:..$/0:&/
         s/:/ /g' |
    awk '{if($2<15) $2=0;
          if($2>=15 && $2<30) $2=0.25;
          if($2>=30 && $2<45) $2=0.5;
          if($2>=45) $2=0.75;
          print $1+$2}'`
elif test $PAGELEN -eq 4
then
    XTIC=`echo "5 / 60" | bc -l`
    XMIN0=`echo $START |
    sed 's/^.:..$/0&/
         s/^..:..$/0:&/
         s/:/ /g' |
    awk '{if($2<30) $2=0; if($2>=30) $2=0.5; print $1+$2}'`
elif test $PAGELEN -eq 8
then
    XTIC=`echo "5 / 60" | bc -l`
    XMIN0=`echo $START |
    sed 's/^.:..$/0&/
         s/^..:..$/0:&/
         s/:.*//'`
elif test $PAGELEN -eq 16 -o $PAGELEN -eq 24 -o $PAGELEN -eq 32
then
    XTIC=`echo "15 / 60" | bc -l`
    XMIN0=`echo $START |
    sed 's/^.:..$/0&/
         s/^..:..$/0:&/
         s/:.*//'`
fi
XMAX7=`echo "scale=2; $XMIN0 + $PAGELEN" | bc`

X0=0.065
X1=0.965

YMIN=`echo $YLIMS | awk '{print $1}'`
YMAX=`echo $YLIMS | awk '{print $2}'`

if test "$NFLAG"
then
    DATA="NN $DATA"
    NRR0=`awk '{print $7}' foo.n0`
    NRR1=`awk '{print $5}' foo.n0`
else
    DATA="RR $DATA"
fi
if test "$FILT"
then
    NRR1=`awk '{print $7}' foo.n1`
    NRR2=`awk '{print $5}' foo.n1`
    NFILT=`cat foo.exc | wc -l`
fi
if test "$NFLAG" -a "$FILT"
then
    RATIO=`echo "$NRR2 $NRR1 $NRR0" | 
    awk '{printf "Filt : NN : RR = %d : %d : %d = %.3f : %.3f = %.3f\n", \
          $1, $2, $3, $1/$2, $2/$3, $1/$3}'`
    EXCLUDED=`echo "$NFILT $NRR1 $NRR0" |
    awk '{printf "[%d Filtered, %d non-NN]\n", $1, $3-$2}'`
elif test "$NFLAG" -a ! "$FILT"
then
    RATIO=`echo "$NRR1 $NRR0" | 
    awk '{printf "NN : RR = %d : %d = %.3f\n", $1, $2, $1/$2}'`
    EXCLUDED=`echo "$NRR1 $NRR0" | 
    awk '{printf "[%d non-NN]\n", $2-$1}'`
elif test "$FILT" -a ! "$NFLAG"
then
    RATIO=`echo "$NRR2 $NRR1" | 
    awk '{printf "Filt : RR = %d : %d = %.3f\n", $1, $2, $1/$2}'`
    EXCLUDED=`echo "$NFILT" | 
    awk '{printf "[%d Filtered]\n", $1}'`
fi

if test "$FILT"
then PROG="filt $FILT"
fi
if test "$PROG"
then PROG="($PROG)"
fi

if test "$PPLT"
then
    P1='p 0,1S5(P2)'
    P2='p 0,1S0(P5)'
else
    P1='p (W0)'
    P2='p 0,1S5(P5)'
fi

awk "\$1>=$XMIN0 && \$1<=$XMAX7 {print}
     \$1>$XMAX7 {print \$1 >\"foo.next\"; exit}" <foo.dat >foo.rr

PAGE=0

while test -s foo.rr -o -s foo.next
do

PAGE=`expr $PAGE + 1`

XMAX0=`echo "scale=2; $XMIN0 + $LINELEN" | bc`
XMIN1=$XMAX0
XMAX1=`echo "scale=2; $XMIN1 + $LINELEN" | bc`
XMIN2=$XMAX1
XMAX2=`echo "scale=2; $XMIN2 + $LINELEN" | bc`
XMIN3=$XMAX2
XMAX3=`echo "scale=2; $XMIN3 + $LINELEN" | bc`
XMIN4=$XMAX3
XMAX4=`echo "scale=2; $XMIN4 + $LINELEN" | bc`
XMIN5=$XMAX4
XMAX5=`echo "scale=2; $XMIN5 + $LINELEN" | bc`
XMIN6=$XMAX5
XMAX6=`echo "scale=2; $XMIN6 + $LINELEN" | bc`
XMIN7=$XMAX6

XMIN=$XMIN0
XMAX=$XMAX0


awk "{if(\$2<$YMIN) \$2=$YMIN; if(\$2>$YMAX) \$2=$YMAX}
     \$1>=$XMIN0 && \$1<=$XMAX0 {print >\"foo.rr0\"}
     \$1>=$XMIN1 && \$1<=$XMAX1 {print >\"foo.rr1\"}
     \$1>=$XMIN2 && \$1<=$XMAX2 {print >\"foo.rr2\"}
     \$1>=$XMIN3 && \$1<=$XMAX3 {print >\"foo.rr3\"}
     \$1>=$XMIN4 && \$1<=$XMAX4 {print >\"foo.rr4\"}
     \$1>=$XMIN5 && \$1<=$XMAX5 {print >\"foo.rr5\"}
     \$1>=$XMIN6 && \$1<=$XMAX6 {print >\"foo.rr6\"}
     \$1>=$XMIN7 && \$1<=$XMAX7 {print >\"foo.rr7\"}
     \$1>=$XMAX7 {exit}" <foo.rr


if test "$PLTFILT"
then
awk "{\$1/=3600}
     {if(\$2<$YMIN) \$2=$YMIN; if(\$2>$YMAX) \$2=$YMAX}
     \$1>=$XMIN0 && \$1<=$XMAX0 {print >\"foo.exc0\"}
     \$1>=$XMIN1 && \$1<=$XMAX1 {print >\"foo.exc1\"}
     \$1>=$XMIN2 && \$1<=$XMAX2 {print >\"foo.exc2\"}
     \$1>=$XMIN3 && \$1<=$XMAX3 {print >\"foo.exc3\"}
     \$1>=$XMIN4 && \$1<=$XMAX4 {print >\"foo.exc4\"}
     \$1>=$XMIN5 && \$1<=$XMAX5 {print >\"foo.exc5\"}
     \$1>=$XMIN6 && \$1<=$XMAX6 {print >\"foo.exc6\"}
     \$1>=$XMIN7 && \$1<=$XMAX7 {print >\"foo.exc7\"}
     \$1>=$XMAX7 {exit}" <foo.exc
fi


TITLE1="${RRFILE:-$REC $ANN} ($START) : $DATA"

if test "$PAGE" -eq 1
then
    if test "$PROG"
    then
	TITLE2="$PROG"
	TITLE3="$RATIO $EXCLUDED"
    else
	TITLE2="$RATIO $EXCLUDED"
    fi
else
    TITLE2="$PROG"
    TITLE3=""
fi


( plt -wm 0 -F"
  t
  L (P14) .5 1.005 CT $TITLE1
  L (P11) .5 0.980 CT $TITLE2
  L (P11) .5 0.955 CT $TITLE3
  s f"

  for i in 0 1 2 3 4 5 6 7
  do

  if test -s foo.rr$i
  then

  Y0=`echo "scale=4; 0.845 - ($i * 0.114)" | bc`
  Y1=`echo "scale=4; 0.925 - ($i * 0.114)" | bc`

  if test $PAGELEN -eq 2
  then
  echo $XMIN |
  sed 's/^[0-9][0-9]*$/&.00/
       s/^\./0&/
       s/\./ &/' |
  awk '$2==.00 {printf("xt %f %d:00:00\n", $1+$2, $1);
                printf("xt %f %d:05:00\n", $1+$2+5/60, $1);
                printf("xt %f %d:10:00\n", $1+$2+10/60, $1);
                printf("xt %f %d:15:00\n", $1+$2+0.25, $1);
                printf("xts %f\n", $1+1/60)}
       $2==.25 {printf("xt %f %d:15:00\n", $1+$2, $1);
                printf("xt %f %d:20:00\n", $1+$2+5/60, $1);
                printf("xt %f %d:25:00\n", $1+$2+10/60, $1);
                printf("xt %f %d:30:00\n", $1+$2+0.25, $1);
                printf("xts %f\n", $1+16/60)}
       $2==.50 {printf("xt %f %d:30:00\n", $1+$2, $1);
                printf("xt %f %d:35:00\n", $1+$2+5/60, $1);
                printf("xt %f %d:40:00\n", $1+$2+10/60, $1);
                printf("xt %f %d:45:00\n", $1+$2+0.25, $1);
                printf("xts %f\n", $1+31/60)}
       $2==.75 {printf("xt %f %d:45:00\n", $1+$2, $1);
                printf("xt %f %d:50:00\n", $1+$2+5/60, $1);
                printf("xt %f %d:55:00\n", $1+$2+10/60, $1);
                printf("xt %f %d:00:00\n", $1+$2+0.25, $1+1);
                printf("xts %f\n", $1+46/60)}' >foo.xlabels

  elif test $PAGELEN -eq 4
  then
  echo $XMIN |
  sed 's/^[0-9][0-9]*$/&.00/
       s/^\./0&/
       s/\./ &/' |
  awk '$2==.00 {printf("xt %f %d:00:00\n", $1+$2, $1);
                printf("xt %f %d:15:00\n", $1+$2+0.25, $1);
                printf("xt %f %d:30:00\n", $1+$2+0.50, $1)}
       $2==.50 {printf("xt %f %d:30:00\n", $1+$2, $1);
                printf("xt %f %d:45:00\n", $1+$2+0.25, $1);
                printf("xt %f %d:00:00\n", $1+$2+0.50, $1+1)}' >foo.xlabels

  elif test $PAGELEN -eq 8
  then
  echo $XMIN |
  awk '{printf("xt %f %d:00:00\n", $1, $1);
        printf("xt %f %d:15:00\n", $1+0.25, $1);
        printf("xt %f %d:30:00\n", $1+0.50, $1);
        printf("xt %f %d:45:00\n", $1+0.75, $1);
        printf("xt %f %d:00:00\n", $1+1.00, $1+1)}' >foo.xlabels

  elif test $PAGELEN -eq 16
  then
  echo $XMIN |
  awk '{printf("xt %f %d:00:00\n", $1, $1);
        printf("xt %f %d:30:00\n", $1+0.50, $1);
        printf("xt %f %d:00:00\n", $1+1.00, $1+1);
        printf("xt %f %d:30:00\n", $1+1.50, $1+1);
        printf("xt %f %d:00:00\n", $1+2.00, $1+2)}' >foo.xlabels

  elif test $PAGELEN -eq 24
  then
  echo $XMIN |
  awk '{printf("xt %f %d:00:00\n", $1, $1);
        printf("xt %f %d:00:00\n", $1+1, $1+1);
        printf("xt %f %d:00:00\n", $1+2, $1+2);
        printf("xt %f %d:00:00\n", $1+3, $1+3)}' >foo.xlabels

  elif test $PAGELEN -eq 32
  then
  echo $XMIN |
  awk '{printf("xt %f %d:00:00\n", $1, $1);
        printf("xt %f %d:00:00\n", $1+1, $1+1);
        printf("xt %f %d:00:00\n", $1+2, $1+2);
        printf("xt %f %d:00:00\n", $1+3, $1+3);
        printf("xt %f %d:00:00\n", $1+4, $1+4)}' >foo.xlabels

  fi


  plt foo.rr$i % -wms 1 -F"
  W $X0 $Y0 $X1 $Y1
  sf all P10
  t 
  x
  y
  vl -.06 .5 - 1
  $YLABEL
  s X
  s n
  xa $XMIN $XMAX $XTIC
  `cat foo.xlabels`
  ya $YMIN $YMAX
  $P1"

  if test -s foo.exc$i
  then
  plt foo.exc$i -wms 1 -F"
  W $X0 $Y0 $X1 $Y1
  sf all P10
  s t
  s x
  s y
  xa $XMIN $XMAX
  ya $YMIN $YMAX
  $P2"
  fi

  fi

  XMIN=$XMAX
  XMAX=`echo "scale=2; $XMIN + $LINELEN" | bc`

  done

  if test -s foo.rr
  then
  plt : -wms 1 -F"
  W $X0 $Y0 $X1 $Y1
  sf all P10
  s t
  s x
  s y
  hl 0.5 -0.5 - 1
  TIME (hours)
  xa $XMIN $XMAX
  ya $YMIN $YMAX"
  fi

) |
(
if test "$PTERM"
then cat | lwcat -full $PS
else cat
fi
)


rm -f foo.rr? foo.exc? foo.xlabels foo.next


XMIN0=$XMAX7
XMAX7=`echo "scale=2; $XMAX7 + $PAGELEN" | bc`

STARTSEC=`echo "$XMIN0" | awk '{printf "%.0f\n", $1*3600}'`
START=`hours $STARTSEC`

awk "\$1>$XMIN0 && \$1<=$XMAX7 {print}
     \$1>$XMAX7 {print \$1 >\"foo.next\"; exit}" <foo.dat >foo.rr

done

rm -f foo.dat foo.rr foo.n? foo.exc foo.next