#!/usr/bin/perl -w

#  piv2vec - Inserts a third and fifth column of a PIV data stream in order 
#            to prepare a data file for plotmtv vector representation.
#
#   Copyright (C) 2002 Gerber van der Graaf

#   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, 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.
#------------------------------------------------------------------

$VERSION = q$Id: piv2vec.pl,v 1.8 2007-01-29 14:26:54 gerber Exp $;
$HELP = "Adds header to piv data for a vector plot with Plotmtv";
$USAGE = "gpiv_piv2vec [-al length][-au \"units\"[-flipx][-flipy][-g][-h]
        [-p][-s scale][-tl label][-v][-xl label][-yl label] ][filename]
        < input > output

keys:
-al:    plots a vector annotation of 'length'
-au:    plots a vector annotation of 'units'
-flipx: flips the plot in x-direction; x data from high to low
-flipy: flips the plot in y-direction; y data from high to low
-g:     launches plotmtv
-h:     on-line help
-nd:    combined with -g; adds option -nodate (only ps output doesn't
        contain date!)
-k:     keep plot-file
-s:     vector scale (default: 1 px)
-tl:    defines top label (title) (with -f default: \"file_name\")
-v:     prints version
-xl:    defines x-label (default: \"x (pixels)\")
-yl:    defines y-label (default: \"y (pixels)\")
filename:       input PIV data file. Substitutes stdin and stdout
";


#----------------- Command line arguments handling ----------
#$opt_fn = 0;
# $opt_an = 0;
$opt_g = 0;
$opt_h = 0;
$opt_k = 0;
$opt_v = 0;
# $opt_s = 0;
$filename_logic = 0;
# $flipx = 0;
# $flipy = 0;
$opt_nd = 0;

use Getopt::Long;
#$result = 
GetOptions("g|graphic", "h|help", "k|keep", "v|version",
"s|scale=f" => \$vscale,
'tl|toplabel=s' => \$top_label,
'xl|xlabel=s' => \$x_label,
'yl|ylabel=s' => \$y_label,
'nd|no_date',
'al|annotation_length=f' => \$length_an,
'au|annotation_unit=s' => \$unit_an,
"flipx", "flipy",
);


if ($opt_h) {
  print ("$HELP\n");
  print ("$USAGE\n");
  exit;
}
if ($opt_v) {
  print ("$VERSION\n");
  exit;
}


if ($#ARGV == 0) {
    $filename_logic = 1;
    $filename = shift (@ARGV);
} elsif ($#ARGV == -1) {
    printf ("\nUsage: $USAGE\n");
    exit;
}

if ($opt_g && !$filename_logic) {
  print ("graphic output needs filename");
  exit;
}


sub FileBase {
#--------------- extracts file basename from a full filename
 my ($file_base_name, $file_extension);
 @file_fields = split(/\./,$_[0]);
 pop @file_fields;
 $file_base_name = join(".", @file_fields);
 return $file_base_name;
}

$file_basename = FileBase($filename);


#------------------------------- default parameters
if (!$unit_an) {$unit_an = "px"}
if (!$vscale) {$vscale = 1.0}

if ($file_basename && !$top_label) {$top_label = $file_basename}
if (!$x_label) {$x_label = "x (pixels)"}
if (!$y_label) {$x_label = "y (pixels)"}


#--------------- Initializing variables

$line = 0;
$x_max = -10000;
$x_min = 10000;
$y_max = 0;
$y_max = -1000;
$y_min = 1000;


#-------------------- Defines location and value of third component
$insert_3_loc = 0.0;
$insert_3_val = 0.0;


if ($filename_logic == 0) {
} elsif  ($filename_logic == 1) {
}


#--------------- Inserts data with third component (necesary for Plotmtv)

if ($filename_logic == 0) {
#------------------------------- Inserts header
  print("\$ DATA=VECTOR\n");
  print("\% vscale=$vscale\n");
  print("\% equalscale\n");
  if ($top_label) {
    print("\% toplabel = \"$top_label\"\n");
  } else {
    print("\% toplabel = \" \"\n");
  }
  if ($x_label) {print("\% xlabel = \"$x_label\"\n");}
  if ($y_label) {print("\% ylabel = \"$y_label\"\n");}
  if ($opt_flipx) {print("\% xflip\n");}
  if ($opt_flipy) {print("\% yflip\n");}
  while (<STDIN>) {
    chomp;

  if ($_ ne "" && (!/^(\#|;)/)) {  #skip blank lines, # or ; signs at first col

    s/,/./g;                    #substitutes eventually komma's by dot 
                                #(for example at LaVision's code)
    s/^ *//;                    #removes eventually leading space

      @words = split(/\s+/,$_);      #splitting line $_ up in words
                                   #same as @words = split
    $px[$line]=$words[0];
    $py[$line]=$words[1];
    $dx[$line]=$words[2];
    $dy[$line]=$words[3];


#------------------------------- Testing if they are numbers
    if ($#words == 5 ) {
      if (($px[$line] =~ /\d/) && ($py[$line] =~ /\d/) && ($dx[$line] =~ /\d/) &&
	  ($dy[$line] =~ /\d/) && ($snr[$line] =~ /\d/)) {
	$snr[$line]=$words[4];
      }
    } elsif ($#words == 6 ) {
      if (($px[$line] =~ /\d/) && ($py[$line] =~ /\d/) && ($dx[$line] =~ /\d/) &&
	  ($dy[$line] =~ /\d/) && ($snr[$line] =~ /\d/) && ($peak[$line] =~ /\d/) ) {
	$snr[$line]=$words[4];
	$peak[$line]=$words[5];
      }
    } else {
      if (($px[$line] =~ /\d/) && ($py[$line] =~ /\d/) && ($dx[$line] =~ /\d/) &&
	  ($dy[$line] =~ /\d/)) {
      }
    }
#----------------------- If vector annotation; calculate min and max values
    if ($length_an) {
      if ($px[$line] > $x_max) {$x_max = $px[$line];}
      if ($px[$line] < $x_min) {$x_min = $px[$line];}
      if ($py[$line] > $y_max) {$y_max = $py[$line];}
      if ($py[$line] < $y_min) {$y_min = $py[$line];}
    }

    $line++;
  }
  }

$nlines = $line;
#----------------------- If vector annotation; print to stdout
  if ($length_an) {
    $x1_an = $x_min+($x_max-$x_min)/2.;
    $x2_an = $x1_an + $length_an*$vscale;
    if ($opt_flipy){
      $y1_an = $y_min-$y_max*0.1;
      $y2_an = $y_min-$y_max*0.1;
    } else {
      $y1_an = $y_max+$y_max*0.1;
      $y2_an = $y_max+$y_max*0.1;
    }
      printf("\n@ arrow x1=%f y1=%f z1=0.0 x2=%f y2=%f z2=0.0 \\
linetype=1 linecolor=0 clip=false linelabel=\"%6.2f %s\"\n\n", 
	     $x1_an, $y1_an, $x2_an, $y2_an, $length_an, $unit_an);
  }

#----------------------- Print data
  for ($line=0; $line < $nlines; $line++) {
    if ($#words == 5 ) {
      print("$px[$line] $py[$line] $insert_3_loc $dx[$line] $dy[$line] $insert_3_val $snr[$line]\n");
    } elsif ($#words == 6 ) {
	print("$px[$line] $py[$line] $insert_3_loc $dx[$line] $dy[$line] $insert_3_val $snr[$line] $peak[$line]\n");
    } else {
	print("$px[$line] $py[$line] $insert_3_loc $dx[$line] $dy[$line] $insert_3_val\n");
      }
  }



} elsif  ($filename_logic == 1) {
#------------------------------- filename handling
  $file_name_piv=$file_basename.".piv";
  $file_name_vec=$file_basename.".vec";
  $infile=$file_name_piv;
  $outfile=$file_name_vec;
#  print "\ninfile=$infile outfile=$outfile";
  open (IN,"$infile") || die 'PIV2VEC error: can\'t open $infile';
  open (OUT,">$outfile") || die 'PIV2VEC error: can\'t open $outfile';

#------------------------------- Inserts header
  print(OUT "\$ DATA=VECTOR\n");
  print(OUT "\% vscale=$vscale\n");
  print(OUT "\% equalscale\n");
  if ($top_label) {
    print(OUT "\% toplabel = \"$top_label\"\n");
  } else {
    print(OUT "\% toplabel = \" \"\n");
  }
  if ($x_label) {print(OUT "\% xlabel = \"$x_label\"\n");}
  if ($y_label) {print(OUT "\% ylabel = \"$y_label\"\n");}
  if ($opt_flipx) {print(OUT "\% xflip\n");}
  if ($opt_flipy) {print(OUT "\% yflip\n");}


  while (<IN>) {
    chomp;
    if ($_ ne "" && (!/^(\#|;)/)) {  #skip blank lines, # or ; signs at first col

    s/,/./g;                    #substitutes eventually komma's by dot 
                                #(for example at LaVision's code)
    s/^ *//;                    #removes eventually leading space
      @words = split(/\s+/,$_);      #splitting line $_ up in words
                                   #same as @words = split
    $px[$line] = $words[0];
    $py[$line] = $words[1];
    $dx[$line] = $words[2];
    $dy[$line] = $words[3];
    $snr[$line] = $words[4];
    $peak[$line] = $words[5];
###printf("\n** AA:: peak = $peak[$line] ** \n");

#------------------------------- Testing if they are numbers
    if ($#words == 5 ) {
      if (($px[$line] =~ /\d/) && ($py[$line] =~ /\d/) && ($dx[$line] =~ /\d/) &&
	  ($dy[$line] =~ /\d/) && ($snr[$line] =~ /\d/)) {
#	$snr[$line]=$words[4];
      }
    } elsif ($#words == 6 ) {
      if (($px[$line] =~ /\d/) && ($py[$line] =~ /\d/) && ($dx[$line] =~ /\d/) &&
	  ($dy[$line] =~ /\d/) && ($snr[$line] =~ /\d/) && ($peak[$line] =~ /\d/) ) {
#	$snr[$line]=$words[4];
#	$peak[$line]=$words[5];
      }
    } else {
      if (($px[$line] =~ /\d/) && ($py[$line] =~ /\d/) && ($dx[$line] =~ /\d/) &&
	  ($dy[$line] =~ /\d/)) {
      }
    }
#----------------------- If vector annotation; calculate min and max values
#----------------------- of location for placing annotation
    if ($length_an) {
      if ($px[$line] > $x_max) {$x_max = $px[$line];}
      if ($px[$line] < $x_min) {$x_min = $px[$line];}
      if ($py[$line] > $y_max) {$y_max = $py[$line];}
      if ($py[$line] < $y_min) {$y_min = $py[$line];}
    }

    $line++;
  }
}


$nlines = $line;
#----------------------- If vector annotation; print to file
  if ($length_an) {
    $x1_an = $x_min+($x_max-$x_min)/2.;
    $x2_an = $x1_an + $length_an*$vscale;
    if ($opt_flipy){
      $y1_an = $y_min-$y_max*0.1;
      $y2_an = $y_min-$y_max*0.1;
    } else {
      $y1_an = $y_max+$y_max*0.1;
      $y2_an = $y_max+$y_max*0.1;
    }
      print("\nx1_an=$x1_an x2_an=$x2_an");
      printf(OUT "\n@ arrow x1=%f y1=%f z1=0.0 x2=%f y2=%f z2=0.0 \\
linetype=1 linecolor=0 clip=false linelabel=\"%6.2f %s\"\n\n", 
	     $x1_an, $y1_an, $x2_an, $y2_an, $length_an, $unit_an);
  }

#----------------------- Print data
  for ($line=0; $line < $nlines; $line++) {
      if ($#words == 5 ) {
###printf("\n** BB:: NO words == $#words snr = $snr[$line] peak = $peak[$line]**\n");
	if ($peak[$line] != -1) {            # $peak[$line] != 0 && 
	print(OUT "$px[$line] $py[$line] $insert_3_loc $dx[$line] $dy[$line] $insert_3_val $snr[$line]\n");
	}
      } elsif ($#words == 6 ) {
	  print(OUT "$px[$line] $py[$line] $insert_3_loc $dx[$line] $dy[$line] $insert_3_val $snr[$line] $peak[$line]\n");
      } else {
	print(OUT "$px[$line] $py[$line] $insert_3_loc $dx[$line] $dy[$line] $insert_3_val\n");
      }
  }
close (IN) || die 'PIV2VEC error: can\'t close $infile';
close (OUT) || die 'PIV2VEC error: can\'t close $outfile';
}

#------------------------------- Launches Plotmtv and cleans
if ($opt_g) {
  if ($opt_nd) {
    @args=("plotmtv", "-nodate", $file_name_vec);
  } else {
    @args=("plotmtv", $file_name_vec);
  }
  system (@args) == 0 || die "PIV2VEC error: system @args failed: $?";
  if (!$opt_k) {
    @args=("rm", $file_name_vec);
    system (@args) == 0 || die "PIV2VEC error: system @args failed: $?";
  }
}
print ("\n");
