#!/usr/bin/perl -w 
#
# werte-aus(IMPERATIV): 
#       automated evaluation of U-I-Curves
#
# Autor:        Frank Rocholl <rocholl@hottemax.uni-muenster.de>, <rocholl@hottemax.org>
# Datum:        14.08.99
# Version:      0.3.7   
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# 
# needs gnuplot 3.5 patchlevel beta 336 && latex2e && dvips && perl 5
# Hilfe mit: werte-aus -h

#--- Pakete ---

use Getopt::Std;


# ---Variablen ---

$gnuplot_tmp = "werte-aus.gnu.$$";
                                # temp. Gnuplot-File
$latex_tmp = "werte-aus";       # temp. LaTeX-File
$true = 1;                      # wahr
$false = 0;                     # falsch
$debug = $false;                # -D: debug modus
$cylinder = $false;             # -c: Cylinder Geometrie
$fitalg = "sbezier";            # -F: Fitalgorithmus
$all_in_one = $false;           # -a: Alle Kurven in einen Plot
$del_cond = $false;             # -C: Loeschen der temp. 
                                # Leitfaehigkeitsfiles
$help = $false;                 # -h: Hilfe
$latex_output = $false;         # -l: LaTeX-Ausgabe
$oxygen_p_p = 0.2;              # -o: Referenz Sauerstoffpartialdruck
$point_contact = 20;            # -p: Spitzenradius
$small_latex_output = $false;   # -s: 8 Abbildungen pro Seite
$version = $false;              # -v: Versionsausgabe
$version_number = "0.3.7";      # Versionsnummer
$faktor = -1;                   # Vorzeichenkorrektur 


#--- Elektrochemische Konstanten ---

$F = 96485;     # Faraday Konstante
$R = 8.4314;    # allgemeine Gaskonstante

