#! /bin/bash
# Last edited on 2022-10-22 11:32:42 by stolfi

# Reads from stdin a file with least two numeric variables {X,Y}.
# Creates a FNI (float-valued) image file with a histogram of those variables.
# Writes the image to stdout, and displays it with {fni_view}.

# Usage:
# 
#  $0 [-noex] [-norm x|y|xy] {XCOL} {XMIN} {XMAX} {XNUM} {YCOL} {YMIN} {YMAX} {YNUM} 
#
# where
#
#  {XCOL,YCOL} = indices (from 1) of the columns with {X} and {Y} values.
#  {XNUM,YNUM} = bin counts for {X} and {Y}
#
# The "-noex" option rejects pairs outside the given ranges; otherwise such
# points are mapepd to the nearest bin.
#
# The "-norm" option specifies that bin values should be normalized 
# to unit sum along each row ("x"), each column ("y") or in the whole
# histogram ("xy"). In any case, the denominator includes points outside of 
# the given ranges, even if "-noex" is specified.

noex=0
norm=''
while [[ ( $# -gt 1 ) && ( "/$1" =~ /-.* ) ]]; do
  if [[ "/$1" == "/-noex" ]]; then
    noex=1; shift;
  elif [[ ( "/$1" == "/-norm" ) && ( $# -gt 2 ) ]]; then
    norm="$2"; shift; shift;
  else
    echo "** invalid option \"$1\"" 1>&2; exit 1
  fi
done

xcol="$1"; shift;  # Index (from 1) of column in file with {X} values (hor axis).
xmin="$1"; shift;  # Min value of {X} to plot.
xmax="$1"; shift;  # Max value of {X} to plot.
xnum="$1"; shift;  # Number of histogram bins for {X}.

ycol="$1"; shift;  # Index (from 1) of column in file with {Y} values (ver axis).
ymin="$1"; shift;  # Min value of {Y} to plot.
ymax="$1"; shift;  # Max value of {Y} to plot.
ynum="$1"; shift;  # Number of histogram bins for {Y}.

tmp="/tmp/$$"

pfile="${tmp}-r.fni"
dfile="${tmp}-d.dat"

cat | sed -e '/^[ ]*\([#]|$\)/d' > ${dfile}
dnum="`cat ${dfile} | wc -l`"

export GDFONTPATH=${STOLFILOCAL}/ttf

${STOLFIHOME}/bin/build_2d_histogram_image.gawk \
    -f ${STOLFIHOME}/lib/write_fni_image.gawk \
    -v xcol=${xcol} -v xmin=${xmin} -v xmax=${xmax} -v xnum=${xnum} \
    -v ycol=${ycol} -v ymin=${ymin} -v ymax=${ymax} -v ynum=${ynum} \
    -v noex=${noex} \
    -v norm=${norm} \
  < ${dfile} \
  > ${pfile}
  
if [[ -s ${pfile} ]]; then

  # Choose a scale value for display:
  # if [[ ${xnum} -gt ${ynum} ]]; then  mnum=${xnum}; else mnum=${ynum}; fi
  # if [[ "/${norm}" == "/" ]]; then
  #   zscale=`echo "0.5*(${mnum}*${xnum}*${ynum})/(${dnum})" | bc -lq`;
  # elif [[ "/${norm}" == "/x" ]]; then
  #   zscale=`echo "(${mnum})*(${ynum})" | bc -lq`
  # elif [[ "/${norm}" == "/y" ]]; then
  #   zscale=`echo "(${mnum})*(${xnum})" | bc -lq`;
  # elif  [[ "/${norm}" == "/xy" ]]; then
  #   zscale=${mnum};
  # else
  #   echo "** invalid option \"-norm ${norm}\"" 1>&2; exit 1
  # fi
  
  zscale=`echo "0.5*sqrt((${xnum})^2 + (${ynum})^2)" | bc -lq`;
  echo "zscale = ${zscale}" 1>&2
  
  cat ${pfile}

  fni_view \
      -hist 1 \
      -range auto \
      -scale ${zscale} \
    < ${pfile}

  rm -f ${pfile}
else
  echo "** plot failed" 1>&2
  rm -f ${pfile} # In case it exists but is empty.
  exit 1
fi