# --- Einlesen der Optionen ---

 getopts('CDachlo:p:sv', \%opt) || usage("usage:");
  $debug = $true if $opt{'D'};
  $del_cond = $true if $opt{'C'};
  $all_in_one = $true if $opt{'a'};
  $cylinder = $true if $opt{'c'};
  $oxygen_p_p = $opt{'o'} if $opt{'o'};
  $point_contact = $opt{'p'} if $opt{'p'};
  $help = $true if $opt{'h'};
  $latex_output = $true if $opt{'l'};
  $small_latex_output = $true if $opt{'s'};
  $version = $true if $opt{'v'};

 if ($help == $true)
   {
     &help_func();
     exit(0);
   }

 if ($version == $true)
   {
     &version_func();
     exit(0);
   }

 if ($cylinder == $true)
   {
     $geometry = "4";
     $geom_info = "cylinder";
   }

 else
   {
     $geometry = "2*pi";
     $geom_info = "radial";
   }

 print "this is ";
 &version_func();
 
 die "Error: No files to calculate\n" if ($#ARGV lt 0);
 @ARGUMENTE=<@ARGV>;

#--- Ausgabe einiger Variablen ---
 print "****\n";
 print "geometry:\t\t\t\t$geom_info\n";
 print "referenz oxygen partial pressure:\t$oxygen_p_p\n";
 print "tip radius:\t\t\t\t$point_contact \\mu m\n";
 print "****\n";

 if ($latex_output == $true && $small_latex_output == $true)
   {
     print "Do you really want a large *and* a small latex output?\n";
     print "I set it to a small one :)\n";
     $latex_output = $false;
   }



#############################################
#                  Rechnung                 #
#############################################

 foreach $var (@ARGUMENTE)
   {
     -e $var || die "Error: $var don't exists\n";
     -d $var && die "Error: $var is a directory\n"; 
     open (SPLINE_FILE, ">$var.tmp") 
       || die "Error: can't write $var.tmp\n";
     &diff_data(SPLINE_FILE,$var);
     close (SPLINE_FILE);
   
     system "gnuplot $var.tmp";
     
     if ($debug == $false)
       {
         unlink ("$var.tmp") || die "Error: can't delete $var.tmp\n"; 
       }

     &ezdiff($var); 
     
     if ($debug == $false)
       {
         unlink ("$var.dat") || die "Error: can't delete $var.dat\n";
       }
   }

 open (GNUPLOT_TMP, ">$gnuplot_tmp") 
   || die "Error can't write $gnuplot_tmp\n";

 if ($all_in_one == $true)   
   {
     &ui_curve_head(all_ui);
     print GNUPLOT_TMP "plot \\\n";
     $j = 0;

     foreach $var (@ARGUMENTE)
       {
         &ui_curve_plot($var);

         if ($j < $#ARGUMENTE)
           {
             print GNUPLOT_TMP ",\\\n";
           }
         $j++;
       }

     print GNUPLOT_TMP "\n#------------\n";
     print GNUPLOT_TMP "pause -1 \"Hit Return \"\n" if 
       ($latex_output == $false && $small_latex_output == $false);
     &cond_curve_head(all_cond);
     print GNUPLOT_TMP "plot \\\n";
     $j = 0;

     foreach $var (@ARGUMENTE)
       {
         &cond_curve_plot($var);

         if ($j < $#ARGUMENTE)
           {
             print GNUPLOT_TMP ",\\\n";
           }
         $j++;
       }

     print GNUPLOT_TMP "\n#------------\n";
     print GNUPLOT_TMP "pause -1 \"Hit Return \"\n" if 
       ($latex_output ==$false && $small_latex_output == $false);
    
     &partial_pressure_curve_head(all_partial);  
     print GNUPLOT_TMP "plot \\\n";
     $j = 0;

     foreach $var (@ARGUMENTE)
       {
         my($i) = $_;
         &partial_pressure_curve_plot($var);

         if ($j < $#ARGUMENTE)
           {
             print GNUPLOT_TMP ",\\\n";
           }
         $j++;
        }

     print GNUPLOT_TMP "\n#------------\n";
     print GNUPLOT_TMP "pause -1 \"Hit Return \"\n" if 
       ($latex_output == $false && $small_latex_output == $false);
   }

 else
   {
     foreach $var (@ARGUMENTE)
       {
         &ui_curve_head($var);
         print GNUPLOT_TMP "plot \\\n";
         &ui_curve_plot($var);
         print GNUPLOT_TMP "\n#------------\n";
         print GNUPLOT_TMP "pause -1 \"Hit Return \"\n" if 
           ($latex_output == $false && $small_latex_output == $false);
       }

     foreach $var (@ARGUMENTE)
       {
         &cond_curve_head($var);    
         print GNUPLOT_TMP "plot \\\n";
         &cond_curve_plot ($var);
         print GNUPLOT_TMP "\n#------------\n";
         print GNUPLOT_TMP "pause -1 \"Hit Return \"\n" if 
           ($latex_output == $false && $small_latex_output == $false);
       }

     foreach $var (@ARGUMENTE)
       {
         &partial_pressure_curve_head($var);
         print GNUPLOT_TMP "plot \\\n";
         &partial_pressure_curve_plot ($var);
         print GNUPLOT_TMP "\n#------------\n";
         print GNUPLOT_TMP "pause -1 \"Hit Return \"\n" if 
           ($latex_output == $false && $small_latex_output == $false);
       }   
   }

 close (GNUPLOT_TMP);
 system "gnuplot $gnuplot_tmp";

 if ($debug == $false && $del_cond == $false)
   {
     unlink "$gnuplot_tmp" || die "can't delete  $gnuplot_tmp\n"; 
   }


#--- Latex Output ---

 if (($latex_output == $true) || ($small_latex_output == $true))
   { 
     open (LATEX_TMP, ">$latex_tmp.tex");
     &latex_head();

     if ($all_in_one == $true)
       {
         &latex_ui_curve(all_ui);
         &latex_cond_curve(all_cond);
         &latex_partial_pressure_curve(all_partial)
       }

     elsif ($latex_output == $true)
       {
         foreach $var (@ARGUMENTE)
           {
             &latex_ui_curve($var);
           }

         foreach $var (@ARGUMENTE)
           {
             &latex_cond_curve($var);
           }

         foreach $var (@ARGUMENTE)
           {
             &latex_partial_pressure_curve($var);
           }    
       }
     
     else
       {
         $counter = 0;

         foreach $var (@ARGUMENTE)
           {
             &latex_ui_curve_small($var);
             $counter++;
           }     

         foreach $var (@ARGUMENTE)
           {
             &latex_cond_curve_small($var);
             $counter++;
           }

         foreach $var (@ARGUMENTE)
           {
             &latex_partial_pressure_curve_small($var);
             $counter++;
           }

         print LATEX_TMP "\\end{figure}\n" if (($counter % 2 ) == 1); 
       }     

     print LATEX_TMP "\\end{center}\n";
     print LATEX_TMP "\\end{document}\n";
     close (LATEX_TMP);
     print "\n\t--- generating dvi-file ---\n";
     system "latex $latex_tmp.tex";

     unlink "$latex_tmp.tex", "$latex_tmp.aux", "$latex_tmp.log" 
       if ($debug ==$false);

     print "\n\t--- generating postscript-file ---\n";
     system "dvips -o $latex_tmp.ps $latex_tmp.dvi"; 


# --- Loeschen der temporaeren LaTeX-Files--

     if ($debug == $false)
       {
         print "\n\t --- deleting temporary-files ---\n";
         unlink "$latex_tmp.tex", 
           "$latex_tmp.aux", "$latex_tmp.log" ,"$latex_tmp.dvi"
           || die "can't delete TeX-files\n";

         if ($all_in_one == $true)
           {
             unlink "all_ui.eps", 
               "all_cond.cond.eps", "all_partial.partial.eps"
               || die "can't delete eps-files\n";
               print "all_ui.eps 
                 all_cond.cond.eps all_partial.partial.eps\n";
           }

         else
           {
             foreach $var (@ARGUMENTE)
               {
                 unlink "$var.eps", 
                   "$var.cond.eps", "$var.partial.eps" 
                   || die "can't  delete eps-files\n";
                 print "$var.eps $var.cond.eps $var.partial.eps\n";
               }
           } 
       }
   }

#--- Loeschen der temporaeren Files --- 

 if ($del_cond == $false)
   {
     print "deleting ";

     foreach $var (@ARGUMENTE)
       {
         unlink "$var.dat.leit" || die "can't delete $var.dat.leit\n";
         print "$var.dat.leit ";
       }

     print "\n"
   }

 print "\tHAVE A LOT OF FUN!\n";

########################################
#           Funktionen                 #
########################################

#--- U-I-Kurvenkopf ---

 sub ui_curve_head {
   my ($i) = @_; 

   print GNUPLOT_TMP "reset\n";

   if ($latex_output ==1 || $small_latex_output == 1)
     {
       print GNUPLOT_TMP "set term postscript eps\n";
       print GNUPLOT_TMP "set out \"$i.eps\"\n";
     }

   print GNUPLOT_TMP "set grid \n";
   print GNUPLOT_TMP "set title \"U-I-Curve\"\n";
   print GNUPLOT_TMP <<EO_UI;
   set xlabel "U / V"
   set ylabel "I / A"
   set zero 1e-10
EO_UI
 }

#--- U-I-Kurvenplot ---
 sub ui_curve_plot {
   my ($j) = @_;

   print  GNUPLOT_TMP 
     "\"$j\" using ($faktor*\$1*1e-3):($faktor*\$2*1e-9) \\
     '\%lf,\%lf' smooth $fitalg t \"\",\\\n";
   print GNUPLOT_TMP  
     "\"$j\" using ($faktor*\$1*0.001):($faktor*\$2*1e-9) \\
     '\%lf,\%lf' t \"$j\"";
 }


#--- Berechnung der Steigung ---

 sub diff_data {
   my ($i,$j) =@_;

   print  $i "set term table\n";
   print  $i "set out \"$j.dat\"\n";
   print  $i "set zero 1e-10\n";
   print  $i "plot \"$j\" using (\$1*1e-3):(\$2*1e-9) \\
     '\%lf,\%lf' smooth $fitalg\n"
 }

#--- Leitfaehigkeit-U-Kurvenkopf
 sub cond_curve_head {
   my ($i) = @_;

   print GNUPLOT_TMP  "\nreset \n";
   
   if ($latex_output == $true || $small_latex_output == $true)
     {
       print GNUPLOT_TMP "set term postscript eps\n";
       print GNUPLOT_TMP "set out \"$i.cond.eps\"\n";
     }

   print GNUPLOT_TMP  "set zero 1e-10 \n";
   print GNUPLOT_TMP  "set grid \n";
   print GNUPLOT_TMP  "set title \\
     \"Conductivity-Voltage-Curve ($geom_info geometry)\"\n";
   print GNUPLOT_TMP  "set xlabel \"U / V\"\n";
   print GNUPLOT_TMP  "set ylabel \"Conductivity / (Ohm cm)^-1\"\n";
 }


#--- Leitfaehigkeit-U-Kurvenplot

 sub cond_curve_plot {
   my ($j) = @_;

   print GNUPLOT_TMP  "\"$j.dat.leit\" using \\\n";
   print GNUPLOT_TMP  
     "($faktor*\$1):(\$2/($geometry)/$point_contact/1e-4*1e-9) t \"$j\"";
 }

#--- Leitf.-Partialdruckkurvenkopf
 sub partial_pressure_curve_head {
   my ($i) = @_;

   print GNUPLOT_TMP "\nreset\n";

   if ($latex_output == $true || $small_latex_output == $true)
     {
       print GNUPLOT_TMP "set term postscript eps\n";
       print GNUPLOT_TMP "set out \"$i.partial.eps\"\n";
     }

   print GNUPLOT_TMP "set grid\n";
   print GNUPLOT_TMP "set zero 1e-10\n";
   print GNUPLOT_TMP "set title \\
     \"Conductivity-PartialPressure-Curve ($geom_info geometry)\"\n";
   print GNUPLOT_TMP "set xlabel \"Oxygen partial pressure / bar\"\n";
   print GNUPLOT_TMP "set ylabel \"log Conductivity\"\n";
   print GNUPLOT_TMP "set logscale x 10\n";
 }


#--- Leitf.-Partialdruckkurvenplot

 sub partial_pressure_curve_plot {
   my ($i) = @_;
   @last_sign = split m#/#, $i;
   my ($temp) = $last_sign[$#last_sign];

   if ($temp =~s/\D+//g)
     { 
       ;
     }

   print " -calculating: $i\ttemperature: $temp C\n";
   print GNUPLOT_TMP "\"$i.dat.leit\" \\
     using ($oxygen_p_p/exp(\$1*4*$F/$R/($temp+273.15))):\\\n"; 
   print GNUPLOT_TMP 
     "(log10(1/($geometry*$point_contact*1e-4)*\$2*1e-9)) t \"$i\"";
 }

#--- Differenzieren
 sub ezdiff {
   my ($j) = @_;
   my (@xdata);
   my (@ydata);
   my ($y_diff);
   my ($i);

   open (DAT_FILE,"<$j.dat") || die "can't read $j.dat\n";
   
   while (<DAT_FILE>)
     {
       next if /^#/; 
       push(@xdata, (split(/\s/))[0]);
       push(@ydata, (split(/\s/))[1]);
     }
     
   close (DAT_FILE);
   open(DIFF_FILE, ">$j.dat.leit")  
     || die "can't write $j.dat.leit\n";
     
   for ($i=1; $i<$#xdata; $i++)
     {
       $y_diff[$i] = (($ydata[$i] - $ydata[$i-1]) 
         / ($xdata[$i] - $xdata[$i-1])
         + ($ydata[$i+1] - $ydata[$i]) / ($xdata[$i+1] - $xdata[$i]))
         *1e+09 / 2;
       print DIFF_FILE "$xdata[$i]\t$y_diff[$i]\n";
     }

   close(DIFF_FILE);     
 }


#-- LATEX-OUTPUT ---
 sub latex_head {
   print LATEX_TMP <<"LATEX_HEAD_1";
   \\documentclass[a4paper]{article}
   \\usepackage{epsfig,fancyheadings}
   \\usepackage{float}
   \\restylefloat{figure} 
   \\rfoot{\\copyright \\/ F. Rocholl}
LATEX_HEAD_1

   print LATEX_TMP "\\cfoot{tip radius = $point_contact \$\\mu m\$}";
   print LATEX_TMP <<"LATEX_HEAD_2";
   \\lhead{{\\bf  WERTE-AUS:} automated evaluation of U-I-Curves}
   \\rhead{\\rm\\thepage}
   \\lfoot{{\\footnotesize evaluated at \\today}}
   \\setlength{\\textwidth}{19cm}
   \\oddsidemargin = -1.2cm
   \\evensidemargin = -1.2cm
   \\pagestyle{fancy}
   \\begin{document}
   \\begin{center}
LATEX_HEAD_2
 }


#--- LaTeX U-I-Kurve

 sub latex_ui_curve {
   my ($i) = @_;
   
   print LATEX_TMP "\\begin{figure}[H]\\noindent\n";
   print LATEX_TMP 
     "\\centering\\epsfig{file=$i.eps,width=\\linewidth}\n";
   print LATEX_TMP "\\end{figure}\n";
 }


#--- LaTeX U-I-Kurve (klein)

 sub latex_ui_curve_small {
   my ($i) = @_;
   
   if ($counter % 2 == 0)
     {
       print LATEX_TMP "\\begin{figure}[H]\\noindent\n";
       print LATEX_TMP "\\begin{minipage}[b]{0.46\\linewidth}\n";
       print LATEX_TMP 
         "\\centering\\epsfig{file=$i.eps,width=\\linewidth}\n";
       print LATEX_TMP "\\end{minipage}\\hfill\n";
     }

   else
     {
       print LATEX_TMP "\\begin{minipage}[b]{0.46\\linewidth}\n";
       print LATEX_TMP 
         "\\centering\\epsfig{file=$i.eps,width=\\linewidth}\n";
       print LATEX_TMP "\\end{minipage}\\end{figure}\n\%-----\n";
     }
 }


#--- LaTeX U-Leitf.-Kurve

 sub latex_cond_curve {
   my ($i) = @_;
   
   print LATEX_TMP "\\begin{figure}[H]\\noindent\n";
   print LATEX_TMP 
     "\\centering\\epsfig{file=$i.cond.eps,width=\\linewidth}\n";
   print LATEX_TMP "\\end{figure}\n";
 }


#--- LaTeX U-Leitf.-Kurve (klein) ---

 sub latex_cond_curve_small {
   my ($i) = @_;
   
   if ($counter % 2 == 0)
     {
       print LATEX_TMP "\\begin{figure}[H]\\noindent\n";
       print LATEX_TMP "\\begin{minipage}[b]{0.46\\linewidth}\n";
       print LATEX_TMP 
         "\\centering\\epsfig{file=$i.cond.eps,width=\\linewidth}\n";
     print LATEX_TMP "\\end{minipage}\\hfill\n";
     }

   else
     {
       print LATEX_TMP "\\begin{minipage}[b]{0.46\\linewidth}\n";
       print LATEX_TMP 
         "\\centering\\epsfig{file=$i.cond.eps,width=\\linewidth}\n";
       print LATEX_TMP "\\end{minipage}\\end{figure}\n\%-----\n";
     }
 }

#--- LaTeX Partialdruck-Leitf.-Kurve ---

 sub latex_partial_pressure_curve {
   my ($i) = @_;
   
   print LATEX_TMP "\\begin{figure}[H]\\noindent\n";
   print LATEX_TMP 
     "\\centering\\epsfig{file=$i.partial.eps,width=\\linewidth}\n";
   print LATEX_TMP "\\end{figure}\n";
 }

#--- LaTeX Partialdruck-Leitf.-Kurve (klein) ---
 sub latex_partial_pressure_curve_small {
   my ($i) = @_;

   if ($counter % 2 == 0)
     {
       print LATEX_TMP "\\begin{figure}[H]\\noindent\n";
       print LATEX_TMP "\\begin{minipage}[b]{0.46\\linewidth}\n";
       print LATEX_TMP 
         "\\centering\\epsfig{file=$i.partial.eps,width=\\linewidth}\n";
       print LATEX_TMP "\\end{minipage}\\hfill\n";
     }

   else
     {
       print LATEX_TMP "\\begin{minipage}[b]{0.46\\linewidth}\n";
       print LATEX_TMP 
         "\\centering\\epsfig{file=$i.partial.eps,width=\\linewidth}\n";
       print LATEX_TMP "\\end{minipage}\\end{figure}\n\%-----\n";
     }
 }





# --- Versionsausgabe ---

 sub version_func {
   $0 =~ s#.*/##g;
   
   print  "$0 Version $version_number\n";
   print "author: Frank Rocholl <rocholl\@hottemax.uni-muenster.de>\n";
 }


#--- Hilfe ---

 sub help_func {
 &version_func();
 print <<"ENDE";
options:
 -D    Debug modus
 -C    don't delete Conductivity-files (*.dat.leit)
 -c    Cylinder geometry (default: radial geometry)
 -a    All in one
 -h    show this Help
 -l    LaTeX output (default: gnuplot output)
 -o <> referenz Oxygen partial pressure (default 0.2 bar)
 -p <> Point contact in \\mu m (default 20 \\mu m)
 -s    Small latex output 
 -v    print Versions number 
ENDE
 }

# --- Usage ---

 sub usage {
  $0 =~ s#.*/##g;
  
  print  "usage: $0 -[CDachlo:p:sv] files\n";
  exit(1);
 }


syntax highlighted by Code2HTML, v. 0.9.1