The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Basic/Complex/complex.pd 01
Basic/Core/Core.pm 13
Basic/Core/Core.xs 12
Basic/Core/Dev.pm 21
Basic/Core/IFiles.pm 2710
Basic/Lite.pm 12
Basic/LiteF.pm 13
Basic/PDL.pm 11
Basic/SourceFilter/NiceSlice.pm 11
Changes 0232
DEPENDENCIES 80
Example/PLplot/refresh.pdl 1900
GENERATED/PDL/Bad.pm 48815
GENERATED/PDL/Complex.pm 0121
GENERATED/PDL/Compression.pm 08
GENERATED/PDL/FFT.pm 012
GENERATED/PDL/GSL/DIFF.pm 012
GENERATED/PDL/GSL/INTEG.pm 044
GENERATED/PDL/GSL/MROOT.pm 04
GENERATED/PDL/GSLSF/AIRY.pm 032
GENERATED/PDL/GSLSF/BESSEL.pm 0108
GENERATED/PDL/GSLSF/CLAUSEN.pm 04
GENERATED/PDL/GSLSF/COULOMB.pm 016
GENERATED/PDL/GSLSF/COUPLING.pm 012
GENERATED/PDL/GSLSF/DAWSON.pm 04
GENERATED/PDL/GSLSF/DEBYE.pm 016
GENERATED/PDL/GSLSF/DILOG.pm 08
GENERATED/PDL/GSLSF/ELEMENTARY.pm 08
GENERATED/PDL/GSLSF/ELLINT.pm 040
GENERATED/PDL/GSLSF/ELLJAC.pm 04
GENERATED/PDL/GSLSF/ERF.pm 020
GENERATED/PDL/GSLSF/EXP.pm 012
GENERATED/PDL/GSLSF/EXPINT.pm 036
GENERATED/PDL/GSLSF/FERMI_DIRAC.pm 020
GENERATED/PDL/GSLSF/GAMMA.pm 076
GENERATED/PDL/GSLSF/GEGENBAUER.pm 08
GENERATED/PDL/GSLSF/HYPERG.pm 032
GENERATED/PDL/GSLSF/LAGUERRE.pm 04
GENERATED/PDL/GSLSF/LEGENDRE.pm 060
GENERATED/PDL/GSLSF/LOG.pm 08
GENERATED/PDL/GSLSF/POLY.pm 04
GENERATED/PDL/GSLSF/POW_INT.pm 04
GENERATED/PDL/GSLSF/PSI.pm 012
GENERATED/PDL/GSLSF/SYNCHROTRON.pm 08
GENERATED/PDL/GSLSF/TRANSPORT.pm 016
GENERATED/PDL/GSLSF/TRIG.pm 056
GENERATED/PDL/GSLSF/ZETA.pm 012
GENERATED/PDL/Graphics/PLplot.pm 57110
GENERATED/PDL/Graphics/TriD/Rout.pm 016
GENERATED/PDL/IO/Browser.pm 04
GENERATED/PDL/IO/GD.pm 016
GENERATED/PDL/IO/Misc.pm 012
GENERATED/PDL/IO/Pnm.pm 012
GENERATED/PDL/Image2D.pm 045
GENERATED/PDL/ImageND.pm 012
GENERATED/PDL/Math.pm 0108
GENERATED/PDL/MatrixOps.pm 020
GENERATED/PDL/Minuit.pm 040
GENERATED/PDL/Ops.pm 0116
GENERATED/PDL/Primitive.pm 0188
GENERATED/PDL/Slatec.pm 092
GENERATED/PDL/Slices.pm 066
GENERATED/PDL/Transform.pm 04
GENERATED/PDL/Ufunc.pm 0283
Graphics/Makefile.PL 11
Graphics/PLplot/Changes 1040
Graphics/PLplot/Makefile.PL 2810
Graphics/PLplot/README 770
Graphics/PLplot/plplot.pd 52670
Known_problems 1213
MANIFEST 80
MANIFEST.SKIP 40
META.json 23
META.yml 12
Makefile.PL 01
Release_Notes 0144
TODO 191
cygwin/INSTALL 80
cygwin/README 50
debian/README.Debian 40
debian/control 20
debian/perldl.conf 130
perldl.conf 140
t/config.t 11
t/plplot.t 5730
t/plplot_no_fork.win32 310
win32/INSTALL 21
87 files changed (This is a version diff) 124213113
@@ -11,6 +11,7 @@ pp_beginwrap; # required for overload to work
 pp_bless('PDL::Complex');
 
 pp_addpm {At => Top}, <<'EOD';
+our $VERSION = '2.009';
    use PDL::Slices;
    use PDL::Types;
    use PDL::Bad;
@@ -5,9 +5,11 @@ package PDL::Core;
 use strict;
 use warnings;
 use PDL::Exporter;
+require PDL; # for $VERSION
 use DynaLoader;
 our @ISA    = qw( PDL::Exporter DynaLoader );
-bootstrap PDL::Core;
+our $VERSION = '2.012';
+bootstrap PDL::Core $VERSION;
 use PDL::Types ':All';
 
 our @EXPORT = qw( piddle pdl null barf ); # Only stuff always exported!
@@ -337,7 +337,8 @@ iscontig(x)
     RETVAL
 
 # using "perl" not $^X because that doesn't work on "perl in space"
-INCLUDE_COMMAND: perl -e "require q{Dev.pm}; PDL::Core::Dev::generate_core_flags()"
+# TODO: switching back to $^X since using "perl" is not a viable fix
+INCLUDE_COMMAND: $^X -e "require q{Dev.pm}; PDL::Core::Dev::generate_core_flags()"
 
 #if 0
 =begin windows_mmap
@@ -515,7 +515,7 @@ sub pdlpp_mkgen {
     $prefix = "$dir/GENERATED/$prefix";
     File::Path::mkpath(dirname($prefix));
     #there is no way to use PDL::PP from perl code, thus calling via system()
-    my @in = map { "-I$_" } @INC;
+    my @in = map { "-I$_" } @INC, 'inc';
     my $rv = system($^X, @in, "-MPDL::PP qw[$mod $mod $prefix]", $pd);
     if ($rv == 0 && -f "$prefix.pm") {
       $added{$manifestpm} = "mod=$mod pd=$pd (added by pdlpp_mkgen)";
@@ -728,7 +728,6 @@ sub datatypes_switch {
     $cname =~ s/^PDL_//;
     push @m, "\tcase $typesym: retval = PDL.bvals.$cname; break;";
   }
-warn "(@m)";
   print map "$_\n", @m;
 }
 
@@ -2,43 +2,26 @@
 
 PDL::Install::Files
 
-=head1 DESCRIPTION
-
-This module is a stub that contains some auxiliary routines useful for
-inlining PDL-aware C code into PDL programs.  
-
-It defines some auxiliary package variables and two routines that are not
-normally called by users.
-
-=head1 METHODS
-
-=head2 deps
-
-=for ref
-
-Returns nothing -- stub for "Inline with => 'PDL'".
+=head1 SYNOPSIS
 
-=head2 Inline
+  use Inline with => 'PDL';
+  # or alternatively, if your XS module uses PDL:
+  use ExtUtils::Depends;
+  my $pkg = ExtUtils::Depends->new(qw(MyPackage PDL));
 
-=for ref
-
-Accepts a class and a lanaguage string.
-
-If the language string is "C",  Inline returns a hash containing TYPEMAPS, INC, 
-AUTO_INCLUDE, and BOOT information that are useful for autogenerated PDL-aware C 
-code using "Inline with => 'PDL'".  The actual data are pulled from methods in 
-C<PDL::Core::Dev>.  
+=head1 DESCRIPTION
 
-If the language string is anything else, then it returns nothing.
+This module is for use by L<ExtUtils::Depends> and L<Inline>. There are
+no user-serviceable parts inside.
 
 =cut
 
-
-
 package PDL::Install::Files;
 # support ExtUtils::Depends
 require PDL::Core::Dev;
 
+our $VERSION = '2.009';
+
 $self = {
   'typemaps' => [ &PDL::Core::Dev::PDL_TYPEMAP ],
   'inc' => &PDL::Core::Dev::PDL_INCLUDE,
@@ -45,7 +45,8 @@ use PDL::Bad '';
 use PDL::Version ;  # Doesn't export anything - no need for ''
 use PDL::Lvalue;
 
-$PDL::Lite::VERSION = $PDL::Version::VERSION;
+package PDL::Lite;
+$VERSION = $PDL::Version::VERSION;
 
 ;# Exit with OK status
 
@@ -27,7 +27,9 @@ smaller see the L<PDL::Lite|PDL::Lite> module.
 
 # get the version: 
 use PDL::Version;
-$PDL::LiteF::VERSION = $PDL::Version::VERSION;
+
+package PDL::LiteF;
+$VERSION = $PDL::Version::VERSION;
 
 
 # Load the fundamental PDL packages, with imports
@@ -146,7 +146,7 @@ start-up modules.
 
 
 # set the version:
-$PDL::VERSION = '2.008';     # Go to sub numbering per git push
+$PDL::VERSION = '2.012';
 
 # Main loader of standard PDL package
 
@@ -26,7 +26,7 @@ no warnings;
 
 package PDL::NiceSlice;
 
-our $VERSION = '1.000_003';
+our $VERSION = '1.001';
 $VERSION = eval $VERSION;
 
 $PDL::NiceSlice::debug = defined($PDL::NiceSlice::debug) ? $PDL::NiceSlice::debug : 0;
@@ -1,3 +1,235 @@
+commit e01c825bb0d60db045ea14e030008c67e1a55bd0
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sun Jun 14 08:27:01 2015 -0400
+
+    Update VERSION in Core.pm to 2.012
+
+ Basic/Core/Core.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit bff552f47905757f4af89a6952194e9c045992c8
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sun Jun 14 08:14:28 2015 -0400
+
+    Update VERSION to 2.012 for CPAN release
+
+ Basic/PDL.pm   |  2 +-
+ Known_problems |  9 ++++++++-
+ Release_Notes  | 31 +++++++++++++++++++++++++++++++
+ 3 files changed, 40 insertions(+), 2 deletions(-)
+
+commit 87487f0c4abd51268b898752d9b3029b926ec7aa
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sun Jun 14 07:53:12 2015 -0400
+
+    Add package statement to PDL::Lite and PDL::LiteF
+    
+    So that they are officially indexed
+
+ Basic/Lite.pm  | 3 ++-
+ Basic/LiteF.pm | 4 +++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+commit 834140083e3080097c55484ea53215661fb464ba
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sun Jun 14 07:46:01 2015 -0400
+
+    Give PDL::NiceSlicee a non-developer version number
+    
+    Now that the back copies of the main PDL distribution
+    are on backpan, there needs to be an official copy to
+    be indexed.
+
+ Basic/SourceFilter/NiceSlice.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0c711c264eef410377b31ae0a52473248ade193b
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sat Jun 13 16:33:59 2015 -0400
+
+    Add File::Path to CONFIGURE_REQUIRES
+
+ Makefile.PL | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 47f91a37309585f1f64d582a80abcb26e09038bb
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sat Jun 13 16:33:01 2015 -0400
+
+    Use $^X instead of "perl" in INCLUDE_COMMAND
+    
+    This was a regression from PDL-2.007
+
+ Basic/Core/Core.xs | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit fa428b0826162cc56e0f23215338115336027daf
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Tue Jun 2 17:01:22 2015 -0400
+
+    Update VERSION to 2.011 for CPAN release
+
+ Basic/PDL.pm   |  2 +-
+ Known_problems |  2 +-
+ Release_Notes  | 12 ++++++++++--
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+commit 1704dd09b10f9f96ffd18744b1857366f38725cc
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Tue Jun 2 17:00:52 2015 -0400
+
+    Hardwire VERSION in Core.pm to work around indexing problem
+
+ Basic/Core/Core.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cb7e307060d98c1f991d3d77d32059eba25b1425
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Tue Jun 2 14:40:15 2015 -0400
+
+    Update VERSION to 2.010 and Known_problems and Release_Notes for CPAN
+
+ Basic/PDL.pm   |  2 +-
+ Known_problems | 10 +++++-----
+ Release_Notes  | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 57 insertions(+), 6 deletions(-)
+
+commit 8e9bc6a6cc48769fa288f3b796575d8a10bb95e4
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Sat May 30 15:51:01 2015 +0100
+
+    Complete purge of PDL::Graphics::PLplot
+
+ .gitignore                  |    4 -
+ .travis.yml                 |    2 +-
+ DEPENDENCIES                |    8 -
+ Example/PLplot/refresh.pdl  |  190 --
+ Graphics/Makefile.PL        |    2 +-
+ Graphics/PLplot/Changes     |  104 -
+ Graphics/PLplot/Makefile.PL |  281 ---
+ Graphics/PLplot/README      |   77 -
+ Graphics/PLplot/plplot.pd   | 5267 -------------------------------------------
+ Known_problems              |    7 -
+ MANIFEST                    |    2 -
+ MANIFEST.SKIP               |    4 -
+ Release_Notes               |    2 +-
+ TODO                        |   20 +-
+ cygwin/INSTALL              |    8 -
+ cygwin/README               |    5 -
+ debian/README.Debian        |    4 -
+ debian/control              |    2 -
+ debian/perldl.conf          |   13 -
+ perldl.conf                 |   14 -
+ t/config.t                  |    2 +-
+ t/plplot.t                  |  573 -----
+ t/plplot_no_fork.win32      |   31 -
+ win32/INSTALL               |    3 +-
+ 24 files changed, 6 insertions(+), 6619 deletions(-)
+
+commit 673f996503403cd7e26db921f682b72e65588773
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Sat May 30 02:21:39 2015 +0100
+
+    Remove debugging warn
+
+ Basic/Core/Dev.pm | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit a7e3d667359aebe5b3028c851d1810300a74becd
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Sat May 30 02:21:15 2015 +0100
+
+    De-hardcode $PDL::Core::VERSION
+
+ Basic/Core/Core.pm | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit ed2a70c19e4f43d2494323dd002351ce05d76566
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Fri May 29 17:47:57 2015 -0400
+
+    Update VERSION to 2.009_01 for development
+
+ Basic/PDL.pm   |  2 +-
+ Known_problems |  2 +-
+ Release_Notes  | 35 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 2 deletions(-)
+
+commit 042dc981fb9bb386a870aa8f1bf58b2d71b099a8
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Fri May 29 12:26:25 2015 -0400
+
+    Update Known_problems and Release_Notes for 2.009 release
+
+ Known_problems |  1 +
+ Release_Notes  | 16 ++++++++++++++--
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+commit a3961b01fc4df1a6faee99f39f03b3a1778bd63a
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Mon May 25 19:13:44 2015 -0400
+
+    Update VERSION to 2.009
+
+ Known_problems | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 741c8cb834cc537a8ff29fcc92aba9ccb1d70a7f
+Author: kmx <kmx@cpan.org>
+Date:   Mon May 25 14:53:24 2015 +0200
+
+    fix for pdlpp_mkgen: cannot convert 'Lib/Transform/Proj4/Proj4.pd'
+
+ Basic/Core/Dev.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 72682a78ea58fe4de0beedff8c88f53deccc6866
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Mon May 25 01:41:03 2015 +0100
+
+    No distrib PDL::Graphics::PLplot in PDL for now
+
+ MANIFEST | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit cc14faf53d562cfb0fb6ce432c7eec2638c3819f
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Mon May 25 01:25:21 2015 +0100
+
+    Add $VERSION so PAUSE can index, correct doc
+
+ Basic/Core/IFiles.pm | 37 ++++++++++---------------------------
+ 1 file changed, 10 insertions(+), 27 deletions(-)
+
+commit 46a2c38af1456298c08ea3a79c133f7595107fc2
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Mon May 25 01:24:49 2015 +0100
+
+    Add $VERSION so PAUSE can index
+
+ Basic/Complex/complex.pd | 1 +
+ Basic/Core/Core.pm       | 3 ++-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 178e4daee357c3e78eaf045baba90b89c6e5a26a
+Author: Ed J <mohawk2@users.noreply.github.com>
+Date:   Mon May 25 01:17:45 2015 +0100
+
+    Update global $VERSION to 2.009, add release notes
+
+ Basic/PDL.pm  | 2 +-
+ Release_Notes | 7 +++++++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+commit f197b41f52b534cd5fbccc6bfa9a3b4e4b8f0e00
+Author: Chris Marshall <devel.chm.01@gmail.com>
+Date:   Sun May 24 18:42:22 2015 -0400
+
+    Update VERSION to 2.008 for CPAN release
+
+ Basic/PDL.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit 006ecc54c8c1883513a38ed9bc20a9b1ca7ad240
 Author: Chris Marshall <devel.chm.01@gmail.com>
 Date:   Sun May 24 18:17:49 2015 -0400
@@ -140,14 +140,6 @@ PDL::Graphics::PGPLOT
                                           and library.
 
 
-PDL::Graphics::PLplot
-                  The PLplot graphics library.
-                  See http://plplot.sourceforge.net 
-
-                                          Module will be built if the
-                                          PLplot library is detected.
-
-
 PDL::Graphics::IIS
                   To be useful an application that supports
                   the 'IIS' protocol must be installed, e.g.
@@ -1,190 +0,0 @@
-#!/usr/bin/perl
-#
-# Figure out which low-level commands are necessary to refresh an
-# interactive PLplot device
-
-use strict;
-use PDL::Graphics::PLplot;
-
-sub refresh{
-
-   my $x = sequence(10);
-   my $y = $x**2;
-
-   #  my $w=PDL::Graphics::PLplot->new(DEV=>'psc',FILE=>'plplottest.ps',JUST=>0);
-   my $w = PDL::Graphics::PLplot->new(DEV=>'xwin',FILE=>':0',JUST=>1);
-   plspause(0);
-
-   ## Either use this chunk of lines
-   #
-   #    print "before first plot BOX is ",@{$w->{BOX}},"\n";
-   #    $w->xyplot2(10*$x,$y);
-   #    print "after first plot BOX is ",@{$w->{BOX}},"\n";
-   #    $w->hold;
-   #    $w->xyplot2(10*$x,$y*2,COLOR=>'RED');
-   #    print "after second plot BOX is ",@{$w->{BOX}},"\n";
-   #    $w->release;
-   #    $w->close;
-
-   ## or use this chunk of lines
-   #
-   my $size = 50;
-   $w->imag(sequence($size,$size),PALETTE=>'GREYSCALE');
-   #    sleep 3;
-   $w->imag(random($size,2*$size));
-   $w->close;
-
-}
-
-sub PDL::Graphics::PLplot::imag {
-   my $self = shift;
-   my $img = shift;
-   my %opts = @_;
-
-   # Set PLplot to right output stream
-   plsstrm($self->{STREAMNUMBER});
-   # Advance the (sub)page unless we're being held or the window is brand new
-   pladv(0) unless $self->held or !exists($self->{BOX});
-
-   # Only process COLORMAP entries once
-   my $z = $opts{COLORMAP};
-   delete ($opts{COLORMAP});
-
-   # Set ticks to be external
-   $self->{XBOX} = $self->{XBOX} . 'i' unless exists($opts{XBOX});# =~ /i/i;
-   $self->{YBOX} = $self->{YBOX} . 'i' unless exists($opts{YBOX});# =~ /i/i;
-
-   $self->setparm(%opts);
-
-   my @borders = (-0.5,$img->dim(0)-0.5,-0.5,$img->dim(1)-0.5);
-
-   unless ( $self->held ) {
-      $self->{BOX} = \@borders;
-   }
-
-   $self->_setwindow;
-   $self->_drawlabels;
-
-   # Draw the image
-   plimage($img,@borders,0,0,@borders);
-
-   # Plot box
-   plcol0(1); # set to frame color
-   plbox($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-      $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-   plflush();
-}
-
-sub PDL::Graphics::PLplot::held{
-   my $self = shift;
-   return $self->{HELD};
-}
-
-sub PDL::Graphics::PLplot::hold{
-   my $self = shift;
-   $self->{HELD} = 1;
-}
-
-sub PDL::Graphics::PLplot::release{
-   my $self = shift;
-   $self->{HELD} = 0;
-}
-
-sub PDL::Graphics::PLplot::xyplot2 {
-   my $self = shift;
-   my $x    = shift;
-   my $y    = shift;
-
-   my %opts = @_;
-
-   # Set PLplot to right output stream
-   plsstrm($self->{STREAMNUMBER});
-
-   # Only process COLORMAP entries once
-   my $z = $opts{COLORMAP};
-   delete ($opts{COLORMAP});
-
-   # Handle ERRORBAR options
-   my $xeb = $opts{XERRORBAR};
-   my $yeb = $opts{YERRORBAR};
-   delete ($opts{XERRORBAR});
-   delete ($opts{YERRORBAR});
-
-
-   # Advance the (sub)page unless we're being held or the window is brand new
-   pladv(0) unless $self->held or !exists($self->{BOX});
-
-   # Apply options
-   $self->setparm(%opts);
-
-   unless ($self->held) {
-      #  unless (exists($self->{BOX})) {
-      $self->{BOX} = [$x->minmax, $y->minmax];
-   }
-
-   # Set up viewport, subpage, world coordinates
-   $self->_setwindow;
-
-   # Draw labels
-   $self->_drawlabels;
-
-   # Plot box
-   plcol0(1); # set to frame color
-   plbox($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-      $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-   # Set the color according to the color specified in the object
-   # (we don't do this as an option, because then the frame might
-   # get the color requested for the line/points
-   plcol0($self->{CURRENT_COLOR_IDX});
-
-   # Set line style for plot only (not box)
-   pllsty($self->{LINESTYLE});
-
-   # Set line width for plot only (not box)
-   plwid($self->{LINEWIDTH});
-
-   # Plot lines if requested
-   if  ($self->{PLOTTYPE} =~ /LINE/) {
-      plline($x, $y);
-   }
-
-   # Set line width back
-   plwid(0);
-
-   # Plot points if requested
-   if ($self->{PLOTTYPE} =~ /POINTS/) {
-      my $c = $self->{SYMBOL};
-      unless (defined($c)) {
-
-         # The default for $c is a PDL of ones with shape
-         # equal to $x with the first dimension removed
-         #
-         my $z = PDL->zeroes($x->nelem);
-         $c = PDL->ones($z->zcover) unless defined($c);
-      }
-      plssym(0, $self->{SYMBOLSIZE}) if (defined($self->{SYMBOLSIZE}));
-
-      if (defined($z)) {  # If a color range plot requested
-         my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $z->minmax;
-         plcolorpoints($x, $y, $z, $c, $min, $max);
-      } else {
-         plsym($x, $y, $c);
-      }
-   }
-
-   # Plot error bars, if requested
-   if (defined($xeb)) {
-      # Horizontal (X) error bars
-      plerrx($x->nelem, $x - $xeb/2, $x + $xeb/2, $y);
-   }
-
-   if (defined($yeb)) {
-      # Vertical (Y) error bars
-      plerry($y->nelem, $x, $y - $yeb/2, $y + $yeb/2);
-   }
-
-   # Flush the PLplot stream.
-   plflush();
-}
@@ -4,7 +4,7 @@
 #
 package PDL::Bad;
 
-@EXPORT_OK  = qw(  badflag check_badflag badvalue orig_badvalue nbad nbadover ngood ngoodover setbadat setbadif setvaltobad setbadtoval setnantobad setbadtonan copybad isbad isgood  );
+@EXPORT_OK  = qw(  badflag check_badflag badvalue orig_badvalue nbad nbadover ngood ngoodover setbadat  PDL::PP isbad PDL::PP isgood PDL::PP nbadover PDL::PP ngoodover PDL::PP setbadif PDL::PP setvaltobad PDL::PP setnantobad PDL::PP setbadtonan PDL::PP setbadtoval PDL::PP copybad );
 %EXPORT_TAGS = (Func=>[@EXPORT_OK]);
 
 use PDL::Core;
@@ -24,15 +24,16 @@ use DynaLoader;
 
 =head1 NAME
 
-PDL::Bad - PDL does not process bad values
+PDL::Bad - PDL does process bad values
 
 =head1 DESCRIPTION
 
-PDL has been compiled with WITH_BADVAL either 0 or undef,
-so it does not contain any bad-value support code.
-Actually, a number of methods are defined, but they are only
-placeholders to make writing other code, that has to handle
-WITH_BADVAL being true or false, easier.
+PDL has been compiled with WITH_BADVAL set to 1. Therefore,
+you can enter the wonderful world of bad value support in
+PDL.
+
+This module is loaded when you do C<use PDL>,
+C<Use PDL::Lite> or C<PDL::LiteF>.
 
 Implementation details are given in
 L<PDL::BadValues>.
@@ -43,7 +44,9 @@ L<PDL::BadValues>.
  print "\nBad value support in PDL is turned " .
      $PDL::Bad::Status ? "on" : "off" . ".\n";
 
- Bad value support in PDL is turned off.
+ Bad value support in PDL is turned on.
+
+ and some other things
 
 =head1 VARIABLES
 
@@ -54,94 +57,858 @@ which may be of use.
 
 =item $PDL::Bad::Status
 
-Set to 0
+Set to 1
 
 =item $PDL::Bad::UseNaN
 
-Set to 0
+Set to 1 if PDL was compiled with C<BADVAL_USENAN> set,
+0 otherwise.
 
 =item $PDL::Bad::PerPdl
 
-Set to 0
+Set to 1 if PDL was compiled with the I<experimental>
+C<BADVAL_PER_PDL> option set, 0 otherwise.
 
 =back
 
 =cut
 
-# really should be a constant
-$PDL::Bad::Status = 0;
+
+
+
+
+
+
+=head1 FUNCTIONS
+
+
+
+=cut
+
+
+
+
+
+# really should be constants
+$PDL::Bad::Status = 1;
 $PDL::Bad::UseNaN = 0;
 $PDL::Bad::PerPdl = 0;
 
-# dummy routines
-#
+use strict;
+
+use PDL::Types;
+use PDL::Primitive;
+
+############################################################
+############################################################
+
+
+
+############################################################
+############################################################
+
 *badflag         = \&PDL::badflag;
 *badvalue        = \&PDL::badvalue;
 *orig_badvalue   = \&PDL::orig_badvalue;
 
-sub PDL::badflag       { return 0; } # no piddles can contain bad values by design
-sub PDL::badvalue      { return undef; }
-sub PDL::orig_badvalue { return undef; }
+############################################################
+############################################################
+
+=head2 badflag
+
+=for ref
+
+getter/setter for the bad data flag
+
+=for example
+
+  if ( $a->badflag() ) {
+    print "Data may contain bad values.\n";
+  }
+  $a->badflag(1);      # set bad data flag
+  $a->badflag(0);      # unset bad data flag
+
+When called as a setter, this modifies the piddle on which
+it is called. This always returns a Perl scalar with the
+final value of the bad flag.
+
+A return value of 1 does not guarantee the presence of
+bad data in a piddle; all it does is say that we need to
+I<check> for the presence of such beasties. To actually
+find out if there are any bad values present in a piddle,
+use the L<check_badflag|/check_badflag> method.
+
+=for bad
+
+This function works with piddles that have bad values. It
+always returns a Perl scalar, so it never returns bad values.
+
+=head2 badvalue
+
+=for ref
+
+returns the value used to indicate a missing (or bad) element
+for the given piddle type. You can give it a piddle,
+a PDL::Type object, or one of C<$PDL_B>, C<$PDL_S>, etc.
+
+=for example
+
+   $badval = badvalue( float );
+   $a = ones(ushort,10);
+   print "The bad data value for ushort is: ",
+      $a->badvalue(), "\n";
+
+This can act as a setter (e.g. C<< $a->badvalue(23) >>)
+if the data type is an integer or C<$PDL::Bad::UseNaN == 0>.
+Note that this B<never touches the data in the piddle>.
+That is, if C<$a> already has bad values, they will not
+be changed to use the given number and if any elements of
+C<$a> have that value, they will unceremoniously be marked
+as bad data. See L</setvaltobad>, L</setbadtoval>, and
+L</setbadif> for ways to actually modify the data in piddles
+
+If the C<$PDL::Bad::PerPdl> flag is set then it is possible to
+change the bad value on a per-piddle basis, so
+
+    $a = sequence (10);
+    $a->badvalue (3); $a->badflag (1);
+    $b = sequence (10);
+    $b->badvalue (4); $b->badflag (1);
+
+will set $a to be C<[0 1 2 BAD 4 5 6 7 8 9]> and $b to be
+C<[0 1 2 3 BAD 5 6 7 8 9]>. If the flag is not set then both
+$a and $b will be set to C<[0 1 2 3 BAD 5 6 7 8 9]>. Please
+note that the code to support per-piddle bad values is
+I<experimental> in the current release, and it requires that
+you modify the settings under which PDL is compiled.
+
+=for bad
+
+This method does not care if you call it on an input piddle
+that has bad values. It always returns a Perl scalar
+with the current or new bad value.
+
+=head2 orig_badvalue
+
+=for ref
+
+returns the original value used to represent bad values for
+a given type.
+
+This routine operates the same as L<badvalue|/badvalue>,
+except you can not change the values.
+
+It also has an I<awful> name.
+
+=for example
+
+   $orig_badval = orig_badvalue( float );
+   $a = ones(ushort,10);
+   print "The original bad data value for ushort is: ", 
+      $a->orig_badvalue(), "\n";
+
+=for bad
+
+This method does not care if you call it on an input piddle
+that has bad values. It always returns a Perl scalar
+with the original bad value for the associated type.
+
+=head2 check_badflag
+
+=for ref
+
+Clear the bad-value flag of a piddle if it does not
+contain any bad values
+
+Given a piddle whose bad flag is set, check whether it
+actually contains any bad values and, if not, clear the flag.
+It returns the final state of the bad-value flag.
+
+=for example
+
+ print "State of bad flag == ", $pdl->check_badflag;
+
+=for bad
+
+This method accepts piddles with or without bad values. It
+returns a Perl scalar with the final bad-value flag, so it
+never returns bad values itself.
+
+=cut
 
 *check_badflag = \&PDL::check_badflag;
-sub PDL::check_badflag { return 0; } # no piddles can contain bad values by design
 
-*isbad  = \&PDL::isbad;
+sub PDL::check_badflag {
+    my $pdl = shift;
+    $pdl->badflag(0) if $pdl->badflag and $pdl->nbad == 0;
+    return $pdl->badflag;
+} # sub: check_badflag()
+
+
+
+
+# note:
+#  if sent a piddle, we have to change it's bad values
+#  (but only if it contains bad values)
+#  - there's a slight overhead in that the badflag is
+#    cleared and then set (hence propagating to all
+#    children) but we'll ignore that)
+#  - we can ignore this for float/double types
+#    since we can't change the bad value
+#
+sub PDL::badvalue {
+    no strict 'refs';
+
+    my ( $self, $val ) = @_;
+    my $num;
+    if ( UNIVERSAL::isa($self,"PDL") ) {
+	$num = $self->get_datatype;
+	if ( $num < 4 and defined($val) and $self->badflag ) {
+	    $self->inplace->setbadtoval( $val );
+	    $self->badflag(1);
+	}
+
+	if ($PDL::Config{BADVAL_PER_PDL}) {
+	    my $name = "PDL::_badvalue_per_pdl_int$num";
+	    if ( defined $val ) {
+		return &{$name}($self, $val )->sclr;
+	    } else {
+		return &{$name}($self)->sclr;
+	    }
+	}
+
+    } elsif ( UNIVERSAL::isa($self,"PDL::Type") ) {
+	$num = $self->enum;
+    } else {
+        # assume it's a number
+        $num = $self;
+    }
+
+    my $name = "PDL::_badvalue_int$num";
+    if ( defined $val ) {
+	return &{$name}( $val )->sclr;
+    } else {
+	return &{$name}()->sclr;
+    }
+
+} # sub: badvalue()
+
+sub PDL::orig_badvalue {
+    no strict 'refs';
+
+    my $self = shift;
+    my $num;
+    if ( UNIVERSAL::isa($self,"PDL") ) {
+	$num = $self->get_datatype;
+    } elsif ( UNIVERSAL::isa($self,"PDL::Type") ) {
+	$num = $self->enum;
+    } else {
+        # assume it's a number
+        $num = $self;
+    }
+
+    my $name = "PDL::_default_badvalue_int$num";
+    return &${name}();
+
+} # sub: orig_badvalue()
+
+############################################################
+############################################################
+
+
+
+
+
+=head2 isbad
+
+=for sig
+
+  Signature: (a(); int [o]b())
+
+=for ref
+
+Returns a binary mask indicating which values of
+the input are bad values
+
+Returns a 1 if the value is bad, 0 otherwise.
+Similar to L<isfinite|PDL::Math/isfinite>.
+
+=for example
+
+ $a = pdl(1,2,3);
+ $a->badflag(1);
+ set($a,1,$a->badvalue);
+ $b = isbad($a);
+ print $b, "\n";
+ [0 1 0]
+
+=for bad
+
+This method works with input piddles that are bad. The ouptut piddle
+will never contain bad values, but its bad value flag will be the
+same as the input piddle's flag.
+
+
+
+=cut
+
+
+
+
+
+*isbad = \&PDL::isbad;
+
+
+
+
+
+=head2 isgood
+
+=for sig
+
+  Signature: (a(); int [o]b())
+
+=for ref
+
+Is a value good?
+
+Returns a 1 if the value is good, 0 otherwise.
+Also see L<isfinite|PDL::Math/isfinite>.
+
+=for example
+
+ $a = pdl(1,2,3);
+ $a->badflag(1);
+ set($a,1,$a->badvalue);
+ $b = isgood($a);
+ print $b, "\n";
+ [1 0 1]
+
+=for bad
+
+This method works with input piddles that are bad. The ouptut piddle
+will never contain bad values, but its bad value flag will be the
+same as the input piddle's flag.
+
+
+
+=cut
+
+
+
+
+
 *isgood = \&PDL::isgood;
 
-sub PDL::isbad  { return 0; } # no piddles can contain bad values by design
-sub PDL::isgood { return 1; } # no piddles can contain bad values by design
 
-*nbadover  = \&PDL::nbadover;
+
+
+
+=head2 nbadover
+
+=for sig
+
+  Signature: (a(n); int+ [o] b())
+
+=for ref
+
+Find the number of bad elements along the 1st dimension.
+
+This function reduces the dimensionality of a piddle by one by finding the
+number of bad elements along the 1st dimension. In this sense it shares
+much in common with the functions defined in L<PDL::Ufunc>. In particular,
+by using L<xchg|PDL::Slices/xchg> and similar dimension rearranging methods,
+it is possible to perform this calculation over I<any> dimension.
+
+=for usage
+
+ $a = nbadover($b);
+
+=for example
+
+ $spectrum = nbadover $image->xchg(0,1)
+
+=for bad
+
+nbadover processes input values that are bad. The ouput piddle will not have
+any bad values, but the bad flag will be set if the input piddle had its bad
+flag set.
+
+
+
+=cut
+
+
+
+
+
+*nbadover = \&PDL::nbadover;
+
+
+
+
+
+=head2 ngoodover
+
+=for sig
+
+  Signature: (a(n); int+ [o] b())
+
+=for ref
+
+Find the number of good elements along the 1st dimension.
+
+This function reduces the dimensionality of a piddle
+by one by finding the number of good elements
+along the 1st dimension.
+
+By using L<xchg|PDL::Slices/xchg> etc. it is possible to use
+I<any> dimension.
+
+=for usage
+
+ $a = ngoodover($b);
+
+=for example
+
+ $spectrum = ngoodover $image->xchg(0,1)
+
+=for bad
+
+ngoodover processes input values that are bad. The ouput piddle will not have
+any bad values, but the bad flag will be set if the input piddle had its bad
+flag set.
+
+
+
+=cut
+
+
+
+
+
 *ngoodover = \&PDL::ngoodover;
-*nbad      = \&PDL::nbad;
-*ngood     = \&PDL::ngood;
 
-#        Pars => 'a(n); int+ [o]b();',
-# collapse the input piddle along it's first dimension and set to 0's
-# - using sumover to do the projection as I'm too lazy to do it
-#   myself
-#
-sub PDL::nbadover  { return PDL::sumover( $_[0] * 0 ); }
-sub PDL::ngoodover { return PDL::sumover( $_[0] * 0 + 1 ); }
 
-sub PDL::nbad  { return 0; }
-sub PDL::ngood { return $_[0]->nelem; }
+
+
+*nbad = \&PDL::nbad;
+sub PDL::nbad {
+	my($x) = @_; my $tmp;
+	$x->clump(-1)->nbadover($tmp=PDL->nullcreate($x) );
+	return $tmp->at();
+}
+
+
+
+*ngood = \&PDL::ngood;
+sub PDL::ngood {
+	my($x) = @_; my $tmp;
+	$x->clump(-1)->ngoodover($tmp=PDL->nullcreate($x) );
+	return $tmp->at();
+}
+
+
+
+=head2 nbad
+
+=for ref
+
+Returns the number of bad values in a piddle
+
+=for usage
+
+ $x = nbad($data);
+
+=for bad
+
+Accepts good and bad input piddles; output is a Perl scalar
+and therefore is always good.
+
+=head2 ngood
+
+=for ref
+
+Returns the number of good values in a piddle
+
+=for usage
+
+ $x = ngood($data);
+
+=for bad
+
+Accepts good and bad input piddles; output is a Perl scalar
+and therefore is always good.
+
+=head2 setbadat
+
+=for ref
+
+Set the value to bad at a given position.
+
+=for usage
+
+ setbadat $piddle, @position
+
+C<@position> is a coordinate list, of size equal to the
+number of dimensions in the piddle.
+This is a wrapper around L<set|PDL::Core/set> and is
+probably mainly useful in test scripts!
+
+=for example
+
+ pdl> $x = sequence 3,4
+ pdl> $x->setbadat 2,1
+ pdl> p $x
+ [
+  [  0   1   2]
+  [  3   4 BAD]
+  [  6   7   8]
+  [  9  10  11]
+ ]
+
+=for bad
+
+This method can be called on piddles that have bad values.
+The remainder of the arguments should be Perl scalars indicating
+the position to set as bad. The ouptut piddle will have bad values
+and will have its badflag turned on.
+
+=cut
 
 *setbadat = \&PDL::setbadat;
+sub PDL::setbadat {
+    barf 'Usage: setbadat($pdl, $x, $y, ...)' if $#_<1;
+    my $self  = shift; 
+    PDL::Core::set_c ($self, [@_], $self->badvalue);
+    $self->badflag(1);
+    return $self;
+}
+
+
+
+
+
+=head2 setbadif
+
+=for sig
+
+  Signature: (a(); int mask(); [o]b())
+
+=for ref
+
+Set elements bad based on the supplied mask, otherwise
+copy across the data.
+
+=for example
+
+ pdl> $a = sequence(5,5)
+ pdl> $a = $a->setbadif( $a % 2 )
+ pdl> p "a badflag: ", $a->badflag, "\n"
+ a badflag: 1
+ pdl> p "a is\n$a"
+ [
+  [  0 BAD   2 BAD   4]
+  [BAD   6 BAD   8 BAD]
+  [ 10 BAD  12 BAD  14]
+  [BAD  16 BAD  18 BAD]
+  [ 20 BAD  22 BAD  24]
+ ]
+
+Unfortunately, this routine can I<not> be run inplace, since the
+current implementation can not handle the same piddle used as
+C<a> and C<mask> (eg C<< $a->inplace->setbadif($a%2) >> fails).
+Even more unfortunate: we can't catch this error and tell you.
+
+=for bad
+
+The output always has its bad flag set, even if it does not contain
+any bad values (use L<check_badflag|/check_badflag> to check
+whether there are any bad values in the output). 
+The input piddle can have bad values: any bad values in the input piddles
+are copied across to the output piddle.
+
+Also see L<setvaltobad|/setvaltobad> and L<setnantobad|/setnantobad>.
+
+
+
+=cut
+
+
+
+
+
 *setbadif = \&PDL::setbadif;
 
-# As these can't be done inplace we try to keep the
-# same behaviour here
-#
-sub PDL::setbadat { $_[0]->set_inplace(0); return $_[0]->copy; }
-sub PDL::setbadif { $_[0]->set_inplace(0); return $_[0]->copy; }
+
+
+
+
+=head2 setvaltobad
+
+=for sig
+
+  Signature: (a(); [o]b(); double value)
+
+=for ref
+
+Set bad all those elements which equal the supplied value.
+
+=for example
+
+ $a = sequence(10) % 3;
+ $a->inplace->setvaltobad( 0 );
+ print "$a\n";
+ [BAD 1 2 BAD 1 2 BAD 1 2 BAD]
+
+This is a simpler version of L<setbadif|/setbadif>, but this
+function can be done inplace.  See L<setnantobad|/setnantobad>
+if you want to convert NaN/Inf to the bad value.
+
+=for bad
+
+The output always has its bad flag set, even if it does not contain
+any bad values (use L<check_badflag|/check_badflag> to check
+whether there are any bad values in the output). 
+Any bad values in the input piddles are copied across to the output piddle.
+
+
+
+=cut
+
+
+
+
 
 *setvaltobad = \&PDL::setvaltobad;
-*setbadtoval = \&PDL::setvaltobad;
+
+
+
+
+
+=head2 setnantobad
+
+=for sig
+
+  Signature: (a(); [o]b())
+
+=for ref
+
+Sets NaN/Inf values in the input piddle bad
+(only relevant for floating-point piddles).
+Can be done inplace.
+
+=for usage
+
+ $b = $a->setnantobad;
+ $a->inplace->setnantobad;
+
+=for bad
+
+This method can process piddles with bad values: those bad values
+are propagated into the output piddle. Any value that is not finite
+is also set to bad in the output piddle. If all values from the input
+piddle are good and finite, the output piddle will B<not> have its
+bad flag set. One more caveat: if done inplace, and if the input piddle's
+bad flag is set, it will no
+
+
+
+=cut
+
+
+
+
+
 *setnantobad = \&PDL::setnantobad;
+
+
+
+
+
+=head2 setbadtonan
+
+=for sig
+
+  Signature: (a(); [o] b();)
+
+=for ref
+
+Sets Bad values to NaN
+
+This is only relevant for floating-point piddles. The input piddle can be
+of any type, but if done inplace, the input must be floating point.
+
+=for usage
+
+ $b = $a->setbadtonan;
+ $a->inplace->setbadtonan;
+
+=for bad
+
+This method processes input piddles with bad values. The output piddles will
+not contain bad values (insofar as NaN is not Bad as far as PDL is concerned)
+and the output piddle does not have its bad flag set. As an inplace
+operation, it clears the bad flag.
+
+
+
+=cut
+
+
+
+
+
 *setbadtonan = \&PDL::setbadtonan;
 
-# this can be done inplace
-# fortunately PDL::copy handles inplace ops
-sub PDL::setvaltobad { return $_[0]->copy; }
-sub PDL::setbadtoval { return $_[0]->copy; }
-sub PDL::setnantobad { return $_[0]->copy; }
-sub PDL::setbadtonan { return $_[0]->copy; }
 
-*copybad = \&PDL::copybad;
 
-sub PDL::copybad { return $_[0]->copy; } # ignore the mask
+
+
+=head2 setbadtoval
+
+=for sig
+
+  Signature: (a(); [o]b(); double newval)
+
+=for ref
+
+Replace any bad values by a (non-bad) value. 
+
+Can be done inplace. Also see
+L<badmask|PDL::Math/badmask>.
+
+=for example
+
+ $a->inplace->setbadtoval(23); 
+ print "a badflag: ", $a->badflag, "\n";
+ a badflag: 0
+
+=for bad
+
+The output always has its bad flag cleared.
+If the input piddle does not have its bad flag set, then
+values are copied with no replacement.
+
+
+
+=cut
+
+
+
+
+
+*setbadtoval = \&PDL::setbadtoval;
+
 
 
 
 
+=head2 copybad
+
+=for sig
+
+  Signature: (a(); mask(); [o]b())
+
+=for ref
+
+Copies values from one piddle to another, setting them
+bad if they are bad in the supplied mask.
+
+Can be done inplace.
+
+=for example
+
+ $a = byte( [0,1,3] );
+ $mask = byte( [0,0,0] );
+ set($mask,1,$mask->badvalue);
+ $a->inplace->copybad( $mask );
+ p $a;
+ [0 BAD 3]
+
+It is equivalent to:
+
+ $c = $a + $mask * 0
+
+=for bad
+
+This handles input piddles that are bad. If either C<$a>
+or C<$mask> have bad values, those values will be marked
+as bad in the output piddle and the output piddle will have
+its bad value flag set to true.
+
+
+
+=cut
+
+
+
+
+
+*copybad = \&PDL::copybad;
 
 
 
 ;
 
 
+=head1 CHANGES
+
+The I<experimental> C<BADVAL_PER_PDL> configuration option,
+which - when set - allows per-piddle bad values, was added
+after the 2.4.2 release of PDL.
+The C<$PDL::Bad::PerPdl> variable can be
+inspected to see if this feature is available.
+
+
+=head1 CONFIGURATION
+
+The way the PDL handles the various bad value settings depends on your
+compile-time configuration settings, as held in C<perldl.conf>.
+
+=over
+
+=item C<$PDL::Config{WITH_BADVAL}>
+
+Set this configuration option to a true value if you want bad value
+support. The default setting is for this to be true.
+
+=item C<$PDL::Config{BADVAL_USENAN}>
+
+Set this configuration option to a true value if you want floating-pont
+numbers to use NaN to represent the bad value. If set to false, you can
+use any number to represent a bad value, which is generally more
+flexible. In the default configuration, this is set to a false value.
+
+=item C<$PDL::Config{BADVAL_PER_PDL}>
+
+Set this configuration option to a true value if you want each of your
+piddles to keep track of their own bad values. This means that for one
+piddle you can set the bad value to zero, while in another piddle you
+can set the bad value to NaN (or any other useful number). This is
+usually set to false.
+
+=back
+
+=head1 AUTHOR
+
+Doug Burke (djburke@cpan.org), 2000, 2001, 2003, 2006.
+
+The per-piddle bad value support is by Heiko Klein (2006).
+
+CPAN documentation fixes by David Mertens (2010, 2013).
+
+All rights reserved. There is no warranty. You are allowed to
+redistribute this software / documentation under certain conditions. For
+details, see the file COPYING in the PDL distribution. If this file is
+separated from the PDL distribution, the copyright notice should be
+included in the file.
+
+=cut
+
+
+
+
 
 # Exit with OK status
 
@@ -21,6 +21,7 @@ BEGIN {
 
 
 
+our $VERSION = '2.009';
    use PDL::Slices;
    use PDL::Types;
    use PDL::Bad;
@@ -251,6 +252,10 @@ sub real($) {
 
 convert real to complex, assuming an imaginary part of zero
 
+=for bad
+
+r2C does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -284,6 +289,10 @@ BEGIN {*r2C = \&PDL::Complex::r2C;
 
 convert imaginary to complex, assuming a real part of zero
 
+=for bad
+
+i2C does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -309,6 +318,10 @@ BEGIN {*i2C = \&PDL::Complex::i2C;
 
 convert complex numbers in rectangular form to polar (mod,arg) form. Works inplace
 
+=for bad
+
+Cr2p does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -334,6 +347,10 @@ BEGIN {*Cr2p = \&PDL::Complex::Cr2p;
 
 convert complex numbers in polar (mod,arg) form to rectangular form. Works inplace
 
+=for bad
+
+Cp2r does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -371,6 +388,10 @@ BEGIN {*Csub = \&PDL::Complex::Csub;
 
 complex multiplication
 
+=for bad
+
+Cmul does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -396,6 +417,10 @@ BEGIN {*Cmul = \&PDL::Complex::Cmul;
 
 Project via product to N-1 dimension
 
+=for bad
+
+Cprodover does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -421,6 +446,10 @@ BEGIN {*Cprodover = \&PDL::Complex::Cprodover;
 
 mixed complex/real multiplication
 
+=for bad
+
+Cscale does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -446,6 +475,10 @@ BEGIN {*Cscale = \&PDL::Complex::Cscale;
 
 complex division
 
+=for bad
+
+Cdiv does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -471,6 +504,10 @@ BEGIN {*Cdiv = \&PDL::Complex::Cdiv;
 
 Complex comparison oeprator (spaceship). It orders by real first, then by imaginary. Hm, but it is mathematical nonsense! Complex numbers cannot be ordered.
 
+=for bad
+
+Ccmp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -496,6 +533,10 @@ BEGIN {*Ccmp = \&PDL::Complex::Ccmp;
 
 complex conjugation. Works inplace
 
+=for bad
+
+Cconj does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -521,6 +562,10 @@ BEGIN {*Cconj = \&PDL::Complex::Cconj;
 
 complex C<abs()> (also known as I<modulus>)
 
+=for bad
+
+Cabs does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -551,6 +596,10 @@ BEGIN {*Cabs = \&PDL::Complex::Cabs;
 
 complex squared C<abs()> (also known I<squared modulus>)
 
+=for bad
+
+Cabs2 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -581,6 +630,10 @@ BEGIN {*Cabs2 = \&PDL::Complex::Cabs2;
 
 complex argument function ("angle")
 
+=for bad
+
+Carg does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -611,6 +664,10 @@ BEGIN {*Carg = \&PDL::Complex::Carg;
 
   sin (a) = 1/(2*i) * (exp (a*i) - exp (-a*i)). Works inplace
 
+=for bad
+
+Csin does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -636,6 +693,10 @@ BEGIN {*Csin = \&PDL::Complex::Csin;
 
   cos (a) = 1/2 * (exp (a*i) + exp (-a*i)). Works inplace
 
+=for bad
+
+Ccos does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -673,6 +734,10 @@ sub Ctan($) { Csin($_[0]) / Ccos($_[0]) }
 
 exp (a) = exp (real (a)) * (cos (imag (a)) + i * sin (imag (a))). Works inplace
 
+=for bad
+
+Cexp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -698,6 +763,10 @@ BEGIN {*Cexp = \&PDL::Complex::Cexp;
 
 log (a) = log (cabs (a)) + i * carg (a). Works inplace
 
+=for bad
+
+Clog does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -723,6 +792,10 @@ BEGIN {*Clog = \&PDL::Complex::Clog;
 
 complex C<pow()> (C<**>-operator)
 
+=for bad
+
+Cpow does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -748,6 +821,10 @@ BEGIN {*Cpow = \&PDL::Complex::Cpow;
 
 Works inplace
 
+=for bad
+
+Csqrt does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -773,6 +850,10 @@ BEGIN {*Csqrt = \&PDL::Complex::Csqrt;
 
 Works inplace
 
+=for bad
+
+Casin does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -798,6 +879,10 @@ BEGIN {*Casin = \&PDL::Complex::Casin;
 
 Works inplace
 
+=for bad
+
+Cacos does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -837,6 +922,10 @@ sub Catan($) {
 
   sinh (a) = (exp (a) - exp (-a)) / 2. Works inplace
 
+=for bad
+
+Csinh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -862,6 +951,10 @@ BEGIN {*Csinh = \&PDL::Complex::Csinh;
 
   cosh (a) = (exp (a) + exp (-a)) / 2. Works inplace
 
+=for bad
+
+Ccosh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -887,6 +980,10 @@ BEGIN {*Ccosh = \&PDL::Complex::Ccosh;
 
 Works inplace
 
+=for bad
+
+Ctanh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -912,6 +1009,10 @@ BEGIN {*Ctanh = \&PDL::Complex::Ctanh;
 
 Works inplace
 
+=for bad
+
+Casinh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -937,6 +1038,10 @@ BEGIN {*Casinh = \&PDL::Complex::Casinh;
 
 Works inplace
 
+=for bad
+
+Cacosh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -962,6 +1067,10 @@ BEGIN {*Cacosh = \&PDL::Complex::Cacosh;
 
 Works inplace
 
+=for bad
+
+Catanh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -987,6 +1096,10 @@ BEGIN {*Catanh = \&PDL::Complex::Catanh;
 
 compute the projection of a complex number to the riemann sphere. Works inplace
 
+=for bad
+
+Cproj does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1012,6 +1125,10 @@ BEGIN {*Cproj = \&PDL::Complex::Cproj;
 
 Compute the C<n> roots of C<a>. C<n> must be a positive integer. The result will always be a complex type!
 
+=for bad
+
+Croots does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1059,6 +1176,10 @@ sub im($) { bless $_[0]->slice("(1)"), 'PDL'; }
 
 evaluate the polynomial with (real) coefficients C<coeffs> at the (complex) position(s) C<x>. C<coeffs[0]> is the constant term.
 
+=for bad
+
+rCpolynomial does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -128,6 +128,10 @@ Working on astronomical or solar image data, typical compression ratios of
 
 
 
+=for bad
+
+rice_compress ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -194,6 +198,10 @@ Unsquishes a PDL that has been squished by rice_expand.
      
 
 
+=for bad
+
+rice_expand ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -474,6 +474,10 @@ sub PDL::fftconvolve_inplace {
 
 Internal routine doing maths for convolution
 
+=for bad
+
+convmath does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -499,6 +503,10 @@ Internal routine doing maths for convolution
 
 Complex multiplication
 
+=for bad
+
+cmul does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -524,6 +532,10 @@ Complex multiplication
 
 Complex division
 
+=for bad
+
+cdiv does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -106,6 +106,10 @@ sub gsldiff{
 info not available
 
 
+=for bad
+
+diff_central does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -133,6 +137,10 @@ info not available
 info not available
 
 
+=for bad
+
+diff_backward does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -160,6 +168,10 @@ info not available
 info not available
 
 
+=for bad
+
+diff_forward does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +161,10 @@ sub gslinteg_qng{
 info not available
 
 
+=for bad
+
+qng_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -204,6 +208,10 @@ sub gslinteg_qag{
 info not available
 
 
+=for bad
+
+qag_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -247,6 +255,10 @@ sub gslinteg_qags{
 info not available
 
 
+=for bad
+
+qags_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -290,6 +302,10 @@ sub gslinteg_qagp{
 info not available
 
 
+=for bad
+
+qagp_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -333,6 +349,10 @@ sub gslinteg_qagi{
 info not available
 
 
+=for bad
+
+qagi_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -376,6 +396,10 @@ sub gslinteg_qagiu{
 info not available
 
 
+=for bad
+
+qagiu_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -419,6 +443,10 @@ sub gslinteg_qagil{
 info not available
 
 
+=for bad
+
+qagil_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -462,6 +490,10 @@ sub gslinteg_qawc{
 info not available
 
 
+=for bad
+
+qawc_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -506,6 +538,10 @@ sub gslinteg_qaws{
 info not available
 
 
+=for bad
+
+qaws_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -557,6 +593,10 @@ sub gslinteg_qawo{
 info not available
 
 
+=for bad
+
+qawo_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -606,6 +646,10 @@ sub gslinteg_qawf{
 info not available
 
 
+=for bad
+
+qawf_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -107,6 +107,10 @@ sub gslmroot_fsolver{
 info not available
 
 
+=for bad
+
+fsolver_meat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Airy Function Ai(x).
 
+=for bad
+
+gsl_sf_airy_Ai does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Airy Function Ai(x).
 
 Airy Function Bi(x).
 
+=for bad
+
+gsl_sf_airy_Bi does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Airy Function Bi(x).
 
 Scaled Airy Function Ai(x). Ai(x) for x < 0  and exp(+2/3 x^{3/2}) Ai(x) for  x > 0.
 
+=for bad
+
+gsl_sf_airy_Ai_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Scaled Airy Function Ai(x). Ai(x) for x < 0  and exp(+2/3 x^{3/2}) Ai(x) for  x
 
 Scaled Airy Function Bi(x). Bi(x) for x < 0  and exp(+2/3 x^{3/2}) Bi(x) for  x > 0.
 
+=for bad
+
+gsl_sf_airy_Bi_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Scaled Airy Function Bi(x). Bi(x) for x < 0  and exp(+2/3 x^{3/2}) Bi(x) for  x
 
 Derivative Airy Function Ai`(x).
 
+=for bad
+
+gsl_sf_airy_Ai_deriv does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ Derivative Airy Function Ai`(x).
 
 Derivative Airy Function Bi`(x).
 
+=for bad
+
+gsl_sf_airy_Bi_deriv does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ Derivative Airy Function Bi`(x).
 
 Derivative Scaled Airy Function Ai(x). Ai`(x) for x < 0  and exp(+2/3 x^{3/2}) Ai`(x) for  x > 0.
 
+=for bad
+
+gsl_sf_airy_Ai_deriv_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ Derivative Scaled Airy Function Ai(x). Ai`(x) for x < 0  and exp(+2/3 x^{3/2}) A
 
 Derivative Scaled Airy Function Bi(x). Bi`(x) for x < 0  and exp(+2/3 x^{3/2}) Bi`(x) for  x > 0.
 
+=for bad
+
+gsl_sf_airy_Bi_deriv_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Regular Bessel Function J_n(x).
 
+=for bad
+
+gsl_sf_bessel_Jn does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Regular Bessel Function J_n(x).
 
 Array of Regular Bessel Functions J_{s}(x) to J_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_J_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Array of Regular Bessel Functions J_{s}(x) to J_{s+n-1}(x).
 
 IrRegular Bessel Function Y_n(x).
 
+=for bad
+
+gsl_sf_bessel_Yn does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ IrRegular Bessel Function Y_n(x).
 
 Array of Regular Bessel Functions Y_{s}(x) to Y_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_Y_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Array of Regular Bessel Functions Y_{s}(x) to Y_{s+n-1}(x).
 
 Regular Modified Bessel Function I_n(x).
 
+=for bad
+
+gsl_sf_bessel_In does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ Regular Modified Bessel Function I_n(x).
 
 Array of Regular Modified Bessel Functions I_{s}(x) to I_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_I_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ Array of Regular Modified Bessel Functions I_{s}(x) to I_{s+n-1}(x).
 
 Scaled Regular Modified Bessel Function exp(-|x|) I_n(x).
 
+=for bad
+
+gsl_sf_bessel_In_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ Scaled Regular Modified Bessel Function exp(-|x|) I_n(x).
 
 Array of Scaled Regular Modified Bessel Functions exp(-|x|) I_{s}(x) to exp(-|x|) I_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_I_scaled_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -261,6 +293,10 @@ Array of Scaled Regular Modified Bessel Functions exp(-|x|) I_{s}(x) to exp(-|x|
 
 IrRegular Modified Bessel Function K_n(x).
 
+=for bad
+
+gsl_sf_bessel_Kn does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -286,6 +322,10 @@ IrRegular Modified Bessel Function K_n(x).
 
 Array of IrRegular Modified Bessel Functions K_{s}(x) to K_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_K_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -311,6 +351,10 @@ Array of IrRegular Modified Bessel Functions K_{s}(x) to K_{s+n-1}(x).
 
 Scaled IrRegular Modified Bessel Function exp(-|x|) K_n(x).
 
+=for bad
+
+gsl_sf_bessel_Kn_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -336,6 +380,10 @@ Scaled IrRegular Modified Bessel Function exp(-|x|) K_n(x).
 
 Array of Scaled IrRegular Modified Bessel Functions exp(-|x|) K_{s}(x) to exp(-|x|) K_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_K_scaled_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -361,6 +409,10 @@ Array of Scaled IrRegular Modified Bessel Functions exp(-|x|) K_{s}(x) to exp(-|
 
 Regular Sphericl Bessel Function J_n(x).
 
+=for bad
+
+gsl_sf_bessel_jl does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -386,6 +438,10 @@ Regular Sphericl Bessel Function J_n(x).
 
 Array of Spherical Regular Bessel Functions J_{0}(x) to J_{n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_j_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -411,6 +467,10 @@ Array of Spherical Regular Bessel Functions J_{0}(x) to J_{n-1}(x).
 
 IrRegular Spherical Bessel Function y_n(x).
 
+=for bad
+
+gsl_sf_bessel_yl does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -436,6 +496,10 @@ IrRegular Spherical Bessel Function y_n(x).
 
 Array of Regular Spherical Bessel Functions y_{0}(x) to y_{n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_y_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -461,6 +525,10 @@ Array of Regular Spherical Bessel Functions y_{0}(x) to y_{n-1}(x).
 
 Scaled Regular Modified Spherical Bessel Function exp(-|x|) i_n(x).
 
+=for bad
+
+gsl_sf_bessel_il_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -486,6 +554,10 @@ Scaled Regular Modified Spherical Bessel Function exp(-|x|) i_n(x).
 
 Array of Scaled Regular Modified Spherical Bessel Functions exp(-|x|) i_{0}(x) to exp(-|x|) i_{n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_i_scaled_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -511,6 +583,10 @@ Array of Scaled Regular Modified Spherical Bessel Functions exp(-|x|) i_{0}(x) t
 
 Scaled IrRegular Modified Spherical Bessel Function exp(-|x|) k_n(x).
 
+=for bad
+
+gsl_sf_bessel_kl_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -536,6 +612,10 @@ Scaled IrRegular Modified Spherical Bessel Function exp(-|x|) k_n(x).
 
 Array of Scaled IrRegular Modified Spherical Bessel Functions exp(-|x|) k_{s}(x) to exp(-|x|) k_{s+n-1}(x).
 
+=for bad
+
+gsl_sf_bessel_k_scaled_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -561,6 +641,10 @@ Array of Scaled IrRegular Modified Spherical Bessel Functions exp(-|x|) k_{s}(x)
 
 Regular Cylindrical Bessel Function J_nu(x).
 
+=for bad
+
+gsl_sf_bessel_Jnu does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -586,6 +670,10 @@ Regular Cylindrical Bessel Function J_nu(x).
 
 IrRegular Cylindrical Bessel Function J_nu(x).
 
+=for bad
+
+gsl_sf_bessel_Ynu does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -611,6 +699,10 @@ IrRegular Cylindrical Bessel Function J_nu(x).
 
 Scaled Modified Cylindrical Bessel Function exp(-|x|) I_nu(x).
 
+=for bad
+
+gsl_sf_bessel_Inu_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -636,6 +728,10 @@ Scaled Modified Cylindrical Bessel Function exp(-|x|) I_nu(x).
 
 Modified Cylindrical Bessel Function I_nu(x).
 
+=for bad
+
+gsl_sf_bessel_Inu does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -661,6 +757,10 @@ Modified Cylindrical Bessel Function I_nu(x).
 
 Scaled Modified Cylindrical Bessel Function exp(-|x|) K_nu(x).
 
+=for bad
+
+gsl_sf_bessel_Knu_scaled does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -686,6 +786,10 @@ Scaled Modified Cylindrical Bessel Function exp(-|x|) K_nu(x).
 
 Modified Cylindrical Bessel Function K_nu(x).
 
+=for bad
+
+gsl_sf_bessel_Knu does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -711,6 +815,10 @@ Modified Cylindrical Bessel Function K_nu(x).
 
 Logarithm of Modified Cylindrical Bessel Function K_nu(x).
 
+=for bad
+
+gsl_sf_bessel_lnKnu does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Clausen Integral. Cl_2(x) := Integrate[-Log[2 Sin[t/2]], {t,0,x}]
 
+=for bad
+
+gsl_sf_clausen does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Normalized Hydrogenic bound states. Radial dipendence.
 
+=for bad
+
+gsl_sf_hydrogenicR does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Normalized Hydrogenic bound states. Radial dipendence.
 
  Coulomb wave functions F_{lam_F}(eta,x), G_{lam_G}(eta,x) and their derivatives; lam_G := lam_F - k_lam_G. if ovfw is signaled then F_L(eta,x)  =  fc[k_L] * exp(fe) and similar. 
 
+=for bad
+
+gsl_sf_coulomb_wave_FGp_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Normalized Hydrogenic bound states. Radial dipendence.
 
  Coulomb wave function divided by the argument, F(xi, eta)/xi. This is the function which reduces to spherical Bessel functions in the limit eta->0. 
 
+=for bad
+
+gsl_sf_coulomb_wave_sphF_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Normalized Hydrogenic bound states. Radial dipendence.
 
 Coulomb wave function normalization constant. [Abramowitz+Stegun 14.1.8, 14.1.9].
 
+=for bad
+
+gsl_sf_coulomb_CL_e does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 3j Symbols:  (ja jb jc) over (ma mb mc).
 
+=for bad
+
+gsl_sf_coupling_3j does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 6j Symbols:  (ja jb jc) over (jd je jf).
 
+=for bad
+
+gsl_sf_coupling_6j does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 9j Symbols:  (ja jb jc) over (jd je jf) over (jg jh ji).
 
+=for bad
+
+gsl_sf_coupling_9j does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Dawsons integral: Exp[-x^2] Integral[ Exp[t^2], {t,0,x}]
 
+=for bad
+
+gsl_sf_dawson does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
+=for bad
+
+gsl_sf_debye_1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
 D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
+=for bad
+
+gsl_sf_debye_2 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
 D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
+=for bad
+
+gsl_sf_debye_3 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
 D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}]
 
+=for bad
+
+gsl_sf_debye_4 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 /* Real part of DiLogarithm(x), for real argument. In Lewins notation, this is Li_2(x). Li_2(x) = - Re[ Integrate[ Log[1-s] / s, {s, 0, x}] ]
 
+=for bad
+
+gsl_sf_dilog does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 DiLogarithm(z), for complex argument z = r Exp[i theta].
 
+=for bad
+
+gsl_sf_complex_dilog does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Multiplication.
 
+=for bad
+
+gsl_sf_multiply does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Multiplication.
 
 Multiplication with associated errors.
 
+=for bad
+
+gsl_sf_multiply_err does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Legendre form of complete elliptic integrals K(k) = Integral[1/Sqrt[1 - k^2 Sin[t]^2], {t, 0, Pi/2}].
 
+=for bad
+
+gsl_sf_ellint_Kcomp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Legendre form of complete elliptic integrals K(k) = Integral[1/Sqrt[1 - k^2 Sin[
 
 Legendre form of complete elliptic integrals E(k) = Integral[  Sqrt[1 - k^2 Sin[t]^2], {t, 0, Pi/2}]
 
+=for bad
+
+gsl_sf_ellint_Ecomp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Legendre form of complete elliptic integrals E(k) = Integral[  Sqrt[1 - k^2 Sin[
 
 Legendre form of incomplete elliptic integrals F(phi,k)   = Integral[1/Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}]
 
+=for bad
+
+gsl_sf_ellint_F does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Legendre form of incomplete elliptic integrals F(phi,k)   = Integral[1/Sqrt[1 -
 
 Legendre form of incomplete elliptic integrals E(phi,k)   = Integral[  Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}]
 
+=for bad
+
+gsl_sf_ellint_E does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -162,6 +178,10 @@ Legendre form of incomplete elliptic integrals E(phi,k)   = Integral[  Sqrt[1 -
 
 Legendre form of incomplete elliptic integrals P(phi,k,n) = Integral[(1 + n Sin[t]^2)^(-1)/Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}]
 
+=for bad
+
+gsl_sf_ellint_P does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -188,6 +208,10 @@ Legendre form of incomplete elliptic integrals P(phi,k,n) = Integral[(1 + n Sin[
 
 Legendre form of incomplete elliptic integrals D(phi,k,n)
 
+=for bad
+
+gsl_sf_ellint_D does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -213,6 +237,10 @@ Legendre form of incomplete elliptic integrals D(phi,k,n)
 
 Carlsons symmetric basis of functions RC(x,y)   = 1/2 Integral[(t+x)^(-1/2) (t+y)^(-1)], {t,0,Inf}
 
+=for bad
+
+gsl_sf_ellint_RC does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -238,6 +266,10 @@ Carlsons symmetric basis of functions RC(x,y)   = 1/2 Integral[(t+x)^(-1/2) (t+y
 
 Carlsons symmetric basis of functions RD(x,y,z) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-3/2), {t,0,Inf}]
 
+=for bad
+
+gsl_sf_ellint_RD does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -263,6 +295,10 @@ Carlsons symmetric basis of functions RD(x,y,z) = 3/2 Integral[(t+x)^(-1/2) (t+y
 
 Carlsons symmetric basis of functions RF(x,y,z) = 1/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2), {t,0,Inf}]
 
+=for bad
+
+gsl_sf_ellint_RF does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -288,6 +324,10 @@ Carlsons symmetric basis of functions RF(x,y,z) = 1/2 Integral[(t+x)^(-1/2) (t+y
 
 Carlsons symmetric basis of functions RJ(x,y,z,p) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2) (t+p)^(-1), {t,0,Inf}]
 
+=for bad
+
+gsl_sf_ellint_RJ does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Jacobian elliptic functions sn, dn, cn by descending Landen transformations
 
+=for bad
+
+gsl_sf_elljac does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Complementary Error Function erfc(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,x,Infinity}]
 
+=for bad
+
+gsl_sf_erfc does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Complementary Error Function erfc(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,x,Inf
 
 Log Complementary Error Function
 
+=for bad
+
+gsl_sf_log_erfc does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Log Complementary Error Function
 
 Error Function erf(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,0,x}]
 
+=for bad
+
+gsl_sf_erf does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Error Function erf(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,0,x}]
 
 Z(x) :  Abramowitz+Stegun 26.2.1
 
+=for bad
+
+gsl_sf_erf_Z does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Z(x) :  Abramowitz+Stegun 26.2.1
 
 Q(x) :  Abramowitz+Stegun 26.2.1
 
+=for bad
+
+gsl_sf_erf_Q does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Exponential
 
+=for bad
+
+gsl_sf_exp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Exponential
 
 N-relative Exponential. exprel_N(x) = N!/x^N (exp(x) - Sum[x^k/k!, {k,0,N-1}]) = 1 + x/(N+1) + x^2/((N+1)(N+2)) + ... = 1F1(1,1+N,x)
 
+=for bad
+
+gsl_sf_exprel_n does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ N-relative Exponential. exprel_N(x) = N!/x^N (exp(x) - Sum[x^k/k!, {k,0,N-1}]) =
 
 Exponential of a quantity with given error.
 
+=for bad
+
+gsl_sf_exp_err does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 E_1(x) := Re[ Integrate[ Exp[-xt]/t, {t,1,Infinity}] ]
 
+=for bad
+
+gsl_sf_expint_E1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ E_1(x) := Re[ Integrate[ Exp[-xt]/t, {t,1,Infinity}] ]
 
 E_2(x) := Re[ Integrate[ Exp[-xt]/t^2, {t,1,Infity}] ]
 
+=for bad
+
+gsl_sf_expint_E2 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ E_2(x) := Re[ Integrate[ Exp[-xt]/t^2, {t,1,Infity}] ]
 
 Ei(x) := PV Integrate[ Exp[-t]/t, {t,-x,Infinity}]
 
+=for bad
+
+gsl_sf_expint_Ei does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Ei(x) := PV Integrate[ Exp[-t]/t, {t,-x,Infinity}]
 
 Shi(x) := Integrate[ Sinh[t]/t, {t,0,x}]
 
+=for bad
+
+gsl_sf_Shi does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Shi(x) := Integrate[ Sinh[t]/t, {t,0,x}]
 
 Chi(x) := Re[ M_EULER + log(x) + Integrate[(Cosh[t]-1)/t, {t,0,x}] ]
 
+=for bad
+
+gsl_sf_Chi does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ Chi(x) := Re[ M_EULER + log(x) + Integrate[(Cosh[t]-1)/t, {t,0,x}] ]
 
 Ei_3(x) := Integral[ Exp[-t^3], {t,0,x}]
 
+=for bad
+
+gsl_sf_expint_3 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ Ei_3(x) := Integral[ Exp[-t^3], {t,0,x}]
 
 Si(x) := Integrate[ Sin[t]/t, {t,0,x}]
 
+=for bad
+
+gsl_sf_Si does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ Si(x) := Integrate[ Sin[t]/t, {t,0,x}]
 
 Ci(x) := -Integrate[ Cos[t]/t, {t,x,Infinity}]
 
+=for bad
+
+gsl_sf_Ci does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -261,6 +293,10 @@ Ci(x) := -Integrate[ Cos[t]/t, {t,x,Infinity}]
 
 AtanInt(x) := Integral[ Arctan[t]/t, {t,0,x}]
 
+=for bad
+
+gsl_sf_atanint does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -71,6 +71,10 @@ Incomplete Fermi-Dirac Integrals:
 
 Complete integral F_j(x) for integer j
 
+=for bad
+
+gsl_sf_fermi_dirac_int does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -96,6 +100,10 @@ Complete integral F_j(x) for integer j
 
 Complete integral F_{-1/2}(x)
 
+=for bad
+
+gsl_sf_fermi_dirac_mhalf does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -121,6 +129,10 @@ Complete integral F_{-1/2}(x)
 
 Complete integral F_{1/2}(x)
 
+=for bad
+
+gsl_sf_fermi_dirac_half does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -146,6 +158,10 @@ Complete integral F_{1/2}(x)
 
 Complete integral F_{3/2}(x)
 
+=for bad
+
+gsl_sf_fermi_dirac_3half does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -171,6 +187,10 @@ Complete integral F_{3/2}(x)
 
 Incomplete integral F_0(x,b) = ln(1 + e^(b-x)) - (b-x)
 
+=for bad
+
+gsl_sf_fermi_dirac_inc_0 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Log[Gamma(x)], x not a negative integer Uses real Lanczos method. Determines the sign of Gamma[x] as well as Log[|Gamma[x]|] for x < 0. So Gamma[x] = sgn * Exp[result_lg].
 
+=for bad
+
+gsl_sf_lngamma does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Log[Gamma(x)], x not a negative integer Uses real Lanczos method. Determines the
 
 Gamma(x), x not a negative integer
 
+=for bad
+
+gsl_sf_gamma does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Gamma(x), x not a negative integer
 
 Regulated Gamma Function, x > 0 Gamma^*(x) = Gamma(x)/(Sqrt[2Pi] x^(x-1/2) exp(-x)) = (1 + 1/(12x) + ...),  x->Inf
 
+=for bad
+
+gsl_sf_gammastar does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Regulated Gamma Function, x > 0 Gamma^*(x) = Gamma(x)/(Sqrt[2Pi] x^(x-1/2) exp(-
 
 1/Gamma(x)
 
+=for bad
+
+gsl_sf_gammainv does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Regulated Gamma Function, x > 0 Gamma^*(x) = Gamma(x)/(Sqrt[2Pi] x^(x-1/2) exp(-
 
 Log[Gamma(z)] for z complex, z not a negative integer. Calculates: lnr = log|Gamma(z)|, arg = arg(Gamma(z))  in (-Pi, Pi]
 
+=for bad
+
+gsl_sf_lngamma_complex does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ Log[Gamma(z)] for z complex, z not a negative integer. Calculates: lnr = log|Gam
 
 x^n / n!
 
+=for bad
+
+gsl_sf_taylorcoeff does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ x^n / n!
 
 n!
 
+=for bad
+
+gsl_sf_fact does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ n!
 
 n!! = n(n-2)(n-4)
 
+=for bad
+
+gsl_sf_doublefact does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -261,6 +293,10 @@ n!! = n(n-2)(n-4)
 
 ln n!
 
+=for bad
+
+gsl_sf_lnfact does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -286,6 +322,10 @@ ln n!
 
 ln n!!
 
+=for bad
+
+gsl_sf_lndoublefact does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -311,6 +351,10 @@ ln n!!
 
 log(n choose m)
 
+=for bad
+
+gsl_sf_lnchoose does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -336,6 +380,10 @@ log(n choose m)
 
 n choose m
 
+=for bad
+
+gsl_sf_choose does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -361,6 +409,10 @@ n choose m
 
 Logarithm of Pochammer (Apell) symbol, with sign information. result = log( |(a)_x| ), sgn    = sgn( (a)_x ) where (a)_x := Gamma[a + x]/Gamma[a]
 
+=for bad
+
+gsl_sf_lnpoch does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -386,6 +438,10 @@ Logarithm of Pochammer (Apell) symbol, with sign information. result = log( |(a)
 
 Pochammer (Apell) symbol (a)_x := Gamma[a + x]/Gamma[x]
 
+=for bad
+
+gsl_sf_poch does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -411,6 +467,10 @@ Pochammer (Apell) symbol (a)_x := Gamma[a + x]/Gamma[x]
 
 Relative Pochammer (Apell) symbol ((a,x) - 1)/x where (a,x) = (a)_x := Gamma[a + x]/Gamma[a]
 
+=for bad
+
+gsl_sf_pochrel does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -436,6 +496,10 @@ Relative Pochammer (Apell) symbol ((a,x) - 1)/x where (a,x) = (a)_x := Gamma[a +
 
 Normalized Incomplete Gamma Function Q(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t), {t,x,Infinity} ]
 
+=for bad
+
+gsl_sf_gamma_inc_Q does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -461,6 +525,10 @@ Normalized Incomplete Gamma Function Q(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t
 
 Complementary Normalized Incomplete Gamma Function P(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t), {t,0,x} ]
 
+=for bad
+
+gsl_sf_gamma_inc_P does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -486,6 +554,10 @@ Complementary Normalized Incomplete Gamma Function P(a,x) = 1/Gamma(a) Integral[
 
 Logarithm of Beta Function Log[B(a,b)]
 
+=for bad
+
+gsl_sf_lnbeta does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -511,6 +583,10 @@ Logarithm of Beta Function Log[B(a,b)]
 
 Beta Function B(a,b)
 
+=for bad
+
+gsl_sf_beta does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Evaluate Gegenbauer polynomials.
 
+=for bad
+
+gsl_sf_gegenpoly_n does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Evaluate Gegenbauer polynomials.
 
 Calculate array of Gegenbauer polynomials from 0 to n-1.
 
+=for bad
+
+gsl_sf_gegenpoly_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 /* Hypergeometric function related to Bessel functions 0F1[c,x] = Gamma[c]    x^(1/2(1-c)) I_{c-1}(2 Sqrt[x]) Gamma[c] (-x)^(1/2(1-c)) J_{c-1}(2 Sqrt[-x])
 
+=for bad
+
+gsl_sf_hyperg_0F1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Confluent hypergeometric function  for integer parameters. 1F1[a,b,x] = M(a,b,x)
 
+=for bad
+
+gsl_sf_hyperg_1F1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Confluent hypergeometric function  for integer parameters. 1F1[a,b,x] = M(a,b,x)
 
 Confluent hypergeometric function  for integer parameters. U(a,b,x)
 
+=for bad
+
+gsl_sf_hyperg_U does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Confluent hypergeometric function  for integer parameters. U(a,b,x)
 
 Confluent hypergeometric function  for integer parameters. 2F1[a,b,c,x]
 
+=for bad
+
+gsl_sf_hyperg_2F1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Confluent hypergeometric function  for integer parameters. 2F1[a,b,c,x]
 
 Gauss hypergeometric function 2F1[aR + I aI, aR - I aI, c, x]
 
+=for bad
+
+gsl_sf_hyperg_2F1_conj does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ Gauss hypergeometric function 2F1[aR + I aI, aR - I aI, c, x]
 
 Renormalized Gauss hypergeometric function 2F1[a,b,c,x] / Gamma[c]
 
+=for bad
+
+gsl_sf_hyperg_2F1_renorm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ Renormalized Gauss hypergeometric function 2F1[a,b,c,x] / Gamma[c]
 
 Renormalized Gauss hypergeometric function 2F1[aR + I aI, aR - I aI, c, x] / Gamma[c]
 
+=for bad
+
+gsl_sf_hyperg_2F1_conj_renorm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ Renormalized Gauss hypergeometric function 2F1[aR + I aI, aR - I aI, c, x] / Gam
 
 Mysterious hypergeometric function. The series representation is a divergent hypergeometric series. However, for x < 0 we have 2F0(a,b,x) = (-1/x)^a U(a,1+a-b,-1/x)
 
+=for bad
+
+gsl_sf_hyperg_2F0 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Evaluate generalized Laguerre polynomials.
 
+=for bad
+
+gsl_sf_laguerre_n does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 P_l(x)
 
+=for bad
+
+gsl_sf_legendre_Pl does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ P_l(x)
 
 P_l(x) from 0 to n-1.
 
+=for bad
+
+gsl_sf_legendre_Pl_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ P_l(x) from 0 to n-1.
 
 Q_l(x)
 
+=for bad
+
+gsl_sf_legendre_Ql does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Q_l(x)
 
 P_lm(x)
 
+=for bad
+
+gsl_sf_legendre_Plm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ P_lm(x)
 
 P_lm(x) for l from 0 to n-2+m.
 
+=for bad
+
+gsl_sf_legendre_Plm_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ P_lm(x) for l from 0 to n-2+m.
 
 P_lm(x), normalized properly for use in spherical harmonics
 
+=for bad
+
+gsl_sf_legendre_sphPlm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ P_lm(x), normalized properly for use in spherical harmonics
 
 P_lm(x), normalized properly for use in spherical harmonics for l from 0 to n-2+m.
 
+=for bad
+
+gsl_sf_legendre_sphPlm_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ P_lm(x), normalized properly for use in spherical harmonics for l from 0 to n-2+
 
 Irregular Spherical Conical Function P^{1/2}_{-1/2 + I lambda}(x)
 
+=for bad
+
+gsl_sf_conicalP_half does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -261,6 +293,10 @@ Irregular Spherical Conical Function P^{1/2}_{-1/2 + I lambda}(x)
 
 Regular Spherical Conical Function P^{-1/2}_{-1/2 + I lambda}(x)
 
+=for bad
+
+gsl_sf_conicalP_mhalf does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -286,6 +322,10 @@ Regular Spherical Conical Function P^{-1/2}_{-1/2 + I lambda}(x)
 
 Conical Function P^{0}_{-1/2 + I lambda}(x)
 
+=for bad
+
+gsl_sf_conicalP_0 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -311,6 +351,10 @@ Conical Function P^{0}_{-1/2 + I lambda}(x)
 
 Conical Function P^{1}_{-1/2 + I lambda}(x)
 
+=for bad
+
+gsl_sf_conicalP_1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -336,6 +380,10 @@ Conical Function P^{1}_{-1/2 + I lambda}(x)
 
 Regular Spherical Conical Function P^{-1/2-l}_{-1/2 + I lambda}(x)
 
+=for bad
+
+gsl_sf_conicalP_sph_reg does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -361,6 +409,10 @@ Regular Spherical Conical Function P^{-1/2-l}_{-1/2 + I lambda}(x)
 
 Regular Cylindrical Conical Function P^{-m}_{-1/2 + I lambda}(x)
 
+=for bad
+
+gsl_sf_conicalP_cyl_reg_e does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -386,6 +438,10 @@ Regular Cylindrical Conical Function P^{-m}_{-1/2 + I lambda}(x)
 
 lth radial eigenfunction of the Laplacian on the 3-dimensional hyperbolic space.
 
+=for bad
+
+gsl_sf_legendre_H3d does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -411,6 +467,10 @@ lth radial eigenfunction of the Laplacian on the 3-dimensional hyperbolic space.
 
 Array of H3d(ell), for l from 0 to n-1.
 
+=for bad
+
+gsl_sf_legendre_H3d_array does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Provide a logarithm function with GSL semantics.
 
+=for bad
+
+gsl_sf_log does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Provide a logarithm function with GSL semantics.
 
 Complex Logarithm exp(lnr + I theta) = zr + I zi Returns argument in [-pi,pi].
 
+=for bad
+
+gsl_sf_complex_log does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -64,6 +64,10 @@ changing the directory structure at this time.  These fixes should allow things
 
 c[0] + c[1] x + c[2] x^2 + ... + c[m-1] x^(m-1)
 
+=for bad
+
+gsl_poly_eval does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Calculate x^n.
 
+=for bad
+
+gsl_sf_pow_int does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -66,6 +66,10 @@ psi(m,x) := (d/dx)^m psi(0,x) = (d/dx)^{m+1} log(gamma(x))
 
 Di-Gamma Function psi(x).
 
+=for bad
+
+gsl_sf_psi does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -91,6 +95,10 @@ Di-Gamma Function psi(x).
 
 Di-Gamma Function Re[psi(1 + I y)]
 
+=for bad
+
+gsl_sf_psi_1piy does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -116,6 +124,10 @@ Di-Gamma Function Re[psi(1 + I y)]
 
 Poly-Gamma Function psi^(n)(x)
 
+=for bad
+
+gsl_sf_psi_n does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 First synchrotron function: synchrotron_1(x) = x Integral[ K_{5/3}(t), {t, x, Infinity}]
 
+=for bad
+
+gsl_sf_synchrotron_1 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ First synchrotron function: synchrotron_1(x) = x Integral[ K_{5/3}(t), {t, x, In
 
 Second synchroton function: synchrotron_2(x) = x * K_{2/3}(x)
 
+=for bad
+
+gsl_sf_synchrotron_2 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -65,6 +65,10 @@ Transport function:
 
 J(2,x)
 
+=for bad
+
+gsl_sf_transport_2 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -90,6 +94,10 @@ J(2,x)
 
 J(3,x)
 
+=for bad
+
+gsl_sf_transport_3 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -115,6 +123,10 @@ J(3,x)
 
 J(4,x)
 
+=for bad
+
+gsl_sf_transport_4 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -140,6 +152,10 @@ J(4,x)
 
 J(5,x)
 
+=for bad
+
+gsl_sf_transport_5 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Sin(x) with GSL semantics.
 
+=for bad
+
+gsl_sf_sin does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Sin(x) with GSL semantics.
 
 Cos(x) with GSL semantics.
 
+=for bad
+
+gsl_sf_cos does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Cos(x) with GSL semantics.
 
 Hypot(x,xx) with GSL semantics.
 
+=for bad
+
+gsl_sf_hypot does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -136,6 +148,10 @@ Hypot(x,xx) with GSL semantics.
 
 Sin(z) for complex z
 
+=for bad
+
+gsl_sf_complex_sin does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -161,6 +177,10 @@ Sin(z) for complex z
 
 Cos(z) for complex z
 
+=for bad
+
+gsl_sf_complex_cos does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -186,6 +206,10 @@ Cos(z) for complex z
 
 Log(Sin(z)) for complex z
 
+=for bad
+
+gsl_sf_complex_logsin does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -211,6 +235,10 @@ Log(Sin(z)) for complex z
 
 Log(Sinh(x)) with GSL semantics.
 
+=for bad
+
+gsl_sf_lnsinh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -236,6 +264,10 @@ Log(Sinh(x)) with GSL semantics.
 
 Log(Cos(x)) with GSL semantics.
 
+=for bad
+
+gsl_sf_lncosh does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -261,6 +293,10 @@ Log(Cos(x)) with GSL semantics.
 
 Convert polar to rectlinear coordinates.
 
+=for bad
+
+gsl_sf_polar_to_rect does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -286,6 +322,10 @@ Convert polar to rectlinear coordinates.
 
 Convert rectlinear to polar coordinates. return argument in range [-pi, pi].
 
+=for bad
+
+gsl_sf_rect_to_polar does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -311,6 +351,10 @@ Convert rectlinear to polar coordinates. return argument in range [-pi, pi].
 
 Force an angle to lie in the range (-pi,pi].
 
+=for bad
+
+gsl_sf_angle_restrict_symm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -336,6 +380,10 @@ Force an angle to lie in the range (-pi,pi].
 
 Force an angle to lie in the range [0,2 pi).
 
+=for bad
+
+gsl_sf_angle_restrict_pos does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -361,6 +409,10 @@ Force an angle to lie in the range [0,2 pi).
 
 Sin(x) for quantity with an associated error.
 
+=for bad
+
+gsl_sf_sin_err does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -386,6 +438,10 @@ Sin(x) for quantity with an associated error.
 
 Cos(x) for quantity with an associated error.
 
+=for bad
+
+gsl_sf_cos_err does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -61,6 +61,10 @@ This is an interface to the Special Function package present in the GNU Scientif
 
 Riemann Zeta Function zeta(x) = Sum[ k^(-s), {k,1,Infinity} ], s != 1.0
 
+=for bad
+
+gsl_sf_zeta does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -86,6 +90,10 @@ Riemann Zeta Function zeta(x) = Sum[ k^(-s), {k,1,Infinity} ], s != 1.0
 
 Hurwicz Zeta Function zeta(s,q) = Sum[ (k+q)^(-s), {k,0,Infinity} ]
 
+=for bad
+
+gsl_sf_hzeta does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -111,6 +119,10 @@ Hurwicz Zeta Function zeta(s,q) = Sum[ (k+q)^(-s), {k,0,Infinity} ]
 
 Eta Function eta(s) = (1-2^(1-s)) zeta(s)
 
+=for bad
+
+gsl_sf_eta does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1,5711 +0,0 @@
-
-#
-# GENERATED WITH PDL::PP! Don't modify!
-#
-package PDL::Graphics::PLplot;
-
-@EXPORT_OK  = qw( PL_PARSE_PARTIAL PL_PARSE_FULL PL_PARSE_QUIET PL_PARSE_NODELETE PL_PARSE_SHOWALL PL_PARSE_OVERRIDE PL_PARSE_NOPROGRAM PL_PARSE_NODASH PL_PARSE_SKIP DRAW_LINEX DRAW_LINEY DRAW_LINEXY MAG_COLOR BASE_CONT TOP_CONT SURF_CONT DRAW_SIDES FACETED MESH PL_FCI_SANS PL_FCI_MONO PLK_BackSpace PLK_Tab PLK_Linefeed PLK_Return PLK_Escape PLK_Delete PLK_Clear PLK_Pause PLK_Scroll_Lock PLK_Home PLK_Left PLK_Up PLK_Right PLK_Down PLK_Prior PLK_Next PLK_End PLK_Begin PLK_Select PLK_Print PLK_Execute PLK_Insert PLK_Undo PLK_Redo PLK_Menu PLK_Find PLK_Cancel PLK_Help PLK_Break PLK_Mode_switch PLK_script_switch PLK_Num_Lock PLK_KP_Space PLK_KP_Tab PLK_KP_Enter PLK_KP_F1 PLK_KP_F2 PLK_KP_F3 PLK_KP_F4 PLK_KP_Equal PLK_KP_Multiply PLK_KP_Add PLK_KP_Separator PLK_KP_Subtract PLK_KP_Decimal PLK_KP_Divide PLK_KP_0 PLK_KP_1 PLK_KP_2 PLK_KP_3 PLK_KP_4 PLK_KP_5 PLK_KP_6 PLK_KP_7 PLK_KP_8 PLK_KP_9 PLK_F1 PLK_F2 PLK_F3 PLK_F4 PLK_F5 PLK_F6 PLK_F7 PLK_F8 PLK_F9 PLK_F10 PLK_F11 PLK_L1 PLK_F12 PLK_L2 PLK_F13 PLK_L3 PLK_F14 PLK_L4 PLK_F15 PLK_L5 PLK_F16 PLK_L6 PLK_F17 PLK_L7 PLK_F18 PLK_L8 PLK_F19 PLK_L9 PLK_F20 PLK_L10 PLK_F21 PLK_R1 PLK_F22 PLK_R2 PLK_F23 PLK_R3 PLK_F24 PLK_R4 PLK_F25 PLK_R5 PLK_F26 PLK_R6 PLK_F27 PLK_R7 PLK_F28 PLK_R8 PLK_F29 PLK_R9 PLK_F30 PLK_R10 PLK_F31 PLK_R11 PLK_F32 PLK_R12 PLK_R13 PLK_F33 PLK_F34 PLK_R14 PLK_F35 PLK_R15 PLK_Shift_L PLK_Shift_R PLK_Control_L PLK_Control_R PLK_Caps_Lock PLK_Shift_Lock PLK_Meta_L PLK_Meta_R PLK_Alt_L PLK_Alt_R PLK_Super_L PLK_Super_R PLK_Hyper_L PLK_Hyper_R GRID_CSA GRID_DTLI GRID_NNI GRID_NNIDW GRID_NNLI GRID_NNAIDW plplot_use_standard_argument_order PDL::PP pladv plaxes PDL::PP plaxes_pp PDL::PP plbin plbop plbox PDL::PP plbox_pp plbox3 PDL::PP plbox3_pp plclear PDL::PP plcol0 PDL::PP plcol1 PDL::PP plcpstrm PDL::PP pldid2pc PDL::PP pldip2dc plend plend1 PDL::PP plenv PDL::PP plenv0 pleop PDL::PP plerrx PDL::PP plerry plfamadv PDL::PP plfill3 plflush PDL::PP plfont PDL::PP plfontld PDL::PP plgchr PDL::PP plgcompression PDL::PP plgdidev PDL::PP plgdiori PDL::PP plgdiplt PDL::PP plgfam PDL::PP plglevel PDL::PP plgpage plgra PDL::PP plgspa PDL::PP plgvpd PDL::PP plgvpw PDL::PP plgxax PDL::PP plgyax PDL::PP plgzax plinit PDL::PP pljoin pllab PDL::PP pllightsource PDL::PP pllsty plmtex PDL::PP plmtex_pp plmtex3 PDL::PP plmtex3_pp PDL::PP plpat PDL::PP plprec PDL::PP plpsty PDL::PP plptex PDL::PP plptex3 plreplot PDL::PP plschr PDL::PP plscmap0n PDL::PP plscmap1n PDL::PP plscol0 PDL::PP plscolbg PDL::PP plscolor PDL::PP plscompression plsdev PDL::PP plsdidev PDL::PP plsdimap PDL::PP plsdiori PDL::PP plsdiplt PDL::PP plsdiplz PDL::PP pl_setcontlabelparam PDL::PP pl_setcontlabelformat PDL::PP plsfam plsfnam PDL::PP plsmaj PDL::PP plsmin PDL::PP plsori PDL::PP plspage PDL::PP plspause PDL::PP plsstrm PDL::PP plssub PDL::PP plssym PDL::PP plstar plstart PDL::PP plstart_pp PDL::PP plstripa PDL::PP plstripd PDL::PP plsvpa PDL::PP plsxax PDL::PP plsxwin PDL::PP plsyax PDL::PP plszax pltext PDL::PP plvasp PDL::PP plvpas PDL::PP plvpor plvsta PDL::PP plw3d PDL::PP plwid PDL::PP plwind plsetopt PDL::PP plP_gpixmm PDL::PP plscolbga PDL::PP plscol0a PDL::PP plline PDL::PP plcolorpoints PDL::PP plfbox PDL::PP plunfbox PDL::PP plParseOpts PDL::PP plpoin PDL::PP plpoin3 PDL::PP plline3 PDL::PP plpoly3 PDL::PP plhist PDL::PP plfill PDL::PP plsym PDL::PP plsurf3d PDL::PP plstyl pltr0 pltr1 pltr2 PDL::PP plAllocGrid plFreeGrid PDL::PP plAlloc2dGrid plFree2dGrid PDL::PP init_pltr plmap PDL::PP plmap_pp plmeridians PDL::PP plmeridians_pp plshades PDL::PP plshades_pp PDL::PP plcont PDL::PP plmesh PDL::PP plmeshc PDL::PP plot3d PDL::PP plot3dc PDL::PP plscmap1l plshade1 PDL::PP plshade1_pp PDL::PP plimage plxormod plGetCursor plgstrm plgdev plgfnam plmkstrm plgver plstripc PDL::PP plstripc_pp PDL::PP plgriddata plbtime plconfigtime plctime pltimefmt plsesc PDL::PP plhlsrgb PDL::PP plgcol0 PDL::PP plgcolbg PDL::PP plscmap0 PDL::PP plscmap1 PDL::PP plgcol0a PDL::PP plgcolbga PDL::PP plscmap0a PDL::PP plscmap1a PDL::PP plscmap1la PDL::PP plcalc_world  plgfci  plsfci );
-%EXPORT_TAGS = (Func=>[@EXPORT_OK]);
-
-use PDL::Core;
-use PDL::Exporter;
-use DynaLoader;
-
-
-
-   
-   @ISA    = ( 'PDL::Exporter','DynaLoader' );
-   push @PDL::Core::PP, __PACKAGE__;
-   bootstrap PDL::Graphics::PLplot ;
-
-
-
-
-
-our $VERSION;
-BEGIN {
-$VERSION = '0.61'
-};
-
-=head1 NAME
-
-PDL::Graphics::PLplot - Object-oriented interface from perl/PDL to the PLPLOT plotting library
-
-=head1 SYNOPSIS
-
-  use PDL;
-  use PDL::Graphics::PLplot;
-
-  my $pl = PDL::Graphics::PLplot->new (DEV => "png", FILE => "test.png");
-  my $x  = sequence(10);
-  my $y  = $x**2;
-  $pl->xyplot($x, $y);
-  $pl->close;
-
-For more information on PLplot, see
-
- http://www.plplot.org/
-
-Also see the test file, F<t/plplot.pl> in this distribution for some working examples.
-
-=head1 LONG NAMES
-
-If you are annoyed by the long constructor call, consider installing the
-L<aliased|aliased> CPAN package. Using C<aliased>, the above example
-becomes
-
-  use PDL;
-  use aliased 'PDL::Graphics::PLplot';
-
-  my $pl = PLplot->new (DEV => "png", FILE => "test.png");
-  my $x  = sequence(10);
-  # etc, as above
-
-=head1 DESCRIPTION
-
-This is the PDL interface to the PLplot graphics library.  It provides
-a familiar 'perlish' Object Oriented interface as well as access to
-the low-level PLplot commands from the C-API.
-
-=head1 OPTIONS
-
-The following options are supported.  Most options can be used
-with any function.  A few are only supported on the call to 'new'.
-
-=head2 Options used upon creation of a PLplot object (with 'new'):
-
-=head3 BACKGROUND
-
-Set the color for index 0, the plot background
-
-=head3 DEV
-
-Set the output device type.  To see a list of allowed types, try:
-
-  PDL::Graphics::PLplot->new();
-
-=for example
-
-   PDL::Graphics::PLplot->new(DEV => 'png', FILE => 'test.png');
-
-=head3 FILE
-
-Set the output file or display.  For file output devices, sets
-the output file name.  For graphical displays (like C<'xwin'>) sets
-the name of the display, eg (C<'hostname.foobar.com:0'>)
-
-=for example
-
-   PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png');
-   PDL::Graphics::PLplot->new(DEV => 'xwin', FILE => ':0');
-
-=head3 OPTS
-
-Set plotting options.  See the PLplot documentation for the complete
-listing of available options.  The value of C<'OPTS'> must be a hash
-reference, whose keys are the names of the options.  For instance, to obtain
-PostScript fonts with the ps output device, use:
-
-=for example
-
-   PDL::Graphics::PLplot->new(DEV => 'ps', OPTS => {drvopt => 'text=1'});
-
-=head3 MEM
-
-This option is used in conjunction with C<< DEV => 'mem' >>.  This option
-takes as input a PDL image and allows one to 'decorate' it using PLplot.
-The 'decorated' PDL image can then be written to an image file using,
-for example, L<PDL::IO::Pic|PDL::IO::Pic>.  This option may not be available if
-plplot does not include the 'mem' driver.
-
-=for example
-
-  # read in Earth image and draw an equator.
-  my $pl = PDL::Graphics::PLplot->new (MEM => $earth, DEV => 'mem');
-  my $x  = pdl(-180, 180);
-  my $y  = zeroes(2);
-  $pl->xyplot($x, $y,
-              BOX => [-180,180,-90,90],
-              VIEWPORT => [0.0, 1.0, 0.0, 1.0],
-              XBOX => '', YBOX => '',
-              PLOTTYPE => 'LINE');
-  $pl->close;
-
-=head3 FRAMECOLOR
-
-Set color index 1, the frame color
-
-=head3 JUST
-
-A flag used to specify equal scale on the axes.  If this is
-not specified, the default is to scale the axes to fit best on
-the page.
-
-=for example
-
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', JUST => 1);
-
-=head3 ORIENTATION
-
-The orientation of the plot:
-
-  0 --   0 degrees (landscape mode)
-  1 --  90 degrees (portrait mode)
-  2 -- 180 degrees (seascape mode)
-  3 -- 270 degrees (upside-down mode)
-
-Intermediate values (0.2) are acceptable if you are feeling daring.
-
-=for example
-
-  # portrait orientation
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', ORIENTATION => 1);
-
-=head3 PAGESIZE
-
-Set the size in pixels of the output page.
-
-=for example
-
-  # PNG 500 by 600 pixels
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', PAGESIZE => [500,600]);
-
-=head3 SUBPAGES
-
-Set the number of sub pages in the plot, [$nx, $ny]
-
-=for example
-
-  # PNG 300 by 600 pixels
-  # Two subpages stacked on top of one another.
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', PAGESIZE => [300,600],
-                                              SUBPAGES => [1,2]);
-
-=head2 Options used after initialization (after 'new')
-
-=head3 BOX
-
-Set the plotting box in world coordinates.  Used to explicitly
-set the size of the plotting area.
-
-=for example
-
- my $pl = PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png');
- $pl->xyplot ($x, $y, BOX => [0,100,0,200]);
-
-=head3 CHARSIZE
-
-Set the size of text in multiples of the default size.
-C<< CHARSIZE => 1.5 >> gives characters 1.5 times the normal size.
-
-=head3 COLOR
-
-Set the current color for plotting and character drawing.
-Colors are specified not as color indices but as RGB triples.
-Some pre-defined triples are included:
-
-  BLACK        GREEN        WHEAT        BLUE
-  RED          AQUAMARINE   GREY         BLUEVIOLET
-  YELLOW       PINK         BROWN        CYAN
-  TURQUOISE    MAGENTA      SALMON       WHITE
-  ROYALBLUE    DEEPSKYBLUE  VIOLET       STEELBLUE1
-  DEEPPINK     MAGENTA      DARKORCHID1  PALEVIOLETRED2
-  TURQUOISE1   LIGHTSEAGREEN SKYBLUE     FORESTGREEN
-  CHARTREUSE3  GOLD2        SIENNA1      CORAL
-  HOTPINK      LIGHTCORAL   LIGHTPINK1   LIGHTGOLDENROD
-
-=for example
-
- # These two are equivalent:
- $pl->xyplot ($x, $y, COLOR => 'YELLOW');
- $pl->xyplot ($x, $y, COLOR => [0,255,0]);
-
-=head3 LINEWIDTH
-
-Set the line width for plotting.  Values range from 1 to a device dependent maximum.
-
-=head3 LINESTYLE
-
-Set the line style for plotting.  Pre-defined line styles use values 1 to 8, one being
-a solid line, 2-8 being various dashed patterns.
-
-=head3 MAJTICKSIZE
-
-Set the length of major ticks as a fraction of the default setting.
-One (default) means leave these ticks the normal size.
-
-=head3 MINTICKSIZE
-
-Set the length of minor ticks (and error bar terminals) as a fraction of the default setting.
-One (default) means leave these ticks the normal size.
-
-=head3 NXSUB
-
-The number of minor tick marks between each major tick mark on the X axis.
-Specify zero (default) to let PLplot compute this automatically.
-
-=head3 NYSUB
-
-The number of minor tick marks between each major tick mark on the Y axis.
-Specify zero (default) to let PLplot compute this automatically.
-
-=head3 PALETTE
-
-Load pre-defined color map 1 color ranges.  Currently, values include:
-
-  RAINBOW   -- from Red to Violet through the spectrum
-  REVERSERAINBOW   -- Violet through Red
-  GREYSCALE -- from black to white via grey.
-  REVERSEGREYSCALE -- from white to black via grey.
-  GREENRED  -- from green to red
-  REDGREEN  -- from red to green
-
-=for example
-
- # Plot x/y points with the z axis in color
- $pl->xyplot ($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
-
-=head3 PLOTTYPE
-
-Specify which type of XY plot is desired:
-
-  LINE       -- A line
-  POINTS     -- A bunch of symbols
-  LINEPOINTS -- both
-
-=head3 SUBPAGE
-
-Set which subpage to plot on.  Subpages are numbered 1 to N.
-A zero can be specified meaning 'advance to the next subpage' (just a call to
-L<pladv()|/pladv>).
-
-=for example
-
-  my $pl = PDL::Graphics::PLplot->new(DEV      => 'png',
-                                        FILE     => 'test.png',
-                                        SUBPAGES => [1,2]);
-  $pl->xyplot ($x, $y, SUBPAGE => 1);
-  $pl->xyplot ($a, $b, SUBPAGE => 2);
-
-
-=head3 SYMBOL
-
-Specify which symbol to use when plotting C<< PLOTTYPE => 'POINTS' >>.
-A large variety of symbols are available, see:
-http://plplot.sourceforge.net/examples-data/demo07/x07.*.png, where * is 01 - 17.
-You are most likely to find good plotting symbols in the 800s:
-http://plplot.sourceforge.net/examples-data/demo07/x07.06.png
-
-=head3 SYMBOLSIZE
-
-Specify the size of symbols plotted in multiples of the default size (1).
-Value are real numbers from 0 to large.
-
-=head3 TEXTPOSITION
-
-Specify the placement of text.  Either relative to border, specified as:
-
- [$side, $disp, $pos, $just]
-
-Where
-
-  side = 't', 'b', 'l', or 'r' for top, bottom, left and right
-  disp is the number of character heights out from the edge
-  pos  is the position along the edge of the viewport, from 0 to 1.
-  just tells where the reference point of the string is: 0 = left, 1 = right, 0.5 = center.
-
-or inside the plot window, specified as:
-
- [$x, $y, $dx, $dy, $just]
-
-Where
-
-  x  = x coordinate of reference point of string.
-  y  = y coordinate of reference point of string.
-  dx   Together with dy, this specifies the inclination of the string.
-       The baseline of the string is parallel to a line joining (x, y) to (x+dx, y+dy).
-  dy   Together with dx, this specifies the inclination of the string.
-  just Specifies the position of the string relative to its reference point.
-       If just=0, the reference point is at the left and if just=1,
-       it is at the right of the string. Other values of just give
-       intermediate justifications.
-
-=for example
-
- # Plot text on top of plot
- $pl->text ("Top label",  TEXTPOSITION => ['t', 4.0, 0.5, 0.5]);
-
- # Plot text in plotting area
- $pl->text ("Line label", TEXTPOSITION => [50, 60, 5, 5, 0.5]);
-
-=head3 TITLE
-
-Add a title on top of a plot.
-
-=for example
-
- # Plot text on top of plot
- $pl->xyplot ($x, $y, TITLE => 'X vs. Y');
-
-=head3 UNFILLED_BARS
-
-For 'bargraph', if set to true then plot the bars as outlines
-in the current color and not as filled boxes
-
-=for example
-
- # Plot text on top of plot
- $pl->bargraph($labels, $values, UNFILLED_BARS => 1);
-
-=head3 VIEWPORT
-
-Set the location of the plotting window on the page.
-Takes a four element array ref specifying:
-
- xmin -- The coordinate of the left-hand edge of the viewport. (0 to 1)
- xmax -- The coordinate of the right-hand edge of the viewport. (0 to 1)
- ymin -- The coordinate of the bottom edge of the viewport. (0 to 1)
- ymax -- The coordinate of the top edge of the viewport. (0 to 1)
-
-You will need to use this to make color keys or insets.
-
-=for example
-
- # Make a small plotting window in the lower left of the page
- $pl->xyplot ($x, $y, VIEWPORT => [0.1, 0.5, 0.1, 0.5]);
-
- # Also useful in creating color keys:
- $pl->xyplot   ($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
- $pl->colorkey ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-
- # Plot an inset; first the primary data and then the inset. In this
- # case, the inset contains a selection of the orignal data
- $pl->xyplot ($x, $y);
- $pl->xyplot (where($x, $y, $x < 1.2), VIEWPORT => [0.7, 0.9, 0.6, 0.8]);
-
-=head3 XBOX
-
-Specify how to label the X axis of the plot as a string of option letters:
-
-  a: Draws axis, X-axis is horizontal line (y=0), and Y-axis is vertical line (x=0).
-  b: Draws bottom (X) or left (Y) edge of frame.
-  c: Draws top (X) or right (Y) edge of frame.
-  f: Always use fixed point numeric labels.
-  g: Draws a grid at the major tick interval.
-  h: Draws a grid at the minor tick interval.
-  i: Inverts tick marks, so they are drawn outwards, rather than inwards.
-  l: Labels axis logarithmically. This only affects the labels, not the data,
-     and so it is necessary to compute the logarithms of data points before
-     passing them to any of the drawing routines.
-  m: Writes numeric labels at major tick intervals in the
-     unconventional location (above box for X, right of box for Y).
-  n: Writes numeric labels at major tick intervals in the conventional location
-     (below box for X, left of box for Y).
-  s: Enables subticks between major ticks, only valid if t is also specified.
-  t: Draws major ticks.
-
-The default is C<'BCNST'> which draws lines around the plot, draws major and minor
-ticks and labels major ticks.
-
-=for example
-
- # plot two lines in a box with independent X axes labeled
- # differently on top and bottom
- $pl->xyplot($x1, $y, XBOX  => 'bnst',  # bottom line, bottom numbers, ticks, subticks
-	              YBOX  => 'bnst'); # left line, left numbers, ticks, subticks
- $pl->xyplot($x2, $y, XBOX => 'cmst', # top line, top numbers, ticks, subticks
-	              YBOX => 'cst',  # right line, ticks, subticks
-	              BOX => [$x2->minmax, $y->minmax]);
-
-=head3 XERRORBAR
-
-Used only with L</xyplot>.  Draws horizontal error bars at all points (C<$x>, C<$y>) in the plot.
-Specify a PDL containing the same number of points as C<$x> and C<$y>
-which specifies the width of the error bar, which will be centered at (C<$x>, C<$y>).
-
-=head3 XLAB
-
-Specify a label for the X axis.
-
-=head3 XTICK
-
-Interval (in graph units/world coordinates) between major x axis tick marks.
-Specify zero (default) to allow PLplot to compute this automatically.
-
-=head3 YBOX
-
-Specify how to label the Y axis of the plot as a string of option letters.
-See L</XBOX>.
-
-=head3 YERRORBAR
-
-Used only for xyplot.  Draws vertical error bars at all points (C<$x>, C<$y>) in the plot.
-Specify a PDL containing the same number of points as C<$x> and C<$y>
-which specifies the width of the error bar, which will be centered at (C<$x>, C<$y>).
-
-=head3 YLAB
-
-Specify a label for the Y axis.
-
-=head3 YTICK
-
-Interval (in graph units/world coordinates) between major y axis tick marks.
-Specify zero (default) to allow PLplot to compute this automatically.
-
-=head3 ZRANGE
-
-For L</xyplot> (when C<COLORMAP> is specified), for
-L</shadeplot> and for L</colorkey>.
-Normally, the range of the Z variable (color) is taken as
-C<< $z->minmax >>.  If a different range is desired,
-specify it in C<ZRANGE>, like so:
-
-  $pl->shadeplot ($z, $nlevels, PALETTE => 'GREENRED', ZRANGE => [0,100]);
-
-or
-
-  $pl->xyplot ($x, $y, PALETTE  => 'RAINBOW', PLOTTYPE => 'POINTS',
-	               COLORMAP => $z,        ZRANGE => [-90,-20]);
-  $pl->colorkey  ($z, 'v', VIEWPORT => [0.93, 0.96, 0.13, 0.85],
-                       ZRANGE => [-90,-20]);
-
-=head1 METHODS
-
-These are the high-level, object oriented methods for PLplot.
-
-=head2 new
-
-=for ref
-
-Create an object representing a plot.
-
-=for usage
-
- Arguments:
- none.
-
- Supported options:
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-=for example
-
-  my $pl = PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png');
-
-
-=head2 setparm
-
-=for ref
-
-Set options for a plot object.
-
-=for usage
-
- Arguments:
- none.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->setparm (TEXTSIZE => 2);
-
-=head2 xyplot
-
-=for ref
-
-Plot XY lines and/or points.  Also supports color scales for points.
-This function works with bad values.  If a bad value is specified for
-a points plot, it is omitted.  If a bad value is specified for a line
-plot, the bad value makes a gap in the line.  This is useful for
-drawing maps; for example C<$x> and C<$y> can be the continent boundary
-latitude and longitude.
-
-=for usage
-
- Arguments:
- $x, $y
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->xyplot($x, $y, PLOTTYPE => 'POINTS', COLOR => 'BLUEVIOLET', SYMBOL => 1, SYMBOLSIZE => 4);
-  $pl->xyplot($x, $y, PLOTTYPE => 'LINEPOINTS', COLOR => [50,230,30]);
-  $pl->xyplot($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
-
-=head2 stripplots
-
-=for ref
-
-Plot a set of strip plots with a common X axis, but with different Y axes.
-Looks like a stack of long, thin XY plots, all line up on the same X axis.
-
-=for usage
-
- Arguments:
- $xs -- 1D PDL with common X axis values, length = N
- $ys -- reference to a list of 1D PDLs with Y-axis values, length = N
-        or 2D PDL with N x M elements
- -- OR --
- $xs -- reference to a list of 1D PDLs with X-axis values
- $ys -- reference to a list of 1D PDLs with Y-axis values
- %opts -- Options hash
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  my $x  = sequence(20);
-  my $y1  = $x**2;
-  my $y2  = sqrt($x);
-  my $y3  = $x**3;
-  my $y4  = sin(($x/20) * 2 * $pi);
-  $ys  = cat($y1, $y2, $y3, $y4);
-  $pl->stripplots($x, $ys, PLOTTYPE => 'LINE', TITLE => 'functions',
-                           YLAB     => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                           COLOR    => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-  # Equivalent to above:
-  $pl->stripplots($x, [$y1, $y2, $y3, $y4],
-                           PLOTTYPE => 'LINE', TITLE => 'functions',
-                           YLAB     => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                           COLOR    => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-
-  # Here's something a bit different. Notice that different xs have
-  # different lengths.
-  $x1  = sequence(20);
-  $y1  = $x1**2;
-
-  $x2  = sequence(18);
-  $y2  = sqrt($x2);
-
-  $x3  = sequence(24);
-  $y3  = $x3**3;
-
-  my $x4  = sequence(27);
-  $a  = ($x4/20) * 2 * $pi;
-  my $y4  = sin($a);
-
-  $xs  = [$x1, $x2, $x3, $x4];
-  $ys  = [$y1, $y2, $y3, $y4];
-  $pl->stripplots($xs, $ys, PLOTTYPE => 'LINE', TITLE => 'functions',
-                YLAB => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                         COLOR => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-
-In addition, COLOR may be specified as a reference to a list of colors.  If
-this is done, the colors are applied separately to each plot.
-
-Also, the options Y_BASE and Y_GUTTER can be specified.  Y_BASE gives the Y offset
-of the bottom of the lowest plot (0-1, specified like a VIEWPORT, defaults to 0.1) and Y_GUTTER
-gives the gap between the graphs (0-1, default = 0.02).
-
-=head2 colorkey
-
-=for ref
-
-Plot a color key showing which color represents which value
-
-=for usage
-
- Arguments:
- $range   : A PDL which tells the range of the color values
- $orientation : 'v' for vertical color key, 'h' for horizontal
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  # Plot X vs. Y with Z shown by the color.  Then plot
-  # vertical key to the right of the original plot.
-  $pl->xyplot ($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
-  $pl->colorkey ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-
-
-=head2 shadeplot
-
-=for ref
-
-Create a shaded contour plot of 2D PDL 'z' with 'nsteps' contour levels.
-Linear scaling is used to map the coordinates of Z(X, Y) to world coordinates
-via the L</BOX> option.
-
-=for usage
-
- Arguments:
- $z : A 2D PDL which contains surface values at each XY coordinate.
- $nsteps : The number of contour levels requested for the plot.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  # vertical key to the right of the original plot.
-  # The BOX must be specified to give real coordinate values to the $z array.
-  $pl->shadeplot ($z, $nsteps, BOX => [-1, 1, -1, 1], PALETTE => 'RAINBOW', ZRANGE => [0,100]);
-  $pl->colorkey  ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85], ZRANGE => [0,100]);
-
-=head2 histogram
-
-=for ref
-
-Create a histogram of a 1-D variable.
-
-=for usage
-
- Arguments:
- $x : A 1D PDL
- $nbins : The number of bins to use in the histogram.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->histogram ($x, $nbins, BOX => [$min, $max, 0, 100]);
-
-=head2 bargraph
-
-=for ref
-
-Simple utility to plot a bar chart with labels on the X axis.
-The usual options can be specified, plus one other:  MAXBARLABELS
-specifies the maximum number of labels to allow on the X axis.
-The default is 20.  If this value is exceeded, then every other
-label is plotted.  If twice MAXBARLABELS is exceeded, then only
-every third label is printed, and so on.
-
-if UNFILLED_BARS is set to true, then plot the bars as outlines
-and not as filled rectangles.
-
-=for usage
-
- Arguments:
- $labels -- A reference to a perl list of strings.
- $values -- A PDL of values to be plotted.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $labels = ['one', 'two', 'three'];
-  $values = pdl(1, 2, 3);
-
-  # Note if TEXTPOSITION is specified, it must be in 4 argument mode (border mode):
-  # [$side, $disp, $pos, $just]
-  #
-  # Where side = 't', 'b', 'l', or 'r' for top, bottom, left and right
-  #              'tv', 'bv', 'lv' or 'rv' for top, bottom, left or right perpendicular to the axis.
-  #
-  #     disp is the number of character heights out from the edge
-  #     pos  is the position along the edge of the viewport, from 0 to 1.
-  #     just tells where the reference point of the string is: 0 = left, 1 = right, 0.5 = center.
-  #
-  # The '$pos' entry will be ignored (computed by the bargraph routine)
-  $pl->bargraph($labels, $values, MAXBARLABELS => 30, TEXTPOSITION => ['bv', 0.5, 1.0, 1.0]);
-
-=head2 text
-
-=for ref
-
-Write text on a plot.  Text can either be written
-with respect to the borders or at an arbitrary location and angle
-(see the L</TEXTPOSITION> entry).
-
-=for usage
-
- Arguments:
- $t : The text.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->text("Count", COLOR => 'PINK',
-	    TEXTPOSITION => ['t', 3, 0.5, 0.5]); # top, 3 units out, string ref. pt in
-                                                 # center of string, middle of axis
-
-=head2 close
-
-=for ref
-
-Close a PLplot object, writing out the file and cleaning up.
-
-=for usage
-
-Arguments:
-None
-
-Returns:
-Nothing
-
-This closing of the PLplot object can be done explicitly though the
-'close' method.  Alternatively, a DESTROY block does an automatic
-close whenever the PLplot object passes out of scope.
-
-=for example
-
-  $pl->close;
-
-=cut
-
-# pull in low level interface
-use vars qw(%_constants %_actions);
-
-# Colors (from rgb.txt) are stored as RGB triples
-# with each value from 0-255
-sub cc2t { [map {hex} split ' ', shift] }
-%_constants = (
-	       BLACK          => [  0,  0,  0],
-	       RED            => [240, 50, 50],
-	       YELLOW         => [255,255,  0],
-	       GREEN          => [  0,255,  0],
-	       AQUAMARINE     => [127,255,212],
-	       PINK           => [255,192,203],
-	       WHEAT          => [245,222,179],
-	       GREY           => [190,190,190],
-	       BROWN          => [165, 42, 42],
-	       BLUE           => [  0,  0,255],
-	       BLUEVIOLET     => [138, 43,226],
-	       CYAN           => [  0,255,255],
-	       TURQUOISE      => [ 64,224,208],
-	       MAGENTA        => [255,  0,255],
-	       SALMON         => [250,128,114],
-	       WHITE          => [255,255,255],
-               ROYALBLUE      => cc2t('2B 60 DE'),
-               DEEPSKYBLUE    => cc2t('3B B9 FF'),
-               VIOLET         => cc2t('8D 38 C9'),
-               STEELBLUE1     => cc2t('5C B3 FF'),
-               DEEPPINK       => cc2t('F5 28 87'),
-               MAGENTA        => cc2t('FF 00 FF'),
-               DARKORCHID1    => cc2t('B0 41 FF'),
-               PALEVIOLETRED2 => cc2t('E5 6E 94'),
-               TURQUOISE1     => cc2t('52 F3 FF'),
-               LIGHTSEAGREEN  => cc2t('3E A9 9F'),
-               SKYBLUE        => cc2t('66 98 FF'),
-               FORESTGREEN    => cc2t('4E 92 58'),
-               CHARTREUSE3    => cc2t('6C C4 17'),
-               GOLD2          => cc2t('EA C1 17'),
-               SIENNA1        => cc2t('F8 74 31'),
-               CORAL          => cc2t('F7 65 41'),
-               HOTPINK        => cc2t('F6 60 AB'),
-               LIGHTCORAL     => cc2t('E7 74 71'),
-               LIGHTPINK1     => cc2t('F9 A7 B0'),
-               LIGHTGOLDENROD => cc2t('EC D8 72'),
-	      );
-
-# a hash of subroutines to invoke when certain keywords are specified
-# These are called with arg(0) = $self (the plot object)
-#                   and arg(1) = value specified for keyword
-%_actions =
-  (
-
-
-   # Set color for index 0, the plot background
-   BACKGROUND => sub {
-     my $self  = shift;
-     my $color = _color(shift);
-     $self->{COLORS}[0] = $color;
-     plscolbg (@$color);
-   },
-
-   # set plotting box in world coordinates
-   BOX        => sub {
-     my $self  = shift;
-     my $box   = shift;
-     die "Box must be a ref to a four element array" unless (ref($box) =~ /ARRAY/ and @$box == 4);
-     $self->{BOX} = $box;
-   },
-
-   CHARSIZE   => sub { my $self = shift;
-                       $self->{CHARSIZE} = $_[0];
-                       plschr   (0, $_[0]) },  # 0 - N
-
-   COLOR =>
-   # maintain color map, set to specified rgb triple
-   sub {
-     my $self  = shift;
-     my $color = _color(shift);
-
-     # init.
-     $self->{COLORS} = [] unless exists($self->{COLORS});
-
-     my @idx = @{$self->{COLORS}}; # map of color index (0-15) to RGB triples
-     my $found = 0;
-     for (my $i=2;$i<@idx;$i++) {  # map entries 0 and 1 are reserved for BACKGROUND and FRAMECOLOR
-       if (_coloreq ($color, $idx[$i])) {
-	 $self->{CURRENT_COLOR_IDX} = $i;
-	 $found = 1;
-	 plscol0 ($self->{CURRENT_COLOR_IDX}, @$color);
-       }
-     }
-     return if ($found);
-
-     die "Too many colors used! (max 15)" if (@{$self->{COLORS}} > 14);
-
-     # add this color as index 2 or greater (entries 0 and 1 reserved)
-     my $idx = (@{$self->{COLORS}} > 1) ? @{$self->{COLORS}} : 2;
-     $self->{COLORS}[$idx]      = $color;
-     $self->{CURRENT_COLOR_IDX} = $idx;
-     plscol0 ($self->{CURRENT_COLOR_IDX}, @$color);
-   },
-
-   # set output device type
-   DEV        => sub { my $self = shift;
-                       my $dev  = shift;
-                       $self->{DEV} = $dev;
-                       plsdev   ($dev)
-                     },   # this must be specified with call to new!
-
-   # set PDL to plot into (alternative to specifying DEV)
-   MEM        => sub { my $self = shift;
-		       my $pdl  = shift;
-		       my $x    = $pdl->getdim(1);
-		       my $y    = $pdl->getdim(2);
-		       plsmem   ($x, $y, $pdl);
-		     },
-
-   # set output file
-   FILE       => sub { plsfnam  ($_[1]) },   # this must be specified with call to new!
-
-   # set color for index 1, the plot frame and text
-   FRAMECOLOR =>
-   # set color index 1, the frame color
-   sub {
-     my $self  = shift;
-     my $color = _color(shift);
-     $self->{COLORS}[1] = $color;
-     plscol0 (1, @$color);
-   },
-
-   # Set flag for equal scale axes
-   JUST => sub {
-     my $self  = shift;
-     my $just  = shift;
-     die "JUST must be 0 or 1 (defaults to 0)" unless ($just == 0 or $just == 1);
-     $self->{JUST} = $just;
-   },
-
-    LINEWIDTH  => sub {
-      my $self = shift;
-      my $wid  = shift;
-      die "LINEWIDTH must range from 0 to LARGE8" unless ($wid >= 0);
-      $self->{LINEWIDTH} = $wid;
-    },
-
-   LINESTYLE  => sub {
-     my $self = shift;
-     my $sty  = shift;
-     die "LINESTYLE must range from 1 to 8" unless ($sty >= 1 and $sty <= 8);
-     $self->{LINESTYLE} = $sty;
-   },
-
-   MAJTICKSIZE  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "MAJTICKSIZE must be greater than or equal to zero"
-       unless ($val >= 0);
-     plsmaj (0, $val);
-   },
-
-   MINTICKSIZE  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "MINTICKSIZE must be greater than or equal to zero"
-       unless ($val >= 0);
-     plsmin (0, $val);
-   },
-
-   NXSUB  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "NXSUB must be an integer greater than or equal to zero"
-       unless ($val >= 0 and int($val) == $val);
-     $self->{NXSUB} = $val;
-   },
-
-   NYSUB  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "NYSUB must be an integer greater than or equal to zero"
-       unless ($val >= 0 and int($val) == $val);
-     $self->{NYSUB} = $val;
-   },
-
-   # set driver options, example for ps driver, {text => 1} is accepted
-   OPTS => sub {
-     my $self = shift;
-     my $opts = shift;
-
-     foreach my $opt (keys %$opts) {
-       plsetopt ($opt, $$opts{$opt});
-     }
-   },
-
-   # set driver options, example for ps driver, {text => 1} is accepted
-   ORIENTATION => sub {
-     my $self   = shift;
-     my $orient = shift;
-
-     die "Orientation must be between 0 and 4" unless ($orient >= 0 and $orient <= 4);
-     $self->{ORIENTATION} = $orient;
-   },
-
-   PAGESIZE   =>
-     # set plot size in mm.  Only useful in call to 'new'
-     sub {
-       my $self = shift;
-       my $dims = shift;
-
-       die "plot size must be a 2 element array ref:  X size in pixels, Y size in pixels"
-	 if ((ref($dims) !~ /ARRAY/) || @$dims != 2);
-       $self->{PAGESIZE} = $dims;
-     },
-
-   PALETTE =>
-
-   # load some pre-done color map 1 setups
-   sub {
-     my $self = shift;
-     my $pal  = shift;
-
-     my %legal = (REVERSERAINBOW => 1, REVERSEGREYSCALE => 1, REDGREEN => 1, RAINBOW => 1, GREYSCALE => 1, GREENRED => 1);
-     if ($legal{$pal}) {
-       $self->{PALETTE} = $pal;
-       if      ($pal eq 'RAINBOW') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,300), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(0,0));
-       } elsif ($pal eq 'REVERSERAINBOW') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(270,-30), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(0,0));
-       } elsif ($pal eq 'GREYSCALE') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,0),   PDL->new(0,1), PDL->new(0,0), PDL->new(0,0));
-       } elsif ($pal eq 'REVERSEGREYSCALE') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,0),   PDL->new(1,0), PDL->new(0,0), PDL->new(0,0));
-       } elsif ($pal eq 'GREENRED') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(120,0), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(1,1));
-       } elsif ($pal eq 'REDGREEN') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,120), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(1,1));
-       }
-     } else {
-       die "Illegal palette name.  Legal names are: " . join (" ", keys %legal);
-     }
-   },
-
-   PLOTTYPE =>
-   # specify plot type (LINE, POINTS, LINEPOINTS)
-   sub {
-     my $self = shift;
-     my $val  = shift;
-
-     my %legal = (LINE => 1, POINTS => 1, LINEPOINTS => 1);
-     if ($legal{$val}) {
-       $self->{PLOTTYPE} = $val;
-     } else {
-       die "Illegal plot type.  Legal options are: " . join (" ", keys %legal);
-     }
-   },
-
-   SUBPAGE =>
-   # specify which subpage to plot on 1-N or 0 (meaning 'next')
-   sub {
-     my $self = shift;
-     my $val  = shift;
-     my $err  = "SUBPAGE = \$npage where \$npage = 1-N or 0 (for 'next subpage')";
-     if ($val >= 0) {
-       $self->{SUBPAGE} = $val;
-     } else {
-       die $err;
-     }
-   },
-
-   SUBPAGES =>
-   # specify number of sub pages [nx, ny]
-   sub {
-     my $self = shift;
-     my $val  = shift;
-     my $err  = "SUBPAGES = [\$nx, \$ny] where \$nx and \$ny are between 1 and 127";
-     if (ref($val) =~ /ARRAY/ and @$val == 2) {
-       my ($nx, $ny) = @$val;
-       if ($nx > 0 and $nx < 128 and $ny > 0 and $ny < 128) {
-	 $self->{SUBPAGES} = [$nx, $ny];
-       } else {
-	 die $err;
-       }
-     } else {
-       die $err;
-     }
-   },
-
-   SYMBOL =>
-   # specify type of symbol to plot
-   sub {
-     my $self = shift;
-     my $val  = shift;
-
-     if ($val >= 0 && $val < 3000) {
-       $self->{SYMBOL} = $val;
-     } else {
-       die "Illegal symbol number.  Legal symbols are between 0 and 3000";
-     }
-   },
-
-   SYMBOLSIZE => sub {
-     my ($self, $size) = @_;
-     die "symbol size must be a real number from 0 to (large)" unless ($size >= 0);
-     $self->{SYMBOLSIZE} = $size;
-   },
-
-   TEXTPOSITION =>
-   # specify placement of text.  Either relative to border, specified as:
-   # [$side, $disp, $pos, $just]
-   # or
-   # inside plot window, specified as:
-   # [$x, $y, $dx, $dy, $just] (see POD doc for details)
-   sub {
-     my $self = shift;
-     my $val  = shift;
-
-     die "TEXTPOSITION value must be an array ref with either:
-          [$side, $disp, $pos, $just] or [$x, $y, $dx, $dy, $just]"
-       unless ((ref($val) =~ /ARRAY/) and ((@$val == 4) || (@$val == 5)));
-
-     if (@$val == 4) {
-       $self->{TEXTMODE} = 'border';
-     } else {
-       $self->{TEXTMODE} = 'plot';
-     }
-     $self->{TEXTPOSITION} = $val;
-   },
-
-   # draw a title for the graph
-   TITLE      => sub {
-     my $self = shift;
-     my $text = shift;
-     $self->{TITLE} = $text;
-   },
-
-   # Specify outline bars for bargraph
-   UNFILLED_BARS => sub {
-     my $self = shift;
-     my $val  = shift;
-     $self->{UNFILLED_BARS} = $val;
-   },
-
-   # set the location of the plotting window on the page
-   VIEWPORT => sub {
-     my $self  = shift;
-     my $vp    = shift;
-     die "Viewport must be a ref to a four element array"
-       unless (ref($vp) =~ /ARRAY/ and @$vp == 4);
-     $self->{VIEWPORT} = $vp;
-   },
-
-   XBOX       =>
-     # set X axis label options.  See pod for definitions.
-     sub {
-       my $self = shift;
-       my $opts = lc shift;
-
-       my @opts = split '', $opts;
-       map { 'abcdfghilmnst' =~ /$_/i || die "Illegal option $_.  Only abcdfghilmnst permitted" } @opts;
-
-       $self->{XBOX} = $opts;
-     },
-
-   # draw an X axis label for the graph
-   XLAB       => sub {
-     my $self = shift;
-     my $text = shift;
-     $self->{XLAB} = $text;
-   },
-
-   XTICK  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "XTICK must be greater than or equal to zero"
-       unless ($val >= 0);
-     $self->{XTICK} = $val;
-   },
-
-   YBOX       =>
-     # set Y axis label options.  See pod for definitions.
-     sub {
-       my $self = shift;
-       my $opts = shift;
-
-       my @opts = split '', $opts;
-       map { 'abcfghilmnstv' =~ /$_/i || die "Illegal option $_.  Only abcfghilmnstv permitted" } @opts;
-
-       $self->{YBOX} = $opts;
-     },
-
-   # draw an Y axis label for the graph
-   YLAB       => sub {
-     my $self = shift;
-     my $text = shift;
-     $self->{YLAB} = $text;
-   },
-
-   YTICK  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "YTICK must be greater than or equal to zero"
-       unless ($val >= 0);
-     $self->{YTICK} = $val;
-   },
-
-   ZRANGE  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "ZRANGE must be a perl array ref with min and max Z values"
-       unless (ref($val) =~ /ARRAY/ && @$val == 2);
-     $self->{ZRANGE} = $val;
-   },
-
-);
-
-
-#
-## Internal utility routines
-#
-
-# handle color as string in _constants hash or [r,g,b] triple
-# Input:  either color name or [r,g,b] array ref
-# Output: [r,g,b] array ref or exception
-sub _color {
-  my $c = shift;
-  if      (ref($c) =~ /ARRAY/) {
-    return $c;
-  } elsif ($c = $_constants{$c}) {
-    return $c;
-  } else {
-    die "Color $c not defined";
-  }
-}
-
-# return 1 if input [r,g,b] triples are equal.
-sub _coloreq {
-  my ($a, $b) = @_;
-  for (my $i=0;$i<3;$i++) { return 0 if ($$a[$i] != $$b[$i]); }
-  return 1;
-}
-
-# Initialize plotting window given the world coordinate box and
-# a 'justify' flag (for equal axis scales).
-sub _setwindow {
-
-  my $self = shift;
-
-  # choose correct subwindow
-  pladv ($self->{SUBPAGE}) if (exists ($self->{SUBPAGE}));
-  delete ($self->{SUBPAGE});  # get rid of SUBPAGE so future plots will stay on same
-                              # page unless user asks for specific page
-
-  my $box  = $self->{BOX} || [0,1,0,1]; # default window
-
-  sub MAX { ($_[0] > $_[1]) ? $_[0] : $_[1]; }
-
-  # get subpage offsets from page left/bottom of image
-  my ($spxmin, $spxmax, $spymin, $spymax) = (PDL->new(0),PDL->new(0),PDL->new(0),PDL->new(0));
-  plgspa($spxmin, $spxmax, $spymin, $spymax);
-  $spxmin = $spxmin->at(0);
-  $spxmax = $spxmax->at(0);
-  $spymin = $spymin->at(0);
-  $spymax = $spymax->at(0);
-  my $xsize = $spxmax - $spxmin;
-  my $ysize = $spymax - $spymin;
-
-  my @vp = @{$self->{VIEWPORT}};  # view port xmin, xmax, ymin, ymax in fraction of image size
-
-  # if JUSTify is zero, set to the user specified (or default) VIEWPORT
-  if ($self->{JUST} == 0) {
-    plvpor(@vp);
-
-  # compute viewport to allow the same scales for both axes
-  } else {
-    my $p_def = PDL->new(0);
-    my $p_ht  = PDL->new(0);
-    plgchr ($p_def, $p_ht);
-    $p_def = $p_def->at(0);
-    my $lb = 8.0 * $p_def;
-    my $rb = 5.0 * $p_def;
-    my $tb = 5.0 * $p_def;
-    my $bb = 5.0 * $p_def;
-    my $dx = $$box[1] - $$box[0];
-    my $dy = $$box[3] - $$box[2];
-    my $xscale = $dx / ($xsize - $lb - $rb);
-    my $yscale = $dy / ($ysize - $tb - $bb);
-    my $scale  = MAX($xscale, $yscale);
-    my $vpxmin = MAX($lb, 0.5 * ($xsize - $dx / $scale));
-    my $vpxmax = $vpxmin + ($dx / $scale);
-    my $vpymin = MAX($bb, 0.5 * ($ysize - $dy / $scale));
-    my $vpymax = $vpymin + ($dy / $scale);
-    plsvpa($vpxmin, $vpxmax, $vpymin, $vpymax);
-    $self->{VIEWPORT} = [$vpxmin/$xsize, $vpxmax/$xsize, $vpymin/$ysize, $vpymax/$ysize];
-  }
-
-  # set up world coords in window
-  plwind (@$box);
-
-}
-
-# Add title and axis labels.
-sub _drawlabels {
-
-  my $self = shift;
-
-  plcol0  (1); # set to frame color
-  plmtex   (2.5, 0.5, 0.5, 't', $self->{TITLE}) if ($self->{TITLE});
-  plmtex   (3.0, 0.5, 0.5, 'b', $self->{XLAB})  if ($self->{XLAB});
-  plmtex   (3.5, 0.5, 0.5, 'l', $self->{YLAB})  if ($self->{YLAB});
-  plcol0  ($self->{CURRENT_COLOR_IDX}); # set back
-
-}
-
-
-#
-## user-visible routines
-#
-
-# Pool of PLplot stream numbers.  One of these stream numbers is taken when 'new' is called
-# and when the corresponding 'close' is called, it is returned to the pool.  The pool is
-# just a queue:  'new' shifts stream numbers from the top of the queue, 'close' pushes them
-# back on the bottom of the queue.
-my @plplot_stream_pool = (0..99);
-
-# This routine starts out a plot.  Generally one specifies
-# DEV and FILE (device and output file name) as options.
-sub new {
-  my $type = shift;
-  my $self = {};
-
-  # set up object
-  $self->{PLOTTYPE} = 'LINE';
-  # $self->{CURRENT_COLOR_IDX} = 1;
-  $self->{COLORS} = [];
-
-  bless $self, $type;
-
-  # set stream number first
-  $self->{STREAMNUMBER} = shift @plplot_stream_pool;
-  die "No more PLplot streams left, too many open PLplot objects!" if (!defined($self->{STREAMNUMBER}));
-  plsstrm($self->{STREAMNUMBER});
-
-  # set background and frame color first
-  $self->setparm(BACKGROUND => 'WHITE',
-		 FRAMECOLOR => 'BLACK');
-
-  # set defaults, allow input options to override
-  my %opts = (
-	      COLOR      => 'BLACK',
-	      XBOX       => 'BCNST',
-	      YBOX       => 'BCNST',
-	      JUST       => 0,
-	      SUBPAGES   => [1,1],
-	      VIEWPORT   => [0.1, 0.87, 0.13, 0.82],
-	      SUBPAGE    => 0,
-	      PAGESIZE   => [600, 500],
-	      LINESTYLE  => 1,
-              LINEWIDTH  => 0,
-              SYMBOL     => 751, # a small square
-	      NXSUB      => 0,
-	      NYSUB      => 0,
-	      ORIENTATION=> 0,
-	      XTICK      => 0,
-	      YTICK      => 0,
-	      CHARSIZE   => 1,
-	      @_);
-
-
-  # apply options
-  $self->setparm(%opts);
-
-  # Do initial setup
-  plspage (0, 0, @{$self->{PAGESIZE}}, 0, 0) if (defined($self->{PAGESIZE}));
-  plssub (@{$self->{SUBPAGES}});
-  plfontld (1); # extented symbol pages
-  plscmap0n (16);   # set up color map 0 to 16 colors.  Is this needed?
-  plscmap1n (128);  # set map 1 to 128 colors (should work for devices with 256 colors)
-  plinit ();
-
-  # set page orientation
-  plsdiori ($self->{ORIENTATION});
-
-  # set up plotting box
-  $self->_setwindow;
-
-  return $self;
-}
-
-# set parameters.  Called from user directly or from other routines.
-sub setparm {
-  my $self = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply all options
- OPTION:
-  foreach my $o (keys %opts) {
-    unless (exists($_actions{$o})) {
-      warn "Illegal option $o, ignoring";
-      next OPTION;
-    }
-    &{$_actions{$o}}($self, $opts{$o});
-  }
-}
-
-# handle 2D plots
-sub xyplot {
-  my $self = shift;
-  my $x    = shift;
-  my $y    = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # only process COLORMAP entries once
-  my $z = $opts{COLORMAP};
-  delete ($opts{COLORMAP});
-
-  # handle ERRORBAR options
-  my $xeb = $opts{XERRORBAR};
-  my $yeb = $opts{YERRORBAR};
-  delete ($opts{XERRORBAR});
-  delete ($opts{YERRORBAR});
-
-  # apply options
-  $self->setparm(%opts);
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [$x->minmax, $y->minmax];
-  }
-
-  # set up viewport, subpage, world coordinates
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-  # set the color according to the color specified in the object
-  # (we don't do this as an option, because then the frame might
-  # get the color requested for the line/points
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  # set line style for plot only (not box)
-  pllsty ($self->{LINESTYLE});
-
-  # set line width for plot only (not box)
-  plwid  ($self->{LINEWIDTH});
-
-  # Plot lines if requested
-  if  ($self->{PLOTTYPE} =~ /LINE/) {
-    plline ($x, $y);
-  }
-
-  # set line width back
-  plwid  (0);
-
-  # plot points if requested
-  if ($self->{PLOTTYPE} =~ /POINTS/) {
-    my $c = $self->{SYMBOL};
-    unless (defined($c)) {
-
-      # the default for $c is a PDL of ones with shape
-      # equal to $x with the first dimension removed
-      my $z = PDL->zeroes($x->nelem);
-      $c = PDL->ones($z->zcover) unless defined($c);
-    }
-    plssym   (0, $self->{SYMBOLSIZE}) if (defined($self->{SYMBOLSIZE}));
-
-    if (defined($z)) {  # if a color range plot requested
-      my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $z->minmax;
-      plcolorpoints ($x, $y, $z, $c, $min, $max);
-    } else {
-      plsym ($x, $y, $c);
-    }
-  }
-
-  # Plot error bars, if requested
-  if (defined($xeb)) {
-    # horizontal (X) error bars
-    plerrx ($x->nelem, $x - $xeb/2, $x + $xeb/2, $y);
-  }
-
-  if (defined($yeb)) {
-    # vertical (Y) error bars
-    plerry ($y->nelem, $x, $y - $yeb/2, $y + $yeb/2);
-  }
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-
-# Handle sets of 2D strip plots sharing one X axis.  Input is
-# $self -- PLplot object with existing options
-# $xs   -- Ref to list of 1D PDLs with X values
-# $ys   -- Ref to list of 1D PDLs with Y values
-#          or a 2D PDL
-# %opts -- Options values
-sub stripplots {
-
-  my $self    = shift;
-  my $xs      = shift;
-  my $yargs   = shift;
-
-  my %opts = @_;
-
-  # NYTICK => number of y axis ticks
-  my $nytick = $opts{NYTICK} || 2;
-  delete ($opts{NYTICK});
-
-  # only process COLORMAP entries once
-  my $zs = $opts{COLORMAP};
-  delete ($opts{COLORMAP});
-
-  # handle XLAB, YLAB and TITLE options
-  my $title = $opts{TITLE} || '';
-  my $xlab  = $opts{XLAB}  || '';
-  my @ylabs = defined($opts{YLAB}) && (ref($opts{YLAB}) =~ /ARRAY/) ? @{$opts{YLAB}} : ();
-  delete @opts{qw(TITLE XLAB YLAB)};
-
-  # Ensure we're dealing with an array reference
-  my $ys;
-  if (ref ($yargs) eq 'ARRAY') {
-    $ys = $yargs;
-  }
-  elsif (ref ($yargs) =~ /PDL/) {
-    $ys = [dog $yargs];
-  }
-  else {
-    barf("stripplots requires that its second argument be either a 2D piddle or\na reference to a list of 1D piddles, but you provided neither.");
-  }
-
-# This doesn't work because $xs can be an anonymous array, too
-#  # Let's be sure the user sent us what we expected:
-#  foreach (@$ys) {
-#    barf ("stripplots needs to have piddles for its y arguments!")
-#      unless (ref =~ /PDL/);
-#    barf("stripplots requires that the x and y dimensions agree!")
-#      unless ($_->nelem == $xs->nelem);
-#  }
-
-  my $nplots = @$ys;
-
-  # Use list of colors, or single color.  If COLOR not specified, default to BLACK for each graph
-  my @colors = (defined ($opts{COLOR}) && ref($opts{COLOR}) =~ /ARRAY/) ? @{$opts{COLOR}}
-             :  defined ($opts{COLOR})                                  ? ($opts{COLOR}) x $nplots
-             : ('BLACK') x $nplots;
-  delete @opts{qw(COLOR)};
-
-  my $y_base   = defined($opts{Y_BASE})   ? $opts{Y_BASE}   : 0.1;  # Y offset to start bottom plot
-  my $y_gutter = defined($opts{Y_GUTTER}) ? $opts{Y_GUTTER} : 0.02; # Y gap between plots
-  delete @opts{qw(Y_BASE Y_GUTTER)};
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($xmin, $xmax);
-  if (ref ($xs) =~ /PDL/) {
-    ($xmin, $xmax) = $xs->minmax;
-  }
-  else {
-    $xmin = pdl(map { $_->min } @$xs)->min;
-    $xmax = pdl(map { $_->max } @$xs)->max;
-  }
-
-  SUBPAGE:
-    for (my $subpage=0;$subpage<$nplots;$subpage++) {
-
-      my $y = $ys->[$subpage];
-      my $x = ref ($xs) =~ /PDL/ ? $xs : $xs->[$subpage];
-      my $mask = $y->isgood;
-      $y = $y->where($mask);
-      $x = $x->where($mask);
-      my $z = $zs->slice(":,($subpage)")->where($mask)      if (defined($zs));
-      my $yeb  = $yebs->slice(":,($subpage)")->where($mask) if (defined($yebs));
-      my $ylab = $ylabs[$subpage];
-
-      my $bottomplot = ($subpage == 0);
-      my $topplot    = ($subpage == $nplots-1);
-
-      my $xbox = 'bc';
-      $xbox = 'cstnb' if ($bottomplot);
-
-      my $box = $opts{BOX};
-      my $yrange = defined($box) ? $$box[3] - $$box[2] : $y->max - $y->min;
-      my $del = $yrange ? $yrange * 0.05 : 1;
-      my @ybounds = ($y->min - $del, $y->max + $del);
-      my $ytick = ($yrange/$nytick);
-      my @COLORMAP  = (COLORMAP => $z)    if defined($z);
-      $self->xyplot($x, $y,
-		  COLOR     => $colors[$subpage],
-		  BOX       => defined($box) ? $box : [$xmin, $xmax, @ybounds],
-		  XBOX      => $xbox,
-		  YBOX      => 'BCNT',
-                  YTICK     => $ytick,
-                  MAJTICKSIZE => 0.6,
-		  CHARSIZE  => 0.4,
-                  @COLORMAP,
-		  VIEWPORT  => [
-				0.15,
-				0.9,
-                                $y_base             + ($subpage     * (0.8/$nplots)),
-                                $y_base - $y_gutter + (($subpage+1) * (0.8/$nplots)),
-				],
-		  );
-
-      $self->text($ylab,  TEXTPOSITION => ['L', 4, 0.5, 0.5], COLOR => 'BLACK', CHARSIZE => 0.6) if (defined($ylab));
-      $self->text($xlab,  TEXTPOSITION => ['B', 3, 0.5, 0.5], COLOR => 'BLACK', CHARSIZE => 0.6) if ($xlab && $bottomplot);
-      $self->text($title, TEXTPOSITION => ['T', 2, 0.5, 0.5], COLOR => 'BLACK', CHARSIZE => 1.3) if ($title && $topplot);
-
-    }
-
-}
-
-
-# Draw a color key or wedge showing the scale of map1 colors
-sub colorkey {
-  my $self = shift;
-  my $var  = shift;
-  my $orientation = shift; # 'v' (for vertical) or 'h' (for horizontal)
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(%opts);
-
-  # set up viewport, subpage, world coordinates
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # Allow user to set X, Y box type for color key scale.  D. Hunt 1/7/2009
-  my $xbox = exists($self->{XBOX}) ? $self->{XBOX} : 'TM';
-  my $ybox = exists($self->{YBOX}) ? $self->{YBOX} : 'TM';
-
-  my @box;
-
-  plcol0  (1); # set to frame color
-
-  my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $var->minmax;
-
-  # plot box
-  if      ($orientation eq 'v') {
-    # set world coordinates based on input variable
-    @box = (0, 1, $min, $max);
-    plwind (@box);
-    plbox (0, 0, 0, 0, '', $ybox);  # !!! note out of order call
-  } elsif ($orientation eq 'h') {
-    @box = ($min, $max, 0, 1);
-    plwind (@box);
-    plbox (0, 0, 0, 0, $xbox, '');  # !!! note out of order call
-  } else {
-    die "Illegal orientation value: $orientation.  Should be 'v' (vertical) or 'h' (horizontal)";
-  }
-
-  # restore color setting
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  # This is the number of colors shown in the color wedge.  Make
-  # this smaller for gif images as these are limited to 256 colors total.
-  # D. Hunt 8/9/2006
-  my $ncols = ($self->{DEV} =~ /gif/) ? 32 : 128;
-
-  if ($orientation eq 'v') {
-    my $yinc = ($box[3] - $box[2])/$ncols;
-    my $y0 = $box[2];
-    for (my $i=0;$i<$ncols;$i++) {
-      $y0 = $box[2] + ($i * $yinc);
-      my $y1 = $y0 + $yinc;
-      PDL::Graphics::PLplot::plcol1($i/$ncols);
-
-      # Instead of using plfill (which is not supported on some devices)
-      # use multiple calls to plline to color in the space. D. Hunt 8/9/2006
-      foreach my $inc (0..9) {
-        my $frac = $inc * 0.1;
-        my $y = $y0 + (($y1 - $y0) * $frac);
-        PDL::Graphics::PLplot::plline (PDL->new(0,1), PDL->new($y,$y));
-      }
-
-    }
-  } else {
-    my $xinc = ($box[1] - $box[0])/$ncols;
-    my $x0 = $box[0];
-    for (my $i=0;$i<$ncols;$i++) {
-      $x0 = $box[0] + ($i * $xinc);
-      my $x1 = $x0 + $xinc;
-      PDL::Graphics::PLplot::plcol1($i/$ncols);
-
-      # Instead of using plfill (which is not supported on some devices)
-      # use multiple calls to plline to color in the space. D. Hunt 8/9/2006
-      foreach my $inc (0..9) {
-        my $frac = $inc * 0.1;
-        my $x = $x0 + (($x1 - $x0) * $frac);
-        PDL::Graphics::PLplot::plline (PDL->new($x,$x), PDL->new(0,1));
-      }
-
-    }
-  }
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# handle shade plots of gridded (2D) data
-sub shadeplot {
-  my $self   = shift;
-  my $z      = shift;
-  my $nsteps = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($nx, $ny) = $z->dims;
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [0, $nx, 0, $ny];
-  }
-
-  # set up plotting box
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-  my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $z->minmax;
-  my $clevel = ((PDL->sequence($nsteps)*(($max - $min)/($nsteps-1))) + $min);
-
-  # may add as options later.  Now use constants
-  my $fill_width = 2;
-  my $cont_color = 0;
-  my $cont_width = 0;
-
-  my $rectangular = 1; # only false for non-linear coord mapping (not done yet in perl)
-
-  # map X coords linearly to X range, Y coords linearly to Y range
-  my $xmap = ((PDL->sequence($nx)*(($self->{BOX}[1] - $self->{BOX}[0])/($nx - 1))) + $self->{BOX}[0]);
-  my $ymap = ((PDL->sequence($ny)*(($self->{BOX}[3] - $self->{BOX}[2])/($ny - 1))) + $self->{BOX}[2]);
-
-  my $grid = plAllocGrid ($xmap, $ymap);
-
-  plshades($z, @{$self->{BOX}}, $clevel, $fill_width,
-           $cont_color, $cont_width, $rectangular,
-	   0, \&pltr1, $grid);
-
-  plFreeGrid ($grid);
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# handle histograms
-sub histogram {
-  my $self   = shift;
-  my $x      = shift;
-  my $nbins  = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($min, $max) = $x->minmax;
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [$min, $max, 0, $x->nelem]; # box probably too tall!
-  }
-
-  # set up plotting box
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-  # set line style for plot only (not box)
-  pllsty ($self->{LINESTYLE});
-
-  # set line width for plot only (not box)
-  plwid  ($self->{LINEWIDTH});
-
-  # set color for histograms
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  plhist ($x, $min, $max, $nbins, 1);  # '1' is oldbins parm:  dont call plenv!
-
-  # set line width back
-  plwid  (0);
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# Draw bar graphs
-sub bargraph {
-  my $self   = shift;
-  my $labels = shift; # ref to perl list of labels for bars
-  my $values = shift; # pdl of values for bars
-
-  my %opts = @_;
-
-  # max number of readable labels on x axis
-  my $maxlab = defined($opts{MAXBARLABELS}) ? $opts{MAXBARLABELS} : 20;
-  delete ($opts{MAXBARLABELS});
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-  my $xmax = scalar(@$labels);
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($ymin, $ymax) = $values->minmax;
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [0, $xmax, $ymin, $ymax]; # box probably too tall!
-  }
-
-  # set up plotting box
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 'bc', $self->{YBOX}); # !!! note out of order call
-
-  # Now respect TEXTPOSITION setting if TEXTMODE eq 'border'
-  # This allows the user to tweak the label placement.  D. Hunt 9/4/2007
-  my ($side, $disp, $foo, $just) = ('BV', 0.2, 0, 1.0);
-  if (defined($self->{TEXTMODE}) && $self->{TEXTMODE} eq 'border') {
-    ($side, $disp, $foo, $just) = @{$self->{TEXTPOSITION}};
-  }
-
-  # plot labels
-  plschr   (0, $self->{CHARSIZE} * 0.7); # use smaller characters
-  my $pos = 0;
-  my $skip   = int($xmax/$maxlab) + 1;
-  for (my $i=0;$i<$xmax;$i+=$skip) {
-    $pos = ((0.5+$i)/$xmax);
-    my $lab = $$labels[$i];
-    plmtex ($disp, $pos, $just, $side, $lab); # !!! out of order parms
-  }
-
-  plcol0  ($self->{CURRENT_COLOR_IDX}); # set back to line color
-
-  # set line style for plot only (not box)
-  pllsty ($self->{LINESTYLE});
-
-  # set line width for plot only (not box)
-  plwid  ($self->{LINEWIDTH});
-
-  # draw bars
-  if ($self->{UNFILLED_BARS}) {
-    plunfbox (PDL->sequence($xmax)+0.5, $values);
-  } else {
-    plfbox (PDL->sequence($xmax)+0.5, $values);
-  }
-
-  # set line width back
-  plwid  (0);
-
-  # set char size back
-  plschr (0, $self->{CHARSIZE});
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# Add text to a plot
-sub text {
-  my $self = shift;
-  my $text = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(@_);
-
-  # set the color according to the color specified in the object
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  # plot either relative to border, or inside view port
-  if      ($self->{TEXTMODE} eq 'border') {
-    my ($side, $disp, $pos, $just) = @{$self->{TEXTPOSITION}};
-    plmtex ($disp, $pos, $just, $side, $text); # !!! out of order parms
-  } elsif ($self->{TEXTMODE} eq 'plot') {
-    my ($x, $y, $dx, $dy, $just) = @{$self->{TEXTPOSITION}};
-    plptex ($x, $y, $dx, $dy, $just, $text);
-  }
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# Clear the current page. This should only be used with interactive devices!
-sub clear {
-  my $self = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  plclear();
-  return;
-}
-
-# Get mouse click coordinates (OO version). This should only be used with interactive devices!
-sub cursor {
-  my $self = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # Flush the stream, to make sure the plot is visible & current
-  plflush();
-
-  # Get the cursor position
-  my %gin = plGetCursor();
-
-  # Return an array with the coordinates of the mouse click
-  return ($gin{"wX"}, $gin{"wY"}, $gin{"pX"}, $gin{"pY"}, $gin{"dX"}, $gin{"dY"});
-}
-
-# Explicitly close a plot and free the object
-sub close {
-  my $self = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  plend1 ();
-
-  # Return this stream number to the pool.
-  push (@plplot_stream_pool, $self->{STREAMNUMBER});
-  delete $self->{STREAMNUMBER};
-
-  return;
-}
-
-
-
-
-
-
-=head1 FUNCTIONS
-
-
-
-=cut
-
-
-
-
-sub reorder {
-  my $name = shift;
-  my %reorder = (
-                 plaxes       => [0,1,6,2,3,7,4,5],
-		 plbox        => [4,0,1,5,2,3], # 4th arg -> 0th arg, 0th arg -> 1st arg, etc
-                 plbox3       => [6,7,0,1,8,9,2,3,10,11,4,5],
-                 plmtex       => [3,0,1,2,4],
-                 plmtex3      => [3,0,1,2,4],
-                 plstart      => [2,0,1],
-                 plstripc     => [13,14,0,1,2,3,4,5,6,7,8,9,10,11,12,15,16,17,18],
-                 plmap        => [4,5,0,1,2,3],
-                 plmeridians  => [6,0,1,2,3,4,5],
-                 plshades     => [0,10,1,2,3,4,5,6,7,8,9,11,12],
-                 plshade1     => [0,15,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17],
-		);
-  my $ordering = $reorder{$name};
-  die "Cannot find argument reordering for $name" if (!defined($ordering));
-  my @out;
-  for (my $i=0;$i<@_;$i++) {
-    $out[$$ordering[$i]] = $_[$i];
-  }
-  return @out;
-}
-
-# Routine for users to set normal plplot argument order
-sub plplot_use_standard_argument_order {
-  $PDL::Graphics::PLplot::standard_order = shift;
-}
-
-
-
-=pod
-
-The PDL low-level interface to the PLplot library closely mimics the C API.
-Users are referred to the PLplot User's Manual, distributed with the source
-PLplot tarball.  This manual is also available on-line at the PLplot web
-site (L<http://www.plplot.org/>).
-
-There are three differences in the way the functions are called.  The first
-one is due to a limitation in the pp_def wrapper of PDL, which forces all
-the non-piddle arguments to be at the end of the arguments list.  It is
-the case of strings (C<char *>) arguments in the C API.  This affects the
-following functions:
-
-plaxes
-plbox
-plbox3
-plmtex
-plmtex3
-plstart
-plstripc
-plmap
-plmeridians
-plshades
-plshade1
-
-This difference can be got around by a call to
-
-plplot_use_standard_argument_order(1);
-
-This re-arranges the string arguments to their proper/intuitive position
-compared with the C plplot interface.  This can be restored to it's default
-by calling:
-
-plplot_use_standard_argument_order(0);
-
-The second notable different between the C and the PDL APIs is that many of
-the PDL calls do not need arguments to specify the size of the the vectors
-and/or matrices being passed.  These size parameters are deduced from the
-size of the piddles, when possible and are just omitted from the C call
-when translating it to perl.
-
-The third difference has to do with output parameters.  In C these are
-passed in with the input parameters.  In the perl interface, they are omitted.
-For example:
-
-C:
-
-  pllegend(&p_legend_width, &p_legend_height,
-           opt, position, x, y, plot_width, bg_color, bb_color, bb_style, nrow, ncolumn, nlegend,
-           opt_array,
-           text_offset, text_scale, text_spacing, text_justification,
-           text_colors, (const char **)text, box_colors, box_patterns, box_scales, box_line_widths,
-           line_colors, line_styles, line_widths, symbol_colors, symbol_scales, symbol_numbers, (const char **)symbols);
-
-perl:
-
-  my ($legend_width, $legend_height) =
-    pllegend ($position, $opt, $x, $y, $plot_width, $bg_color, $nlegend,
-    \@opt_array,
-    $text_offset, $text_scale, $text_spacing, $test_justification,
-    \@text_colors, \@text, \@box_colors, \@box_patterns, \@box_scales, \@line_colors,
-    \@line_styles, \@line_widths, \@symbol_colors, \@symbol_scales, \@symbol_numbers, \@symbols);
-
-Some of the API functions implemented in PDL have other specificities in
-comparison with the C API and will be discussed below.
-
-=cut
-
-
-
-
-
-=head2 pladv
-
-=for sig
-
-  Signature: (int page())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pladv = \&PDL::pladv;
-
-
-
-
-
-=head2 plaxes_pp
-
-=for sig
-
-  Signature: (double xzero();double yzero();double xtick();int nxsub();double ytick();int nysub(); char *xopt;char *yopt)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plaxes_pp = \&PDL::plaxes_pp;
-
-
-
-
-
-=head2 plbin
-
-=for sig
-
-  Signature: (int nbin();double x(dima);double y(dima);int center())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plbin = \&PDL::plbin;
-
-
-
-sub plbox { plbox_pp ($standard_order ? reorder ("plbox", @_) : @_) }
-
-
-
-=head2 plbox_pp
-
-=for sig
-
-  Signature: (double xtick();int nxsub();double ytick();int nysub(); char *xopt;char *yopt)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plbox_pp = \&PDL::plbox_pp;
-
-
-
-sub plbox3 { plbox3_pp ($standard_order ? reorder ("plbox3", @_) : @_) }
-
-
-
-=head2 plbox3_pp
-
-=for sig
-
-  Signature: (double xtick();int nsubx();double ytick();int nsuby();double ztick();int nsubz(); char *xopt;char *xlabel;char *yopt;char *ylabel;char *zopt;char *zlabel)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plbox3_pp = \&PDL::plbox3_pp;
-
-
-
-
-
-=head2 plcol0
-
-=for sig
-
-  Signature: (int icolzero())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plcol0 = \&PDL::plcol0;
-
-
-
-
-
-=head2 plcol1
-
-=for sig
-
-  Signature: (double colone())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plcol1 = \&PDL::plcol1;
-
-
-
-
-
-=head2 plcpstrm
-
-=for sig
-
-  Signature: (int iplsr();int flags())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plcpstrm = \&PDL::plcpstrm;
-
-
-
-
-
-=head2 pldid2pc
-
-=for sig
-
-  Signature: (double xmin(dima);double ymin(dima);double xmax(dima);double ymax(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pldid2pc = \&PDL::pldid2pc;
-
-
-
-
-
-=head2 pldip2dc
-
-=for sig
-
-  Signature: (double xmin(dima);double ymin(dima);double xmax(dima);double ymax(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pldip2dc = \&PDL::pldip2dc;
-
-
-
-
-
-=head2 plenv
-
-=for sig
-
-  Signature: (double xmin();double xmax();double ymin();double ymax();int just();int axis())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plenv = \&PDL::plenv;
-
-
-
-
-
-=head2 plenv0
-
-=for sig
-
-  Signature: (double xmin();double xmax();double ymin();double ymax();int just();int axis())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plenv0 = \&PDL::plenv0;
-
-
-
-
-
-=head2 plerrx
-
-=for sig
-
-  Signature: (int n();double xmin(dima);double xmax(dima);double y(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plerrx = \&PDL::plerrx;
-
-
-
-
-
-=head2 plerry
-
-=for sig
-
-  Signature: (int n();double x(dima);double ymin(dima);double ymax(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plerry = \&PDL::plerry;
-
-
-
-
-
-=head2 plfill3
-
-=for sig
-
-  Signature: (int n();double x(dima);double y(dima);double z(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plfill3 = \&PDL::plfill3;
-
-
-
-
-
-=head2 plfont
-
-=for sig
-
-  Signature: (int ifont())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plfont = \&PDL::plfont;
-
-
-
-
-
-=head2 plfontld
-
-=for sig
-
-  Signature: (int fnt())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plfontld = \&PDL::plfontld;
-
-
-
-
-
-=head2 plgchr
-
-=for sig
-
-  Signature: (double [o]p_def();double [o]p_ht())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgchr = \&PDL::plgchr;
-
-
-
-
-
-=head2 plgcompression
-
-=for sig
-
-  Signature: (int [o]compression())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgcompression = \&PDL::plgcompression;
-
-
-
-
-
-=head2 plgdidev
-
-=for sig
-
-  Signature: (double [o]p_mar();double [o]p_aspect();double [o]p_jx();double [o]p_jy())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgdidev = \&PDL::plgdidev;
-
-
-
-
-
-=head2 plgdiori
-
-=for sig
-
-  Signature: (double [o]p_rot())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgdiori = \&PDL::plgdiori;
-
-
-
-
-
-=head2 plgdiplt
-
-=for sig
-
-  Signature: (double [o]p_xmin();double [o]p_ymin();double [o]p_xmax();double [o]p_ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgdiplt = \&PDL::plgdiplt;
-
-
-
-
-
-=head2 plgfam
-
-=for sig
-
-  Signature: (int [o]p_fam();int [o]p_num();int [o]p_bmax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgfam = \&PDL::plgfam;
-
-
-
-
-
-=head2 plglevel
-
-=for sig
-
-  Signature: (int [o]p_level())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plglevel = \&PDL::plglevel;
-
-
-
-
-
-=head2 plgpage
-
-=for sig
-
-  Signature: (double [o]p_xp();double [o]p_yp();int [o]p_xleng();int [o]p_yleng();int [o]p_xoff();int [o]p_yoff())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgpage = \&PDL::plgpage;
-
-
-
-
-
-=head2 plgspa
-
-=for sig
-
-  Signature: (double [o]xmin();double [o]xmax();double [o]ymin();double [o]ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgspa = \&PDL::plgspa;
-
-
-
-
-
-=head2 plgvpd
-
-=for sig
-
-  Signature: (double [o]p_xmin();double [o]p_xmax();double [o]p_ymin();double [o]p_ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgvpd = \&PDL::plgvpd;
-
-
-
-
-
-=head2 plgvpw
-
-=for sig
-
-  Signature: (double [o]p_xmin();double [o]p_xmax();double [o]p_ymin();double [o]p_ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgvpw = \&PDL::plgvpw;
-
-
-
-
-
-=head2 plgxax
-
-=for sig
-
-  Signature: (int [o]p_digmax();int [o]p_digits())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgxax = \&PDL::plgxax;
-
-
-
-
-
-=head2 plgyax
-
-=for sig
-
-  Signature: (int [o]p_digmax();int [o]p_digits())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgyax = \&PDL::plgyax;
-
-
-
-
-
-=head2 plgzax
-
-=for sig
-
-  Signature: (int [o]p_digmax();int [o]p_digits())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgzax = \&PDL::plgzax;
-
-
-
-
-
-=head2 pljoin
-
-=for sig
-
-  Signature: (double xone();double yone();double xtwo();double ytwo())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pljoin = \&PDL::pljoin;
-
-
-
-
-
-=head2 pllightsource
-
-=for sig
-
-  Signature: (double x();double y();double z())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pllightsource = \&PDL::pllightsource;
-
-
-
-
-
-=head2 pllsty
-
-=for sig
-
-  Signature: (int lin())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pllsty = \&PDL::pllsty;
-
-
-
-sub plmtex { plmtex_pp ($standard_order ? reorder ("plmtex", @_) : @_) }
-
-
-
-=head2 plmtex_pp
-
-=for sig
-
-  Signature: (double disp();double pos();double just(); char *side;char *text)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plmtex_pp = \&PDL::plmtex_pp;
-
-
-
-sub plmtex3 { plmtex3_pp ($standard_order ? reorder ("plmtex3", @_) : @_) }
-
-
-
-=head2 plmtex3_pp
-
-=for sig
-
-  Signature: (double disp();double pos();double just(); char *side;char *text)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plmtex3_pp = \&PDL::plmtex3_pp;
-
-
-
-
-
-=head2 plpat
-
-=for sig
-
-  Signature: (int nlin();int inc(dima);int del(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plpat = \&PDL::plpat;
-
-
-
-
-
-=head2 plprec
-
-=for sig
-
-  Signature: (int setp();int prec())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plprec = \&PDL::plprec;
-
-
-
-
-
-=head2 plpsty
-
-=for sig
-
-  Signature: (int patt())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plpsty = \&PDL::plpsty;
-
-
-
-
-
-=head2 plptex
-
-=for sig
-
-  Signature: (double x();double y();double dx();double dy();double just(); char *text)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plptex = \&PDL::plptex;
-
-
-
-
-
-=head2 plptex3
-
-=for sig
-
-  Signature: (double x();double y();double z();double dx();double dy();double dz();double sx();double sy();double sz();double just(); char *text)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plptex3 = \&PDL::plptex3;
-
-
-
-
-
-=head2 plschr
-
-=for sig
-
-  Signature: (double def();double scale())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plschr = \&PDL::plschr;
-
-
-
-
-
-=head2 plscmap0n
-
-=for sig
-
-  Signature: (int ncolzero())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap0n = \&PDL::plscmap0n;
-
-
-
-
-
-=head2 plscmap1n
-
-=for sig
-
-  Signature: (int ncolone())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap1n = \&PDL::plscmap1n;
-
-
-
-
-
-=head2 plscol0
-
-=for sig
-
-  Signature: (int icolzero();int r();int g();int b())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscol0 = \&PDL::plscol0;
-
-
-
-
-
-=head2 plscolbg
-
-=for sig
-
-  Signature: (int r();int g();int b())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscolbg = \&PDL::plscolbg;
-
-
-
-
-
-=head2 plscolor
-
-=for sig
-
-  Signature: (int color())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscolor = \&PDL::plscolor;
-
-
-
-
-
-=head2 plscompression
-
-=for sig
-
-  Signature: (int compression())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscompression = \&PDL::plscompression;
-
-
-
-
-
-=head2 plsdidev
-
-=for sig
-
-  Signature: (double mar();double aspect();double jx();double jy())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsdidev = \&PDL::plsdidev;
-
-
-
-
-
-=head2 plsdimap
-
-=for sig
-
-  Signature: (int dimxmin();int dimxmax();int dimymin();int dimymax();double dimxpmm();double dimypmm())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsdimap = \&PDL::plsdimap;
-
-
-
-
-
-=head2 plsdiori
-
-=for sig
-
-  Signature: (double rot())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsdiori = \&PDL::plsdiori;
-
-
-
-
-
-=head2 plsdiplt
-
-=for sig
-
-  Signature: (double xmin();double ymin();double xmax();double ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsdiplt = \&PDL::plsdiplt;
-
-
-
-
-
-=head2 plsdiplz
-
-=for sig
-
-  Signature: (double xmin();double ymin();double xmax();double ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsdiplz = \&PDL::plsdiplz;
-
-
-
-
-
-=head2 pl_setcontlabelparam
-
-=for sig
-
-  Signature: (double offset();double size();double spacing();int active())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pl_setcontlabelparam = \&PDL::pl_setcontlabelparam;
-
-
-
-
-
-=head2 pl_setcontlabelformat
-
-=for sig
-
-  Signature: (int lexp();int sigdig())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*pl_setcontlabelformat = \&PDL::pl_setcontlabelformat;
-
-
-
-
-
-=head2 plsfam
-
-=for sig
-
-  Signature: (int fam();int num();int bmax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsfam = \&PDL::plsfam;
-
-
-
-
-
-=head2 plsmaj
-
-=for sig
-
-  Signature: (double def();double scale())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsmaj = \&PDL::plsmaj;
-
-
-
-
-
-=head2 plsmin
-
-=for sig
-
-  Signature: (double def();double scale())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsmin = \&PDL::plsmin;
-
-
-
-
-
-=head2 plsori
-
-=for sig
-
-  Signature: (int ori())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsori = \&PDL::plsori;
-
-
-
-
-
-=head2 plspage
-
-=for sig
-
-  Signature: (double xp();double yp();int xleng();int yleng();int xoff();int yoff())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plspage = \&PDL::plspage;
-
-
-
-
-
-=head2 plspause
-
-=for sig
-
-  Signature: (int pause())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plspause = \&PDL::plspause;
-
-
-
-
-
-=head2 plsstrm
-
-=for sig
-
-  Signature: (int strm())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsstrm = \&PDL::plsstrm;
-
-
-
-
-
-=head2 plssub
-
-=for sig
-
-  Signature: (int nx();int ny())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plssub = \&PDL::plssub;
-
-
-
-
-
-=head2 plssym
-
-=for sig
-
-  Signature: (double def();double scale())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plssym = \&PDL::plssym;
-
-
-
-
-
-=head2 plstar
-
-=for sig
-
-  Signature: (int nx();int ny())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plstar = \&PDL::plstar;
-
-
-
-sub plstart { plstart_pp ($standard_order ? reorder ("plstart", @_) : @_) }
-
-
-
-=head2 plstart_pp
-
-=for sig
-
-  Signature: (int nx();int ny(); char *devname)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plstart_pp = \&PDL::plstart_pp;
-
-
-
-
-
-=head2 plstripa
-
-=for sig
-
-  Signature: (int id();int pen();double x();double y())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plstripa = \&PDL::plstripa;
-
-
-
-
-
-=head2 plstripd
-
-=for sig
-
-  Signature: (int id())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plstripd = \&PDL::plstripd;
-
-
-
-
-
-=head2 plsvpa
-
-=for sig
-
-  Signature: (double xmin();double xmax();double ymin();double ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsvpa = \&PDL::plsvpa;
-
-
-
-
-
-=head2 plsxax
-
-=for sig
-
-  Signature: (int digmax();int digits())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsxax = \&PDL::plsxax;
-
-
-
-
-
-=head2 plsxwin
-
-=for sig
-
-  Signature: (int window_id())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsxwin = \&PDL::plsxwin;
-
-
-
-
-
-=head2 plsyax
-
-=for sig
-
-  Signature: (int digmax();int digits())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsyax = \&PDL::plsyax;
-
-
-
-
-
-=head2 plszax
-
-=for sig
-
-  Signature: (int digmax();int digits())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plszax = \&PDL::plszax;
-
-
-
-
-
-=head2 plvasp
-
-=for sig
-
-  Signature: (double aspect())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plvasp = \&PDL::plvasp;
-
-
-
-
-
-=head2 plvpas
-
-=for sig
-
-  Signature: (double xmin();double xmax();double ymin();double ymax();double aspect())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plvpas = \&PDL::plvpas;
-
-
-
-
-
-=head2 plvpor
-
-=for sig
-
-  Signature: (double xmin();double xmax();double ymin();double ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plvpor = \&PDL::plvpor;
-
-
-
-
-
-=head2 plw3d
-
-=for sig
-
-  Signature: (double basex();double basey();double height();double xminzero();double xmaxzero();double yminzero();double ymaxzero();double zminzero();double zmaxzero();double alt();double az())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plw3d = \&PDL::plw3d;
-
-
-
-
-
-=head2 plwid
-
-=for sig
-
-  Signature: (int width())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plwid = \&PDL::plwid;
-
-
-
-
-
-=head2 plwind
-
-=for sig
-
-  Signature: (double xmin();double xmax();double ymin();double ymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plwind = \&PDL::plwind;
-
-
-
-
-
-=head2 plP_gpixmm
-
-=for sig
-
-  Signature: (double p_x(dima);double p_y(dima))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plP_gpixmm = \&PDL::plP_gpixmm;
-
-
-
-
-
-=head2 plscolbga
-
-=for sig
-
-  Signature: (int r();int g();int b();double a())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscolbga = \&PDL::plscolbga;
-
-
-
-
-
-=head2 plscol0a
-
-=for sig
-
-  Signature: (int icolzero();int r();int g();int b();double a())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscol0a = \&PDL::plscol0a;
-
-
-
-
-
-=head2 plline
-
-=for sig
-
-  Signature: (x(n); y(n))
-
-=for ref
-
-Draws line segments along (x1,y1)->(x2,y2)->(x3,y3)->...
-
-=for bad
-
-If the nth value of either x or y are bad, then it will be skipped, breaking
-the line.  In this way, you can specify multiple line segments with a single
-pair of x and y piddles.
-
-The usage is straight-forward:
-
-=for usage
-
- plline($x, $y);
-
-For example:
-
-=for example
-
- # Draw a sine wave
- $x = sequence(100)/10;
- $y = sin($x);
-
- # Draws the sine wave:
- plline($x, $y);
-
- # Set values above 3/4 to 'bad', effectively drawing a bunch of detached,
- # capped waves
- $y->setbadif($y > 3/4);
- plline($x, $y);
-
-
-
-
-
-=cut
-
-
-
-
-
-
-*plline = \&PDL::plline;
-
-
-
-
-
-=head2 plcolorpoints
-
-=for sig
-
-  Signature: (x(n); y(n); z(n); int sym(); minz(); maxz())
-
-=for ref
-
-PDL-specific: Implements what amounts to a threaded version of plsym.
-
-=for bad
-
-Bad values for z are simply skipped; all other bad values are not processed.
-
-In the following usage, all of the piddles must have the same dimensions:
-
-=for usage
-
- plcolorpoints($x, $y, $z, $symbol_index, $minz, $maxz)
-
-For example:
-
-=for example
-
- # Generate a parabola some points
- my $x = sequence(30) / 3;   # Regular sampling
- my $y = $x**2;              # Parabolic y
- my $z = 30 - $x**3;         # Cubic coloration
- my $symbols = floor($x);    # Use different symbols for each 1/3 of the plot
-                             #  These should be integers.
-
- plcolorpoints($x, $y, $z, $symbols, -5, 20);  # Thread over everything
- plcolorpoints($x, $y, 1, 1, -1, 2);           # same color and symbol for all
-
-
-
-
-
-=cut
-
-
-
-
-
-
-*plcolorpoints = \&PDL::plcolorpoints;
-
-
-
-
-
-=head2 plfbox
-
-=for sig
-
-  Signature: (xo(); yo())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plfbox = \&PDL::plfbox;
-
-
-
-
-
-=head2 plunfbox
-
-=for sig
-
-  Signature: (xo(); yo())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plunfbox = \&PDL::plunfbox;
-
-
-
-
-
-=head2 plParseOpts
-
-=for sig
-
-  Signature: (int [o] retval(); SV* argv; int mode)
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plParseOpts = \&PDL::plParseOpts;
-
-
-
-
-
-=head2 plpoin
-
-=for sig
-
-  Signature: (x(n); y(n); int code())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plpoin = \&PDL::plpoin;
-
-
-
-
-
-=head2 plpoin3
-
-=for sig
-
-  Signature: (x(n); y(n); z(n); int code())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plpoin3 = \&PDL::plpoin3;
-
-
-
-
-
-=head2 plline3
-
-=for sig
-
-  Signature: (x(n); y(n); z(n))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plline3 = \&PDL::plline3;
-
-
-
-
-
-=head2 plpoly3
-
-=for sig
-
-  Signature: (x(n); y(n); z(n); int draw(m); int ifcc())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plpoly3 = \&PDL::plpoly3;
-
-
-
-
-
-=head2 plhist
-
-=for sig
-
-  Signature: (data(n); datmin(); datmax(); int nbin(); int oldwin())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plhist = \&PDL::plhist;
-
-
-
-
-
-=head2 plfill
-
-=for sig
-
-  Signature: (x(n); y(n))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plfill = \&PDL::plfill;
-
-
-
-
-
-=head2 plsym
-
-=for sig
-
-  Signature: (x(n); y(n); int code())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsym = \&PDL::plsym;
-
-
-
-
-
-=head2 plsurf3d
-
-=for sig
-
-  Signature: (x(nx); y(ny); z(nx,ny); int opt(); clevel(nlevel))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plsurf3d = \&PDL::plsurf3d;
-
-
-
-
-
-=head2 plstyl
-
-=for sig
-
-  Signature: (int mark(nms); int space(nms))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plstyl = \&PDL::plstyl;
-
-
-
-
-
-=head2 plAllocGrid
-
-=for sig
-
-  Signature: (double xg(nx); double yg(ny); longlong [o] grid())
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plAllocGrid = \&PDL::plAllocGrid;
-
-
-
-
-
-=head2 plAlloc2dGrid
-
-=for sig
-
-  Signature: (double xg(nx,ny); double yg(nx,ny); longlong [o] grid())
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plAlloc2dGrid = \&PDL::plAlloc2dGrid;
-
-
-
-
-
-=head2 init_pltr
-
-=for sig
-
-  Signature: (P(); C(); SV* p0; SV* p1; SV* p2)
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*init_pltr = \&PDL::init_pltr;
-
-
-
-init_pltr (\&pltr0, \&pltr1, \&pltr2);
-
-
-sub plmap { plmap_pp ($standard_order ? reorder ("plmap", @_) : @_) }
-
-
-
-=head2 plmap_pp
-
-=for sig
-
-  Signature: (minlong(); maxlong(); minlat(); maxlat(); SV* mapform; char* type)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plmap_pp = \&PDL::plmap_pp;
-
-
-
-sub plmeridians { plmeridians_pp ($standard_order ? reorder ("plmeridians", @_) : @_) }
-
-
-
-=head2 plmeridians_pp
-
-=for sig
-
-  Signature: (dlong(); dlat(); minlong(); maxlong(); minlat(); maxlat(); SV* mapform)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plmeridians_pp = \&PDL::plmeridians_pp;
-
-
-
-sub plshades { plshades_pp ($standard_order ? reorder ("plshades", @_) : @_) }
-
-
-
-=head2 plshades_pp
-
-=for sig
-
-  Signature: (z(x,y); xmin(); xmax(); ymin(); ymax();
-                  clevel(l); int fill_width(); int cont_color();
-                  int cont_width(); int rectangular(); SV* defined; SV* pltr; SV* pltr_data)
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plshades_pp = \&PDL::plshades_pp;
-
-
-
-
-
-=head2 plcont
-
-=for sig
-
-  Signature: (f(nx,ny); int kx(); int lx(); int ky(); int ly(); clevel(nlevel); SV* pltr; SV* pltr_data)
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plcont = \&PDL::plcont;
-
-
-
-
-
-=head2 plmesh
-
-=for sig
-
-  Signature: (x(nx); y(ny); z(nx,ny); int opt())
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plmesh = \&PDL::plmesh;
-
-
-
-
-
-=head2 plmeshc
-
-=for sig
-
-  Signature: (x(nx); y(ny); z(nx,ny); int opt(); clevel(nlevel))
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plmeshc = \&PDL::plmeshc;
-
-
-
-
-
-=head2 plot3d
-
-=for sig
-
-  Signature: (x(nx); y(ny); z(nx,ny); int opt(); int side())
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plot3d = \&PDL::plot3d;
-
-
-
-
-
-=head2 plot3dc
-
-=for sig
-
-  Signature: (x(nx); y(ny); z(nx,ny); int opt(); clevel(nlevel))
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plot3dc = \&PDL::plot3dc;
-
-
-
-
-
-=head2 plscmap1l
-
-=for sig
-
-  Signature: (int itype(); isty(n); coord1(n); coord2(n); coord3(n); int rev(nrev))
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap1l = \&PDL::plscmap1l;
-
-
-
-sub plshade1 { plshade1_pp ($standard_order ? reorder ("plshade1", @_) : @_) }
-
-
-
-=head2 plshade1_pp
-
-=for sig
-
-  Signature: (a(nx,ny); left(); right(); bottom(); top(); shade_min();shade_max(); sh_cmap(); sh_color(); sh_width();min_color(); min_width(); max_color(); max_width();rectangular(); SV* defined; SV* pltr; SV* pltr_data)
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plshade1_pp = \&PDL::plshade1_pp;
-
-
-
-
-
-=head2 plimage
-
-=for sig
-
-  Signature: (idata(nx,ny); xmin(); xmax(); ymin(); ymax();zmin(); zmax(); Dxmin(); Dxmax(); Dymin(); Dymax())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plimage = \&PDL::plimage;
-
-
-
-=head2 plxormod
-
-=for sig
-
-  $status = plxormod ($mode)
-
-=for ref
-
-See the PLplot manual for reference.
-
-=cut
-
-
-=head2 plGetCursor
-
-=for sig
-
-  %gin = plGetCursor ()
-
-=for ref
-
-plGetCursor waits for graphics input event and translate to world
-coordinates and returns a hash with the following keys:
-
-    type:      of event (CURRENTLY UNUSED)
-    state:     key or button mask
-    keysym:    key selected
-    button:    mouse button selected
-    subwindow: subwindow (alias subpage, alias subplot) number
-    string:    translated string
-    pX, pY:    absolute device coordinates of pointer
-    dX, dY:    relative device coordinates of pointer
-    wX, wY:    world coordinates of pointer
-
-Returns an empty hash if no translation to world coordinates is possible.
-
-=cut
-
-
-=head2 plgstrm
-
-=for sig
-
-  $strm = plgstrm ()
-
-=for ref
-
-Returns the number of the current output stream.
-
-=cut
-
-
-=head2 plgsdev
-
-=for sig
-
-  $driver = plgdev ()
-
-=for ref
-
-Returns the current driver name.
-
-=cut
-
-
-=head2 plmkstrm
-
-=for sig
-
-  $strm = plmkstrm ()
-
-=for ref
-
-Creates a new stream and makes it the default.  Returns the number of
-the created stream.
-
-=cut
-
-
-=head2 plgver
-
-=for sig
-
-  $version = plgver ()
-
-=for ref
-
-See the PLplot manual for reference.
-
-=cut
-
-
-sub plstripc { plstripc_pp ($standard_order ? reorder ("plstripc", @_) : @_) }
-
-
-
-=head2 plstripc_pp
-
-=for sig
-
-  Signature: (xmin(); xmax(); xjump(); ymin(); ymax();xlpos(); ylpos(); int y_ascl(); int acc();int colbox(); int collab();int colline(n); int styline(n);  int [o] id(); char* xspec; char* yspec; SV* legline;char* labx; char* laby; char* labtop)
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plstripc_pp = \&PDL::plstripc_pp;
-
-
-
-
-
-=head2 plgriddata
-
-=for sig
-
-  Signature: (x(npts); y(npts); z(npts); xg(nptsx); yg(nptsy);int type(); data(); [o] zg(nptsx,nptsy))
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plgriddata = \&PDL::plgriddata;
-
-
-
-=head2 plbtime
-
-=for sig
-
-  my ($year, $month, $day, $hour, $min, $sec) = plbtime($ctime);
-
-=for ref
-
-  Calculate broken-down time from continuous time for current stream.
-
-=cut
-
-
-=head2 plconfigtime
-
-=for sig
-
-  plconfigtime($scale, $offset1, $offset2, $ccontrol, $ifbtime_offset, $year, $month, $day, $hour, $min, $sec);
-
-=for ref
-
-Configure transformation between continuous and broken-down time (and
-vice versa) for current stream.
-
-=cut
-
-
-=head2 plctime
-
-=for sig
-
-  my $ctime = plctime($year, $month, $day, $hour, $min, $sec);
-
-=for ref
-
-  Calculate continuous time from broken-down time for current stream.
-
-=cut
-
-
-=head2 pltimefmt
-
-=for sig
-
-  pltimefmt($fmt);
-
-=for ref
-
-Set format for date / time labels.  See the PLplot manual for more details.
-
-=cut
-
-
-=head2 plsesc
-
-=for sig
-
-  plsesc($esc);
-
-=for ref
-
-
-Set the escape character for text strings.  See the PLplot manual for more details.
-
-=cut
-
-
-
-
-=head2 plhlsrgb
-
-=for sig
-
-  Signature: (double h();double l();double s();double [o]p_r();double [o]p_g();double [o]p_b())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plhlsrgb = \&PDL::plhlsrgb;
-
-
-
-
-
-=head2 plgcol0
-
-=for sig
-
-  Signature: (int icolzero(); int [o]r(); int [o]g(); int [o]b())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgcol0 = \&PDL::plgcol0;
-
-
-
-
-
-=head2 plgcolbg
-
-=for sig
-
-  Signature: (int [o]r(); int [o]g(); int [o]b())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgcolbg = \&PDL::plgcolbg;
-
-
-
-
-
-=head2 plscmap0
-
-=for sig
-
-  Signature: (int r(n); int g(n); int b(n))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap0 = \&PDL::plscmap0;
-
-
-
-
-
-=head2 plscmap1
-
-=for sig
-
-  Signature: (int r(n); int g(n); int b(n))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap1 = \&PDL::plscmap1;
-
-
-
-
-
-=head2 plgcol0a
-
-=for sig
-
-  Signature: (int icolzero(); int [o]r(); int [o]g(); int [o]b(); double [o]a())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgcol0a = \&PDL::plgcol0a;
-
-
-
-
-
-=head2 plgcolbga
-
-=for sig
-
-  Signature: (int [o]r(); int [o]g(); int [o]b(); double [o]a())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plgcolbga = \&PDL::plgcolbga;
-
-
-
-
-
-=head2 plscmap0a
-
-=for sig
-
-  Signature: (int r(n); int g(n); int b(n); double a(n))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap0a = \&PDL::plscmap0a;
-
-
-
-
-
-=head2 plscmap1a
-
-=for sig
-
-  Signature: (int r(n); int g(n); int b(n); double a(n))
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap1a = \&PDL::plscmap1a;
-
-
-
-
-
-=head2 plscmap1la
-
-=for sig
-
-  Signature: (int itype(); isty(n); coord1(n); coord2(n); coord3(n); coord4(n); int rev(nrev))
-
-=for ref
-
-FIXME: documentation here!
-
-
-
-=cut
-
-
-
-
-
-
-*plscmap1la = \&PDL::plscmap1la;
-
-
-
-
-
-=head2 plcalc_world
-
-=for sig
-
-  Signature: (double rx(); double ry(); double [o]wx(); double [o]wy(); int [o]window())
-
-
-=for ref
-
-info not available
-
-
-
-
-=cut
-
-
-
-
-
-
-*plcalc_world = \&PDL::plcalc_world;
-
-
-
-
-=pod
-
-=head1 WARNINGS AND ERRORS
-
-PLplot gives many errors and warnings.  Some of these are given by the
-PDL interface while others are internal PLplot messages.  Below are
-some of these messages, and what you need to do to address them:
-
-=over
-
-=item *
-Box must be a ref to a four element array
-
-When specifying a box, you must pass a reference to a
-four-element array, or use an anonymous four-element array.
-
- # Gives trouble:
- $pl->xyplot($x, $y, BOX => (0, 0, 100, 200) );
- # What you meant to say was:
- $pl->xyplot($x, $y, BOX => [0, 0, 100, 200] );
-
-=item *
-Too many colors used! (max 15)
-
-
-=back
-
-=head1 AUTHORS
-
-  Doug Hunt <dhunt@ucar.edu>
-  Rafael Laboissiere <rlaboiss@users.sourceforge.net>
-  David Mertens <mertens2@illinois.edu>
-
-=head1 SEE ALSO
-
-perl(1), PDL(1), L<http://www.plplot.org/>
-
-The other common graphics packages include L<PDL::PGPLOT>
-and L<PDL::TriD>.
-
-=cut
-
-
-
-;
-
-
-
-# Exit with OK status
-
-1;
-
-		   
\ No newline at end of file
@@ -63,6 +63,10 @@ of which is 3. This routine does dataflow automatically.
 
 
 
+=for bad
+
+combcoords does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -105,6 +109,10 @@ For definition of the potential, see the actual function.
 
 
 
+=for bad
+
+repulse does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -147,6 +155,10 @@ For definition of the potential, see the actual function.
 
 
 
+=for bad
+
+attract does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -174,6 +186,10 @@ For definition of the potential, see the actual function.
 info not available
 
 
+=for bad
+
+vrmlcoordsvert does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -77,6 +77,10 @@ around a PDL array using the cursor keys.
 
 
 
+=for bad
+
+browse does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -92,6 +92,10 @@ Writes a 2-d PDL varable out to a PNG file, using the supplied color look-up-tab
 The LUT contains a line for each value 0-255 with a corresponding R, G, and B value.
 
 
+=for bad
+
+write_png does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -118,6 +122,10 @@ The LUT contains a line for each value 0-255 with a corresponding R, G, and B va
 Same as write_png(), except you can specify the compression level (0-9) as the last arguement.
 
 
+=for bad
+
+write_png_ex does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -144,6 +152,10 @@ Writes an (x, y, z(3)) PDL varable out to a PNG file, using a true color format.
 This means a larger file on disk, but can contain more than 256 colors.
 
 
+=for bad
+
+write_true_png does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -170,6 +182,10 @@ This means a larger file on disk, but can contain more than 256 colors.
 Same as write_true_png(), except you can specify the compression level (0-9) as the last arguement.
 
 
+=for bad
+
+write_true_png_ex does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -75,6 +75,10 @@ use strict;
 
 Swaps pairs of bytes in argument x()
 
+=for bad
+
+bswap2 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -100,6 +104,10 @@ Swaps pairs of bytes in argument x()
 
 Swaps quads of bytes in argument x()
 
+=for bad
+
+bswap4 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -125,6 +133,10 @@ Swaps quads of bytes in argument x()
 
 Swaps octets of bytes in argument x()
 
+=for bad
+
+bswap8 does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -121,6 +121,10 @@ C<im> follows I<strictly> the type of C<type>).
 
 
 
+=for bad
+
+pnminraw does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -150,6 +154,10 @@ Read in an ascii pnm file.
 
 
 
+=for bad
+
+pnminascii does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -181,6 +189,10 @@ naturally.
 
 
 
+=for bad
+
+pnmout does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -110,7 +110,9 @@ will be quicker.
 
 
 
+=for bad
 
+Unlike the FFT routines, conv2d is able to process bad values.
 
 =cut
 
@@ -175,7 +177,10 @@ is rather pointless)
 
 
 
+=for bad
 
+Bad values are ignored in the calculation. If all elements within the
+kernel are bad, the output is set bad.
 
 =cut
 
@@ -242,6 +247,10 @@ Note: this routine does the median over all points in a rectangular
 
 
 
+=for bad
+
+med2df does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -303,6 +312,10 @@ approximately linearly with window size.
 
 
 
+=for bad
+
+box2d does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -340,7 +353,9 @@ copied across.
 
 
 
+=for bad
 
+This routine does not handle bad values - use L<patchbad2d|/patchbad2d> instead
 
 =cut
 
@@ -377,7 +392,10 @@ is performed (see L<patch2d|/patch2d>).
 
 
 
+=for bad
 
+patchbad2d handles bad values. The output piddle I<may> contain
+bad values, depending on the pattern of bad values in the input piddle.
 
 =cut
 
@@ -407,6 +425,11 @@ Contributed by Tim Jeness
 
 
 
+=for bad
+
+Bad values are excluded from the search. If all pixels
+are bad then the output is set bad.
+
 
 
 =cut
@@ -438,6 +461,12 @@ is C<+/- $box/2>.
 
 
 
+=for bad
+
+Bad pixels are excluded from the centroid calculation. If all elements are
+bad (or the pixel sum is 0 - but why would you be centroiding
+something with negatives in...) then the output values are set bad.
+
 
 
 =cut
@@ -526,6 +555,10 @@ where the second parameter specifies the connectivity (4 or 8) of the labeling.
 
 
 
+=for bad
+
+ccNcompt ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -766,6 +799,10 @@ rot2d is faster.
 
 
 
+=for bad
+
+rot2d ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -796,6 +833,10 @@ piddle which is supposed to be larger than the first one.
 
 
 
+=for bad
+
+bilin2d ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -831,6 +872,10 @@ rescale2d.
 
 
 
+=for bad
+
+rescale2d ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -93,6 +93,10 @@ it runs faster and handles a variety of boundary conditions.
 
 
 
+=for bad
+
+convolve does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -206,6 +210,10 @@ instead.  PDL::Transform::map runs slower but is more flexible.
 
 
 
+=for bad
+
+rebin does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -494,6 +502,10 @@ its own threadloops.
 
 
 
+=for bad
+
+convolveND does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -77,6 +77,10 @@ BEGIN {use PDL::MatrixOps;}
 
 The usual trigonometric function. Works inplace.
 
+=for bad
+
+acos processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -102,6 +106,10 @@ The usual trigonometric function. Works inplace.
 
 The usual trigonometric function. Works inplace.
 
+=for bad
+
+asin processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -127,6 +135,10 @@ The usual trigonometric function. Works inplace.
 
 The usual trigonometric function. Works inplace.
 
+=for bad
+
+atan processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -152,6 +164,10 @@ The usual trigonometric function. Works inplace.
 
 The standard hyperbolic function. Works inplace.
 
+=for bad
+
+cosh processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -177,6 +193,10 @@ The standard hyperbolic function. Works inplace.
 
 The standard hyperbolic function. Works inplace.
 
+=for bad
+
+sinh processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -202,6 +222,10 @@ The standard hyperbolic function. Works inplace.
 
 The usual trigonometric function. Works inplace.
 
+=for bad
+
+tan processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -227,6 +251,10 @@ The usual trigonometric function. Works inplace.
 
 The standard hyperbolic function. Works inplace.
 
+=for bad
+
+tanh processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -252,6 +280,10 @@ The standard hyperbolic function. Works inplace.
 
 Round to integer values in floating-point format. Works inplace.
 
+=for bad
+
+ceil processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -277,6 +309,10 @@ Round to integer values in floating-point format. Works inplace.
 
 Round to integer values in floating-point format. Works inplace.
 
+=for bad
+
+floor processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -313,6 +349,10 @@ If you are looking to round half-integers up (regardless of sign), try
 C<floor($x+0.5)>.  If you want to round half-integers away from zero,
 try C<< floor(abs($x)+0.5)*($x<=>0) >>. Works inplace.
 
+=for bad
+
+rint processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -338,6 +378,10 @@ try C<< floor(abs($x)+0.5)*($x<=>0) >>. Works inplace.
 
 Synonym for `**'. Works inplace.
 
+=for bad
+
+pow processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -363,6 +407,10 @@ Synonym for `**'. Works inplace.
 
 The standard hyperbolic function. Works inplace.
 
+=for bad
+
+acosh processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -388,6 +436,10 @@ The standard hyperbolic function. Works inplace.
 
 The standard hyperbolic function. Works inplace.
 
+=for bad
+
+asinh processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -413,6 +465,10 @@ The standard hyperbolic function. Works inplace.
 
 The standard hyperbolic function. Works inplace.
 
+=for bad
+
+atanh processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -438,6 +494,10 @@ The standard hyperbolic function. Works inplace.
 
 The error function. Works inplace.
 
+=for bad
+
+erf processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -463,6 +523,10 @@ The error function. Works inplace.
 
 The complement of the error function. Works inplace.
 
+=for bad
+
+erfc processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -488,6 +552,10 @@ The complement of the error function. Works inplace.
 
 The regular Bessel function of the first kind, J_n Works inplace.
 
+=for bad
+
+bessj0 processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -513,6 +581,10 @@ The regular Bessel function of the first kind, J_n Works inplace.
 
 The regular Bessel function of the first kind, J_n Works inplace.
 
+=for bad
+
+bessj1 processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -538,6 +610,10 @@ The regular Bessel function of the first kind, J_n Works inplace.
 
 The regular Bessel function of the second kind, Y_n. Works inplace.
 
+=for bad
+
+bessy0 processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -563,6 +639,10 @@ The regular Bessel function of the second kind, Y_n. Works inplace.
 
 The regular Bessel function of the second kind, Y_n. Works inplace.
 
+=for bad
+
+bessy1 processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -592,6 +672,10 @@ This takes a second int argument which gives the order
 of the function required.
  Works inplace.
 
+=for bad
+
+bessjn processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -621,6 +705,10 @@ This takes a second int argument which gives the order
 of the function required.
  Works inplace.
 
+=for bad
+
+bessyn processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -653,6 +741,10 @@ things.
 
 
 
+=for bad
+
+lgamma processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -685,7 +777,9 @@ badmask can be run with C<$a> inplace:
 
 
 
+=for bad
 
+If bad values are present, these are also cleared.
 
 =cut
 
@@ -710,7 +804,9 @@ badmask can be run with C<$a> inplace:
 
 Sets C<$mask> true if C<$a> is not a C<NaN> or C<inf> (either positive or negative). Works inplace.
 
+=for bad
 
+Bad values are treated as C<NaN> or C<inf>.
 
 =cut
 
@@ -735,6 +831,10 @@ Sets C<$mask> true if C<$a> is not a C<NaN> or C<inf> (either positive or negati
 
 The inverse of the error function. Works inplace.
 
+=for bad
+
+erfi processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -762,6 +862,10 @@ The value for which the area under the
 Gaussian probability density function (integrated from
 minus infinity) is equal to the argument (cf L<erfi|/erfi>). Works inplace.
 
+=for bad
+
+ndtri processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -796,6 +900,10 @@ of decreasing powers.
 
 
 
+=for bad
+
+polyroots does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -483,6 +483,10 @@ runs across their components.
 
 
 
+=for bad
+
+eigens_sym ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -596,6 +600,10 @@ numbers.  It might be useful to be able to return complex eigenvalues.
 
 
 
+=for bad
+
+eigens ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -698,6 +706,10 @@ orientation of the ellipsoid of transformation:
 
 
 
+=for bad
+
+svd ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1237,6 +1249,10 @@ less opaque interface.
 
 
 
+=for bad
+
+simq ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1265,6 +1281,10 @@ Convert a symmetric square matrix to triangular vector storage.
 
 
 
+=for bad
+
+squaretotri does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -118,6 +118,10 @@ sub mn_init{
 info not available
 
 
+=for bad
+
+mninit does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -145,6 +149,10 @@ info not available
 info not available
 
 
+=for bad
+
+mn_abre does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -172,6 +180,10 @@ info not available
 info not available
 
 
+=for bad
+
+mn_cierra does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -248,6 +260,10 @@ sub mn_def_pars{
 info not available
 
 
+=for bad
+
+mnparm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -305,6 +321,10 @@ sub mn_excm{
 info not available
 
 
+=for bad
+
+mnexcm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -359,6 +379,10 @@ info not available
 info not available
 
 
+=for bad
+
+mnpout does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -403,6 +427,10 @@ info not available
 info not available
 
 
+=for bad
+
+mnstat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -452,6 +480,10 @@ info not available
 info not available
 
 
+=for bad
+
+mnemat does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -502,6 +534,10 @@ info not available
 info not available
 
 
+=for bad
+
+mnerrs does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -557,6 +593,10 @@ info not available
 info not available
 
 
+=for bad
+
+mncont does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -85,6 +85,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+plus processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -124,6 +128,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+mult processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -163,6 +171,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+minus processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -202,6 +214,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+divide processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -241,6 +257,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+gt processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -280,6 +300,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+lt processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -319,6 +343,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+le processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -358,6 +386,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+ge processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -397,6 +429,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+eq processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -436,6 +472,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+ne processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -475,6 +515,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+shiftleft processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -514,6 +558,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+shiftright processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -553,6 +601,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+or2 processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -592,6 +644,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+and2 processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -631,6 +687,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+xor processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -666,6 +726,10 @@ This function is used to overload the unary C<~> operator/function.
 
 
 
+=for bad
+
+bitnot processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -705,6 +769,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+power processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -744,6 +812,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+atan2 processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -783,6 +855,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+modulo processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -822,6 +898,10 @@ This restriction is expected to go away in future releases.
 
 
 
+=for bad
+
+spaceship processes bad values.
+The state of the bad-value flag of the output piddles is unknown.
 
 
 =cut
@@ -857,6 +937,10 @@ This function is used to overload the unary C<sqrt> operator/function.
 
 
 
+=for bad
+
+sqrt processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -892,6 +976,10 @@ This function is used to overload the unary C<abs> operator/function.
 
 
 
+=for bad
+
+abs processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -927,6 +1015,10 @@ This function is used to overload the unary C<sin> operator/function.
 
 
 
+=for bad
+
+sin processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -962,6 +1054,10 @@ This function is used to overload the unary C<cos> operator/function.
 
 
 
+=for bad
+
+cos processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -997,6 +1093,10 @@ This function is used to overload the unary C<!> operator/function.
 
 
 
+=for bad
+
+not processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1032,6 +1132,10 @@ This function is used to overload the unary C<exp> operator/function.
 
 
 
+=for bad
+
+exp processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1067,6 +1171,10 @@ This function is used to overload the unary C<log> operator/function.
 
 
 
+=for bad
+
+log processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1102,6 +1210,10 @@ This function is used to overload the unary C<log10> operator/function.
 
 
 
+=for bad
+
+log10 processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1144,6 +1256,10 @@ sub PDL::log10 {
 
 Plain numerical assignment. This is used to implement the ".=" operator
 
+=for bad
+
+assgn does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -80,6 +80,14 @@ Inner product over one dimension
 
 
 
+=for bad
+
+=for bad
+
+If C<a() * b()> contains only bad data,
+C<c()> is set bad. Otherwise C<c()> will have its bad flag cleared,
+as it will not contain any bad values.
+
 
 
 =cut
@@ -113,6 +121,10 @@ operator but this function is provided for convenience.
 
 
 
+=for bad
+
+outer processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -228,6 +240,10 @@ For usage, see L<x|/x>, a description of the overloaded 'x' operator
 
 
 
+=for bad
+
+matmult ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -276,6 +292,10 @@ Weighted (i.e. triple) inner product
 
 
 
+=for bad
+
+innerwt processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -310,6 +330,10 @@ very wasteful. Instead, you should use a temporary for C<b*c>.
 
 
 
+=for bad
+
+inner2 processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -343,6 +367,10 @@ Equivalent to
 
 
 
+=for bad
+
+inner2d processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -384,6 +412,10 @@ closures at some point.
 
 
 
+=for bad
+
+inner2t processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -421,6 +453,10 @@ orthogonal to C<$a> and C<$b>
 
 
 
+=for bad
+
+crossp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -446,6 +482,10 @@ orthogonal to C<$a> and C<$b>
 
 Normalises a vector to unit Euclidean length
 
+=for bad
+
+norm processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -499,6 +539,12 @@ Threaded Example:
 
 
 
+=for bad
+
+=for bad
+
+The routine barfs if any of the indices are bad.
+
 
 
 =cut
@@ -574,6 +620,10 @@ unless special care is taken.
 
 
 
+=for bad
+
+conv1d ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -631,6 +681,10 @@ and is generally faster.
 
 
 
+=for bad
+
+in does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -675,6 +729,20 @@ elements rather than the values.
 
 
 
+=for bad
+
+Bad values are not considered unique by uniq and are ignored.
+
+ $a=sequence(10);
+ $a=$a->setbadif($a%3);
+ print $a->uniq;
+ [0 3 6 9]
+
+=cut
+
+
+
+
 *uniq = \&PDL::uniq;
 # return unique elements of array
 # find as jumps in the sorted array
@@ -729,6 +797,15 @@ indices.
 
 
 
+=for bad
+
+Bad values are not considered unique by uniqind and are ignored.
+
+=cut
+
+
+
+
 *uniqind = \&PDL::uniqind;
 # return unique elements of array
 # find as jumps in the sorted array
@@ -793,6 +870,20 @@ lexicographcally.
 
 
 
+=for bad
+
+If a vector contains all bad values, it is ignored as in L<uniq|uniq>.
+If some of the values are good, it is treated as a normal vector. For
+example, [1 2 BAD] and [BAD 2 3] could be returned, but [BAD BAD BAD] 
+could not.  Vectors containing BAD values will be returned after any
+non-NaN and non-BAD containing vectors, followed by the NaN vectors.
+
+
+=cut
+
+
+
+
 sub PDL::uniqvec {
 
    my($pdl) = shift;
@@ -864,6 +955,10 @@ sub PDL::uniqvec {
 
 clip (threshold) C<$a> by C<$b> (C<$b> is upper bound)
 
+=for bad
+
+hclip processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -898,6 +993,10 @@ sub PDL::hclip {
 
 clip (threshold) C<$a> by C<$b> (C<$b> is lower bound)
 
+=for bad
+
+lclip processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -937,6 +1036,17 @@ Clip (threshold) a piddle by (optional) upper or lower bounds.
 
 
 
+=for bad
+
+clip handles bad values since it is just a
+wrapper around L<hclip|/hclip> and
+L<lclip|/lclip>.
+
+=cut
+
+
+
+
 
 =head2 clip
 
@@ -950,6 +1060,10 @@ Clip (threshold) a piddle by (optional) upper or lower bounds.
 info not available
 
 
+=for bad
+
+clip processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1017,6 +1131,13 @@ The formula is
 
 
 
+=for bad
+
+=for bad
+
+Bad values are ignored in any calculation; C<$b> will only
+have its bad flag set if the output contains any bad data.
+
 
 
 =cut
@@ -1096,6 +1217,13 @@ use C<clump(-1)> directly on the piddle or call C<stats>.
 
 
 
+=for bad
+
+=for bad
+
+Bad values are simply ignored in the calculation, effectively reducing
+the sample size.  If all data are bad then the output data are marked bad.
+
 
 
 =cut
@@ -1150,6 +1278,16 @@ returned quantities.
 
 
 
+
+=for bad
+
+Bad values are handled; if all input values are bad, then all of the output
+values are flagged bad.
+
+=cut
+
+
+
 *stats	  = \&PDL::stats;
 sub PDL::stats {
     barf('Usage: ($mean,[$rms]) = stats($data,[$weights])') if $#_>1;
@@ -1211,6 +1349,10 @@ For a higher-level interface, see L<hist|PDL::Basic/hist>.
 
 
 
+=for bad
+
+histogram processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1261,6 +1403,10 @@ you want.
 
 
 
+=for bad
+
+whistogram processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1316,6 +1462,10 @@ upper limit is put in the last bin.
 
 
 
+=for bad
+
+histogram2d processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1372,6 +1522,10 @@ upper limit is put in the last bin.
 
 
 
+=for bad
+
+whistogram2d processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1397,6 +1551,10 @@ upper limit is put in the last bin.
 
 Constructor - a vector with Fibonacci's sequence
 
+=for bad
+
+fibonacci does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1445,6 +1603,10 @@ Similar functions include L<glue|/glue> (below) and L<cat|PDL::Core/cat>.
 
 
 
+=for bad
+
+append does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1557,6 +1719,10 @@ and alters its argument.
 
 
 
+=for bad
+
+axisvalues does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1849,7 +2015,9 @@ function to obtain cumulative probabilities from absolute probabilities.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -1941,7 +2109,9 @@ leftmost (by index in array) duplicate if I<V> matches.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -2033,7 +2203,9 @@ leftmost (by index in array) duplicate if I<V> matches.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -2083,7 +2255,9 @@ duplicated values, I<I> may refer to any of them.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -2173,7 +2347,9 @@ righmost (by index in array) duplicate if I<V> matches.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -2263,7 +2439,9 @@ righmost (by index in array) duplicate if I<V> matches.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -2313,7 +2491,9 @@ is printed rather than returning an error piddle.
 
 
 
+=for bad
 
+needs major (?) work to handles bad values
 
 =cut
 
@@ -2717,6 +2897,10 @@ L<whichND|/whichND> returns N-D indices into a multidimensional PDL.
 
 
 
+=for bad
+
+which processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -2767,6 +2951,10 @@ C<$c_i>.
 
 
 
+=for bad
+
+which_both processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -465,6 +465,10 @@ sub PDL::polyvalue {
 
 singular value decomposition of a matrix
 
+=for bad
+
+svdc does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -489,6 +493,10 @@ singular value decomposition of a matrix
 Factor a real symmetric positive definite matrix
 and estimate the condition number of the matrix.
 
+=for bad
+
+poco does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -513,6 +521,10 @@ and estimate the condition number of the matrix.
 Factor a matrix using Gaussian elimination and estimate
 the condition number of the matrix.
 
+=for bad
+
+geco does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -538,6 +550,10 @@ the condition number of the matrix.
 
 Factor a matrix using Gaussian elimination.
 
+=for bad
+
+gefa does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -563,6 +579,10 @@ Compute the determinant and inverse of a certain real
 symmetric positive definite matrix using the factors
 computed by L<poco|/poco>.
 
+=for bad
+
+podi does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -587,6 +607,10 @@ computed by L<poco|/poco>.
 Compute the determinant and inverse of a matrix using the
 factors computed by L<geco|/geco> or L<gefa|/gefa>.
 
+=for bad
+
+gedi does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -611,6 +635,10 @@ factors computed by L<geco|/geco> or L<gefa|/gefa>.
 Solve the real system C<A*X=B> or C<TRANS(A)*X=B> using the
 factors computed by L<geco|/geco> or L<gefa|/gefa>.
 
+=for bad
+
+gesl does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -637,6 +665,10 @@ subroutines from the eigensystem subroutine package (EISPACK)
 to find the eigenvalues and eigenvectors (if desired)
 of a REAL SYMMETRIC matrix.
 
+=for bad
+
+rs does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -665,6 +697,10 @@ The prime factorization
 of C<n> together with a tabulation of the trigonometric functions
 are computed and stored in C<wsave()>.
 
+=for bad
+
+ezffti does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -690,6 +726,10 @@ are computed and stored in C<wsave()>.
 
 
 
+=for bad
+
+ezfftf does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -715,6 +755,10 @@ are computed and stored in C<wsave()>.
 
 
 
+=for bad
+
+ezfftb does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -739,6 +783,10 @@ are computed and stored in C<wsave()>.
 Convert the C<polfit> coefficients to Taylor series form.
 C<c> and C<a()> must be of the same type.
 
+=for bad
+
+pcoef does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -765,6 +813,10 @@ polynomial fit of degree C<l>, along with the first C<nder> of
 its derivatives, at a specified point. C<x> and C<a> must be of the
 same type.
 
+=for bad
+
+pvalue does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -828,6 +880,10 @@ monotonicity (data still valid).
 
 
 
+=for bad
+
+chim does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -967,6 +1023,10 @@ for monotonicity.
 
 
 
+=for bad
+
+chic does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1083,6 +1143,10 @@ for the interior derivative values.
 
 
 
+=for bad
+
+chsp does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1149,6 +1213,10 @@ which should never happen.
 
 
 
+=for bad
+
+chfd does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1210,6 +1278,10 @@ E<gt>0 if extrapolation was performed at C<ierr> points
 
 
 
+=for bad
+
+chfe does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1284,6 +1356,10 @@ which should never happen.
 
 
 
+=for bad
+
+chia does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1345,6 +1421,10 @@ Error status returned by C<$ierr>:
 
 
 
+=for bad
+
+chid does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1435,6 +1515,10 @@ Error status returned by C<$ierr>:
 
 
 
+=for bad
+
+chcm does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1532,6 +1616,10 @@ Error status returned by C<$ierr>:
 
 
 
+=for bad
+
+chbs does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1557,6 +1645,10 @@ Fit discrete data in a least squares sense by polynomials
           in one variable. C<x()>, C<y()> and C<w()> must be of the same type.
 	  This version handles bad values appropriately
 
+=for bad
+
+polfit processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -119,6 +119,10 @@ Internal vaffine identity function.
 
 
 
+=for bad
+
+s_identity processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -204,7 +208,9 @@ L<indexND|/indexND>.
 
 
 
+=for bad
 
+index barfs if any of the index values are bad.
 
 =cut
 
@@ -289,7 +295,9 @@ L<indexND|/indexND>.
 
 
 
+=for bad
 
+index1d propagates BAD index elements to the output variable.
 
 =cut
 
@@ -374,7 +382,9 @@ L<indexND|/indexND>.
 
 
 
+=for bad
 
+index2d barfs if either of the index values are bad.
 
 =cut
 
@@ -746,6 +756,10 @@ to tease out the algorithm.
 
 
 
+=for bad
+
+rangeb processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -780,6 +794,10 @@ decode to C<$c>.
 
 
 
+=for bad
+
+rld does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -830,6 +848,10 @@ first instance of C<0> in C<$a> should be considered.
 
 
 
+=for bad
+
+rle does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -888,6 +910,10 @@ are exchanged with each other i.e.
 
 
 
+=for bad
+
+xchg does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1050,6 +1076,10 @@ The other dimensions are moved accordingly.
 Negative dimension indices count from the end.
 
 
+=for bad
+
+mv does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1164,6 +1194,10 @@ depending on whether you prefer error-reporting clarity or speed of execution.
 
 
 
+=for bad
+
+oslice does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1243,6 +1277,10 @@ to C<$a-E<gt>at(2,1,2,0,1,2)>.
 NOTE: diagonal doesn't handle threadids correctly. XXX FIX
 
 
+=for bad
+
+diagonalI does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1297,6 +1335,10 @@ negative and will then be counted from the last dim backwards
 in the usual way (-1 = last dim).
 
 
+=for bad
+
+lags does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1335,6 +1377,10 @@ the expression
 is always true (C<x> has to be less than 3).
 
 
+=for bad
+
+splitdim does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1361,6 +1407,10 @@ is always true (C<x> has to be less than 3).
 Shift vector elements along with wrap. Flows data back&forth.
 
 
+=for bad
+
+rotate does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1394,6 +1444,10 @@ Put some dimensions to a threadid.
 
 
 
+=for bad
+
+threadI does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1422,6 +1476,10 @@ A vaffine identity transformation (includes thread_id copying).
 Mainly for internal use.
 
 
+=for bad
+
+identvaff does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1450,6 +1508,10 @@ All threaded dimensions are made real again.
 See [TBD Doc] for details and examples.
 
 
+=for bad
+
+unthread does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1851,6 +1913,10 @@ sub PDL::slice (;@) {
 info not available
 
 
+=for bad
+
+sliceb does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -694,6 +694,10 @@ Maybe that someone is you.
 
 
 
+=for bad
+
+map does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -93,6 +93,10 @@ I<any> dimension.
 
 
 
+=for bad
+
+prodover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -138,6 +142,10 @@ precision.
 
 
 
+=for bad
+
+dprodover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -185,6 +193,10 @@ is the first element of the parameter.
 
 
 
+=for bad
+
+cumuprodover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -233,6 +245,10 @@ precision.
 
 
 
+=for bad
+
+dcumuprodover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -277,6 +293,10 @@ I<any> dimension.
 
 
 
+=for bad
+
+sumover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -322,6 +342,10 @@ precision.
 
 
 
+=for bad
+
+dsumover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -369,6 +393,10 @@ is the first element of the parameter.
 
 
 
+=for bad
+
+cumusumover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -417,6 +445,10 @@ precision.
 
 
 
+=for bad
+
+dcumusumover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -461,7 +493,11 @@ I<any> dimension.
 
 
 
+=for bad
 
+If C<a()> contains only bad data (and its bad flag is set), 
+C<b()> is set bad. Otherwise C<b()> will have its bad flag cleared,
+as it will not contain any bad values.
 
 =cut
 
@@ -505,7 +541,11 @@ I<any> dimension.
 
 
 
+=for bad
 
+If C<a()> contains only bad data (and its bad flag is set), 
+C<b()> is set bad. Otherwise C<b()> will have its bad flag cleared,
+as it will not contain any bad values.
 
 =cut
 
@@ -549,7 +589,11 @@ I<any> dimension.
 
 
 
+=for bad
 
+If C<a()> contains only bad data (and its bad flag is set), 
+C<b()> is set bad. Otherwise C<b()> will have its bad flag cleared,
+as it will not contain any bad values.
 
 =cut
 
@@ -593,7 +637,11 @@ I<any> dimension.
 
 
 
+=for bad
 
+If C<a()> contains only bad data (and its bad flag is set), 
+C<b()> is set bad. Otherwise C<b()> will have its bad flag cleared,
+as it will not contain any bad values.
 
 =cut
 
@@ -637,7 +685,11 @@ I<any> dimension.
 
 
 
+=for bad
 
+If C<a()> contains only bad data (and its bad flag is set), 
+C<b()> is set bad. Otherwise C<b()> will have its bad flag cleared,
+as it will not contain any bad values.
 
 =cut
 
@@ -690,6 +742,10 @@ is the natural (and correct) choice for binned data, of course.
 
 
 
+=for bad
+
+intover ignores the bad-value flag of the input piddles.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -734,6 +790,10 @@ I<any> dimension.
 
 
 
+=for bad
+
+average processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -779,6 +839,10 @@ precision.
 
 
 
+=for bad
+
+daverage processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -823,6 +887,10 @@ I<any> dimension.
 
 
 
+=for bad
+
+medover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -875,6 +943,10 @@ some circumstances.
 
 
 
+=for bad
+
+oddmedover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -930,6 +1002,10 @@ BAD is the most common element, the returned value is also BAD.
 
 
 
+=for bad
+
+modeover does not process bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -979,6 +1055,10 @@ I<any> dimension.
 
 
 
+=for bad
+
+pctover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1024,6 +1104,10 @@ I<any> dimension.
 
 
 
+=for bad
+
+oddpctover processes bad values.
+It will set the bad-value flag of all output piddles if the flag is set for any of the input piddles.
 
 
 =cut
@@ -1106,6 +1190,14 @@ See the documentation for L<average|/average> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *avg = \&PDL::avg;
 sub PDL::avg {
@@ -1132,6 +1224,14 @@ See the documentation for L<sumover|/sumover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *sum = \&PDL::sum;
 sub PDL::sum {
@@ -1158,6 +1258,14 @@ See the documentation for L<prodover|/prodover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *prod = \&PDL::prod;
 sub PDL::prod {
@@ -1184,6 +1292,14 @@ See the documentation for L<daverage|/daverage> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *davg = \&PDL::davg;
 sub PDL::davg {
@@ -1210,6 +1326,14 @@ See the documentation for L<dsumover|/dsumover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *dsum = \&PDL::dsum;
 sub PDL::dsum {
@@ -1236,6 +1360,14 @@ See the documentation for L<dprodover|/dprodover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *dprod = \&PDL::dprod;
 sub PDL::dprod {
@@ -1262,6 +1394,14 @@ See the documentation for L<zcover|/zcover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *zcheck = \&PDL::zcheck;
 sub PDL::zcheck {
@@ -1288,6 +1428,14 @@ See the documentation for L<andover|/andover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *and = \&PDL::and;
 sub PDL::and {
@@ -1314,6 +1462,14 @@ See the documentation for L<bandover|/bandover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *band = \&PDL::band;
 sub PDL::band {
@@ -1340,6 +1496,14 @@ See the documentation for L<orover|/orover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *or = \&PDL::or;
 sub PDL::or {
@@ -1366,6 +1530,14 @@ See the documentation for L<borover|/borover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *bor = \&PDL::bor;
 sub PDL::bor {
@@ -1392,6 +1564,14 @@ See the documentation for L<minimum|/minimum> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *min = \&PDL::min;
 sub PDL::min {
@@ -1418,6 +1598,14 @@ See the documentation for L<maximum|/maximum> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *max = \&PDL::max;
 sub PDL::max {
@@ -1444,6 +1632,14 @@ See the documentation for L<medover|/medover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *median = \&PDL::median;
 sub PDL::median {
@@ -1470,6 +1666,14 @@ See the documentation for L<modeover|/modeover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *mode = \&PDL::mode;
 sub PDL::mode {
@@ -1496,6 +1700,14 @@ See the documentation for L<oddmedover|/oddmedover> for more information.
 
 
 
+=for bad
+
+This routine handles bad values.
+
+=cut
+
+
+
 
 *oddmedian = \&PDL::oddmedian;
 sub PDL::oddmedian {
@@ -1522,6 +1734,15 @@ Useful in conditional expressions:
 
 
 
+=for bad
+
+See L<or|/or> for comments on what happens when all elements
+in the check are bad.
+
+=cut
+
+
+
 *any = \&or;
 *PDL::any = \&PDL::or;
 
@@ -1541,6 +1762,15 @@ Useful in conditional expressions:
 
 
 
+=for bad
+
+See L<and|/and> for comments on what happens when all elements
+in the check are bad.
+
+=cut
+
+
+
 
 *all = \&and;
 *PDL::all = \&PDL::and;
@@ -1600,6 +1830,14 @@ Quicksort a vector into ascending order.
 
 
 
+=for bad
+
+Bad values are moved to the end of the array:
+
+ pdl> p $b
+ [42 47 98 BAD 22 96 74 41 79 76 96 BAD 32 76 25 59 BAD 96 32 BAD]
+ pdl> p qsort($b)
+ [22 25 32 32 41 42 47 59 74 76 76 79 96 96 96 98 BAD BAD BAD BAD]
 
 
 =cut
@@ -1633,6 +1871,14 @@ Quicksort a vector and return index of elements in ascending order.
 
 
 
+=for bad
+
+Bad elements are moved to the end of the array:
+
+ pdl> p $b
+ [42 47 98 BAD 22 96 74 41 79 76 96 BAD 32 76 25 59 BAD 96 32 BAD]
+ pdl> p $b->index( qsorti($b) )
+ [22 25 32 32 41 42 47 59 74 76 76 79 96 96 96 98 BAD BAD BAD BAD]
 
 
 =cut
@@ -1677,6 +1923,9 @@ the 1st dimension is list order.  Higher dimensions are threaded over.
 
 
 
+=for bad
+
+Vectors with bad components should be moved to the end of the array:
 
 
 =cut
@@ -1716,6 +1965,9 @@ so qsortveci may be thought of as a collapse operator of sorts (groan).
 
 
 
+=for bad
+
+Vectors with bad components should be moved to the end of the array:
 
 
 =cut
@@ -1760,6 +2012,14 @@ I<any> dimension.
 
 
 
+=for bad
+
+Output is set bad if all elements of the input are bad,
+otherwise the bad flag is cleared for the output piddle.
+
+Note that C<NaNs> are considered to be valid values;
+see L<isfinite|PDL::Math/isfinite> and L<badmask|PDL::Math/badmask>
+for ways of masking NaNs.
 
 
 =cut
@@ -1785,7 +2045,10 @@ I<any> dimension.
 
 Like minimum but returns the index rather than the value
 
+=for bad
 
+Output is set bad if all elements of the input are bad,
+otherwise the bad flag is cleared for the output piddle.
 
 =cut
 
@@ -1810,7 +2073,9 @@ Like minimum but returns the index rather than the value
 
 Returns the index of C<m> minimum elements
 
+=for bad
 
+Not yet been converted to ignore bad values
 
 =cut
 
@@ -1854,6 +2119,14 @@ I<any> dimension.
 
 
 
+=for bad
+
+Output is set bad if all elements of the input are bad,
+otherwise the bad flag is cleared for the output piddle.
+
+Note that C<NaNs> are considered to be valid values;
+see L<isfinite|PDL::Math/isfinite> and L<badmask|PDL::Math/badmask>
+for ways of masking NaNs.
 
 
 =cut
@@ -1879,7 +2152,10 @@ I<any> dimension.
 
 Like maximum but returns the index rather than the value
 
+=for bad
 
+Output is set bad if all elements of the input are bad,
+otherwise the bad flag is cleared for the output piddle.
 
 =cut
 
@@ -1904,7 +2180,9 @@ Like maximum but returns the index rather than the value
 
 Returns the index of C<m> maximum elements
 
+=for bad
 
+Not yet been converted to ignore bad values
 
 =cut
 
@@ -1941,7 +2219,12 @@ See also L<minmax|/minmax>, which clumps the piddle together.
 
 
 
+=for bad
 
+If C<a()> contains only bad data, then the output piddles will
+be set bad, along with their bad flag.
+Otherwise they will have their bad flags cleared,
+since they will not contain any bad values.
 
 =cut
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 use ExtUtils::MakeMaker;
 
-my @subdirs = qw(PGPLOT LUT IIS PLplot Limits);
+my @subdirs = qw(PGPLOT LUT IIS Limits);
 
 # we try and build unless WITH_3D == 0
 my $t = $PDL::Config{WITH_3D};
@@ -1,104 +0,0 @@
-Revision history for Perl extension PDL::Graphics::PLPLOT
-
-0.01  1/23/2002
-	- original version
-
-0.11  First version released to CPAN.  Does line and point plots and Shade plots.
-      Still missing support for 3D plots (but this could easily be added).
-
-0.19  1/31/2003 First version integrated into the PDL distribution.  Includes
-      Support for 'mem' driver for in-memory plotting on top of RGB images.
-
-0.20  7/16/2003 Broke package apart from main PDL distribution to allow separate development.
-      Now package should work either as part of PDL distro (with plplot.t moved to PDL/t directory)
-      or independently (with plplot.t in PDL-Graphics-PLplot/t directory).
-      Added controls for tick size, tick spacing and error bars.
-
-0.21  11/21/2003 Fixed test suite to use Test::More, updated to work with plplot-5.2.1.
-      Back-ported to main PDL distro.
-
-0.29  6/22/05 Fixed bug in plcolorpoints in the "bad" code for loop
-
-0.30  8/9/06  No longer use plfill for color wedge--this does not work with some
-      drivers including the 'mem' driver.  Also use fewer colors in the color wedge
-      for GIF device plots because of GIF's 256 color limitation
-
-0.31  May 2007 Merge changes from PDL mailing list
-
-0.32  Add TEXTPOSITION support for bargraph
-
-0.33  Added stripplot function for multiple plots with a common X axis.  Added extra colors.
-
-0.34  Added Y_BASE and Y_GUTTER options to stripplot.
-
-0.35  Added new low level functions supporting alpha channels.
-
-0.36  Added pltimefmt call for plplot 5.9.0
-
-0.37  10/15/2008 Handle case of missing PDL better
-
-0.38  10/16/2008 Fixed typo in Makefile.PL that broke build, added plgvpd and plgvpw interfaces
-
-0.39  10/29/2008 Added lib64 paths back in to PLplot library search path.
-
-0.40  12/04/2008 Fixed interface to plgcol0, changed plParseOpts to use c_plparseopts (the current standard)
-                 Added interface to plhlsrgb.
-                 Ported back some changes from PDL-2.4.4 release for backwards compatibility with old plplot
-
-0.41  12/04/2008 Added VERSION in plplot.pd where you can query it from the command line:
-                 perl -MPDL::Graphics::PLplot -e 'print "$PDL::Graphics::PLplot::VERSION\n"'
-
-0.42  12/04/2008 Added plimagefr support to allow complete plplot example x20.pl to work.
-
-0.43  12/05/2008 Added support for environment variables:  PLPLOT_LIBDIR and PLPLOT_INCDIR
-                 to allow the user to specify the plplot location.
-
-0.44  12/05/2008 Added plseed and plrandd interfaces
-
-0.45  12/10/2008 Fixed routines: plgcol0,  plgcolbg,  plscmap0,  plscmap1
-                                 plgcol0a, plgcolbga, plscmap0a, plscmap1a
-                 To handle output parms and SIZE parms consistently
-                 Added 3D labelling functions for example 28.
-
-0.46  12/11/2008 Added font handling routines:  plgfont, plsfont, plgfci, plsfci
-
-0.47  12/18/2008 Added band-aid to get_standard_pltrcb to avoid failure in plshades reported
-                 by Orion Poplawski.  Also added interface to plcalc_world and fixed interface to plgfnam.
-
-0.48  1/7/2009   Allow caller of 'colorkey' high level function to set XBOX or YBOX to set
-                 color key number scale parameters.  Also added logic to allow detection of
-                 new plplot routines to prevent failure with plplot 5.9 and earlier.
-
-0.49  2/26/2009  Fix zero-divide bug in plcolorpoints
-
-0.50  06/15/2009 Took out logic depending upon $PDL::Config{WITH_PLPLOT} (which is set in the
-                 PDL top-level Makefile.PL) for building and testing PDL::Graphics::PLplot.
-                 This dependency required that PLplot detect and build correctly in the original
-                 PDL compile.  One should be able to install PDL::Graphics::PLplot later.
-                 Also stripped a lot of cruft from plplot.t which seems not to be necessary for
-                 more recent plplot versions.
-
-0.51  7/13/2009  Added logic to manage a PLstream pool instead of just incremenenting the pool number
-                 with each call to 'new'.  This allows one to re-use stream numbers after a call to
-                 'close'.  Bug found by Marek Gierlinski.
-
-0.52  11/03/2009 Fixes for 64 bit machines:  plFree2dGrid, plFreeGrid, plAllocGrid, plAlloc2dGrid, pltr0, pltr1, pltr2
-                 Now compiler complains less.
-
-0.53  7/27/2010  Added UNFILLED_BARS option to allow the bargraph routine to plot bars that are not filled.
-
-0.54 12/15/2010  Unified PDL distro version of CPAN stand-alone PDL::Graphics::PLplot version 0.53.
-
-0.55 4/23/2011   Upgraded prior to plplot 5.9.8 release.  
-                 Added support for many functions: plgradient, plstring, plstring3, plarc, plstransform, 
-                                                   plslabelfunc, pllegend, plspal0, plspal1, plbtime, 
-                                                   plconfigtime, plctime, pltimefmt, plsesc
-                 Removed deprecated functions: plarrows, c_plhls, c_plrgb, c_plrgb1
-                 Fixed compiler warnings, did general clean-up.
-0.56 5/06/2011   Added test suite from plplot, plus comparison results from the C tests.
-                 Also added META_MERGE in Makefile.PL to try to get PAUSE/CPAN indexing working.
-
-0.57 8/30/2011   Cleaned up OPTIONS! processing for communication from Makefile.PL to plplot.pd--now based on the approach
-                 by Sisyphus.  Also merged in David Merten's 'NoPthread => 1' option to allow for
-                 use of PLplot in a pthreads environment.
-
@@ -1,281 +0,0 @@
-use strict;
-use warnings;
-use ExtUtils::MakeMaker;
-use Config;
-use File::Spec;
-use Data::Dumper;
-
-# comment this block out for PDL internal version
-#eval {
-#  require PDL::Core::Dev;  # needed for stand-alone version of package.
-#                           # Need to comment out
-#                           # for package included in PDL distro.
-#
-#  PDL::Core::Dev->import;
-#};
-#my $pdl_installed = ($@) ? 0 : 1; # make always == 1 for install from PDL distro.
-#print "PDL ", ($pdl_installed ? 'is' : 'is not'), " installed\n";
-# end comment this block out for PDL internal version
-
-my $pdl_installed = 1; # uncomment for PDL-internal version
-my ($plplot_lib_path, $plplot_include_path);
-
-if (!$pdl_installed) {
-  # write dummy makefile if PDL not installed
-  WriteMakefile(
-		'NAME'         => 'PDL::Graphics::PLplot',
-		'PREREQ_PM'    => { PDL => 0 },
-		);
-  exit;
-}
-
-#
-## Search for plplot library and include file
-#
-print "\nChecking PDL::Graphics::PLplot...\n";
-
-unlink ("OPTIONS!"); # remove file used to communicate with plplot.pd
-
-# on OS-X the library is called libplplotd.dylib, so we
-# use $Config{"so"} to get the extension name
-#
-my $libname = "libplplotd." . $Config{"so"};
-my $incname = "plplot.h";
-my $devnull = File::Spec->devnull(); # Portable null device.
-
-# require bad value support.  D. Hunt 10/20/2008
-unless ($PDL::Config{WITH_BADVAL}) {
-  buildDummy ("Bad value support required!  (Turn on WITH_BADVAL in perldl.conf)");
-  return if (caller); exit;
-}
-
-my $found_plplot =
-    (defined($PDL::Config{WITH_PLPLOT}) && (!$PDL::Config{WITH_PLPLOT}))
-    ? 0 : 1;
-print "found_plplot is $found_plplot\n";
-unless ($found_plplot) {
-  buildDummy ("User requested no PLplot interface!");
-  return if (caller); exit;
-}
-
-foreach my $libdir (
-		    split(/ /, $Config{libpth}),
-		    $ENV{PLPLOT_LIBDIR},
-		    $PDL::Config{WHERE_PLPLOT_LIBS},
-		    '/usr/local/plplot/lib64',
-                    '/usr/local/plplot/lib',
-		    '/usr/local/lib64',
-		    '/usr/local/lib',
-		    '/opt/local/lib',
-		    '/usr/lib64',
-		    '/usr/lib',
-		    '/opt/lib64',
-		    '/opt/lib',
-		    '/ops/tools/lib',
-                    '/sw/lib/',    # default FINK installation
-		                  # Add new library paths here!!
-		    ) {
-
-  next unless $libdir;
-  if (-e "$libdir/$libname") {
-    $plplot_lib_path = $libdir;
-    $ENV{LD_LIBRARY_PATH} .= ":$libdir";
-    last;
-  } elsif (-e "$libdir/libplplotd.a") {
-    $plplot_lib_path = $libdir;
-    $ENV{LD_LIBRARY_PATH} .= ":$libdir";
-    $libname = 'libplplotd.a';
-    last;
-  } elsif (-e "$libdir/libplplotd.dll.a") {
-    $plplot_lib_path = $libdir;
-    $ENV{LD_LIBRARY_PATH} .= ":$libdir";
-    $libname = 'libplplotd.dll.a';
-    last;
-  }
-
-}
-
-unless (defined ($plplot_lib_path)) {
-  buildDummy ("Cannot find plplot library ($libname), skipping PDL::Graphics::PLplot");
-  return if (caller); exit;
-}
-
-foreach my $incdir (
-		    "$Config{usrinc}/plplot",
-		    $ENV{PLPLOT_INCDIR},
-		    $PDL::Config{WHERE_PLPLOT_INCLUDE},
-                    '/usr/local/plplot/include',
-                    '/usr/local/plplot/include/plplot',
-		    '/usr/local/include/plplot',
-		    '/usr/local/include',
-		    '/opt/local/include',
-		    '/usr/include',
-		    '/usr/include/plplot',
-		    '/opt/include',
-		    '/ops/tools/include/plplot',
-		    '/ops/tools/include',
-                    '/sw/include/plplot/',    # default FINK installation
-		                  # Add new header paths here!!
-		    ) {
-
-  if (defined($incdir) && -e "$incdir/$incname") {
-    $plplot_include_path = "-I$incdir";
-    if ($incdir =~ m|/plplot$|) {
-      my $inc2 = $incdir;
-      $inc2 =~ s|/plplot$||;
-      $plplot_include_path .= " -I$inc2";
-    }
-    last;
-  }
-}
-
-unless (defined ($plplot_include_path)) {
-  buildDummy ("Cannot find plplot header file ($incname), skipping PDL::Graphics::PLplot");
-  return if (caller); exit;
-}
-
-# Test that PLplot was compiled --with-double (IE, a PLFLT is a double)
-my $size = compileAndRun ("$plplot_include_path", 1, <<'EOC');
-#include <plplot.h>
-main () {  printf  ("%d", sizeof (PLFLT)); }
-EOC
-
-unless ($size == 8) {
-  print "          Sizeof(PLFLT) must be 8. PLplot must be compiled --with-double (IE ./configure --with-double)\n";
-  buildDummy ("Cannot find good set of libraries for linking PLplot, try fiddling perldl.conf");
-  return if (caller); exit;
-}
-
-# Try linking with library.  New if blocks should be added if necessary
-my $libs;
-foreach my $l (
-	       "-L$plplot_lib_path -lplplotd -lX11",
-	       "-L$plplot_lib_path -lplplotd",
-             "-L$plplot_lib_path -lplplotd -lqsastime -lcsirocsa -lgdi32 -lcomdlg32",
-	       # New lib combinations should be added here!
-	       ) {
-  if (trylink( '', '#include <plplot.h>', 'plinit();', "$l $plplot_include_path")) {
-    $libs = $l;
-    print "\tSucceeded linking PLplot with $libs\n";
-    last;
-  }
-}
-
-unless (defined($libs)) {
-  buildDummy ("Cannot find good set of libraries for linking PLplot, try fiddling perldl.conf");
-  return if (caller); exit;
-}
-
-#
-## Tests for various PLplot features, present in different versions of PLplot
-#
-my %plversion = (); # Information on which PLplot functions/features available.
-$plversion{'plsmem'}      = test_func_exists('plsmem', 'in-memory plotting', 'plsmem( 0, 0, NULL);');
-$plversion{'plsvect'}     = test_func_exists('plsvect', 'vector plotting',   'plsvect (NULL, NULL, 0, 0);');
-$plversion{'c_plgcoloa'}  = test_func_exists('c_plgcoloa', 'alpha transparency', 'c_plgcol0a(0, 0, 0, 0, NULL);');
-$plversion{'c_plseed'}    = test_func_exists('c_plseed',   'random numbers',     'c_plseed (0 );');
-$plversion{'c_plsfont'}   = test_func_exists('c_plsfont',  'set font',           'c_plsfont (0, 0, 0);');
-$plversion{'c_plimagefr'} = test_func_exists('c_plimagefr','2d matrix',
-                                             'c_plimagefr (NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL);' );
-$plversion{'c_pllegend'}  = test_func_exists('c_pllegend', 'Plot legends',
-                                             'c_pllegend(NULL,NULL,0,   0,   0.0, 0.0, 0.0, 0,   0,   0,
-                                                         0,   0,   0,   NULL,0.0, 0.0, 0.0, 0.0, NULL,NULL,
-                                                         NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);');
-# Write these options to a file--used by plplot.pd during the 'make' step
-open my $fh, '>', 'OPTIONS!' or die "Cannot write to OPTIONS! file";
-print  {$fh} Dumper(\%plversion);
-close   $fh;
-
-$PDL::Config{WITH_PLPLOT} = 1;
-
-my @pack = (["plplot.pd", qw(PLplot PDL::Graphics::PLplot)]);
-
-#%hash = pdlpp_stdargs_int(@pack);  # use this for module inside PDL source
-my %hash = pdlpp_stdargs(@pack);          # use this for separate module
-
-# $hash{'PREREQ_PM'} = { PDL => 0 };
-$hash{'OPTIMIZE'}  = '-g'; # If you want to debug, uncomment this.
-$hash{'VERSION_FROM'}   = 'plplot.pd';
-$hash{'META_MERGE'}   = {provides => {'PDL::Graphics::PLplot' => {file => 'plplot.pd', version => 0.57}}};
-
-$hash{'LIBS'}      = [$libs];
-# add this to allow one to use the /ops/tools/lib plplot libs even when
-# another plplot is installed in /usr/local/lib. D. Hunt 6/4/2004
-$hash{'LDDLFLAGS'} = $^O eq 'darwin' ? " -bundle -undefined dynamic_lookup -L$plplot_lib_path " : " -shared -L$plplot_lib_path -L/usr/local/lib ";
-
-$hash{'INC'}      .= " $plplot_include_path";
-$hash{'clean'}     = {'FILES'  =>
-                        'PLplot.pm PLplot.xs PLplot.o PLplot.c PLplot.bs *svg.* *.xfig temp* OPTIONS! Makefile.old'};
-
-#my $postamble = pdlpp_postamble(@pack); # use for external module
-my $postamble = pdlpp_postamble_int(@pack); # use for install inside PDL distro
-
-# Add genpp rule
-undef &MY::postamble; # suppress warning
-*MY::postamble = sub { $postamble };
-
-WriteMakefile(%hash);
-
-sub test_func_exists {
-
-    my ( $func, $comment, $eval, $option ) = @_;
-
-    $option = $func unless defined $option;
-
-    # Test if PLplot has plsmem, for in memory plotting
-    eval { compileAndRun ("$plplot_include_path $libs", 0, <<"EOC");
-#include <plplot.h>
-main () {  $eval }
-EOC
-       };
-
-    my $have_func;
-    if ($@)
-    {
-	print "\t$func function not found, no $comment available\n";
-	$have_func = 0;
-    }
-    else
-    {
-	print "\t$func function found, $comment available!\n";
-	$have_func = 1;
-    }
-
-    return $have_func;
-}
-
-sub compileAndRun {
-  my $flags = shift;
-  my $run   = shift;
-  my $code  = shift;
-
-  open (OUT, ">temp.c");
-  print OUT $code;
-  close OUT;
-  unlink './temp'; # since we work out whether the compile succeeds by presence of this
-  unlink './temp.exe'; # since we work out whether the compile succeeds by presence of this
-
-  my $cc = $Config{cc};
-  my $ccflags = $Config{ccflags};
-  # print "Trying: $cc $ccflags $flags temp.c -o temp\n";
-
-  # The duplication of $flags seems to be necessary, as some systems
-  # need $flags before temp.c and some after.  D. Hunt 2/9/2011
-  system "$cc $ccflags $flags temp.c $flags -o temp > $devnull 2>&1";
-  unlink('./temp.c');
-  die "Cannot compile test program: $code" unless (-e 'temp' or -e 'temp.exe');
-  unless ($run){
-      unlink './temp';
-      unlink './temp.exe';
-      return;
-  }
-  my $res = `./temp`;
-  unlink ('./temp');
-  return $res;
-}
-
-sub buildDummy {
-  my $msg = shift;
-  write_dummy_make( "$msg\nNot building PDL::Graphics::PLplot" );
-  $PDL::Config{WITH_PLPLOT} = 0;
-}
@@ -1,77 +0,0 @@
-PDL::Graphics::PLplot
-
-This is a simple perl/PDL interface to the PLplot plotting library.
-
-http://plplot.sourceforge.net/
-
-I wrote this primarily for web graphics as an alternative to PDL::Graphics::PGPLOT.
-
-The advantages of PLplot over PGPLOT are these:
-
--- It is written all in (generally well structured, comprehensible) C
-   (so you don't need a FORTRAN compiler as for PGPLOT).
--- It is in current development
--- It has a simple autoconf installation with built-in PNG support
-
-(The disadvantage is that it is missing some of PGPLOT's many features).
-
-The interface consists of two levels.  A low level interface which maps closely to
-the PLplot C interface, and a high level, object-oriented interface which is easier to 
-use.
-
-Examples:
-
-use PDL:
-use PDL::Graphics::PLplot;
-
-# Line plot of two 1D PDLs $x and $y
-my $pl = PDL::Graphics::PLplot->new (DEV => "png", FILE => "test1.png");
-$pl->xyplot($x, $y, PLOTTYPE => 'LINE', COLOR => 'GREEN', 
-	            TITLE => 'Sample plot', XLAB => 'frobnitz', YLAB => 'widgets/sec');
-$pl->close;
-
-# Shade plot of a 2D PDL in $z
-my $pl = PDL::Graphics::PLplot->new (DEV => 'png', FILE => "test2.png");
-$pl->shadeplot ($z, $nsteps, BOX => [-1, 1, -1, 1], PALETTE => 'RAINBOW');
-$pl->colorkey ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-$pl->close;
-
-For more examples, see the test.pl file.
-
-PREREQUISITES:
-
-perl 5.6 or higher
-PDL 2.3 or more recent
-PLplot 5.1.0 (5.2.0 support is in the works...)
-
-------------------------------------------------------------------------
-Important:  plplot *must* be compiled --with-double so that all floating
-  point numbers used are doubles.  Install plplot similar to this:
-
-# ./configure --with-double
-# make
-# make install
-
-On some systems (IRIX, for one) it may be necessary to compile plplot
-without fortran support:  --disable-f77.
-------------------------------------------------------------------------
-
-INSTALLATION:
- 
-Installation should be the normal:
- 
-perl Makefile.PL
-make
-make test
- 
-(as root)
-make install
- 
-Best of luck!
- 
-Doug Hunt
-dhunt@ucar.edu
-Software Engineer III
-UCAR - GPS/MET
-
-
@@ -1,5267 +0,0 @@
-use Config;
-
-my $ptrsize = $Config{'ptrsize'};
-my $int_ptr_type = ($ptrsize == 4) ? $Config{i32type} : $Config{i64type}; # pointer type in C code
-my $pp_ptr_type  = ($ptrsize == 4) ? 'int' : 'longlong';    # pointer type in pp_def Pars sections
-
-# User can set this global variable to 1 if he wants
-# to use the normal plplot order of arguments, not the PP-required
-# order for functions with OtherPars.
-$PDL::Graphics::PLplot::standard_order = 0;
-
-# Read in options determined by Makefile.PL and written to the OPTIONS! file
-my $plversion = do 'OPTIONS!';
-pp_addpm({At => Top}, <<'EOD');
-
-our $VERSION;
-BEGIN {
-$VERSION = '0.61'
-};
-
-=head1 NAME
-
-PDL::Graphics::PLplot - Object-oriented interface from perl/PDL to the PLPLOT plotting library
-
-=head1 SYNOPSIS
-
-  use PDL;
-  use PDL::Graphics::PLplot;
-
-  my $pl = PDL::Graphics::PLplot->new (DEV => "png", FILE => "test.png");
-  my $x  = sequence(10);
-  my $y  = $x**2;
-  $pl->xyplot($x, $y);
-  $pl->close;
-
-For more information on PLplot, see
-
- http://www.plplot.org/
-
-Also see the test file, F<t/plplot.pl> in this distribution for some working examples.
-
-=head1 LONG NAMES
-
-If you are annoyed by the long constructor call, consider installing the
-L<aliased|aliased> CPAN package. Using C<aliased>, the above example
-becomes
-
-  use PDL;
-  use aliased 'PDL::Graphics::PLplot';
-
-  my $pl = PLplot->new (DEV => "png", FILE => "test.png");
-  my $x  = sequence(10);
-  # etc, as above
-
-=head1 DESCRIPTION
-
-This is the PDL interface to the PLplot graphics library.  It provides
-a familiar 'perlish' Object Oriented interface as well as access to
-the low-level PLplot commands from the C-API.
-
-=head1 OPTIONS
-
-The following options are supported.  Most options can be used
-with any function.  A few are only supported on the call to 'new'.
-
-=head2 Options used upon creation of a PLplot object (with 'new'):
-
-=head3 BACKGROUND
-
-Set the color for index 0, the plot background
-
-=head3 DEV
-
-Set the output device type.  To see a list of allowed types, try:
-
-  PDL::Graphics::PLplot->new();
-
-=for example
-
-   PDL::Graphics::PLplot->new(DEV => 'png', FILE => 'test.png');
-
-=head3 FILE
-
-Set the output file or display.  For file output devices, sets
-the output file name.  For graphical displays (like C<'xwin'>) sets
-the name of the display, eg (C<'hostname.foobar.com:0'>)
-
-=for example
-
-   PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png');
-   PDL::Graphics::PLplot->new(DEV => 'xwin', FILE => ':0');
-
-=head3 OPTS
-
-Set plotting options.  See the PLplot documentation for the complete
-listing of available options.  The value of C<'OPTS'> must be a hash
-reference, whose keys are the names of the options.  For instance, to obtain
-PostScript fonts with the ps output device, use:
-
-=for example
-
-   PDL::Graphics::PLplot->new(DEV => 'ps', OPTS => {drvopt => 'text=1'});
-
-=head3 MEM
-
-This option is used in conjunction with C<< DEV => 'mem' >>.  This option
-takes as input a PDL image and allows one to 'decorate' it using PLplot.
-The 'decorated' PDL image can then be written to an image file using,
-for example, L<PDL::IO::Pic|PDL::IO::Pic>.  This option may not be available if
-plplot does not include the 'mem' driver.
-
-=for example
-
-  # read in Earth image and draw an equator.
-  my $pl = PDL::Graphics::PLplot->new (MEM => $earth, DEV => 'mem');
-  my $x  = pdl(-180, 180);
-  my $y  = zeroes(2);
-  $pl->xyplot($x, $y,
-              BOX => [-180,180,-90,90],
-              VIEWPORT => [0.0, 1.0, 0.0, 1.0],
-              XBOX => '', YBOX => '',
-              PLOTTYPE => 'LINE');
-  $pl->close;
-
-=head3 FRAMECOLOR
-
-Set color index 1, the frame color
-
-=head3 JUST
-
-A flag used to specify equal scale on the axes.  If this is
-not specified, the default is to scale the axes to fit best on
-the page.
-
-=for example
-
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', JUST => 1);
-
-=head3 ORIENTATION
-
-The orientation of the plot:
-
-  0 --   0 degrees (landscape mode)
-  1 --  90 degrees (portrait mode)
-  2 -- 180 degrees (seascape mode)
-  3 -- 270 degrees (upside-down mode)
-
-Intermediate values (0.2) are acceptable if you are feeling daring.
-
-=for example
-
-  # portrait orientation
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', ORIENTATION => 1);
-
-=head3 PAGESIZE
-
-Set the size in pixels of the output page.
-
-=for example
-
-  # PNG 500 by 600 pixels
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', PAGESIZE => [500,600]);
-
-=head3 SUBPAGES
-
-Set the number of sub pages in the plot, [$nx, $ny]
-
-=for example
-
-  # PNG 300 by 600 pixels
-  # Two subpages stacked on top of one another.
-  PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png', PAGESIZE => [300,600],
-                                              SUBPAGES => [1,2]);
-
-=head2 Options used after initialization (after 'new')
-
-=head3 BOX
-
-Set the plotting box in world coordinates.  Used to explicitly
-set the size of the plotting area.
-
-=for example
-
- my $pl = PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png');
- $pl->xyplot ($x, $y, BOX => [0,100,0,200]);
-
-=head3 CHARSIZE
-
-Set the size of text in multiples of the default size.
-C<< CHARSIZE => 1.5 >> gives characters 1.5 times the normal size.
-
-=head3 COLOR
-
-Set the current color for plotting and character drawing.
-Colors are specified not as color indices but as RGB triples.
-Some pre-defined triples are included:
-
-  BLACK        GREEN        WHEAT        BLUE
-  RED          AQUAMARINE   GREY         BLUEVIOLET
-  YELLOW       PINK         BROWN        CYAN
-  TURQUOISE    MAGENTA      SALMON       WHITE
-  ROYALBLUE    DEEPSKYBLUE  VIOLET       STEELBLUE1
-  DEEPPINK     MAGENTA      DARKORCHID1  PALEVIOLETRED2
-  TURQUOISE1   LIGHTSEAGREEN SKYBLUE     FORESTGREEN
-  CHARTREUSE3  GOLD2        SIENNA1      CORAL
-  HOTPINK      LIGHTCORAL   LIGHTPINK1   LIGHTGOLDENROD
-
-=for example
-
- # These two are equivalent:
- $pl->xyplot ($x, $y, COLOR => 'YELLOW');
- $pl->xyplot ($x, $y, COLOR => [0,255,0]);
-
-=head3 LINEWIDTH
-
-Set the line width for plotting.  Values range from 1 to a device dependent maximum.
-
-=head3 LINESTYLE
-
-Set the line style for plotting.  Pre-defined line styles use values 1 to 8, one being
-a solid line, 2-8 being various dashed patterns.
-
-=head3 MAJTICKSIZE
-
-Set the length of major ticks as a fraction of the default setting.
-One (default) means leave these ticks the normal size.
-
-=head3 MINTICKSIZE
-
-Set the length of minor ticks (and error bar terminals) as a fraction of the default setting.
-One (default) means leave these ticks the normal size.
-
-=head3 NXSUB
-
-The number of minor tick marks between each major tick mark on the X axis.
-Specify zero (default) to let PLplot compute this automatically.
-
-=head3 NYSUB
-
-The number of minor tick marks between each major tick mark on the Y axis.
-Specify zero (default) to let PLplot compute this automatically.
-
-=head3 PALETTE
-
-Load pre-defined color map 1 color ranges.  Currently, values include:
-
-  RAINBOW   -- from Red to Violet through the spectrum
-  REVERSERAINBOW   -- Violet through Red
-  GREYSCALE -- from black to white via grey.
-  REVERSEGREYSCALE -- from white to black via grey.
-  GREENRED  -- from green to red
-  REDGREEN  -- from red to green
-
-=for example
-
- # Plot x/y points with the z axis in color
- $pl->xyplot ($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
-
-=head3 PLOTTYPE
-
-Specify which type of XY plot is desired:
-
-  LINE       -- A line
-  POINTS     -- A bunch of symbols
-  LINEPOINTS -- both
-
-=head3 SUBPAGE
-
-Set which subpage to plot on.  Subpages are numbered 1 to N.
-A zero can be specified meaning 'advance to the next subpage' (just a call to
-L<pladv()|/pladv>).
-
-=for example
-
-  my $pl = PDL::Graphics::PLplot->new(DEV      => 'png',
-                                        FILE     => 'test.png',
-                                        SUBPAGES => [1,2]);
-  $pl->xyplot ($x, $y, SUBPAGE => 1);
-  $pl->xyplot ($a, $b, SUBPAGE => 2);
-
-
-=head3 SYMBOL
-
-Specify which symbol to use when plotting C<< PLOTTYPE => 'POINTS' >>.
-A large variety of symbols are available, see:
-http://plplot.sourceforge.net/examples-data/demo07/x07.*.png, where * is 01 - 17.
-You are most likely to find good plotting symbols in the 800s:
-http://plplot.sourceforge.net/examples-data/demo07/x07.06.png
-
-=head3 SYMBOLSIZE
-
-Specify the size of symbols plotted in multiples of the default size (1).
-Value are real numbers from 0 to large.
-
-=head3 TEXTPOSITION
-
-Specify the placement of text.  Either relative to border, specified as:
-
- [$side, $disp, $pos, $just]
-
-Where
-
-  side = 't', 'b', 'l', or 'r' for top, bottom, left and right
-  disp is the number of character heights out from the edge
-  pos  is the position along the edge of the viewport, from 0 to 1.
-  just tells where the reference point of the string is: 0 = left, 1 = right, 0.5 = center.
-
-or inside the plot window, specified as:
-
- [$x, $y, $dx, $dy, $just]
-
-Where
-
-  x  = x coordinate of reference point of string.
-  y  = y coordinate of reference point of string.
-  dx   Together with dy, this specifies the inclination of the string.
-       The baseline of the string is parallel to a line joining (x, y) to (x+dx, y+dy).
-  dy   Together with dx, this specifies the inclination of the string.
-  just Specifies the position of the string relative to its reference point.
-       If just=0, the reference point is at the left and if just=1,
-       it is at the right of the string. Other values of just give
-       intermediate justifications.
-
-=for example
-
- # Plot text on top of plot
- $pl->text ("Top label",  TEXTPOSITION => ['t', 4.0, 0.5, 0.5]);
-
- # Plot text in plotting area
- $pl->text ("Line label", TEXTPOSITION => [50, 60, 5, 5, 0.5]);
-
-=head3 TITLE
-
-Add a title on top of a plot.
-
-=for example
-
- # Plot text on top of plot
- $pl->xyplot ($x, $y, TITLE => 'X vs. Y');
-
-=head3 UNFILLED_BARS
-
-For 'bargraph', if set to true then plot the bars as outlines
-in the current color and not as filled boxes
-
-=for example
-
- # Plot text on top of plot
- $pl->bargraph($labels, $values, UNFILLED_BARS => 1);
-
-=head3 VIEWPORT
-
-Set the location of the plotting window on the page.
-Takes a four element array ref specifying:
-
- xmin -- The coordinate of the left-hand edge of the viewport. (0 to 1)
- xmax -- The coordinate of the right-hand edge of the viewport. (0 to 1)
- ymin -- The coordinate of the bottom edge of the viewport. (0 to 1)
- ymax -- The coordinate of the top edge of the viewport. (0 to 1)
-
-You will need to use this to make color keys or insets.
-
-=for example
-
- # Make a small plotting window in the lower left of the page
- $pl->xyplot ($x, $y, VIEWPORT => [0.1, 0.5, 0.1, 0.5]);
-
- # Also useful in creating color keys:
- $pl->xyplot   ($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
- $pl->colorkey ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-
- # Plot an inset; first the primary data and then the inset. In this
- # case, the inset contains a selection of the orignal data
- $pl->xyplot ($x, $y);
- $pl->xyplot (where($x, $y, $x < 1.2), VIEWPORT => [0.7, 0.9, 0.6, 0.8]);
-
-=head3 XBOX
-
-Specify how to label the X axis of the plot as a string of option letters:
-
-  a: Draws axis, X-axis is horizontal line (y=0), and Y-axis is vertical line (x=0).
-  b: Draws bottom (X) or left (Y) edge of frame.
-  c: Draws top (X) or right (Y) edge of frame.
-  f: Always use fixed point numeric labels.
-  g: Draws a grid at the major tick interval.
-  h: Draws a grid at the minor tick interval.
-  i: Inverts tick marks, so they are drawn outwards, rather than inwards.
-  l: Labels axis logarithmically. This only affects the labels, not the data,
-     and so it is necessary to compute the logarithms of data points before
-     passing them to any of the drawing routines.
-  m: Writes numeric labels at major tick intervals in the
-     unconventional location (above box for X, right of box for Y).
-  n: Writes numeric labels at major tick intervals in the conventional location
-     (below box for X, left of box for Y).
-  s: Enables subticks between major ticks, only valid if t is also specified.
-  t: Draws major ticks.
-
-The default is C<'BCNST'> which draws lines around the plot, draws major and minor
-ticks and labels major ticks.
-
-=for example
-
- # plot two lines in a box with independent X axes labeled
- # differently on top and bottom
- $pl->xyplot($x1, $y, XBOX  => 'bnst',  # bottom line, bottom numbers, ticks, subticks
-	              YBOX  => 'bnst'); # left line, left numbers, ticks, subticks
- $pl->xyplot($x2, $y, XBOX => 'cmst', # top line, top numbers, ticks, subticks
-	              YBOX => 'cst',  # right line, ticks, subticks
-	              BOX => [$x2->minmax, $y->minmax]);
-
-=head3 XERRORBAR
-
-Used only with L</xyplot>.  Draws horizontal error bars at all points (C<$x>, C<$y>) in the plot.
-Specify a PDL containing the same number of points as C<$x> and C<$y>
-which specifies the width of the error bar, which will be centered at (C<$x>, C<$y>).
-
-=head3 XLAB
-
-Specify a label for the X axis.
-
-=head3 XTICK
-
-Interval (in graph units/world coordinates) between major x axis tick marks.
-Specify zero (default) to allow PLplot to compute this automatically.
-
-=head3 YBOX
-
-Specify how to label the Y axis of the plot as a string of option letters.
-See L</XBOX>.
-
-=head3 YERRORBAR
-
-Used only for xyplot.  Draws vertical error bars at all points (C<$x>, C<$y>) in the plot.
-Specify a PDL containing the same number of points as C<$x> and C<$y>
-which specifies the width of the error bar, which will be centered at (C<$x>, C<$y>).
-
-=head3 YLAB
-
-Specify a label for the Y axis.
-
-=head3 YTICK
-
-Interval (in graph units/world coordinates) between major y axis tick marks.
-Specify zero (default) to allow PLplot to compute this automatically.
-
-=head3 ZRANGE
-
-For L</xyplot> (when C<COLORMAP> is specified), for
-L</shadeplot> and for L</colorkey>.
-Normally, the range of the Z variable (color) is taken as
-C<< $z->minmax >>.  If a different range is desired,
-specify it in C<ZRANGE>, like so:
-
-  $pl->shadeplot ($z, $nlevels, PALETTE => 'GREENRED', ZRANGE => [0,100]);
-
-or
-
-  $pl->xyplot ($x, $y, PALETTE  => 'RAINBOW', PLOTTYPE => 'POINTS',
-	               COLORMAP => $z,        ZRANGE => [-90,-20]);
-  $pl->colorkey  ($z, 'v', VIEWPORT => [0.93, 0.96, 0.13, 0.85],
-                       ZRANGE => [-90,-20]);
-
-=head1 METHODS
-
-These are the high-level, object oriented methods for PLplot.
-
-=head2 new
-
-=for ref
-
-Create an object representing a plot.
-
-=for usage
-
- Arguments:
- none.
-
- Supported options:
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-=for example
-
-  my $pl = PDL::Graphics::PLplot->new(DEV => 'png',  FILE => 'test.png');
-
-
-=head2 setparm
-
-=for ref
-
-Set options for a plot object.
-
-=for usage
-
- Arguments:
- none.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->setparm (TEXTSIZE => 2);
-
-=head2 xyplot
-
-=for ref
-
-Plot XY lines and/or points.  Also supports color scales for points.
-This function works with bad values.  If a bad value is specified for
-a points plot, it is omitted.  If a bad value is specified for a line
-plot, the bad value makes a gap in the line.  This is useful for
-drawing maps; for example C<$x> and C<$y> can be the continent boundary
-latitude and longitude.
-
-=for usage
-
- Arguments:
- $x, $y
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->xyplot($x, $y, PLOTTYPE => 'POINTS', COLOR => 'BLUEVIOLET', SYMBOL => 1, SYMBOLSIZE => 4);
-  $pl->xyplot($x, $y, PLOTTYPE => 'LINEPOINTS', COLOR => [50,230,30]);
-  $pl->xyplot($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
-
-=head2 stripplots
-
-=for ref
-
-Plot a set of strip plots with a common X axis, but with different Y axes.
-Looks like a stack of long, thin XY plots, all line up on the same X axis.
-
-=for usage
-
- Arguments:
- $xs -- 1D PDL with common X axis values, length = N
- $ys -- reference to a list of 1D PDLs with Y-axis values, length = N
-        or 2D PDL with N x M elements
- -- OR --
- $xs -- reference to a list of 1D PDLs with X-axis values
- $ys -- reference to a list of 1D PDLs with Y-axis values
- %opts -- Options hash
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  my $x  = sequence(20);
-  my $y1  = $x**2;
-  my $y2  = sqrt($x);
-  my $y3  = $x**3;
-  my $y4  = sin(($x/20) * 2 * $pi);
-  $ys  = cat($y1, $y2, $y3, $y4);
-  $pl->stripplots($x, $ys, PLOTTYPE => 'LINE', TITLE => 'functions',
-                           YLAB     => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                           COLOR    => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-  # Equivalent to above:
-  $pl->stripplots($x, [$y1, $y2, $y3, $y4],
-                           PLOTTYPE => 'LINE', TITLE => 'functions',
-                           YLAB     => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                           COLOR    => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-
-  # Here's something a bit different. Notice that different xs have
-  # different lengths.
-  $x1  = sequence(20);
-  $y1  = $x1**2;
-
-  $x2  = sequence(18);
-  $y2  = sqrt($x2);
-
-  $x3  = sequence(24);
-  $y3  = $x3**3;
-
-  my $x4  = sequence(27);
-  $a  = ($x4/20) * 2 * $pi;
-  my $y4  = sin($a);
-
-  $xs  = [$x1, $x2, $x3, $x4];
-  $ys  = [$y1, $y2, $y3, $y4];
-  $pl->stripplots($xs, $ys, PLOTTYPE => 'LINE', TITLE => 'functions',
-                YLAB => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                         COLOR => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-
-In addition, COLOR may be specified as a reference to a list of colors.  If
-this is done, the colors are applied separately to each plot.
-
-Also, the options Y_BASE and Y_GUTTER can be specified.  Y_BASE gives the Y offset
-of the bottom of the lowest plot (0-1, specified like a VIEWPORT, defaults to 0.1) and Y_GUTTER
-gives the gap between the graphs (0-1, default = 0.02).
-
-=head2 colorkey
-
-=for ref
-
-Plot a color key showing which color represents which value
-
-=for usage
-
- Arguments:
- $range   : A PDL which tells the range of the color values
- $orientation : 'v' for vertical color key, 'h' for horizontal
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  # Plot X vs. Y with Z shown by the color.  Then plot
-  # vertical key to the right of the original plot.
-  $pl->xyplot ($x, $y, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $z);
-  $pl->colorkey ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-
-
-=head2 shadeplot
-
-=for ref
-
-Create a shaded contour plot of 2D PDL 'z' with 'nsteps' contour levels.
-Linear scaling is used to map the coordinates of Z(X, Y) to world coordinates
-via the L</BOX> option.
-
-=for usage
-
- Arguments:
- $z : A 2D PDL which contains surface values at each XY coordinate.
- $nsteps : The number of contour levels requested for the plot.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  # vertical key to the right of the original plot.
-  # The BOX must be specified to give real coordinate values to the $z array.
-  $pl->shadeplot ($z, $nsteps, BOX => [-1, 1, -1, 1], PALETTE => 'RAINBOW', ZRANGE => [0,100]);
-  $pl->colorkey  ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85], ZRANGE => [0,100]);
-
-=head2 histogram
-
-=for ref
-
-Create a histogram of a 1-D variable.
-
-=for usage
-
- Arguments:
- $x : A 1D PDL
- $nbins : The number of bins to use in the histogram.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->histogram ($x, $nbins, BOX => [$min, $max, 0, 100]);
-
-=head2 bargraph
-
-=for ref
-
-Simple utility to plot a bar chart with labels on the X axis.
-The usual options can be specified, plus one other:  MAXBARLABELS
-specifies the maximum number of labels to allow on the X axis.
-The default is 20.  If this value is exceeded, then every other
-label is plotted.  If twice MAXBARLABELS is exceeded, then only
-every third label is printed, and so on.
-
-if UNFILLED_BARS is set to true, then plot the bars as outlines
-and not as filled rectangles.
-
-=for usage
-
- Arguments:
- $labels -- A reference to a perl list of strings.
- $values -- A PDL of values to be plotted.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $labels = ['one', 'two', 'three'];
-  $values = pdl(1, 2, 3);
-
-  # Note if TEXTPOSITION is specified, it must be in 4 argument mode (border mode):
-  # [$side, $disp, $pos, $just]
-  #
-  # Where side = 't', 'b', 'l', or 'r' for top, bottom, left and right
-  #              'tv', 'bv', 'lv' or 'rv' for top, bottom, left or right perpendicular to the axis.
-  #
-  #     disp is the number of character heights out from the edge
-  #     pos  is the position along the edge of the viewport, from 0 to 1.
-  #     just tells where the reference point of the string is: 0 = left, 1 = right, 0.5 = center.
-  #
-  # The '$pos' entry will be ignored (computed by the bargraph routine)
-  $pl->bargraph($labels, $values, MAXBARLABELS => 30, TEXTPOSITION => ['bv', 0.5, 1.0, 1.0]);
-
-=head2 text
-
-=for ref
-
-Write text on a plot.  Text can either be written
-with respect to the borders or at an arbitrary location and angle
-(see the L</TEXTPOSITION> entry).
-
-=for usage
-
- Arguments:
- $t : The text.
-
- Supported options:
- All options except:
-
- BACKGROUND
- DEV
- FILE
- FRAMECOLOR
- JUST
- PAGESIZE
- SUBPAGES
-
-(These must be set in call to 'new'.)
-
-=for example
-
-  $pl->text("Count", COLOR => 'PINK',
-	    TEXTPOSITION => ['t', 3, 0.5, 0.5]); # top, 3 units out, string ref. pt in
-                                                 # center of string, middle of axis
-
-=head2 close
-
-=for ref
-
-Close a PLplot object, writing out the file and cleaning up.
-
-=for usage
-
-Arguments:
-None
-
-Returns:
-Nothing
-
-This closing of the PLplot object can be done explicitly though the
-'close' method.  Alternatively, a DESTROY block does an automatic
-close whenever the PLplot object passes out of scope.
-
-=for example
-
-  $pl->close;
-
-=cut
-
-# pull in low level interface
-use vars qw(%_constants %_actions);
-
-# Colors (from rgb.txt) are stored as RGB triples
-# with each value from 0-255
-sub cc2t { [map {hex} split ' ', shift] }
-%_constants = (
-	       BLACK          => [  0,  0,  0],
-	       RED            => [240, 50, 50],
-	       YELLOW         => [255,255,  0],
-	       GREEN          => [  0,255,  0],
-	       AQUAMARINE     => [127,255,212],
-	       PINK           => [255,192,203],
-	       WHEAT          => [245,222,179],
-	       GREY           => [190,190,190],
-	       BROWN          => [165, 42, 42],
-	       BLUE           => [  0,  0,255],
-	       BLUEVIOLET     => [138, 43,226],
-	       CYAN           => [  0,255,255],
-	       TURQUOISE      => [ 64,224,208],
-	       MAGENTA        => [255,  0,255],
-	       SALMON         => [250,128,114],
-	       WHITE          => [255,255,255],
-               ROYALBLUE      => cc2t('2B 60 DE'),
-               DEEPSKYBLUE    => cc2t('3B B9 FF'),
-               VIOLET         => cc2t('8D 38 C9'),
-               STEELBLUE1     => cc2t('5C B3 FF'),
-               DEEPPINK       => cc2t('F5 28 87'),
-               MAGENTA        => cc2t('FF 00 FF'),
-               DARKORCHID1    => cc2t('B0 41 FF'),
-               PALEVIOLETRED2 => cc2t('E5 6E 94'),
-               TURQUOISE1     => cc2t('52 F3 FF'),
-               LIGHTSEAGREEN  => cc2t('3E A9 9F'),
-               SKYBLUE        => cc2t('66 98 FF'),
-               FORESTGREEN    => cc2t('4E 92 58'),
-               CHARTREUSE3    => cc2t('6C C4 17'),
-               GOLD2          => cc2t('EA C1 17'),
-               SIENNA1        => cc2t('F8 74 31'),
-               CORAL          => cc2t('F7 65 41'),
-               HOTPINK        => cc2t('F6 60 AB'),
-               LIGHTCORAL     => cc2t('E7 74 71'),
-               LIGHTPINK1     => cc2t('F9 A7 B0'),
-               LIGHTGOLDENROD => cc2t('EC D8 72'),
-	      );
-
-# a hash of subroutines to invoke when certain keywords are specified
-# These are called with arg(0) = $self (the plot object)
-#                   and arg(1) = value specified for keyword
-%_actions =
-  (
-
-
-   # Set color for index 0, the plot background
-   BACKGROUND => sub {
-     my $self  = shift;
-     my $color = _color(shift);
-     $self->{COLORS}[0] = $color;
-     plscolbg (@$color);
-   },
-
-   # set plotting box in world coordinates
-   BOX        => sub {
-     my $self  = shift;
-     my $box   = shift;
-     die "Box must be a ref to a four element array" unless (ref($box) =~ /ARRAY/ and @$box == 4);
-     $self->{BOX} = $box;
-   },
-
-   CHARSIZE   => sub { my $self = shift;
-                       $self->{CHARSIZE} = $_[0];
-                       plschr   (0, $_[0]) },  # 0 - N
-
-   COLOR =>
-   # maintain color map, set to specified rgb triple
-   sub {
-     my $self  = shift;
-     my $color = _color(shift);
-
-     # init.
-     $self->{COLORS} = [] unless exists($self->{COLORS});
-
-     my @idx = @{$self->{COLORS}}; # map of color index (0-15) to RGB triples
-     my $found = 0;
-     for (my $i=2;$i<@idx;$i++) {  # map entries 0 and 1 are reserved for BACKGROUND and FRAMECOLOR
-       if (_coloreq ($color, $idx[$i])) {
-	 $self->{CURRENT_COLOR_IDX} = $i;
-	 $found = 1;
-	 plscol0 ($self->{CURRENT_COLOR_IDX}, @$color);
-       }
-     }
-     return if ($found);
-
-     die "Too many colors used! (max 15)" if (@{$self->{COLORS}} > 14);
-
-     # add this color as index 2 or greater (entries 0 and 1 reserved)
-     my $idx = (@{$self->{COLORS}} > 1) ? @{$self->{COLORS}} : 2;
-     $self->{COLORS}[$idx]      = $color;
-     $self->{CURRENT_COLOR_IDX} = $idx;
-     plscol0 ($self->{CURRENT_COLOR_IDX}, @$color);
-   },
-
-   # set output device type
-   DEV        => sub { my $self = shift;
-                       my $dev  = shift;
-                       $self->{DEV} = $dev;
-                       plsdev   ($dev)
-                     },   # this must be specified with call to new!
-
-   # set PDL to plot into (alternative to specifying DEV)
-   MEM        => sub { my $self = shift;
-		       my $pdl  = shift;
-		       my $x    = $pdl->getdim(1);
-		       my $y    = $pdl->getdim(2);
-		       plsmem   ($x, $y, $pdl);
-		     },
-
-   # set output file
-   FILE       => sub { plsfnam  ($_[1]) },   # this must be specified with call to new!
-
-   # set color for index 1, the plot frame and text
-   FRAMECOLOR =>
-   # set color index 1, the frame color
-   sub {
-     my $self  = shift;
-     my $color = _color(shift);
-     $self->{COLORS}[1] = $color;
-     plscol0 (1, @$color);
-   },
-
-   # Set flag for equal scale axes
-   JUST => sub {
-     my $self  = shift;
-     my $just  = shift;
-     die "JUST must be 0 or 1 (defaults to 0)" unless ($just == 0 or $just == 1);
-     $self->{JUST} = $just;
-   },
-
-    LINEWIDTH  => sub {
-      my $self = shift;
-      my $wid  = shift;
-      die "LINEWIDTH must range from 0 to LARGE8" unless ($wid >= 0);
-      $self->{LINEWIDTH} = $wid;
-    },
-
-   LINESTYLE  => sub {
-     my $self = shift;
-     my $sty  = shift;
-     die "LINESTYLE must range from 1 to 8" unless ($sty >= 1 and $sty <= 8);
-     $self->{LINESTYLE} = $sty;
-   },
-
-   MAJTICKSIZE  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "MAJTICKSIZE must be greater than or equal to zero"
-       unless ($val >= 0);
-     plsmaj (0, $val);
-   },
-
-   MINTICKSIZE  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "MINTICKSIZE must be greater than or equal to zero"
-       unless ($val >= 0);
-     plsmin (0, $val);
-   },
-
-   NXSUB  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "NXSUB must be an integer greater than or equal to zero"
-       unless ($val >= 0 and int($val) == $val);
-     $self->{NXSUB} = $val;
-   },
-
-   NYSUB  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "NYSUB must be an integer greater than or equal to zero"
-       unless ($val >= 0 and int($val) == $val);
-     $self->{NYSUB} = $val;
-   },
-
-   # set driver options, example for ps driver, {text => 1} is accepted
-   OPTS => sub {
-     my $self = shift;
-     my $opts = shift;
-
-     foreach my $opt (keys %$opts) {
-       plsetopt ($opt, $$opts{$opt});
-     }
-   },
-
-   # set driver options, example for ps driver, {text => 1} is accepted
-   ORIENTATION => sub {
-     my $self   = shift;
-     my $orient = shift;
-
-     die "Orientation must be between 0 and 4" unless ($orient >= 0 and $orient <= 4);
-     $self->{ORIENTATION} = $orient;
-   },
-
-   PAGESIZE   =>
-     # set plot size in mm.  Only useful in call to 'new'
-     sub {
-       my $self = shift;
-       my $dims = shift;
-
-       die "plot size must be a 2 element array ref:  X size in pixels, Y size in pixels"
-	 if ((ref($dims) !~ /ARRAY/) || @$dims != 2);
-       $self->{PAGESIZE} = $dims;
-     },
-
-   PALETTE =>
-
-   # load some pre-done color map 1 setups
-   sub {
-     my $self = shift;
-     my $pal  = shift;
-
-     my %legal = (REVERSERAINBOW => 1, REVERSEGREYSCALE => 1, REDGREEN => 1, RAINBOW => 1, GREYSCALE => 1, GREENRED => 1);
-     if ($legal{$pal}) {
-       $self->{PALETTE} = $pal;
-       if      ($pal eq 'RAINBOW') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,300), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(0,0));
-       } elsif ($pal eq 'REVERSERAINBOW') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(270,-30), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(0,0));
-       } elsif ($pal eq 'GREYSCALE') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,0),   PDL->new(0,1), PDL->new(0,0), PDL->new(0,0));
-       } elsif ($pal eq 'REVERSEGREYSCALE') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,0),   PDL->new(1,0), PDL->new(0,0), PDL->new(0,0));
-       } elsif ($pal eq 'GREENRED') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(120,0), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(1,1));
-       } elsif ($pal eq 'REDGREEN') {
-	 plscmap1l (0, PDL->new(0,1), PDL->new(0,120), PDL->new(0.5, 0.5), PDL->new(1,1), PDL->new(1,1));
-       }
-     } else {
-       die "Illegal palette name.  Legal names are: " . join (" ", keys %legal);
-     }
-   },
-
-   PLOTTYPE =>
-   # specify plot type (LINE, POINTS, LINEPOINTS)
-   sub {
-     my $self = shift;
-     my $val  = shift;
-
-     my %legal = (LINE => 1, POINTS => 1, LINEPOINTS => 1);
-     if ($legal{$val}) {
-       $self->{PLOTTYPE} = $val;
-     } else {
-       die "Illegal plot type.  Legal options are: " . join (" ", keys %legal);
-     }
-   },
-
-   SUBPAGE =>
-   # specify which subpage to plot on 1-N or 0 (meaning 'next')
-   sub {
-     my $self = shift;
-     my $val  = shift;
-     my $err  = "SUBPAGE = \$npage where \$npage = 1-N or 0 (for 'next subpage')";
-     if ($val >= 0) {
-       $self->{SUBPAGE} = $val;
-     } else {
-       die $err;
-     }
-   },
-
-   SUBPAGES =>
-   # specify number of sub pages [nx, ny]
-   sub {
-     my $self = shift;
-     my $val  = shift;
-     my $err  = "SUBPAGES = [\$nx, \$ny] where \$nx and \$ny are between 1 and 127";
-     if (ref($val) =~ /ARRAY/ and @$val == 2) {
-       my ($nx, $ny) = @$val;
-       if ($nx > 0 and $nx < 128 and $ny > 0 and $ny < 128) {
-	 $self->{SUBPAGES} = [$nx, $ny];
-       } else {
-	 die $err;
-       }
-     } else {
-       die $err;
-     }
-   },
-
-   SYMBOL =>
-   # specify type of symbol to plot
-   sub {
-     my $self = shift;
-     my $val  = shift;
-
-     if ($val >= 0 && $val < 3000) {
-       $self->{SYMBOL} = $val;
-     } else {
-       die "Illegal symbol number.  Legal symbols are between 0 and 3000";
-     }
-   },
-
-   SYMBOLSIZE => sub {
-     my ($self, $size) = @_;
-     die "symbol size must be a real number from 0 to (large)" unless ($size >= 0);
-     $self->{SYMBOLSIZE} = $size;
-   },
-
-   TEXTPOSITION =>
-   # specify placement of text.  Either relative to border, specified as:
-   # [$side, $disp, $pos, $just]
-   # or
-   # inside plot window, specified as:
-   # [$x, $y, $dx, $dy, $just] (see POD doc for details)
-   sub {
-     my $self = shift;
-     my $val  = shift;
-
-     die "TEXTPOSITION value must be an array ref with either:
-          [$side, $disp, $pos, $just] or [$x, $y, $dx, $dy, $just]"
-       unless ((ref($val) =~ /ARRAY/) and ((@$val == 4) || (@$val == 5)));
-
-     if (@$val == 4) {
-       $self->{TEXTMODE} = 'border';
-     } else {
-       $self->{TEXTMODE} = 'plot';
-     }
-     $self->{TEXTPOSITION} = $val;
-   },
-
-   # draw a title for the graph
-   TITLE      => sub {
-     my $self = shift;
-     my $text = shift;
-     $self->{TITLE} = $text;
-   },
-
-   # Specify outline bars for bargraph
-   UNFILLED_BARS => sub {
-     my $self = shift;
-     my $val  = shift;
-     $self->{UNFILLED_BARS} = $val;
-   },
-
-   # set the location of the plotting window on the page
-   VIEWPORT => sub {
-     my $self  = shift;
-     my $vp    = shift;
-     die "Viewport must be a ref to a four element array"
-       unless (ref($vp) =~ /ARRAY/ and @$vp == 4);
-     $self->{VIEWPORT} = $vp;
-   },
-
-   XBOX       =>
-     # set X axis label options.  See pod for definitions.
-     sub {
-       my $self = shift;
-       my $opts = lc shift;
-
-       my @opts = split '', $opts;
-       map { 'abcdfghilmnst' =~ /$_/i || die "Illegal option $_.  Only abcdfghilmnst permitted" } @opts;
-
-       $self->{XBOX} = $opts;
-     },
-
-   # draw an X axis label for the graph
-   XLAB       => sub {
-     my $self = shift;
-     my $text = shift;
-     $self->{XLAB} = $text;
-   },
-
-   XTICK  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "XTICK must be greater than or equal to zero"
-       unless ($val >= 0);
-     $self->{XTICK} = $val;
-   },
-
-   YBOX       =>
-     # set Y axis label options.  See pod for definitions.
-     sub {
-       my $self = shift;
-       my $opts = shift;
-
-       my @opts = split '', $opts;
-       map { 'abcfghilmnstv' =~ /$_/i || die "Illegal option $_.  Only abcfghilmnstv permitted" } @opts;
-
-       $self->{YBOX} = $opts;
-     },
-
-   # draw an Y axis label for the graph
-   YLAB       => sub {
-     my $self = shift;
-     my $text = shift;
-     $self->{YLAB} = $text;
-   },
-
-   YTICK  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "YTICK must be greater than or equal to zero"
-       unless ($val >= 0);
-     $self->{YTICK} = $val;
-   },
-
-   ZRANGE  => sub {
-     my $self = shift;
-     my $val  = shift;
-     die "ZRANGE must be a perl array ref with min and max Z values"
-       unless (ref($val) =~ /ARRAY/ && @$val == 2);
-     $self->{ZRANGE} = $val;
-   },
-
-);
-
-
-#
-## Internal utility routines
-#
-
-# handle color as string in _constants hash or [r,g,b] triple
-# Input:  either color name or [r,g,b] array ref
-# Output: [r,g,b] array ref or exception
-sub _color {
-  my $c = shift;
-  if      (ref($c) =~ /ARRAY/) {
-    return $c;
-  } elsif ($c = $_constants{$c}) {
-    return $c;
-  } else {
-    die "Color $c not defined";
-  }
-}
-
-# return 1 if input [r,g,b] triples are equal.
-sub _coloreq {
-  my ($a, $b) = @_;
-  for (my $i=0;$i<3;$i++) { return 0 if ($$a[$i] != $$b[$i]); }
-  return 1;
-}
-
-# Initialize plotting window given the world coordinate box and
-# a 'justify' flag (for equal axis scales).
-sub _setwindow {
-
-  my $self = shift;
-
-  # choose correct subwindow
-  pladv ($self->{SUBPAGE}) if (exists ($self->{SUBPAGE}));
-  delete ($self->{SUBPAGE});  # get rid of SUBPAGE so future plots will stay on same
-                              # page unless user asks for specific page
-
-  my $box  = $self->{BOX} || [0,1,0,1]; # default window
-
-  sub MAX { ($_[0] > $_[1]) ? $_[0] : $_[1]; }
-
-  # get subpage offsets from page left/bottom of image
-  my ($spxmin, $spxmax, $spymin, $spymax) = (PDL->new(0),PDL->new(0),PDL->new(0),PDL->new(0));
-  plgspa($spxmin, $spxmax, $spymin, $spymax);
-  $spxmin = $spxmin->at(0);
-  $spxmax = $spxmax->at(0);
-  $spymin = $spymin->at(0);
-  $spymax = $spymax->at(0);
-  my $xsize = $spxmax - $spxmin;
-  my $ysize = $spymax - $spymin;
-
-  my @vp = @{$self->{VIEWPORT}};  # view port xmin, xmax, ymin, ymax in fraction of image size
-
-  # if JUSTify is zero, set to the user specified (or default) VIEWPORT
-  if ($self->{JUST} == 0) {
-    plvpor(@vp);
-
-  # compute viewport to allow the same scales for both axes
-  } else {
-    my $p_def = PDL->new(0);
-    my $p_ht  = PDL->new(0);
-    plgchr ($p_def, $p_ht);
-    $p_def = $p_def->at(0);
-    my $lb = 8.0 * $p_def;
-    my $rb = 5.0 * $p_def;
-    my $tb = 5.0 * $p_def;
-    my $bb = 5.0 * $p_def;
-    my $dx = $$box[1] - $$box[0];
-    my $dy = $$box[3] - $$box[2];
-    my $xscale = $dx / ($xsize - $lb - $rb);
-    my $yscale = $dy / ($ysize - $tb - $bb);
-    my $scale  = MAX($xscale, $yscale);
-    my $vpxmin = MAX($lb, 0.5 * ($xsize - $dx / $scale));
-    my $vpxmax = $vpxmin + ($dx / $scale);
-    my $vpymin = MAX($bb, 0.5 * ($ysize - $dy / $scale));
-    my $vpymax = $vpymin + ($dy / $scale);
-    plsvpa($vpxmin, $vpxmax, $vpymin, $vpymax);
-    $self->{VIEWPORT} = [$vpxmin/$xsize, $vpxmax/$xsize, $vpymin/$ysize, $vpymax/$ysize];
-  }
-
-  # set up world coords in window
-  plwind (@$box);
-
-}
-
-# Add title and axis labels.
-sub _drawlabels {
-
-  my $self = shift;
-
-  plcol0  (1); # set to frame color
-  plmtex   (2.5, 0.5, 0.5, 't', $self->{TITLE}) if ($self->{TITLE});
-  plmtex   (3.0, 0.5, 0.5, 'b', $self->{XLAB})  if ($self->{XLAB});
-  plmtex   (3.5, 0.5, 0.5, 'l', $self->{YLAB})  if ($self->{YLAB});
-  plcol0  ($self->{CURRENT_COLOR_IDX}); # set back
-
-}
-
-
-#
-## user-visible routines
-#
-
-# Pool of PLplot stream numbers.  One of these stream numbers is taken when 'new' is called
-# and when the corresponding 'close' is called, it is returned to the pool.  The pool is
-# just a queue:  'new' shifts stream numbers from the top of the queue, 'close' pushes them
-# back on the bottom of the queue.
-my @plplot_stream_pool = (0..99);
-
-# This routine starts out a plot.  Generally one specifies
-# DEV and FILE (device and output file name) as options.
-sub new {
-  my $type = shift;
-  my $self = {};
-
-  # set up object
-  $self->{PLOTTYPE} = 'LINE';
-  # $self->{CURRENT_COLOR_IDX} = 1;
-  $self->{COLORS} = [];
-
-  bless $self, $type;
-
-  # set stream number first
-  $self->{STREAMNUMBER} = shift @plplot_stream_pool;
-  die "No more PLplot streams left, too many open PLplot objects!" if (!defined($self->{STREAMNUMBER}));
-  plsstrm($self->{STREAMNUMBER});
-
-  # set background and frame color first
-  $self->setparm(BACKGROUND => 'WHITE',
-		 FRAMECOLOR => 'BLACK');
-
-  # set defaults, allow input options to override
-  my %opts = (
-	      COLOR      => 'BLACK',
-	      XBOX       => 'BCNST',
-	      YBOX       => 'BCNST',
-	      JUST       => 0,
-	      SUBPAGES   => [1,1],
-	      VIEWPORT   => [0.1, 0.87, 0.13, 0.82],
-	      SUBPAGE    => 0,
-	      PAGESIZE   => [600, 500],
-	      LINESTYLE  => 1,
-              LINEWIDTH  => 0,
-              SYMBOL     => 751, # a small square
-	      NXSUB      => 0,
-	      NYSUB      => 0,
-	      ORIENTATION=> 0,
-	      XTICK      => 0,
-	      YTICK      => 0,
-	      CHARSIZE   => 1,
-	      @_);
-
-
-  # apply options
-  $self->setparm(%opts);
-
-  # Do initial setup
-  plspage (0, 0, @{$self->{PAGESIZE}}, 0, 0) if (defined($self->{PAGESIZE}));
-  plssub (@{$self->{SUBPAGES}});
-  plfontld (1); # extented symbol pages
-  plscmap0n (16);   # set up color map 0 to 16 colors.  Is this needed?
-  plscmap1n (128);  # set map 1 to 128 colors (should work for devices with 256 colors)
-  plinit ();
-
-  # set page orientation
-  plsdiori ($self->{ORIENTATION});
-
-  # set up plotting box
-  $self->_setwindow;
-
-  return $self;
-}
-
-# set parameters.  Called from user directly or from other routines.
-sub setparm {
-  my $self = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply all options
- OPTION:
-  foreach my $o (keys %opts) {
-    unless (exists($_actions{$o})) {
-      warn "Illegal option $o, ignoring";
-      next OPTION;
-    }
-    &{$_actions{$o}}($self, $opts{$o});
-  }
-}
-
-# handle 2D plots
-sub xyplot {
-  my $self = shift;
-  my $x    = shift;
-  my $y    = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # only process COLORMAP entries once
-  my $z = $opts{COLORMAP};
-  delete ($opts{COLORMAP});
-
-  # handle ERRORBAR options
-  my $xeb = $opts{XERRORBAR};
-  my $yeb = $opts{YERRORBAR};
-  delete ($opts{XERRORBAR});
-  delete ($opts{YERRORBAR});
-
-  # apply options
-  $self->setparm(%opts);
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [$x->minmax, $y->minmax];
-  }
-
-  # set up viewport, subpage, world coordinates
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-  # set the color according to the color specified in the object
-  # (we don't do this as an option, because then the frame might
-  # get the color requested for the line/points
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  # set line style for plot only (not box)
-  pllsty ($self->{LINESTYLE});
-
-  # set line width for plot only (not box)
-  plwid  ($self->{LINEWIDTH});
-
-  # Plot lines if requested
-  if  ($self->{PLOTTYPE} =~ /LINE/) {
-    plline ($x, $y);
-  }
-
-  # set line width back
-  plwid  (0);
-
-  # plot points if requested
-  if ($self->{PLOTTYPE} =~ /POINTS/) {
-    my $c = $self->{SYMBOL};
-    unless (defined($c)) {
-
-      # the default for $c is a PDL of ones with shape
-      # equal to $x with the first dimension removed
-      my $z = PDL->zeroes($x->nelem);
-      $c = PDL->ones($z->zcover) unless defined($c);
-    }
-    plssym   (0, $self->{SYMBOLSIZE}) if (defined($self->{SYMBOLSIZE}));
-
-    if (defined($z)) {  # if a color range plot requested
-      my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $z->minmax;
-      plcolorpoints ($x, $y, $z, $c, $min, $max);
-    } else {
-      plsym ($x, $y, $c);
-    }
-  }
-
-  # Plot error bars, if requested
-  if (defined($xeb)) {
-    # horizontal (X) error bars
-    plerrx ($x->nelem, $x - $xeb/2, $x + $xeb/2, $y);
-  }
-
-  if (defined($yeb)) {
-    # vertical (Y) error bars
-    plerry ($y->nelem, $x, $y - $yeb/2, $y + $yeb/2);
-  }
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-
-# Handle sets of 2D strip plots sharing one X axis.  Input is
-# $self -- PLplot object with existing options
-# $xs   -- Ref to list of 1D PDLs with X values
-# $ys   -- Ref to list of 1D PDLs with Y values
-#          or a 2D PDL
-# %opts -- Options values
-sub stripplots {
-
-  my $self    = shift;
-  my $xs      = shift;
-  my $yargs   = shift;
-
-  my %opts = @_;
-
-  # NYTICK => number of y axis ticks
-  my $nytick = $opts{NYTICK} || 2;
-  delete ($opts{NYTICK});
-
-  # only process COLORMAP entries once
-  my $zs = $opts{COLORMAP};
-  delete ($opts{COLORMAP});
-
-  # handle XLAB, YLAB and TITLE options
-  my $title = $opts{TITLE} || '';
-  my $xlab  = $opts{XLAB}  || '';
-  my @ylabs = defined($opts{YLAB}) && (ref($opts{YLAB}) =~ /ARRAY/) ? @{$opts{YLAB}} : ();
-  delete @opts{qw(TITLE XLAB YLAB)};
-
-  # Ensure we're dealing with an array reference
-  my $ys;
-  if (ref ($yargs) eq 'ARRAY') {
-    $ys = $yargs;
-  }
-  elsif (ref ($yargs) =~ /PDL/) {
-    $ys = [dog $yargs];
-  }
-  else {
-    barf("stripplots requires that its second argument be either a 2D piddle or\na reference to a list of 1D piddles, but you provided neither.");
-  }
-
-# This doesn't work because $xs can be an anonymous array, too
-#  # Let's be sure the user sent us what we expected:
-#  foreach (@$ys) {
-#    barf ("stripplots needs to have piddles for its y arguments!")
-#      unless (ref =~ /PDL/);
-#    barf("stripplots requires that the x and y dimensions agree!")
-#      unless ($_->nelem == $xs->nelem);
-#  }
-
-  my $nplots = @$ys;
-
-  # Use list of colors, or single color.  If COLOR not specified, default to BLACK for each graph
-  my @colors = (defined ($opts{COLOR}) && ref($opts{COLOR}) =~ /ARRAY/) ? @{$opts{COLOR}}
-             :  defined ($opts{COLOR})                                  ? ($opts{COLOR}) x $nplots
-             : ('BLACK') x $nplots;
-  delete @opts{qw(COLOR)};
-
-  my $y_base   = defined($opts{Y_BASE})   ? $opts{Y_BASE}   : 0.1;  # Y offset to start bottom plot
-  my $y_gutter = defined($opts{Y_GUTTER}) ? $opts{Y_GUTTER} : 0.02; # Y gap between plots
-  delete @opts{qw(Y_BASE Y_GUTTER)};
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($xmin, $xmax);
-  if (ref ($xs) =~ /PDL/) {
-    ($xmin, $xmax) = $xs->minmax;
-  }
-  else {
-    $xmin = pdl(map { $_->min } @$xs)->min;
-    $xmax = pdl(map { $_->max } @$xs)->max;
-  }
-
-  SUBPAGE:
-    for (my $subpage=0;$subpage<$nplots;$subpage++) {
-
-      my $y = $ys->[$subpage];
-      my $x = ref ($xs) =~ /PDL/ ? $xs : $xs->[$subpage];
-      my $mask = $y->isgood;
-      $y = $y->where($mask);
-      $x = $x->where($mask);
-      my $z = $zs->slice(":,($subpage)")->where($mask)      if (defined($zs));
-      my $yeb  = $yebs->slice(":,($subpage)")->where($mask) if (defined($yebs));
-      my $ylab = $ylabs[$subpage];
-
-      my $bottomplot = ($subpage == 0);
-      my $topplot    = ($subpage == $nplots-1);
-
-      my $xbox = 'bc';
-      $xbox = 'cstnb' if ($bottomplot);
-
-      my $box = $opts{BOX};
-      my $yrange = defined($box) ? $$box[3] - $$box[2] : $y->max - $y->min;
-      my $del = $yrange ? $yrange * 0.05 : 1;
-      my @ybounds = ($y->min - $del, $y->max + $del);
-      my $ytick = ($yrange/$nytick);
-      my @COLORMAP  = (COLORMAP => $z)    if defined($z);
-      $self->xyplot($x, $y,
-		  COLOR     => $colors[$subpage],
-		  BOX       => defined($box) ? $box : [$xmin, $xmax, @ybounds],
-		  XBOX      => $xbox,
-		  YBOX      => 'BCNT',
-                  YTICK     => $ytick,
-                  MAJTICKSIZE => 0.6,
-		  CHARSIZE  => 0.4,
-                  @COLORMAP,
-		  VIEWPORT  => [
-				0.15,
-				0.9,
-                                $y_base             + ($subpage     * (0.8/$nplots)),
-                                $y_base - $y_gutter + (($subpage+1) * (0.8/$nplots)),
-				],
-		  );
-
-      $self->text($ylab,  TEXTPOSITION => ['L', 4, 0.5, 0.5], COLOR => 'BLACK', CHARSIZE => 0.6) if (defined($ylab));
-      $self->text($xlab,  TEXTPOSITION => ['B', 3, 0.5, 0.5], COLOR => 'BLACK', CHARSIZE => 0.6) if ($xlab && $bottomplot);
-      $self->text($title, TEXTPOSITION => ['T', 2, 0.5, 0.5], COLOR => 'BLACK', CHARSIZE => 1.3) if ($title && $topplot);
-
-    }
-
-}
-
-
-# Draw a color key or wedge showing the scale of map1 colors
-sub colorkey {
-  my $self = shift;
-  my $var  = shift;
-  my $orientation = shift; # 'v' (for vertical) or 'h' (for horizontal)
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(%opts);
-
-  # set up viewport, subpage, world coordinates
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # Allow user to set X, Y box type for color key scale.  D. Hunt 1/7/2009
-  my $xbox = exists($self->{XBOX}) ? $self->{XBOX} : 'TM';
-  my $ybox = exists($self->{YBOX}) ? $self->{YBOX} : 'TM';
-
-  my @box;
-
-  plcol0  (1); # set to frame color
-
-  my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $var->minmax;
-
-  # plot box
-  if      ($orientation eq 'v') {
-    # set world coordinates based on input variable
-    @box = (0, 1, $min, $max);
-    plwind (@box);
-    plbox (0, 0, 0, 0, '', $ybox);  # !!! note out of order call
-  } elsif ($orientation eq 'h') {
-    @box = ($min, $max, 0, 1);
-    plwind (@box);
-    plbox (0, 0, 0, 0, $xbox, '');  # !!! note out of order call
-  } else {
-    die "Illegal orientation value: $orientation.  Should be 'v' (vertical) or 'h' (horizontal)";
-  }
-
-  # restore color setting
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  # This is the number of colors shown in the color wedge.  Make
-  # this smaller for gif images as these are limited to 256 colors total.
-  # D. Hunt 8/9/2006
-  my $ncols = ($self->{DEV} =~ /gif/) ? 32 : 128;
-
-  if ($orientation eq 'v') {
-    my $yinc = ($box[3] - $box[2])/$ncols;
-    my $y0 = $box[2];
-    for (my $i=0;$i<$ncols;$i++) {
-      $y0 = $box[2] + ($i * $yinc);
-      my $y1 = $y0 + $yinc;
-      PDL::Graphics::PLplot::plcol1($i/$ncols);
-
-      # Instead of using plfill (which is not supported on some devices)
-      # use multiple calls to plline to color in the space. D. Hunt 8/9/2006
-      foreach my $inc (0..9) {
-        my $frac = $inc * 0.1;
-        my $y = $y0 + (($y1 - $y0) * $frac);
-        PDL::Graphics::PLplot::plline (PDL->new(0,1), PDL->new($y,$y));
-      }
-
-    }
-  } else {
-    my $xinc = ($box[1] - $box[0])/$ncols;
-    my $x0 = $box[0];
-    for (my $i=0;$i<$ncols;$i++) {
-      $x0 = $box[0] + ($i * $xinc);
-      my $x1 = $x0 + $xinc;
-      PDL::Graphics::PLplot::plcol1($i/$ncols);
-
-      # Instead of using plfill (which is not supported on some devices)
-      # use multiple calls to plline to color in the space. D. Hunt 8/9/2006
-      foreach my $inc (0..9) {
-        my $frac = $inc * 0.1;
-        my $x = $x0 + (($x1 - $x0) * $frac);
-        PDL::Graphics::PLplot::plline (PDL->new($x,$x), PDL->new(0,1));
-      }
-
-    }
-  }
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# handle shade plots of gridded (2D) data
-sub shadeplot {
-  my $self   = shift;
-  my $z      = shift;
-  my $nsteps = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($nx, $ny) = $z->dims;
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [0, $nx, 0, $ny];
-  }
-
-  # set up plotting box
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-  my ($min, $max) = exists ($self->{ZRANGE}) ? @{$self->{ZRANGE}} : $z->minmax;
-  my $clevel = ((PDL->sequence($nsteps)*(($max - $min)/($nsteps-1))) + $min);
-
-  # may add as options later.  Now use constants
-  my $fill_width = 2;
-  my $cont_color = 0;
-  my $cont_width = 0;
-
-  my $rectangular = 1; # only false for non-linear coord mapping (not done yet in perl)
-
-  # map X coords linearly to X range, Y coords linearly to Y range
-  my $xmap = ((PDL->sequence($nx)*(($self->{BOX}[1] - $self->{BOX}[0])/($nx - 1))) + $self->{BOX}[0]);
-  my $ymap = ((PDL->sequence($ny)*(($self->{BOX}[3] - $self->{BOX}[2])/($ny - 1))) + $self->{BOX}[2]);
-
-  my $grid = plAllocGrid ($xmap, $ymap);
-
-  plshades($z, @{$self->{BOX}}, $clevel, $fill_width,
-           $cont_color, $cont_width, $rectangular,
-	   0, \&pltr1, $grid);
-
-  plFreeGrid ($grid);
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# handle histograms
-sub histogram {
-  my $self   = shift;
-  my $x      = shift;
-  my $nbins  = shift;
-
-  my %opts = @_;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($min, $max) = $x->minmax;
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [$min, $max, 0, $x->nelem]; # box probably too tall!
-  }
-
-  # set up plotting box
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 $self->{XBOX}, $self->{YBOX}); # !!! note out of order call
-
-  # set line style for plot only (not box)
-  pllsty ($self->{LINESTYLE});
-
-  # set line width for plot only (not box)
-  plwid  ($self->{LINEWIDTH});
-
-  # set color for histograms
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  plhist ($x, $min, $max, $nbins, 1);  # '1' is oldbins parm:  dont call plenv!
-
-  # set line width back
-  plwid  (0);
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# Draw bar graphs
-sub bargraph {
-  my $self   = shift;
-  my $labels = shift; # ref to perl list of labels for bars
-  my $values = shift; # pdl of values for bars
-
-  my %opts = @_;
-
-  # max number of readable labels on x axis
-  my $maxlab = defined($opts{MAXBARLABELS}) ? $opts{MAXBARLABELS} : 20;
-  delete ($opts{MAXBARLABELS});
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-  my $xmax = scalar(@$labels);
-
-  # apply options
-  $self->setparm(%opts);
-
-  my ($ymin, $ymax) = $values->minmax;
-
-  unless (exists($self->{BOX})) {
-    $self->{BOX} = [0, $xmax, $ymin, $ymax]; # box probably too tall!
-  }
-
-  # set up plotting box
-  $self->_setwindow;
-
-  # draw labels
-  $self->_drawlabels;
-
-  # plot box
-  plcol0  (1); # set to frame color
-  plbox ($self->{XTICK}, $self->{NXSUB}, $self->{YTICK}, $self->{NYSUB},
-	 'bc', $self->{YBOX}); # !!! note out of order call
-
-  # Now respect TEXTPOSITION setting if TEXTMODE eq 'border'
-  # This allows the user to tweak the label placement.  D. Hunt 9/4/2007
-  my ($side, $disp, $foo, $just) = ('BV', 0.2, 0, 1.0);
-  if (defined($self->{TEXTMODE}) && $self->{TEXTMODE} eq 'border') {
-    ($side, $disp, $foo, $just) = @{$self->{TEXTPOSITION}};
-  }
-
-  # plot labels
-  plschr   (0, $self->{CHARSIZE} * 0.7); # use smaller characters
-  my $pos = 0;
-  my $skip   = int($xmax/$maxlab) + 1;
-  for (my $i=0;$i<$xmax;$i+=$skip) {
-    $pos = ((0.5+$i)/$xmax);
-    my $lab = $$labels[$i];
-    plmtex ($disp, $pos, $just, $side, $lab); # !!! out of order parms
-  }
-
-  plcol0  ($self->{CURRENT_COLOR_IDX}); # set back to line color
-
-  # set line style for plot only (not box)
-  pllsty ($self->{LINESTYLE});
-
-  # set line width for plot only (not box)
-  plwid  ($self->{LINEWIDTH});
-
-  # draw bars
-  if ($self->{UNFILLED_BARS}) {
-    plunfbox (PDL->sequence($xmax)+0.5, $values);
-  } else {
-    plfbox (PDL->sequence($xmax)+0.5, $values);
-  }
-
-  # set line width back
-  plwid  (0);
-
-  # set char size back
-  plschr (0, $self->{CHARSIZE});
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# Add text to a plot
-sub text {
-  my $self = shift;
-  my $text = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # apply options
-  $self->setparm(@_);
-
-  # set the color according to the color specified in the object
-  plcol0  ($self->{CURRENT_COLOR_IDX});
-
-  # plot either relative to border, or inside view port
-  if      ($self->{TEXTMODE} eq 'border') {
-    my ($side, $disp, $pos, $just) = @{$self->{TEXTPOSITION}};
-    plmtex ($disp, $pos, $just, $side, $text); # !!! out of order parms
-  } elsif ($self->{TEXTMODE} eq 'plot') {
-    my ($x, $y, $dx, $dy, $just) = @{$self->{TEXTPOSITION}};
-    plptex ($x, $y, $dx, $dy, $just, $text);
-  }
-
-  # Flush the PLplot stream.
-  plflush();
-}
-
-# Clear the current page. This should only be used with interactive devices!
-sub clear {
-  my $self = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  plclear();
-  return;
-}
-
-# Get mouse click coordinates (OO version). This should only be used with interactive devices!
-sub cursor {
-  my $self = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  # Flush the stream, to make sure the plot is visible & current
-  plflush();
-
-  # Get the cursor position
-  my %gin = plGetCursor();
-
-  # Return an array with the coordinates of the mouse click
-  return ($gin{"wX"}, $gin{"wY"}, $gin{"pX"}, $gin{"pY"}, $gin{"dX"}, $gin{"dY"});
-}
-
-# Explicitly close a plot and free the object
-sub close {
-  my $self = shift;
-
-  # Set PLplot to right output stream
-  plsstrm($self->{STREAMNUMBER});
-
-  plend1 ();
-
-  # Return this stream number to the pool.
-  push (@plplot_stream_pool, $self->{STREAMNUMBER});
-  delete $self->{STREAMNUMBER};
-
-  return;
-}
-EOD
-
-# Used throughout when generating documentation.
-my $doc;
-
-# Necessary includes for .xs file
-pp_addhdr(<<'EOH');
-#include <plplot.h>
-#include <plplotP.h>
-#include <plevent.h>
-#include <stdio.h>
-
-#ifdef plwidth
-#define c_plwid c_plwidth
-#endif
-
-EOH
-
-# The create_low_level_constants function is used to make the #define'd
-# constants in plplot.h available in Perl in the form of functions.  It
-# should be then possible to write code like this:
-#
-#    plParseOpts (\@ARGV, PL_PARSE_SKIP | PL_PARSE_NOPROGRAM);
-
-sub create_low_level_constants {
-  my $defn = shift;
-  my @lines = split (/\n/, $defn);
-
-  foreach my $line (@lines) {
-    next if (($line =~ /^\#/) or ($line =~ /^\s*$/));
-    foreach my $const ($line =~ /([^\s]+)/g) {
-      my $func = <<"EOC";
-int
-$const()
-PROTOTYPE:
-CODE:
-  RETVAL = $const;
-OUTPUT:
-  RETVAL
-EOC
-    pp_addxs ($func);
-    pp_add_exported ($const);
-    }
-  }
-}
-
-create_low_level_constants (<<'EODEF');
-
-# Definitions used in plParseOpts
-
-PL_PARSE_PARTIAL
-PL_PARSE_FULL
-PL_PARSE_QUIET
-PL_PARSE_NODELETE
-PL_PARSE_SHOWALL
-PL_PARSE_OVERRIDE
-PL_PARSE_NOPROGRAM
-PL_PARSE_NODASH
-PL_PARSE_SKIP
-
-# Definitions for plmesh and plsurf3d
-
-DRAW_LINEX
-DRAW_LINEY
-DRAW_LINEXY
-MAG_COLOR
-BASE_CONT
-TOP_CONT
-SURF_CONT
-DRAW_SIDES
-FACETED
-MESH
-
-# fonts
-
-PL_FCI_SANS
-PL_FCI_MONO
-
-# Input event (especially keyboard) definitions for use from plplot
-# event handlers.
-
-PLK_BackSpace PLK_Tab PLK_Linefeed PLK_Return PLK_Escape PLK_Delete
-PLK_Clear PLK_Pause PLK_Scroll_Lock PLK_Home PLK_Left PLK_Up PLK_Right
-PLK_Down PLK_Prior PLK_Next PLK_End PLK_Begin PLK_Select PLK_Print
-PLK_Execute PLK_Insert PLK_Undo PLK_Redo PLK_Menu PLK_Find PLK_Cancel
-PLK_Help PLK_Break PLK_Mode_switch PLK_script_switch PLK_Num_Lock
-PLK_KP_Space PLK_KP_Tab PLK_KP_Enter PLK_KP_F1 PLK_KP_F2 PLK_KP_F3
-PLK_KP_F4 PLK_KP_Equal PLK_KP_Multiply PLK_KP_Add PLK_KP_Separator
-PLK_KP_Subtract PLK_KP_Decimal PLK_KP_Divide PLK_KP_0 PLK_KP_1
-PLK_KP_2 PLK_KP_3 PLK_KP_4 PLK_KP_5 PLK_KP_6 PLK_KP_7 PLK_KP_8
-PLK_KP_9 PLK_F1 PLK_F2 PLK_F3 PLK_F4 PLK_F5 PLK_F6 PLK_F7 PLK_F8
-PLK_F9 PLK_F10 PLK_F11 PLK_L1 PLK_F12 PLK_L2 PLK_F13 PLK_L3 PLK_F14
-PLK_L4 PLK_F15 PLK_L5 PLK_F16 PLK_L6 PLK_F17 PLK_L7 PLK_F18 PLK_L8
-PLK_F19 PLK_L9 PLK_F20 PLK_L10 PLK_F21 PLK_R1 PLK_F22 PLK_R2 PLK_F23
-PLK_R3 PLK_F24 PLK_R4 PLK_F25 PLK_R5 PLK_F26 PLK_R6 PLK_F27 PLK_R7
-PLK_F28 PLK_R8 PLK_F29 PLK_R9 PLK_F30 PLK_R10 PLK_F31 PLK_R11 PLK_F32
-PLK_R12 PLK_R13 PLK_F33 PLK_F34 PLK_R14 PLK_F35 PLK_R15 PLK_Shift_L
-PLK_Shift_R PLK_Control_L PLK_Control_R PLK_Caps_Lock PLK_Shift_Lock
-PLK_Meta_L PLK_Meta_R PLK_Alt_L PLK_Alt_R PLK_Super_L PLK_Super_R
-PLK_Hyper_L PLK_Hyper_R
-
-# Type of gridding algorithm for plgriddata ()
-
-GRID_CSA
-GRID_DTLI
-GRID_NNI
-GRID_NNIDW
-GRID_NNLI
-GRID_NNAIDW
-
-EODEF
-
-create_low_level_constants (<<'EODEF') if ($plversion->{'c_pllegend'});
-
-# Definitions for plslabelfunc
-
-PL_X_AXIS
-PL_Y_AXIS
-PL_Z_AXIS
-
-# Definitions for colorbar
-
-PL_COLORBAR_SHADE
-PL_COLORBAR_SHADE_LABEL
-PL_COLORBAR_IMAGE
-PL_COLORBAR_GRADIENT
-PL_COLORBAR_CAP_LOW
-PL_COLORBAR_CAP_HIGH
-PL_COLORBAR_LABEL_LEFT
-PL_COLORBAR_LABEL_RIGHT
-PL_COLORBAR_LABEL_TOP
-PL_COLORBAR_LABEL_BOTTOM
-
-# Definitions for pllegend
-
-PL_LEGEND_BACKGROUND
-PL_LEGEND_BOUNDING_BOX
-PL_LEGEND_COLOR_BOX
-PL_LEGEND_LINE
-PL_LEGEND_NONE
-PL_LEGEND_ROW_MAJOR
-PL_LEGEND_SYMBOL
-PL_LEGEND_TEXT_LEFT
-PL_POSITION_BOTTOM
-PL_POSITION_INSIDE
-PL_POSITION_LEFT
-PL_POSITION_OUTSIDE
-PL_POSITION_RIGHT
-PL_POSITION_SUBPAGE
-PL_POSITION_TOP
-PL_POSITION_VIEWPORT
-
-EODEF
-
-# This subroutine is used to reorder PP_DEF arguments into the
-# standard plplot order.  This is necessary for some plplot functions
-# with a mixture of PDL and non-PDL arguments, since pp_def requires
-# all non-PDL (OtherPars) arguments to go at the end of the argument list
-pp_addpm (<<'EOPM');
-sub reorder {
-  my $name = shift;
-  my %reorder = (
-                 plaxes       => [0,1,6,2,3,7,4,5],
-		 plbox        => [4,0,1,5,2,3], # 4th arg -> 0th arg, 0th arg -> 1st arg, etc
-                 plbox3       => [6,7,0,1,8,9,2,3,10,11,4,5],
-                 plmtex       => [3,0,1,2,4],
-                 plmtex3      => [3,0,1,2,4],
-                 plstart      => [2,0,1],
-                 plstripc     => [13,14,0,1,2,3,4,5,6,7,8,9,10,11,12,15,16,17,18],
-                 plmap        => [4,5,0,1,2,3],
-                 plmeridians  => [6,0,1,2,3,4,5],
-                 plshades     => [0,10,1,2,3,4,5,6,7,8,9,11,12],
-                 plshade1     => [0,15,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17],
-		);
-  my $ordering = $reorder{$name};
-  die "Cannot find argument reordering for $name" if (!defined($ordering));
-  my @out;
-  for (my $i=0;$i<@_;$i++) {
-    $out[$$ordering[$i]] = $_[$i];
-  }
-  return @out;
-}
-
-# Routine for users to set normal plplot argument order
-sub plplot_use_standard_argument_order {
-  $PDL::Graphics::PLplot::standard_order = shift;
-}
-EOPM
-pp_add_exported('plplot_use_standard_argument_order');
-
-=head1 LOW-LEVEL INTERFACE
-=cut
-
-pp_addpm (<<'EOPM');
-
-=pod
-
-The PDL low-level interface to the PLplot library closely mimics the C API.
-Users are referred to the PLplot User's Manual, distributed with the source
-PLplot tarball.  This manual is also available on-line at the PLplot web
-site (L<http://www.plplot.org/>).
-
-There are three differences in the way the functions are called.  The first
-one is due to a limitation in the pp_def wrapper of PDL, which forces all
-the non-piddle arguments to be at the end of the arguments list.  It is
-the case of strings (C<char *>) arguments in the C API.  This affects the
-following functions:
-
-plaxes
-plbox
-plbox3
-plmtex
-plmtex3
-plstart
-plstripc
-plmap
-plmeridians
-plshades
-plshade1
-
-This difference can be got around by a call to
-
-plplot_use_standard_argument_order(1);
-
-This re-arranges the string arguments to their proper/intuitive position
-compared with the C plplot interface.  This can be restored to it's default
-by calling:
-
-plplot_use_standard_argument_order(0);
-
-The second notable different between the C and the PDL APIs is that many of
-the PDL calls do not need arguments to specify the size of the the vectors
-and/or matrices being passed.  These size parameters are deduced from the
-size of the piddles, when possible and are just omitted from the C call
-when translating it to perl.
-
-The third difference has to do with output parameters.  In C these are
-passed in with the input parameters.  In the perl interface, they are omitted.
-For example:
-
-C:
-
-  pllegend(&p_legend_width, &p_legend_height,
-           opt, position, x, y, plot_width, bg_color, bb_color, bb_style, nrow, ncolumn, nlegend,
-           opt_array,
-           text_offset, text_scale, text_spacing, text_justification,
-           text_colors, (const char **)text, box_colors, box_patterns, box_scales, box_line_widths,
-           line_colors, line_styles, line_widths, symbol_colors, symbol_scales, symbol_numbers, (const char **)symbols);
-
-perl:
-
-  my ($legend_width, $legend_height) =
-    pllegend ($position, $opt, $x, $y, $plot_width, $bg_color, $nlegend,
-    \@opt_array,
-    $text_offset, $text_scale, $text_spacing, $test_justification,
-    \@text_colors, \@text, \@box_colors, \@box_patterns, \@box_scales, \@line_colors,
-    \@line_styles, \@line_widths, \@symbol_colors, \@symbol_scales, \@symbol_numbers, \@symbols);
-
-Some of the API functions implemented in PDL have other specificities in
-comparison with the C API and will be discussed below.
-
-=cut
-
-EOPM
-
-pp_def ('pladv',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int page()',
-	OtherPars => '',
-	Code => 'c_pladv($page());'
-       );
-
-sub plaxes { plaxes_pp ($standard_order ? reorder ('plaxes', @_) : @_) } pp_add_exported('plaxes');
-pp_def ('plaxes_pp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xzero();double yzero();double xtick();int nxsub();double ytick();int nysub()',
-	OtherPars => 'char *xopt;char *yopt',
-	Code => 'c_plaxes($xzero(),$yzero(),$COMP(xopt),$xtick(),$nxsub(),$COMP(yopt),$ytick(),$nysub());'
-       );
-
-pp_def ('plbin',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int nbin();double x(dima);double y(dima);int center()',
-	OtherPars => '',
-	Code => 'c_plbin($nbin(),$P(x),$P(y),$center());'
-       );
-
-pp_addxs (<<"EOC");
-void
-plbop()
-CODE:
-	c_plbop();
-
-EOC
-pp_add_exported('plbop');
-
-pp_addpm ('sub plbox { plbox_pp ($standard_order ? reorder ("plbox", @_) : @_) }'); pp_add_exported('plbox');
-pp_def ('plbox_pp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xtick();int nxsub();double ytick();int nysub()',
-	OtherPars => 'char *xopt;char *yopt',
-	Code => 'c_plbox($COMP(xopt),$xtick(),$nxsub(),$COMP(yopt),$ytick(),$nysub());'
-       );
-
-pp_addpm ('sub plbox3 { plbox3_pp ($standard_order ? reorder ("plbox3", @_) : @_) }'); pp_add_exported('plbox3');
-pp_def ('plbox3_pp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xtick();int nsubx();double ytick();int nsuby();double ztick();int nsubz()',
-	OtherPars => 'char *xopt;char *xlabel;char *yopt;char *ylabel;char *zopt;char *zlabel',
-	Code => 'c_plbox3($COMP(xopt),$COMP(xlabel),$xtick(),$nsubx(),$COMP(yopt),$COMP(ylabel),$ytick(),$nsuby(),$COMP(zopt),$COMP(zlabel),$ztick(),$nsubz());'
-       );
-
-pp_addxs (<<"EOC");
-void
-plclear()
-CODE:
-	c_plclear();
-
-EOC
-pp_add_exported('plclear');
-
-pp_def ('plcol0',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int icolzero()',
-	OtherPars => '',
-	Code => 'c_plcol0($icolzero());'
-       );
-
-pp_def ('plcol1',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double colone()',
-	OtherPars => '',
-	Code => 'c_plcol1($colone());'
-       );
-
-pp_def ('plcpstrm',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int iplsr();int flags()',
-	OtherPars => '',
-	Code => 'c_plcpstrm($iplsr(),$flags());'
-       );
-
-pp_def ('pldid2pc',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin(dima);double ymin(dima);double xmax(dima);double ymax(dima)',
-	OtherPars => '',
-	Code => 'pldid2pc($P(xmin),$P(ymin),$P(xmax),$P(ymax));'
-       );
-
-pp_def ('pldip2dc',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin(dima);double ymin(dima);double xmax(dima);double ymax(dima)',
-	OtherPars => '',
-	Code => 'pldip2dc($P(xmin),$P(ymin),$P(xmax),$P(ymax));'
-       );
-
-pp_addxs (<<"EOC");
-void
-plend()
-CODE:
-	c_plend();
-
-EOC
-pp_add_exported('plend');
-
-pp_addxs (<<"EOC");
-void
-plend1()
-CODE:
-	c_plend1();
-
-EOC
-pp_add_exported('plend1');
-
-pp_def ('plenv',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double xmax();double ymin();double ymax();int just();int axis()',
-	OtherPars => '',
-	Code => 'c_plenv($xmin(),$xmax(),$ymin(),$ymax(),$just(),$axis());'
-       );
-
-pp_def ('plenv0',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double xmax();double ymin();double ymax();int just();int axis()',
-	OtherPars => '',
-	Code => 'c_plenv0($xmin(),$xmax(),$ymin(),$ymax(),$just(),$axis());'
-       );
-
-pp_addxs (<<"EOC");
-void
-pleop()
-CODE:
-	c_pleop();
-
-EOC
-pp_add_exported('pleop');
-
-pp_def ('plerrx',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int n();double xmin(dima);double xmax(dima);double y(dima)',
-	OtherPars => '',
-	Code => 'c_plerrx($n(),$P(xmin),$P(xmax),$P(y));'
-       );
-
-pp_def ('plerry',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int n();double x(dima);double ymin(dima);double ymax(dima)',
-	OtherPars => '',
-	Code => 'c_plerry($n(),$P(x),$P(ymin),$P(ymax));'
-       );
-
-pp_addxs (<<"EOC");
-void
-plfamadv()
-CODE:
-	c_plfamadv();
-
-EOC
-pp_add_exported('plfamadv');
-
-pp_def ('plfill3',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int n();double x(dima);double y(dima);double z(dima)',
-	OtherPars => '',
-	Code => 'c_plfill3($n(),$P(x),$P(y),$P(z));'
-       );
-
-pp_addxs (<<"EOC");
-void
-plflush()
-CODE:
-	c_plflush();
-
-EOC
-pp_add_exported('plflush');
-
-pp_def ('plfont',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int ifont()',
-	OtherPars => '',
-	Code => 'c_plfont($ifont());'
-       );
-
-pp_def ('plfontld',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int fnt()',
-	OtherPars => '',
-	Code => 'c_plfontld($fnt());'
-       );
-
-pp_def ('plgchr',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_def();double [o]p_ht()',
-	OtherPars => '',
-	Code => 'c_plgchr($P(p_def),$P(p_ht));'
-       );
-
-pp_def ('plgcompression',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int [o]compression()',
-	OtherPars => '',
-	Code => 'c_plgcompression($P(compression));'
-       );
-
-pp_def ('plgdidev',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_mar();double [o]p_aspect();double [o]p_jx();double [o]p_jy()',
-	OtherPars => '',
-	Code => 'c_plgdidev($P(p_mar),$P(p_aspect),$P(p_jx),$P(p_jy));'
-       );
-
-pp_def ('plgdiori',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_rot()',
-	OtherPars => '',
-	Code => 'c_plgdiori($P(p_rot));'
-       );
-
-pp_def ('plgdiplt',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_xmin();double [o]p_ymin();double [o]p_xmax();double [o]p_ymax()',
-	OtherPars => '',
-	Code => 'c_plgdiplt($P(p_xmin),$P(p_ymin),$P(p_xmax),$P(p_ymax));'
-       );
-
-pp_def ('plgfam',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int [o]p_fam();int [o]p_num();int [o]p_bmax()',
-	OtherPars => '',
-	Code => 'c_plgfam($P(p_fam),$P(p_num),$P(p_bmax));'
-       );
-
-pp_def ('plglevel',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int [o]p_level()',
-	OtherPars => '',
-	Code => 'c_plglevel($P(p_level));'
-       );
-
-pp_def ('plgpage',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_xp();double [o]p_yp();int [o]p_xleng();int [o]p_yleng();int [o]p_xoff();int [o]p_yoff()',
-	OtherPars => '',
-	Code => 'c_plgpage($P(p_xp),$P(p_yp),$P(p_xleng),$P(p_yleng),$P(p_xoff),$P(p_yoff));'
-       );
-
-pp_addxs (<<"EOC");
-void
-plgra()
-CODE:
-	c_plgra();
-
-EOC
-pp_add_exported('plgra');
-
-pp_def ('plgspa',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]xmin();double [o]xmax();double [o]ymin();double [o]ymax()',
-	OtherPars => '',
-	Code => 'c_plgspa($P(xmin),$P(xmax),$P(ymin),$P(ymax));'
-       );
-
-pp_def ('plgvpd',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_xmin();double [o]p_xmax();double [o]p_ymin();double [o]p_ymax()',
-	OtherPars => '',
-	Code => 'c_plgvpd($P(p_xmin),$P(p_xmax),$P(p_ymin),$P(p_ymax));'
-       );
-
-pp_def ('plgvpw',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double [o]p_xmin();double [o]p_xmax();double [o]p_ymin();double [o]p_ymax()',
-	OtherPars => '',
-	Code => 'c_plgvpw($P(p_xmin),$P(p_xmax),$P(p_ymin),$P(p_ymax));'
-       );
-
-pp_def ('plgxax',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int [o]p_digmax();int [o]p_digits()',
-	OtherPars => '',
-	Code => 'c_plgxax($P(p_digmax),$P(p_digits));'
-       );
-
-pp_def ('plgyax',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int [o]p_digmax();int [o]p_digits()',
-	OtherPars => '',
-	Code => 'c_plgyax($P(p_digmax),$P(p_digits));'
-       );
-
-pp_def ('plgzax',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int [o]p_digmax();int [o]p_digits()',
-	OtherPars => '',
-	Code => 'c_plgzax($P(p_digmax),$P(p_digits));'
-       );
-
-pp_addxs (<<"EOC");
-void
-plinit()
-CODE:
-	c_plinit();
-
-EOC
-pp_add_exported('plinit');
-
-pp_def ('pljoin',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xone();double yone();double xtwo();double ytwo()',
-	OtherPars => '',
-	Code => 'c_pljoin($xone(),$yone(),$xtwo(),$ytwo());'
-       );
-
-pp_addxs (<<"EOC");
-void
-pllab(xlabel,ylabel,tlabel)
-	char *	xlabel
-	char *	ylabel
-	char *	tlabel
-CODE:
-	c_pllab(xlabel,ylabel,tlabel);
-
-EOC
-pp_add_exported('pllab');
-
-pp_def ('pllightsource',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double x();double y();double z()',
-	OtherPars => '',
-	Code => 'c_pllightsource($x(),$y(),$z());'
-       );
-
-pp_def ('pllsty',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int lin()',
-	OtherPars => '',
-	Code => 'c_pllsty($lin());'
-       );
-
-pp_addpm ('sub plmtex { plmtex_pp ($standard_order ? reorder ("plmtex", @_) : @_) }'); pp_add_exported('plmtex');
-pp_def ('plmtex_pp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double disp();double pos();double just()',
-	OtherPars => 'char *side;char *text',
-	Code => 'c_plmtex($COMP(side),$disp(),$pos(),$just(),$COMP(text));'
-       );
-
-pp_addpm ('sub plmtex3 { plmtex3_pp ($standard_order ? reorder ("plmtex3", @_) : @_) }'); pp_add_exported('plmtex3');
-pp_def ('plmtex3_pp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double disp();double pos();double just()',
-	OtherPars => 'char *side;char *text',
-	Code => 'c_plmtex3($COMP(side),$disp(),$pos(),$just(),$COMP(text));'
-       );
-
-pp_def ('plpat',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int nlin();int inc(dima);int del(dima)',
-	OtherPars => '',
-	Code => 'c_plpat($nlin(),$P(inc),$P(del));'
-       );
-
-pp_def ('plprec',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int setp();int prec()',
-	OtherPars => '',
-	Code => 'c_plprec($setp(),$prec());'
-       );
-
-pp_def ('plpsty',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int patt()',
-	OtherPars => '',
-	Code => 'c_plpsty($patt());'
-       );
-
-pp_def ('plptex',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double x();double y();double dx();double dy();double just()',
-	OtherPars => 'char *text',
-	Code => 'c_plptex($x(),$y(),$dx(),$dy(),$just(),$COMP(text));'
-       );
-
-pp_def ('plptex3',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double x();double y();double z();double dx();double dy();double dz();double sx();double sy();double sz();double just()',
-	OtherPars => 'char *text',
-	Code => 'c_plptex3($x(),$y(),$z(),$dx(),$dy(),$dz(),$sx(),$sy(),$sz(),$just(),$COMP(text));'
-       );
-
-pp_addxs (<<"EOC");
-void
-plreplot()
-CODE:
-	c_plreplot();
-
-EOC
-pp_add_exported('plreplot');
-
-pp_def ('plschr',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double def();double scale()',
-	OtherPars => '',
-	Code => 'c_plschr($def(),$scale());'
-       );
-
-pp_def ('plscmap0n',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int ncolzero()',
-	OtherPars => '',
-	Code => 'c_plscmap0n($ncolzero());'
-       );
-
-pp_def ('plscmap1n',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int ncolone()',
-	OtherPars => '',
-	Code => 'c_plscmap1n($ncolone());'
-       );
-
-pp_def ('plscol0',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int icolzero();int r();int g();int b()',
-	OtherPars => '',
-	Code => 'c_plscol0($icolzero(),$r(),$g(),$b());'
-       );
-
-pp_def ('plscolbg',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int r();int g();int b()',
-	OtherPars => '',
-	Code => 'c_plscolbg($r(),$g(),$b());'
-       );
-
-pp_def ('plscolor',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int color()',
-	OtherPars => '',
-	Code => 'c_plscolor($color());'
-       );
-
-pp_def ('plscompression',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int compression()',
-	OtherPars => '',
-	Code => 'c_plscompression($compression());'
-       );
-
-pp_addxs (<<"EOC");
-void
-plsdev(devname)
-	char *	devname
-CODE:
-	c_plsdev(devname);
-
-EOC
-pp_add_exported('plsdev');
-
-pp_def ('plsdidev',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double mar();double aspect();double jx();double jy()',
-	OtherPars => '',
-	Code => 'c_plsdidev($mar(),$aspect(),$jx(),$jy());'
-       );
-
-pp_def ('plsdimap',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int dimxmin();int dimxmax();int dimymin();int dimymax();double dimxpmm();double dimypmm()',
-	OtherPars => '',
-	Code => 'c_plsdimap($dimxmin(),$dimxmax(),$dimymin(),$dimymax(),$dimxpmm(),$dimypmm());'
-       );
-
-pp_def ('plsdiori',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double rot()',
-	OtherPars => '',
-	Code => 'c_plsdiori($rot());'
-       );
-
-pp_def ('plsdiplt',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double ymin();double xmax();double ymax()',
-	OtherPars => '',
-	Code => 'c_plsdiplt($xmin(),$ymin(),$xmax(),$ymax());'
-       );
-
-pp_def ('plsdiplz',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double ymin();double xmax();double ymax()',
-	OtherPars => '',
-	Code => 'c_plsdiplz($xmin(),$ymin(),$xmax(),$ymax());'
-       );
-
-pp_def ('pl_setcontlabelparam',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double offset();double size();double spacing();int active()',
-	OtherPars => '',
-	Code => 'c_pl_setcontlabelparam($offset(),$size(),$spacing(),$active());'
-       );
-
-pp_def ('pl_setcontlabelformat',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int lexp();int sigdig()',
-	OtherPars => '',
-	Code => 'c_pl_setcontlabelformat($lexp(),$sigdig());'
-       );
-
-pp_def ('plsfam',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int fam();int num();int bmax()',
-	OtherPars => '',
-	Code => 'c_plsfam($fam(),$num(),$bmax());'
-       );
-
-pp_addxs (<<"EOC");
-void
-plsfnam(fnam)
-	char *	fnam
-CODE:
-	c_plsfnam(fnam);
-
-EOC
-pp_add_exported('plsfnam');
-
-pp_def ('plsmaj',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double def();double scale()',
-	OtherPars => '',
-	Code => 'c_plsmaj($def(),$scale());'
-       );
-
-pp_def ('plsmin',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double def();double scale()',
-	OtherPars => '',
-	Code => 'c_plsmin($def(),$scale());'
-       );
-
-pp_def ('plsori',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int ori()',
-	OtherPars => '',
-	Code => 'c_plsori($ori());'
-       );
-
-pp_def ('plspage',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xp();double yp();int xleng();int yleng();int xoff();int yoff()',
-	OtherPars => '',
-	Code => 'c_plspage($xp(),$yp(),$xleng(),$yleng(),$xoff(),$yoff());'
-       );
-
-pp_def ('plspause',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int pause()',
-	OtherPars => '',
-	Code => 'c_plspause($pause());'
-       );
-
-pp_def ('plsstrm',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int strm()',
-	OtherPars => '',
-	Code => 'c_plsstrm($strm());'
-       );
-
-pp_def ('plssub',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int nx();int ny()',
-	OtherPars => '',
-	Code => 'c_plssub($nx(),$ny());'
-       );
-
-pp_def ('plssym',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double def();double scale()',
-	OtherPars => '',
-	Code => 'c_plssym($def(),$scale());'
-       );
-
-pp_def ('plstar',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int nx();int ny()',
-	OtherPars => '',
-	Code => 'c_plstar($nx(),$ny());'
-       );
-
-pp_addpm ('sub plstart { plstart_pp ($standard_order ? reorder ("plstart", @_) : @_) }'); pp_add_exported('plstart');
-pp_def ('plstart_pp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int nx();int ny()',
-	OtherPars => 'char *devname',
-	Code => 'c_plstart($COMP(devname),$nx(),$ny());'
-       );
-
-pp_def ('plstripa',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int id();int pen();double x();double y()',
-	OtherPars => '',
-	Code => 'c_plstripa($id(),$pen(),$x(),$y());'
-       );
-
-pp_def ('plstripd',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int id()',
-	OtherPars => '',
-	Code => 'c_plstripd($id());'
-       );
-
-pp_def ('plsvpa',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double xmax();double ymin();double ymax()',
-	OtherPars => '',
-	Code => 'c_plsvpa($xmin(),$xmax(),$ymin(),$ymax());'
-       );
-
-pp_def ('plsxax',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int digmax();int digits()',
-	OtherPars => '',
-	Code => 'c_plsxax($digmax(),$digits());'
-       );
-
-pp_def ('plsxwin',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int window_id()',
-	OtherPars => '',
-	Code => 'plsxwin($window_id());'
-       );
-
-pp_def ('plsyax',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int digmax();int digits()',
-	OtherPars => '',
-	Code => 'c_plsyax($digmax(),$digits());'
-       );
-
-pp_def ('plszax',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int digmax();int digits()',
-	OtherPars => '',
-	Code => 'c_plszax($digmax(),$digits());'
-       );
-
-pp_addxs (<<"EOC");
-void
-pltext()
-CODE:
-	c_pltext();
-
-EOC
-pp_add_exported('pltext');
-
-pp_def ('plvasp',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double aspect()',
-	OtherPars => '',
-	Code => 'c_plvasp($aspect());'
-       );
-
-pp_def ('plvpas',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double xmax();double ymin();double ymax();double aspect()',
-	OtherPars => '',
-	Code => 'c_plvpas($xmin(),$xmax(),$ymin(),$ymax(),$aspect());'
-       );
-
-pp_def ('plvpor',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double xmax();double ymin();double ymax()',
-	OtherPars => '',
-	Code => 'c_plvpor($xmin(),$xmax(),$ymin(),$ymax());'
-       );
-
-pp_addxs (<<"EOC");
-void
-plvsta()
-CODE:
-	c_plvsta();
-EOC
-
-pp_add_exported('plvsta');
-
-pp_def ('plw3d',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double basex();double basey();double height();double xminzero();double xmaxzero();double yminzero();double ymaxzero();double zminzero();double zmaxzero();double alt();double az()',
-	OtherPars => '',
-	Code => 'c_plw3d($basex(),$basey(),$height(),$xminzero(),$xmaxzero(),$yminzero(),$ymaxzero(),$zminzero(),$zmaxzero(),$alt(),$az());'
-       );
-
-pp_def ('plwid',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int width()',
-	OtherPars => '',
-	Code => 'c_plwid($width());'
-       );
-
-pp_def ('plwind',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double xmin();double xmax();double ymin();double ymax()',
-	OtherPars => '',
-	Code => 'c_plwind($xmin(),$xmax(),$ymin(),$ymax());'
-       );
-
-pp_addxs (<<"EOC");
-void
-plsetopt(opt,optarg)
-	char *	opt
-	char *	optarg
-CODE:
-	c_plsetopt(opt,optarg);
-
-EOC
-pp_add_exported('plsetopt');
-
-pp_def ('plP_gpixmm',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'double p_x(dima);double p_y(dima)',
-	OtherPars => '',
-	Code => 'plP_gpixmm($P(p_x),$P(p_y));'
-       );
-
-pp_def ('plscolbga',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int r();int g();int b();double a()',
-	OtherPars => '',
-	Code => 'c_plscolbga($r(),$g(),$b(),$a());'
-       );
-
-pp_def ('plscol0a',
-        NoPthread => 1,
-	GenericTypes => [D],
-	Pars => 'int icolzero();int r();int g();int b();double a()',
-	OtherPars => '',
-	Code => 'c_plscol0a($icolzero(),$r(),$g(),$b(),$a());'
-       );
-
-# C routine to draw lines with gaps.  This is useful for map continents and other things.
-=head2 plline
-=cut
-
-$doc = <<'EOD';
-=for ref
-
-Draws line segments along (x1,y1)->(x2,y2)->(x3,y3)->...
-
-=for bad
-
-If the nth value of either x or y are bad, then it will be skipped, breaking
-the line.  In this way, you can specify multiple line segments with a single
-pair of x and y piddles.
-
-The usage is straight-forward:
-
-=for usage
-
- plline($x, $y);
-
-For example:
-
-=for example
-
- # Draw a sine wave
- $x = sequence(100)/10;
- $y = sin($x);
-
- # Draws the sine wave:
- plline($x, $y);
-
- # Set values above 3/4 to 'bad', effectively drawing a bunch of detached,
- # capped waves
- $y->setbadif($y > 3/4);
- plline($x, $y);
-
-=cut
-EOD
-
-pp_def ('plline',
-        NoPthread => 1,
-	Pars => 'x(n); y(n)',
-	GenericTypes => [D],
-	HandleBad => 1,
-	NoBadifNaN => 1,
-	Code => 'c_plline($SIZE(n),$P(x),$P(y));',
-	BadCode => 'int i;
-                     int j;
-                     for (i=1;i<$SIZE(n);i++) {
-                       j = i-1;	/* PP does not like using i-1 in a PDL ref.  Use j instead. */
-                       if ($ISGOOD(x(n=>i)) && $ISGOOD(x(n=>j)) && $ISGOOD(y(n=>i)) && $ISGOOD(y(n=>j))) {
-                         c_pljoin ($x(n=>j), $y(n=>j), $x(n=>i), $y(n=>i));
-                       }
-                     }',
-	Doc => $doc,
-       );
-
-=head2 plcolorpoints
-=cut
-
-$doc = <<'EOD';
-=for ref
-
-PDL-specific: Implements what amounts to a threaded version of plsym.
-
-=for bad
-
-Bad values for z are simply skipped; all other bad values are not processed.
-
-In the following usage, all of the piddles must have the same dimensions:
-
-=for usage
-
- plcolorpoints($x, $y, $z, $symbol_index, $minz, $maxz)
-
-For example:
-
-=for example
-
- # Generate a parabola some points
- my $x = sequence(30) / 3;   # Regular sampling
- my $y = $x**2;              # Parabolic y
- my $z = 30 - $x**3;         # Cubic coloration
- my $symbols = floor($x);    # Use different symbols for each 1/3 of the plot
-                             #  These should be integers.
-
- plcolorpoints($x, $y, $z, $symbols, -5, 20);  # Thread over everything
- plcolorpoints($x, $y, 1, 1, -1, 2);           # same color and symbol for all
-
-=cut
-EOD
-
-# C routine to draw points with a color scale
-pp_def ('plcolorpoints',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); z(n); int sym(); minz(); maxz()',
-         GenericTypes => [D],
-         HandleBad => 1,
-         Code => 'int i;
-                  int j;
-                  int ns = $SIZE(n);
-                  PLFLT zrange, ci;
-
-                  zrange  = $maxz() - $minz();
-
-                  for (i=0;i<ns;i++) {
-                    ci = (zrange == 0.0) ? 0.5 : ($z(n=>i) - $minz()) / zrange;  /* get color idx in 0-1 range */
-                    if (ci < 0) ci = 0; /* enforce bounds */
-                    if (ci > 1) ci = 1;
-                    c_plcol1 (ci); /* set current color */
-                    c_plsym (1, &$x(n=>i), &$y(n=>i), $sym()); /* plot it */
-                  }',
-         BadCode =>
-	         'int i;
-                  int j;
-                  int ns = $SIZE(n);
-                  PLFLT zrange, ci;
-
-                  zrange  = $maxz()  - $minz();
-
-                  for (i=0;i<ns;i++) {
-                    if ($ISBAD(z(n=>i))) continue;
-                    ci = (zrange == 0.0) ? 0.5 : ($z(n=>i) - $minz()) / zrange;  /* get color idx in 0-1 range */
-                    if (ci < 0) ci = 0; /* enforce bounds */
-                    if (ci > 1) ci = 1;
-                    c_plcol1 (ci); /* set current color */
-                    c_plsym (1, &$x(n=>i), &$y(n=>i), $sym()); /* plot it */
-
-                  }',
-         Doc => $doc,
-       );
-
-
-
-pp_def ('plsmem',
-        NoPthread => 1,
-	     GenericTypes => [B],
-             Pars => 'int maxx();int maxy();image(3,x,y)',
-             Code => 'c_plsmem($maxx(),$maxy(),$P(image));'
-            ) if ($plversion->{'plsmem'});
-
-#
-## Box drawing primitive, taken from PLPLOT bar graph example
-#
-
-pp_def ('plfbox',
-        NoPthread => 1,
-         Pars => 'xo(); yo()',
-         GenericTypes => [D],
-         Code => 'PLFLT x[4], y[4];
-                  x[0] = $xo() - 0.5;
-                  y[0] = 0.;
-                  x[1] = $xo() - 0.5;
-                  y[1] = $yo();
-                  x[2] = $xo() + 0.5;
-                  y[2] = $yo();
-                  x[3] = $xo() + 0.5;
-                  y[3] = 0.;
-                  plfill(4, x, y);',
-        );
-
-#
-## Similar box drawing primitive, but without fill (just draw outline of box)
-#
-pp_def ('plunfbox',
-        NoPthread => 1,
-         Pars => 'xo(); yo()',
-         GenericTypes => [D],
-         Code => 'PLFLT x[4], y[4];
-                  x[0] = $xo() - 0.5;
-                  y[0] = 0.;
-                  x[1] = $xo() - 0.5;
-                  y[1] = $yo();
-                  x[2] = $xo() + 0.5;
-                  y[2] = $yo();
-                  x[3] = $xo() + 0.5;
-                  y[3] = 0.;
-                  plline(4, x, y);',
-        );
-
-#
-## Parse PLplot options given in @ARGV-like arrays
-#
-
-pp_def ('plParseOpts',
-        NoPthread => 1,
-        GenericTypes => [D],
-        Pars => 'int [o] retval()',
-        OtherPars => 'SV* argv; int mode',
-        Doc => 'FIXME: documentation here!',
-        Code => '
-                SV* sv = $COMP (argv);
-                SV* dummy;
-                AV* arr;
-                int argc, newargc, i, retval;
-                char** args;
-
-                if ( !(SvROK (sv) && SvTYPE (SvRV (sv)) == SVt_PVAV)) {
-                        barf("plParseOpts requires an array ref");
-                }
-
-                arr = (AV*) SvRV (sv);
-                newargc = argc = av_len (arr) + 1;
-                if (argc > 0) {
-                  New(1, args, argc, char *);
-                  if(args == NULL) croak("Failed to allocate memory in plParseOpts");
-
-                  for (i = 0; i < argc; i++) {
-                          STRLEN len;
-                          args[i] = SvPV (* av_fetch (arr, i, 0), len);
-                  }
-
-                  $retval() = c_plparseopts (&newargc, (const char **)args, $COMP (mode));
-
-                  for (i = 0; i < newargc; i++)
-                          av_push (arr, newSVpv (args[i], 0));
-
-                  for (i = 0; i < argc; i++)
-                          dummy = av_shift (arr); /* assign to dummy to suppress compile warning */
-
-                  Safefree (args);
-                }
-        ',
-);
-
-# Plots a character at the specified points
-
-pp_def ('plpoin',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); int code()',
-         GenericTypes => [D],
-         Code => 'c_plpoin($SIZE(n),$P(x),$P(y),$code());'
-        );
-
-# Plots a character at the specified points in 3 space
-
-pp_def ('plpoin3',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); z(n); int code()',
-         GenericTypes => [D],
-         Code => 'c_plpoin3($SIZE(n),$P(x),$P(y),$P(z),$code());'
-        );
-
-# Draw a line in 3 space
-
-pp_def ('plline3',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); z(n)',
-         GenericTypes => [D],
-         Code => 'c_plline3($SIZE(n),$P(x),$P(y),$P(z));'
-        );
-
-# Draws a polygon in 3 space
-pp_def ('plpoly3',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); z(n); int draw(m); int ifcc()',
-         GenericTypes => [D],
-         Code => 'c_plpoly3($SIZE(n),$P(x),$P(y),$P(z),$P(draw),$ifcc());'
-        );
-
-# Plot a histogram from unbinned data
-pp_def ('plhist',
-        NoPthread => 1,
-         Pars => 'data(n); datmin(); datmax(); int nbin(); int oldwin()',
-         GenericTypes => [D],
-         Code => 'c_plhist($SIZE(n),$P(data),$datmin(),$datmax(),$nbin(),$oldwin());'
-        );
-
-# Area fill
-pp_def ('plfill',
-        NoPthread => 1,
-         Pars => 'x(n); y(n)',
-         GenericTypes => [D],
-         Code => 'c_plfill($SIZE(n),$P(x),$P(y));'
-        );
-
-# Area fill with color gradient
-pp_def ('plgradient',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); angle();',
-         GenericTypes => [D],
-         Code => 'c_plgradient($SIZE(n),$P(x),$P(y),$angle());'
-        ) if ($plversion->{'c_pllegend'});
-
-# Plots a symbol at the specified points
-pp_def ('plsym',
-        NoPthread => 1,
-         Pars => 'x(n); y(n); int code()',
-         GenericTypes => [D],
-         Code => 'c_plsym($SIZE(n),$P(x),$P(y),$code());'
-        );
-
-# Plot shaded 3-d surface plot
-pp_def ('plsurf3d',
-        NoPthread => 1,
-         Pars => 'x(nx); y(ny); z(nx,ny); int opt(); clevel(nlevel);',
-         GenericTypes => [D],
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** zz;
-
-           size_x =  $SIZE(nx);
-           size_y =  $SIZE(ny);
-           plAlloc2dGrid (&zz, size_x, size_y);
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               zz[i][j] = $z(nx => i, ny => j);
-           c_plsurf3d ($P(x), $P(y), (const PLFLT **)zz, size_x, size_y, $opt(),
-                       $P(clevel), $SIZE(nlevel));
-           plFree2dGrid (zz, size_x, size_y);'
-        );
-
-# Set line style
-
-pp_def ('plstyl',
-        NoPthread => 1,
-         Pars => 'int mark(nms); int space(nms)',
-         GenericTypes => [D],
-         Code => 'c_plstyl ($SIZE(nms), $P(mark), $P(space));'
-       );
-
-# PLplot standard random number generation.  Using this
-# helps to keep the demo plots identical.
-
-if ($plversion->{'c_plseed'}) {
-
-  pp_def ('plseed',
-          NoPthread => 1,
-          Pars => 'int seed()',
-          Code => 'unsigned int useed = (unsigned int)$seed(); c_plseed(useed);'
-        );
-
-  pp_def ('plrandd',
-          NoPthread => 1,
-          Pars => 'double [o]rand()',
-          Code => '$rand() = c_plrandd();'
-        );
-
-} # $plversion->{'c_plseed'}
-
-# Plot contours
-
-
-# pltr0: Identity transformation
-# pltr1: Linear interpolation from singly dimensioned coord arrays
-# Linear interpolation from doubly dimensioned coord arrays
-
-for my $func ('pltr0', 'pltr1', 'pltr2') {
-
-  pp_addxs (<<"EOC");
-void
-$func (x, y, grid)
-  double x
-  double y
-  long grid
-PPCODE:
-  PLFLT tx, ty;
-
-  $func (x, y, &tx, &ty, (PLPointer) grid);
-
-  EXTEND (SP, 2);
-  PUSHs (sv_2mortal (newSVnv ((double) tx)));
-  PUSHs (sv_2mortal (newSVnv ((double) ty)));
-EOC
-
-  pp_add_exported ($func);
-}
-
-
-# Allocates a PLcGrid object for use in pltr1
-
-pp_def ('plAllocGrid',
-        NoPthread => 1,
-        Pars => "double xg(nx); double yg(ny); $pp_ptr_type [o] grid()",
-        GenericTypes => [D],
-        Doc => 'FIXME: documentation here!',
-        Code => '
-          PLcGrid *grid;
-          int i, nx, ny;
-
-          nx = $SIZE(nx);
-          ny = $SIZE(ny);
-
-          New(1, grid, 1, PLcGrid);
-          if(grid == NULL) croak("Failed to allocate memory for grid");
-          Newz(2, grid->xg, nx, PLFLT);
-          if(grid->xg == NULL) croak("Failed to allocate memory for grid->xg");
-          Newz(3, grid->yg, ny, PLFLT);
-          if(grid->yg == NULL) croak("Failed to allocate memory for grid->yg");
-          grid->nx = nx;
-          grid->ny = ny;
-
-          for (i = 0; i < nx; i++)
-            grid->xg[i] = $xg(nx => i);
-
-          for (i = 0; i < ny; i++)
-            grid->yg[i] = $yg(ny => i);
-
-          $grid() = ('.$int_ptr_type.') grid;'
-        );
-
-
-# Free a PLcGrid object
-
-pp_addxs (<<"EOC");
-void
-plFreeGrid (pg)
-  long pg
-PPCODE:
-  PLcGrid* grid = (PLcGrid*) pg;
-  free (grid->xg);
-  free (grid->yg);
-  free (grid);
-EOC
-
-pp_add_exported (plFreeGrid);
-
-
-# Allocates a PLcGrid2 object for use in pltr2
-
-pp_def ('plAlloc2dGrid',
-        NoPthread => 1,
-        Pars => "double xg(nx,ny); double yg(nx,ny); $pp_ptr_type [o] grid()",
-        GenericTypes => [D],
-        Doc => 'FIXME: documentation here!',
-        Code => '
-          PLcGrid2 *grid;
-          int i, j, nx, ny;
-
-          nx = $SIZE(nx);
-          ny = $SIZE(ny);
-
-          grid = (PLcGrid2*) malloc (sizeof (PLcGrid2));
-          plAlloc2dGrid (&(grid->xg), nx, ny);
-          plAlloc2dGrid (&(grid->yg), nx, ny);
-
-          for (i = 0; i < nx; i++)
-            for (j = 0; j < ny; j++) {
-              grid->xg[i][j] = $xg(nx => i, ny => j);
-              grid->yg[i][j] = $yg(nx => i, ny => j);
-            }
-
-          grid->nx = nx;
-          grid->ny = ny;
-
-          $grid() = ('.$int_ptr_type.') grid;'
-        );
-
-
-# Free a PLcGrid2 object
-
-pp_addxs (<<"EOC");
-void
-plFree2dGrid (pg)
-  long pg
-PPCODE:
-  PLcGrid2* grid = (PLcGrid2*) pg;
-  plFree2dGrid (grid->xg, grid->nx, grid->ny);
-  plFree2dGrid (grid->yg, grid->nx, grid->ny);
-  free (grid);
-EOC
-
-pp_add_exported (plFree2dGrid);
-
-pp_addhdr (<<'EOH');
-
-#define check_sub_pointer(subptr, errmsg) \
-  if (SvTRUE (subptr) \
-      && (! SvROK (subptr) || SvTYPE (SvRV (subptr)) != SVt_PVCV)) \
-    croak (errmsg);
-
-static SV* pltr_subroutine;
-
-static IV pltr0_iv;
-static IV pltr1_iv;
-static IV pltr2_iv;
-
-static void
-pltr_callback (PLFLT x, PLFLT y, PLFLT* tx, PLFLT* ty, PLPointer pltr_data)
-{
-  I32 count;
-  dSP;
-
-  ENTER;
-  SAVETMPS;
-
-  PUSHMARK (SP);
-  XPUSHs (sv_2mortal (newSVnv ((double) x)));
-  XPUSHs (sv_2mortal (newSVnv ((double) y)));
-  XPUSHs ((SV*) pltr_data);
-  PUTBACK;
-
-  count = call_sv (pltr_subroutine, G_ARRAY);
-
-  SPAGAIN;
-
-  if (count != 2)
-    croak ("pltr: must return two scalars");
-
-  *ty = (PLFLT) POPn;
-  *tx = (PLFLT) POPn;
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-}
-
-static void*
-get_standard_pltrcb (SV* cb)
-{
-  if ( !SvROK(cb) ) return NULL; /* Added to prevent bug in plshades for 0 input. D. Hunt 12/18/2008 */
-  IV sub = (IV) SvRV (cb);
-
-  if (sub == pltr0_iv)
-    return (void*) pltr0;
-  else if (sub == pltr1_iv)
-    return (void*) pltr1;
-  else if (sub == pltr2_iv)
-    return (void*) pltr2;
-  else
-    return SvTRUE (cb) ? (void*) pltr_callback : NULL;
-}
-
-static SV* defined_subroutine;
-
-static PLINT
-defined_callback (PLFLT x, PLFLT y)
-{
-  I32 count, retval;
-  dSP;
-
-  ENTER;
-  SAVETMPS;
-
-  PUSHMARK (SP);
-  XPUSHs (sv_2mortal (newSVnv ((double) x)));
-  XPUSHs (sv_2mortal (newSVnv ((double) y)));
-  PUTBACK;
-
-  count = call_sv (defined_subroutine, G_SCALAR);
-
-  SPAGAIN;
-
-  if (count != 1)
-    croak ("defined: must return one scalar");
-
-  retval = POPi;
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-
-  return retval;
-}
-
-static SV* mapform_subroutine;
-
-static void default_magic (pdl *p, int pa) { p->data = 0; }
-
-static void
-mapform_callback (PLINT n, PLFLT* x, PLFLT* y)
-{
-  pdl *x_pdl, *y_pdl;
-  PLFLT *tx, *ty;
-  SV *x_sv, *y_sv;
-#if defined(PDL_CORE_VERSION) && PDL_CORE_VERSION >= 10
-  PDL_Indx dims, i;
-#else
-  int dims, i;
-#endif
-  I32 count, ax;
-  dSP;
-
-  ENTER;
-  SAVETMPS;
-
-  dims = n;
-
-  x_pdl = PDL->pdlnew ();
-  PDL->add_deletedata_magic(x_pdl, default_magic, 0);
-  PDL->setdims (x_pdl, &dims, 1);
-  x_pdl->datatype = PDL_D;
-  x_pdl->data = x;
-  x_pdl->state |= PDL_DONTTOUCHDATA | PDL_ALLOCATED;
-  x_sv = sv_newmortal ();
-  PDL->SetSV_PDL (x_sv, x_pdl);
-
-  y_pdl = PDL->pdlnew ();
-  PDL->add_deletedata_magic(y_pdl, default_magic, 0);
-  PDL->setdims (y_pdl, &dims, 1);
-  y_pdl->datatype = PDL_D;
-  y_pdl->data = y;
-  y_pdl->state |= PDL_DONTTOUCHDATA | PDL_ALLOCATED;
-  y_sv = sv_newmortal ();
-  PDL->SetSV_PDL (y_sv, y_pdl);
-
-  PUSHMARK (SP);
-  XPUSHs (x_sv);
-  XPUSHs (y_sv);
-  PUTBACK;
-
-  count = call_sv (mapform_subroutine, G_ARRAY);
-
-  SPAGAIN;
-  SP -= count ;
-  ax = (SP - PL_stack_base) + 1;
-
-  if (count != 2)
-    croak ("mapform: must return two piddles");
-
-  tx = (PLFLT*) ((PDL->SvPDLV(ST(0)))->data);
-  ty = (PLFLT*) ((PDL->SvPDLV(ST(1)))->data);
-
-  for (i = 0; i < n; i++) {
-    *(x + i) = *(tx + i);
-    *(y + i) = *(ty + i);
-  }
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-}
-EOH
-
-pp_addhdr (<<'EOH') if ($plversion->{'c_pllegend'});
-
-// Subroutines for adding transforms via plstransform
-static SV* xform_subroutine;
-
-static void
-xform_callback ( PLFLT x, PLFLT y, PLFLT *xt, PLFLT *yt, PLPointer data )
-{
-  SV *x_sv, *y_sv; // Perl scalars for the input x and y
-  I32 count, ax;
-  dSP;
-
-  ENTER;
-  SAVETMPS;
-
-  x_sv = newSVnv((double)x);
-  y_sv = newSVnv((double)y);
-
-  PUSHMARK (SP);
-  XPUSHs (x_sv);
-  XPUSHs (y_sv);
-  PUTBACK;
-
-  count = call_sv (xform_subroutine, G_ARRAY);
-
-  SPAGAIN;
-  SP -= count ;
-  ax = (SP - PL_stack_base) + 1;
-
-  if (count != 2)
-    croak ("xform: must return two perl scalars");
-
-  *xt = (PLFLT) SvNV(ST(0));
-  *yt = (PLFLT) SvNV(ST(1));
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-}
-
-// Subroutines for adding label formatting via plslabelfunc
-static SV* labelfunc_subroutine;
-
-void labelfunc_callback (PLINT axis, PLFLT value, char *label_text, PLINT length, void *data )
-{
-  SV *axis_sv, *value_sv, *length_sv; // Perl scalars for inputs
-  I32 count, ax;
-  dSP;
-
-  ENTER;
-  SAVETMPS;
-
-  axis_sv   = newSViv((IV)axis);
-  value_sv  = newSVnv((double)value);
-  length_sv = newSViv((IV)length);
-
-  PUSHMARK (SP);
-  XPUSHs (axis_sv);
-  XPUSHs (value_sv);
-  XPUSHs (length_sv);
-  PUTBACK;
-
-  count = call_sv (labelfunc_subroutine, G_ARRAY);
-
-  SPAGAIN;
-  SP -= count ;
-  ax = (SP - PL_stack_base) + 1;
-
-  if (count != 1)
-    croak ("labelfunc: must return one perl scalar");
-
-  // Copy label into output string
-  snprintf( label_text, length, "%s", (char *)SvPV_nolen(ST(0)) );
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-}
-
-EOH
-
-# The init_pltr is used internally by the PLD::Graphics::PLplot
-# module to set the variables pltr{0,1,2}_iv to the "pointers"
-# of the Perl subroutines pltr{1,2,3}.  These variables are later used by
-# get_standard_pltrcb to provide the pointers to the C function pltr{0,1,2}.
-# This accelerates functions like plcont and plshades when those standard
-# transformation functions are used.
-
-pp_def ('init_pltr',
-        NoPthread => 1,
-         GenericTypes => [D],
-         Pars => '',
-         OtherPars => 'SV* p0; SV* p1; SV* p2;',
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           pltr0_iv = (IV) SvRV ($COMP(p0));
-           pltr1_iv = (IV) SvRV ($COMP(p1));
-           pltr2_iv = (IV) SvRV ($COMP(p2));');
-
-pp_addpm (<<'EOPM');
-init_pltr (\&pltr0, \&pltr1, \&pltr2);
-EOPM
-
-# plot continental outline in world coordinates
-
-pp_addpm ('sub plmap { plmap_pp ($standard_order ? reorder ("plmap", @_) : @_) }'); pp_add_exported('plmap');
-pp_def ('plmap_pp',
-        NoPthread => 1,
-        Pars => 'minlong(); maxlong(); minlat(); maxlat();', # 0-3
-	OtherPars => 'SV* mapform; char* type;', # 4,5
-        GenericTypes => [D],
-        Code => '
-           int use_xform;
-           mapform_subroutine = $COMP(mapform);
-	   check_sub_pointer (mapform_subroutine,
-	     "plmap: mapform must be either 0 or a subroutine pointer");
-
-           use_xform = SvTRUE ($COMP(mapform));
-           plmap (use_xform ? mapform_callback : NULL,
-	     $COMP(type), $minlong(), $maxlong(), $minlat(), $maxlat());',
-       );
-
-# plot a string along a line
-pp_def ('plstring',
-        NoPthread => 1,
-        Pars         => 'x(na); y(na);',
-	OtherPars    => 'char* string;',
-        GenericTypes => [D],
-        Code         => 'c_plstring($SIZE(na), $P(x), $P(y), $COMP(string));',
-       ) if ($plversion->{'c_pllegend'});
-
-# plot a string along a 3D line
-pp_def ('plstring3',
-        NoPthread => 1,
-        Pars         => 'x(na); y(na); z(na)',
-	OtherPars    => 'char* string;',
-        GenericTypes => [D],
-        Code         => 'c_plstring3($SIZE(na), $P(x), $P(y), $P(z), $COMP(string));',
-       ) if ($plversion->{'c_pllegend'});
-
-# Plot the latitudes and longitudes on the background
-pp_addpm ('sub plmeridians { plmeridians_pp ($standard_order ? reorder ("plmeridians", @_) : @_) }'); pp_add_exported('plmeridians');
-pp_def ('plmeridians_pp',
-        NoPthread => 1,
-        Pars => 'dlong(); dlat(); minlong(); maxlong(); minlat(); maxlat();', # 0-5
-	OtherPars => 'SV* mapform;', # 6
-        GenericTypes => [D],
-        Code => '
-           mapform_subroutine = $COMP(mapform);
-	   check_sub_pointer (mapform_subroutine,
-	     "plmeridians: mapform must be either 0 or a subroutine pointer");
-
-           plmeridians (SvTRUE ($COMP(mapform)) ? mapform_callback : NULL,
-	     $dlong(), $dlat(), $minlong(), $maxlong(), $minlat(), $maxlat());'
-       );
-
-# Set the global coordinate transform
-
-# Shade regions on the basis of value
-
-pp_addpm ('sub plshades { plshades_pp ($standard_order ? reorder ("plshades", @_) : @_) }'); pp_add_exported('plshades');
-pp_def ('plshades_pp',
-        NoPthread => 1,
-         Pars => 'z(x,y); xmin(); xmax(); ymin(); ymax();
-                  clevel(l); int fill_width(); int cont_color();
-                  int cont_width(); int rectangular()', # 0-9
-         OtherPars => 'SV* defined; SV* pltr; SV* pltr_data;', # 10-12
-         GenericTypes => [D],
-         Code => '
-           int nx    = $SIZE(x);
-           int ny    = $SIZE(y);
-           int nlvl  = $SIZE(l);
-           int i, j;
-           PLFLT **z;
- 	   void (*pltrcb) ();
-           PLPointer pltrdt;
-
-           plAlloc2dGrid (&z, nx, ny);
-
-           for (i = 0; i < nx; i++)
-             for (j = 0; j < ny; j++)
-               z[i][j] = (PLFLT) $z(x => i, y => j);
-
-           defined_subroutine = $COMP(defined);
-	   check_sub_pointer (defined_subroutine,
-	     "plshades: defined must be either 0 or a subroutine pointer");
-
-           pltr_subroutine = $COMP(pltr);
-	   check_sub_pointer (pltr_subroutine,
-	     "plshades: pltr must be either 0 or a subroutine pointer");
-
-	   pltrcb = get_standard_pltrcb ($COMP(pltr));
-           if (pltrcb != pltr_callback)
-             pltrdt = (PLPointer) SvIV ($COMP(pltr_data));
-           else
-             pltrdt = $COMP(pltr_data);
-
-           c_plshades ((const PLFLT **)z, nx, ny,
-             SvTRUE ($COMP(defined)) ? defined_callback : NULL,
-             $xmin(), $xmax(), $ymin(), $ymax(),
-             $P(clevel), nlvl, $fill_width(), $cont_color(), $cont_width(),
-             plfill, $rectangular(), pltrcb, pltrdt);
-
-           plFree2dGrid(z, nx, ny);',
-       );
-
-pp_def ('plcont',
-        NoPthread => 1,
-         GenericTypes => [D],
-         Pars => 'f(nx,ny); int kx(); int lx(); int ky(); int ly(); '
-                 . 'clevel(nlevel)', # 0-5
-         OtherPars => 'SV* pltr; SV* pltr_data;', # 6,7
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** ff;
-	   void (*pltrcb) ();
-           PLPointer pltrdt;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&ff, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               ff[i][j] = $f(nx => i, ny => j);
-
-           pltr_subroutine = $COMP(pltr);
-	   check_sub_pointer (pltr_subroutine,
-	     "plcont: pltr must be either 0 or a subroutine pointer");
-
-	   pltrcb = get_standard_pltrcb ($COMP(pltr));
-           if (pltrcb != pltr_callback)
-             pltrdt = (PLPointer) SvIV ($COMP(pltr_data));
-           else
-             pltrdt = $COMP(pltr_data);
-
-           c_plcont ((const PLFLT **)ff, size_x, size_y, $kx(), $lx(), $ky(), $ly(),
-                     $P(clevel), $SIZE(nlevel),
-                     pltrcb, pltrdt);
-
-           plFree2dGrid (ff, size_x, size_y);'
-        );
-
-
-# Surface mesh
-
-pp_def ('plmesh',
-        NoPthread => 1,
-         Pars => 'x(nx); y(ny); z(nx,ny); int opt()',
-         GenericTypes => [D],
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** zz;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&zz, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               zz[i][j] = $z(nx => i, ny => j);
-
-           c_plmesh ($P(x), $P(y), (const PLFLT **)zz, size_x, size_y, $opt());
-
-           plFree2dGrid (zz, size_x, size_y);'
-        );
-
-# Magnitude colored plot surface mesh with contour
-
-pp_def ('plmeshc',
-        NoPthread => 1,
-         Pars => 'x(nx); y(ny); z(nx,ny); int opt(); clevel(nlevel)',
-         GenericTypes => [D],
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** zz;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&zz, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               zz[i][j] = $z(nx => i, ny => j);
-
-           c_plmeshc ($P(x), $P(y), (const PLFLT **)zz, size_x, size_y, $opt(),
-                      $P(clevel), $SIZE(nlevel));
-
-           plFree2dGrid (zz, size_x, size_y);'
-        );
-
-# 3-d surface plot
-
-pp_def ('plot3d',
-        NoPthread => 1,
-         Pars => 'x(nx); y(ny); z(nx,ny); int opt(); int side()',
-         GenericTypes => [D],
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** zz;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&zz, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               zz[i][j] = $z(nx => i, ny => j);
-
-           c_plot3d ($P(x), $P(y), (const PLFLT **)zz, size_x, size_y, $opt(), $side());
-
-           plFree2dGrid (zz, size_x, size_y);'
-        );
-
-
-# Plots a 3-d representation of the function z[x][y] with contour
-
-pp_def ('plot3dc',
-        NoPthread => 1,
-         Pars => 'x(nx); y(ny); z(nx,ny); int opt(); clevel(nlevel)',
-         GenericTypes => [D],
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** zz;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&zz, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               zz[i][j] = $z(nx => i, ny => j);
-
-           c_plot3dc ($P(x), $P(y), (const PLFLT **)zz, size_x, size_y, $opt(),
-                      $P(clevel), $SIZE(nlevel));
-
-           plFree2dGrid (zz, size_x, size_y);'
-        );
-
-
-# Set color map1 colors using a piece-wise linear relationship
-
-pp_def ('plscmap1l',
-        NoPthread => 1,
-         Pars => 'int itype(); isty(n); coord1(n); coord2(n); coord3(n);'
-	         . ' int rev(nrev)',
-         GenericTypes => [D],
-         Doc => 'FIXME: documentation here!',
-         Code => '
-	   PLINT* rev;
-
-	   if ($SIZE(nrev) == 0)
-	     rev = NULL;
-	   else if ($SIZE(nrev) == $SIZE(n))
-   	     rev = $P(rev);
-           else
-             croak ("plscmap1l: rev must have either lenght == 0 or have the same length of the other input arguments");
-
-	   c_plscmap1l ($itype(), $SIZE(n), $P(isty), $P(coord1),
-	                       $P(coord2), $P(coord3), rev);'
-        );
-
-# Shade individual region on the basis of value
-
-pp_addpm ('sub plshade1 { plshade1_pp ($standard_order ? reorder ("plshade1", @_) : @_) }'); pp_add_exported('plshade1');
-pp_def ('plshade1_pp',
-        NoPthread => 1,
-         GenericTypes => [D],
-         Pars => 'a(nx,ny); left(); right(); bottom(); top(); shade_min();'
-                 . 'shade_max(); sh_cmap(); sh_color(); sh_width();'
-                 . 'min_color(); min_width(); max_color(); max_width();'
-                 . 'rectangular()', # 0-14
-         OtherPars => 'SV* defined; SV* pltr; SV* pltr_data;',# 15-17
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT* a;
-	   void (*pltrcb) ();
-           PLPointer pltrdt;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           New(3, a, size_x * size_y, PLFLT);
-           if(a == NULL) croak("Failed to allocate memory in plshade1_pp");
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               a[i * size_y + j] = (PLFLT) $a(nx => i, ny => j);
-
-           defined_subroutine = $COMP(defined);
-	   check_sub_pointer (defined_subroutine,
-	     "plshade1: defined must be either 0 or a subroutine pointer");
-
-           pltr_subroutine = $COMP(pltr);
-	   check_sub_pointer (pltr_subroutine,
-	     "plshade1: pltr must be either 0 or a subroutine pointer");
-
-	   pltrcb = get_standard_pltrcb ($COMP(pltr));
-           if (pltrcb != pltr_callback)
-             pltrdt = (PLPointer) SvIV ($COMP(pltr_data));
-           else
-             pltrdt = $COMP(pltr_data);
-
-           c_plshade1 (a, size_x, size_y,
-             SvTRUE ($COMP(defined)) ? defined_callback : NULL,
-             $left(), $right(), $bottom(), $top(),
-             $shade_min(), $shade_max(), $sh_cmap(), $sh_color(), $sh_width(),
-             $min_color(), $min_width(), $max_color(), $max_width(),
-             plfill, $rectangular(), pltrcb, pltrdt);
-
-           Safefree (a);'
-        );
-
-# Plot gray-level image
-
-pp_def ('plimage',
-         NoPthread => 1,
-         GenericTypes => [D],
-         Pars => 'idata(nx,ny); xmin(); xmax(); ymin(); ymax();'
-	         . 'zmin(); zmax(); Dxmin(); Dxmax(); Dymin(); Dymax();',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** idata;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&idata, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               idata[i][j] = $idata(nx => i, ny => j);
-
-           plimage ((const PLFLT **)idata, size_x, size_y,
-	     $xmin(), $xmax(), $ymin(), $ymax(), $zmin(), $zmax(),
-             $Dxmin(), $Dxmax(), $Dymin(), $Dymax());
-
-           plFree2dGrid (idata, size_x, size_y);'
-	);
-
-
-# Plot image with transformation
-
-if ($plversion->{'c_plimagefr'}) {
-
-  pp_def ('plimagefr',
-          NoPthread => 1,
-          GenericTypes => [D],
-          #  plimagefr (idata, nx, ny, xmin, xmax, ymin, ymax, zmin, zmax, valuemin, valuemax, pltr, pltr_data);
-          #  plimagefr ($img,          0,    $width, 0,  $height, 0,    0, $img_min, $img_max, \&pltr2, $grid);
-          Pars => 'idata(nx,ny); xmin(); xmax(); ymin(); ymax();'
-          . 'zmin(); zmax(); valuemin(); valuemax();', # 0-8
-          OtherPars => 'SV* pltr; SV* pltr_data;', # 9,10
-          Code => '
-           int i, j, size_x, size_y;
-           PLFLT** idata;
- 	   void (*pltrcb) ();
-           PLPointer pltrdt;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           pltr_subroutine = $COMP(pltr);
-	   check_sub_pointer (pltr_subroutine, "plimagefr: pltr must be either 0 or a subroutine pointer");
-
-	   pltrcb = get_standard_pltrcb ($COMP(pltr));
-           if (pltrcb != pltr_callback)
-             pltrdt = (PLPointer) SvIV ($COMP(pltr_data));
-           else
-             pltrdt = $COMP(pltr_data);
-
-           plAlloc2dGrid (&idata, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               idata[i][j] = $idata(nx => i, ny => j);
-
-           c_plimagefr ((const PLFLT **)idata, size_x, size_y,
-	     $xmin(), $xmax(), $ymin(), $ymax(), $zmin(), $zmax(),
-             $valuemin(), $valuemax(),
-             (SvTRUE ($COMP(pltr)) ? pltrcb : NULL),
-             (SvTRUE ($COMP(pltr)) ? pltrdt : NULL));
-
-           plFree2dGrid (idata, size_x, size_y);'
-	);
-
-} # $plversion->{'c_plimagefr'}
-
-# Set xor mode:
-# mode = 1-enter, 0-leave, status = 0 if not interactive device
-
-pp_addpm (<<'EOPM');
-=head2 plxormod
-
-=for sig
-
-  $status = plxormod ($mode)
-
-=for ref
-
-See the PLplot manual for reference.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-int
-plxormod (mode)
-  int mode
-CODE:
-  PLINT status;
-  c_plxormod (mode, &status);
-  RETVAL = status;
-OUTPUT:
-  RETVAL
-EOC
-
-pp_add_exported ('plxormod');
-
-# Wait for graphics input event and translate to world coordinates
-
-pp_addpm (<<'EOPM');
-=head2 plGetCursor
-
-=for sig
-
-  %gin = plGetCursor ()
-
-=for ref
-
-plGetCursor waits for graphics input event and translate to world
-coordinates and returns a hash with the following keys:
-
-    type:      of event (CURRENTLY UNUSED)
-    state:     key or button mask
-    keysym:    key selected
-    button:    mouse button selected
-    subwindow: subwindow (alias subpage, alias subplot) number
-    string:    translated string
-    pX, pY:    absolute device coordinates of pointer
-    dX, dY:    relative device coordinates of pointer
-    wX, wY:    world coordinates of pointer
-
-Returns an empty hash if no translation to world coordinates is possible.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-plGetCursor ()
-PPCODE:
-  PLGraphicsIn gin;
-  if (plGetCursor (&gin)) {
-    EXTEND (SP, 24);
-    PUSHs (sv_2mortal (newSVpv ("type", 0)));
-    PUSHs (sv_2mortal (newSViv ((IV) gin.type)));
-    PUSHs (sv_2mortal (newSVpv ("state", 0)));
-    PUSHs (sv_2mortal (newSVuv ((UV) gin.state)));
-    PUSHs (sv_2mortal (newSVpv ("keysym", 0)));
-    PUSHs (sv_2mortal (newSVuv ((UV) gin.keysym)));
-    PUSHs (sv_2mortal (newSVpv ("button", 0)));
-    PUSHs (sv_2mortal (newSVuv ((UV) gin.button)));
-    PUSHs (sv_2mortal (newSVpv ("subwindow", 0)));
-    PUSHs (sv_2mortal (newSViv ((IV) gin.subwindow)));
-    PUSHs (sv_2mortal (newSVpv ("string", 0)));
-    PUSHs (sv_2mortal (newSVpv (gin.string, 0)));
-    PUSHs (sv_2mortal (newSVpv ("pX", 0)));
-    PUSHs (sv_2mortal (newSViv ((IV) gin.pX)));
-    PUSHs (sv_2mortal (newSVpv ("pY", 0)));
-    PUSHs (sv_2mortal (newSViv ((IV) gin.pY)));
-    PUSHs (sv_2mortal (newSVpv ("dX", 0)));
-    PUSHs (sv_2mortal (newSVnv ((double) gin.dX)));
-    PUSHs (sv_2mortal (newSVpv ("dY", 0)));
-    PUSHs (sv_2mortal (newSVnv ((double) gin.dY)));
-    PUSHs (sv_2mortal (newSVpv ("wX", 0)));
-    PUSHs (sv_2mortal (newSVnv ((double) gin.wX)));
-    PUSHs (sv_2mortal (newSVpv ("wY", 0)));
-    PUSHs (sv_2mortal (newSVnv ((double) gin.wY)));
-  }
-EOC
-
-pp_add_exported ('plGetCursor');
-
-pp_addpm (<<'EOPM');
-=head2 plgstrm
-
-=for sig
-
-  $strm = plgstrm ()
-
-=for ref
-
-Returns the number of the current output stream.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-int
-plgstrm ()
-CODE:
-  PLINT strm;
-  c_plgstrm (&strm);
-  RETVAL = strm;
-OUTPUT:
-  RETVAL
-EOC
-
-pp_add_exported ('plgstrm');
-
-pp_addpm (<<'EOPM');
-=head2 plgsdev
-
-=for sig
-
-  $driver = plgdev ()
-
-=for ref
-
-Returns the current driver name.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-char*
-plgdev ()
-CODE:
-  char driver[80];
-  c_plgdev (driver);
-  RETVAL = driver;
-OUTPUT:
-  RETVAL
-EOC
-
-pp_add_exported ('plgdev');
-
-pp_addxs (<<"EOC");
-char*
-plgfnam ()
-CODE:
-  char driver[80];
-  c_plgfnam (driver);
-  RETVAL = driver;
-OUTPUT:
-  RETVAL
-EOC
-
-pp_add_exported ('plgfnam');
-
-pp_addpm (<<'EOPM');
-=head2 plmkstrm
-
-=for sig
-
-  $strm = plmkstrm ()
-
-=for ref
-
-Creates a new stream and makes it the default.  Returns the number of
-the created stream.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-int
-plmkstrm ()
-CODE:
-  PLINT strm;
-  c_plmkstrm (&strm);
-  RETVAL = strm;
-OUTPUT:
-  RETVAL
-EOC
-
-pp_add_exported ('plmkstrm');
-
-# Get the current library version number
-
-pp_addpm (<<'EOPM');
-=head2 plgver
-
-=for sig
-
-  $version = plgver ()
-
-=for ref
-
-See the PLplot manual for reference.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-char*
-plgver ()
-CODE:
-  char ver[80];
-  c_plgver (ver);
-  RETVAL = ver;
-OUTPUT:
-  RETVAL
-EOC
-
-pp_add_exported ('plgver');
-
-
-#----------------------------------------------------------------------------
-
-pp_addpm ('sub plstripc { plstripc_pp ($standard_order ? reorder ("plstripc", @_) : @_) }'); pp_add_exported('plstripc');
-pp_def ('plstripc_pp',
-        NoPthread => 1,
-         GenericTypes => [D],
-         Pars => 'xmin(); xmax(); xjump(); ymin(); ymax();'
-	         . 'xlpos(); ylpos(); int y_ascl(); int acc();'
-                 . 'int colbox(); int collab();'
-                 . 'int colline(n); int styline(n);  int [o] id()', # 0-12
-         OtherPars => 'char* xspec; char* yspec; SV* legline;' # 13-18
-                      . 'char* labx; char* laby; char* labtop',
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           I32 i;
-           PLINT id;
-           char* legline[4];
-           SV* sv_legline = $COMP(legline);
-           AV* av_legline;
-
-           if (! SvROK (sv_legline)
-               || SvTYPE (SvRV (sv_legline)) != SVt_PVAV)
-             croak ("plstripc: legline must be a reference to an array");
-
-           av_legline = (AV*) SvRV (sv_legline);
-
-           if (av_len (av_legline) != 3)
-             croak ("plstripc: legline must have four elements");
-
-           if ($SIZE(n) != 4)
-             croak ("plstripc: colline and styline must have four elements");
-
-           for (i = 0; i < 4; i++) {
-             SV** elem = av_fetch (av_legline, i, 0);
-             legline[i] = (char *) SvPV_nolen (*elem);
-           }
-
-           c_plstripc (&id, $COMP(xspec), $COMP(yspec),
-	     $xmin(), $xmax(), $xjump(), $ymin(), $ymax(),
-	     $xlpos(), $ylpos(),$y_ascl(), $acc(), $colbox(), $collab(),
-	     $P(colline), $P(styline), (const char **)legline,
-	     $COMP(labx), $COMP(laby), $COMP(labtop));
-
-           $id() = (int) id;'
-        );
-
-#----------------------------------------------------------------------------
-
-pp_def ('plgriddata',
-        NoPthread => 1,
-         GenericTypes => [D],
-         Pars => 'x(npts); y(npts); z(npts); xg(nptsx); yg(nptsy);'
-	         . 'int type(); data(); [o] zg(nptsx,nptsy)',
-         Doc => 'FIXME: documentation here!',
-         Code => '
-           int i, j, size_x, size_y;
-           PLFLT** zg;
-
-           size_x = $SIZE(nptsx);
-           size_y = $SIZE(nptsy);
-
-           plAlloc2dGrid (&zg, size_x, size_y);
-
-           c_plgriddata ($P(x), $P(y), $P(z), $SIZE(npts),
-	                 $P(xg), size_x, $P(yg), size_y,
-	                 zg, $type(), $data());
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++)
-               $zg(nptsx => i, nptsy => j) = zg[i][j];
-
-           plFree2dGrid (zg, size_x, size_y);
-         '
-        );
-
-#-----------------------------------------------------------------------------
-
-if ($plversion->{'c_pllegend'}) {
-
-# Draw an arc
-pp_addpm (<<'EOPM');
-=head2 plarc
-
-=for sig
-
-  plarc ($x, $y, $a, $b, $angle1, $angle2, $rotate, $fill);
-
-=for ref
-
-Draw a (possibly) filled arc centered at x, y with semimajor axis a and semiminor axis b, starting at angle1 and ending at angle2.
-See the PLplot manual for reference.
-
-=cut
-EOPM
-pp_addxs (<<"EOC");
-int
-plarc (x, y, a, b, angle1, angle2, rotate, fill)
-  double x
-  double y
-  double a
-  double b
-  double angle1
-  double angle2
-  double rotate
-  int fill
-CODE:
-  plarc (x, y, a, b, angle1, angle2, rotate, fill);
-EOC
-pp_add_exported ('plarc');
-
-#----------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plstransform
-
-=for sig
-
-  plstransform ($subroutine_reference);
-
-=for ref
-
-Sets the default transformation routine for plotting.
-
-  sub mapform {
-    my ($x, $y) = @_;
-
-    my $radius = 90.0 - $y;
-    my $xp = $radius * cos ($x * pi / 180);
-    my $yp = $radius * sin ($x * pi / 180);
-
-    return ($xp, $yp);
-  }
-  plstransform (\&mapform);
-
-See the PLplot manual for more details.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-int
-plstransform (xform)
- SV* xform
-CODE:
-  check_sub_pointer (xform_subroutine, "plstransform: xform must be either 0 or a subroutine pointer");
-  if (SvTRUE(xform)) xform_subroutine = SvRV(xform);
-  plstransform (SvTRUE(xform) ? xform_callback : NULL, NULL);
-EOC
-pp_add_exported ('plstransform');
-
-#----------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plslabelfunc
-
-=for sig
-
-  plslabelfunc ($subroutine_reference);
-
-=for ref
-
-  # A custom axis labeling function for longitudes and latitudes.
-  sub geolocation_labeler {
-    my ($axis, $value, $length) = @_;
-    my ($direction_label, $label_val);
-    if (($axis == PL_Y_AXIS) && $value == 0) {
-        return "Eq";
-      } elsif ($axis == PL_Y_AXIS) {
-      $label_val = $value;
-      $direction_label = ($label_val > 0) ? " N" : " S";
-    } elsif ($axis == PL_X_AXIS) {
-      my $times  = floor((abs($value) + 180.0 ) / 360.0);
-      $label_val = ($value < 0) ? $value + 360.0 * $times : $value - 360.0 * $times;
-      $direction_label = ($label_val > 0) ? " E"
-                       : ($label_val < 0) ? " W"
-                       :                    "";
-    }
-    return substr (sprintf ("%.0f%s", abs($label_val), $direction_label), 0, $length);
-  }
-  plslabelfunc(\&geolocation_labeler);
-
-See the PLplot manual for more details.
-
-=cut
-EOPM
-
-# The PDL version of plslabelfunc only has one argument--the perl subroutine
-# to do the label translation:  my $labeltext = perl_labelfunc($axis, $value, $length);
-# No 'data' argument is used, it is assumed that global data or a closure containing
-# necessary data can be used in 'perl_labelfunc'.
-pp_addxs (<<"EOC");
-int
-plslabelfunc (labelfunc)
- SV* labelfunc
-CODE:
-  check_sub_pointer (labelfunc_subroutine, "plslabelfunc: labelfunc must be either 0 or a subroutine pointer");
-  if (SvTRUE(labelfunc)) labelfunc_subroutine = SvRV(labelfunc);
-  plslabelfunc (SvTRUE(labelfunc) ? labelfunc_callback : NULL, NULL);
-EOC
-pp_add_exported ('plslabelfunc');
-
-#----------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 pllegend
-
-=for sig
-
-my ($legend_width, $legend_height) =
-    pllegend ($position, $opt, $x, $y, $plot_width, $bg_color, $nlegend,
-    \@opt_array,
-    $text_offset, $text_scale, $text_spacing, $test_justification,
-    \@text_colors, \@text, \@box_colors, \@box_patterns, \@box_scales, \@line_colors,
-    \@line_styles, \@line_widths, \@symbol_colors, \@symbol_scales, \@symbol_numbers, \@symbols);
-
-=for ref
-
-See the PLplot manual for more details.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-pllegend(opt, position, x, y, plot_width, bg_color, bb_color, bb_style, nrow, ncolumn, nlegend, opt_array_rv, text_offset, text_scale, text_spacing, text_justification, text_colors_rv, text_rv, box_colors_rv, box_patterns_rv, box_scales_rv, box_line_widths_rv, line_colors_rv, line_styles_rv, line_widths_rv, symbol_colors_rv, symbol_scales_rv, symbol_numbers_rv, symbols_rv)
-  int     opt
-  int     position
-  double  x
-  double  y
-  double  plot_width
-  int     bg_color
-  int     bb_color
-  int     bb_style
-  int     nrow
-  int     ncolumn
-  int     nlegend
-  SV*     opt_array_rv
-  double  text_offset
-  double  text_scale
-  double  text_spacing
-  double  text_justification
-  SV*     text_colors_rv
-  SV*     text_rv
-  SV*     box_colors_rv
-  SV*     box_patterns_rv
-  SV*     box_scales_rv
-  SV*     box_line_widths_rv
-  SV*     line_colors_rv
-  SV*     line_styles_rv
-  SV*     line_widths_rv
-  SV*     symbol_colors_rv
-  SV*     symbol_scales_rv
-  SV*     symbol_numbers_rv
-  SV*     symbols_rv
-PPCODE:
-  int i;
-  double p_legend_width;
-  double p_legend_height;
-  int opt_array[nlegend];
-  int text_colors[nlegend];
-  char *text[nlegend];
-  int box_colors[nlegend];
-  int box_patterns[nlegend];
-  double box_scales[nlegend];
-  int box_line_widths[nlegend];
-  int line_colors[nlegend];
-  int line_styles[nlegend];
-  int line_widths[nlegend];
-  int symbol_colors[nlegend];
-  double symbol_scales[nlegend];
-  int symbol_numbers[nlegend];
-  char *symbols[nlegend];
-  SV **elem;
-
-  for (i = 0; i < nlegend; i++) {
-
-    elem = av_fetch((AV *)SvRV(opt_array_rv),       i, 0); opt_array[i]       = (int)SvIV(*elem);
-    elem = av_fetch((AV *)SvRV(text_colors_rv),     i, 0); text_colors[i]     = (int)SvIV(*elem);
-    elem = av_fetch((AV *)SvRV(text_rv),            i, 0); text[i]            = (char *)SvPV_nolen(*elem);
-    box_colors[i] = 0;
-    if (SvROK(box_colors_rv)) {
-      elem = av_fetch((AV *)SvRV(box_colors_rv),    i, 0);
-      if (elem && SvOK(*elem)) {
-        box_colors[i] = (int)SvIV(*elem);
-      }
-    }
-    box_patterns[i] = 0;
-    if (SvROK(box_patterns_rv)) {
-      elem = av_fetch((AV *)SvRV(box_patterns_rv),  i, 0);
-      if (elem && SvOK(*elem)) {
-        box_patterns[i] = (int)SvIV(*elem);
-      }
-    }
-    box_scales[i] = 0.0;
-    if (SvROK(box_scales_rv)) {
-      elem = av_fetch((AV *)SvRV(box_scales_rv),    i, 0);
-      if (elem && SvOK(*elem)) {
-        box_scales[i] = (double)SvNV(*elem);
-      }
-    }
-    box_line_widths[i] = 0;
-    if (SvROK(box_line_widths_rv)) {
-      elem = av_fetch((AV *)SvRV(box_line_widths_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        box_line_widths[i] = (int)SvIV(*elem);
-      }
-    }
-    line_colors[i] = 0;
-    if (SvROK(line_colors_rv)) {
-      elem = av_fetch((AV *)SvRV(line_colors_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        line_colors[i] = (int)SvIV(*elem);
-      }
-    }
-
-    line_styles[i] = 0;
-    if (SvROK(line_styles_rv)) {
-      elem = av_fetch((AV *)SvRV(line_styles_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        line_styles[i] = (int)SvIV(*elem);
-      }
-    }
-
-    line_widths[i] = 0;
-    if (SvROK(line_widths_rv)) {
-      elem = av_fetch((AV *)SvRV(line_widths_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        line_widths[i] = (int)SvIV(*elem);
-      }
-    }
-
-    symbol_colors[i] = 0;
-    if (SvROK(symbol_colors_rv)) {
-      elem = av_fetch((AV *)SvRV(symbol_colors_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        symbol_colors[i] = (int)SvIV(*elem);
-      }
-    }
-
-    symbol_scales[i] = 0.0;
-    if (SvROK(symbol_scales_rv)) {
-      elem = av_fetch((AV *)SvRV(symbol_scales_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        symbol_scales[i] = (double)SvNV(*elem);
-      }
-    }
-
-    symbol_numbers[i] = 0;
-    if (SvROK(symbol_numbers_rv)) {
-      elem = av_fetch((AV *)SvRV(symbol_numbers_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        symbol_numbers[i] = (int)SvIV(*elem);
-      }
-    }
-
-    symbols[i] = "0";
-    if (SvROK(symbols_rv)) {
-      elem = av_fetch((AV *)SvRV(symbols_rv), i, 0);
-      if (elem && SvOK(*elem)) {
-        symbols[i] = (char *)SvPV_nolen(*elem);
-      }
-    }
-  }
-
-  pllegend(&p_legend_width, &p_legend_height,
-           opt, position, x, y, plot_width, bg_color, bb_color, bb_style, nrow, ncolumn, nlegend,
-           opt_array,
-           text_offset, text_scale, text_spacing, text_justification,
-           text_colors, (const char **)text, box_colors, box_patterns, box_scales, box_line_widths,
-           line_colors, line_styles, line_widths, symbol_colors, symbol_scales, symbol_numbers, (const char **)symbols);
-
-  EXTEND (SP, 2);
-  PUSHs (sv_2mortal (newSVnv (p_legend_width)));
-  PUSHs (sv_2mortal (newSVnv (p_legend_height)));
-EOC
-pp_add_exported ('pllegend');
-
-#----------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plspal0
-
-=for sig
-
-  plspal0($filename);
-
-=for ref
-
-Set color palette 0 from the input .pal file.  See the PLplot manual for more details.
-
-=cut
-EOPM
-
-# The PDL version of plspal0
-pp_addxs (<<"EOC");
-int
-plspal0 (filename)
- char* filename
-PPCODE:
-  plspal0((const char *)filename);
-EOC
-pp_add_exported ('plspal0');
-
-#----------------------------------------------------------------------------
-
-# The PDL version of plspal1
-pp_addpm (<<'EOPM');
-=head2 plspal1
-
-=for sig
-
-  plspal1($filename);
-
-=for ref
-
-Set color palette 1 from the input .pal file.  See the PLplot manual for more details.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-int
-plspal1 (filename, interpolate)
- char* filename
- int   interpolate
-PPCODE:
-  plspal1((const char *)filename, (PLBOOL)interpolate);
-EOC
-pp_add_exported ('plspal1');
-
-} # if $plversion->{'c_pllegend'}
-
-#-----------------------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plbtime
-
-=for sig
-
-  my ($year, $month, $day, $hour, $min, $sec) = plbtime($ctime);
-
-=for ref
-
-  Calculate broken-down time from continuous time for current stream.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-plbtime (ctime)
-  double ctime
-PPCODE:
-  PLINT year;
-  PLINT month;
-  PLINT day;
-  PLINT hour;
-  PLINT min;
-  PLFLT sec;
-  c_plbtime(&year, &month, &day, &hour, &min, &sec, ctime);
-  EXTEND (SP, 6);
-  PUSHs (sv_2mortal (newSViv (year)));
-  PUSHs (sv_2mortal (newSViv (month)));
-  PUSHs (sv_2mortal (newSViv (day)));
-  PUSHs (sv_2mortal (newSViv (hour)));
-  PUSHs (sv_2mortal (newSViv (min)));
-  PUSHs (sv_2mortal (newSVnv (sec)));
-EOC
-pp_add_exported ('plbtime');
-
-#-----------------------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plconfigtime
-
-=for sig
-
-  plconfigtime($scale, $offset1, $offset2, $ccontrol, $ifbtime_offset, $year, $month, $day, $hour, $min, $sec);
-
-=for ref
-
-Configure transformation between continuous and broken-down time (and
-vice versa) for current stream.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-plconfigtime(scale, offset1, offset2, ccontrol, ifbtime_offset, year, month, day, hour, min, sec)
-  double scale
-  double offset1
-  double offset2
-  int ccontrol
-  int ifbtime_offset
-  int year
-  int month
-  int day
-  int hour
-  int min
-  double sec
-PPCODE:
-  c_plconfigtime((PLFLT) scale, (PLFLT) offset1, (PLFLT) offset2,
-                 (PLINT) ccontrol, (PLBOOL) ifbtime_offset, (PLINT) year,
-                 (PLINT) month, (PLINT) day, (PLINT) hour, (PLINT) min, (PLFLT) sec);
-EOC
-pp_add_exported ('plconfigtime');
-
-#-----------------------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plctime
-
-=for sig
-
-  my $ctime = plctime($year, $month, $day, $hour, $min, $sec);
-
-=for ref
-
-  Calculate continuous time from broken-down time for current stream.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-plctime(year, month, day, hour, min, sec)
-  int year
-  int month
-  int day
-  int hour
-  int min
-  double sec
-PPCODE:
-  PLFLT ctime;
-  c_plctime(year, month, day, hour, min, sec, &ctime);
-  EXTEND (SP, 1);
-  PUSHs (sv_2mortal (newSVnv (ctime)));
-EOC
-pp_add_exported ('plctime');
-
-#-----------------------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 pltimefmt
-
-=for sig
-
-  pltimefmt($fmt);
-
-=for ref
-
-Set format for date / time labels.  See the PLplot manual for more details.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-pltimefmt(fmt)
-  char *fmt
-PPCODE:
-  c_pltimefmt((const char *)fmt);
-EOC
-pp_add_exported ('pltimefmt');
-
-#-----------------------------------------------------------------------------------------
-
-pp_addpm (<<'EOPM');
-=head2 plsesc
-
-=for sig
-
-  plsesc($esc);
-
-=for ref
-
-
-Set the escape character for text strings.  See the PLplot manual for more details.
-
-=cut
-EOPM
-
-pp_addxs (<<"EOC");
-void
-plsesc (esc)
-  SV* esc
-PPCODE:
-  char *esc_c;
-  esc_c = (char *)SvPV_nolen(esc);
-  c_plsesc((char)*esc_c);
-
-EOC
-pp_add_exported ('plsesc');
-
-if ($plversion->{'plsvect'}) {
-
-# Vector field plots
-
-  pp_def ('plvect',
-          NoPthread => 1,
-	  GenericTypes => [D],
-	  Pars => 'u(nx,ny); v(nx,ny); scale();',
-	  OtherPars => 'SV* pltr; SV* pltr_data;',
-	  Doc => 'FIXME: documentation here!',
-	  Code => '
-           int i, j, size_x, size_y;
-           PLFLT** u;
-           PLFLT** v;
-	   void (*pltrcb) ();
-           PLPointer pltrdt;
-
-           size_x = $SIZE(nx);
-           size_y = $SIZE(ny);
-
-           plAlloc2dGrid (&u, size_x, size_y);
-           plAlloc2dGrid (&v, size_x, size_y);
-
-           for (i = 0; i < size_x; i++)
-             for (j = 0; j < size_y; j++) {
-               u[i][j] = $u(nx => i, ny => j);
-               v[i][j] = $v(nx => i, ny => j);
-             }
-
-           pltr_subroutine = $COMP(pltr);
-	   check_sub_pointer (pltr_subroutine,
-	     "plvect: pltr must be either 0 or a subroutine pointer");
-
-	   pltrcb = get_standard_pltrcb ($COMP(pltr));
-           if (pltrcb != pltr_callback)
-             pltrdt = (PLPointer) SvIV ($COMP(pltr_data));
-           else
-             pltrdt = $COMP(pltr_data);
-
-           plvect ((const PLFLT **)u, (const PLFLT **)v, size_x, size_y, $scale(), pltrcb, pltrdt);
-
-           plFree2dGrid (u, size_x, size_y);
-           plFree2dGrid (v, size_x, size_y);'
-	 );
-
-  pp_def ('plsvect',
-          NoPthread => 1,
-	  Pars => 'arrowx(npts); arrowy(npts); int fill()',
-	  GenericTypes => [D],
-	  Code => 'c_plsvect ($P(arrowx), $P(arrowy), $SIZE(npts), $fill());'
-	 );
-  }
-
-  pp_def ('plhlsrgb',
-          NoPthread => 1,
-	  GenericTypes => [D],
-	  Pars => 'double h();double l();double s();double [o]p_r();double [o]p_g();double [o]p_b()',
-	  Code => 'c_plhlsrgb($h(),$l(),$s(),$P(p_r),$P(p_g),$P(p_b));'
-	 );
-
-  # void c_plgcol0(PLINT icol0, PLINT *r, PLINT *g, PLINT *b);
-  pp_def ('plgcol0',
-          NoPthread => 1,
-	  Pars => 'int icolzero(); int [o]r(); int [o]g(); int [o]b()',
-	  Code => 'c_plgcol0($icolzero(),$P(r),$P(g),$P(b));'
-	 );
-
-  # void c_plgcolbg(PLINT *r, PLINT *g, PLINT *b);
-  pp_def ('plgcolbg',
-          NoPthread => 1,
-	  Pars => 'int [o]r(); int [o]g(); int [o]b()',
-	  Code => 'c_plgcolbg($P(r),$P(g),$P(b));'
-	 );
-
-  # void c_plscmap0(PLINT *r, PLINT *g, PLINT *b, PLINT ncol0);
-  pp_def ('plscmap0',
-          NoPthread => 1,
-	  Pars => 'int r(n); int g(n); int b(n)',
-	  Code => 'c_plscmap0($P(r),$P(g),$P(b), $SIZE(n));'
-	 );
-
-  # void c_plscmap1(PLINT *r, PLINT *g, PLINT *b, PLINT ncol1);
-  pp_def ('plscmap1',
-          NoPthread => 1,
-	  Pars => 'int r(n); int g(n); int b(n)',
-	  Code => 'c_plscmap1($P(r),$P(g),$P(b), $SIZE(n));'
-	 );
-
-  if (!$noalpha) {
-
-    # void c_plgcol0a(PLINT icol0, PLINT *r, PLINT *g, PLINT *b, PLFLT *a);
-    pp_def ('plgcol0a',
-            NoPthread => 1,
-	    Pars => 'int icolzero(); int [o]r(); int [o]g(); int [o]b(); double [o]a()',
-	    Code => 'c_plgcol0a($icolzero(),$P(r),$P(g),$P(b),$P(a));'
-	   );
-
-    # void c_plgcolbga(PLINT *r, PLINT *g, PLINT *b, PLFLT *a);
-    pp_def ('plgcolbga',
-            NoPthread => 1,
-	    Pars => 'int [o]r(); int [o]g(); int [o]b(); double [o]a()',
-	    Code => 'c_plgcolbga($P(r),$P(g),$P(b),$P(a));'
-	   );
-
-    # void c_plscmap0a(PLINT *r, PLINT *g, PLINT *b, PLFLT *a, PLINT ncol0);
-    pp_def ('plscmap0a',
-            NoPthread => 1,
-	    Pars => 'int r(n); int g(n); int b(n); double a(n)',
-	    Code => 'c_plscmap0a($P(r),$P(g),$P(b),$P(a),$SIZE(n));'
-	   );
-
-    # void c_plscmap1a(PLINT *r, PLINT *g, PLINT *b, PLFLT *a, PLINT ncol1);
-    pp_def ('plscmap1a',
-            NoPthread => 1,
-	    Pars => 'int r(n); int g(n); int b(n); double a(n)',
-	    Code => 'c_plscmap1a($P(r),$P(g),$P(b),$P(a),$SIZE(n));'
-	   );
-
-    # Set color map1 colors using a piece-wise linear relationship, include alpha channel
-
-    pp_def ('plscmap1la',
-            NoPthread => 1,
-	    Pars => 'int itype(); isty(n); coord1(n); coord2(n); coord3(n); coord4(n);'
-	    . ' int rev(nrev)',
-	    GenericTypes => [D],
-	    Doc => 'FIXME: documentation here!',
-	    Code => '
-	      PLINT* rev;
-
-	      if ($SIZE(nrev) == 0)
-	        rev = NULL;
-	      else if ($SIZE(nrev) == $SIZE(n))
-   	        rev = $P(rev);
-              else
-                croak ("plscmap1la: rev must have either length == 0 or have the same length of the other input arguments");
-
-	      c_plscmap1la ($itype(), $SIZE(n), $P(isty), $P(coord1),
-	                    $P(coord2), $P(coord3), $P(coord4), rev);'
-	   );
-    }
-
-
-    #
-    ## UNICODE font manipulation
-    #
-
-    if ($plversion->{'c_plsfont'}) {
-
-      # plgfont(PLINT *p_family, PLINT *p_style, PLINT *p_weight);
-      pp_def ('plgfont',
-              NoPthread => 1,
-	      Pars => 'int [o]p_family(); int [o]p_style(); int [o]p_weight();',
-	      Code => 'c_plgfont($P(p_family),$P(p_style),$P(p_weight));'
-	     );
-
-      #  plsfont (PLINT family, PLINT style, PLINT weight);
-      pp_def ('plsfont',
-              NoPthread => 1,
-	      Pars => 'int family(); int style(); int weight();',
-	      Code => 'c_plsfont($family(),$style(),$weight());'
-	     );
-    } # $plversion->{'c_plsfont'}
-
-    #  plcalc_world (PLFLT rx, PLFLT ry, PLFLT *wx, PLFLT *wy, PLINT *window);
-    pp_def ('plcalc_world',
-            NoPthread => 1,
-	    Pars => 'double rx(); double ry(); double [o]wx(); double [o]wy(); int [o]window()',
-	    Code => 'c_plcalc_world($rx(), $ry(), $P(wx), $P(wy), $P(window));'
-	   );
-
-
-pp_addxs (<<"EOC");
-unsigned int plgfci ()
-    CODE:
-    {
-	unsigned int	RETVAL;
-        unsigned int    fci;
-	c_plgfci(&fci);
-        RETVAL = fci;
-
-	XSprePUSH; PUSHu((UV)RETVAL);
-    }
-    XSRETURN(1);
-EOC
-pp_add_exported('', 'plgfci');
-
-pp_addxs (<<'EOC');
-void
-plsfci(fci)
-        unsigned int fci
-    CODE:
-        c_plsfci(fci);
-EOC
-pp_add_exported('', 'plsfci');
-
-pp_addpm (<<'EOPM');
-
-=pod
-
-=head1 WARNINGS AND ERRORS
-
-PLplot gives many errors and warnings.  Some of these are given by the
-PDL interface while others are internal PLplot messages.  Below are
-some of these messages, and what you need to do to address them:
-
-=over
-
-=item *
-Box must be a ref to a four element array
-
-When specifying a box, you must pass a reference to a
-four-element array, or use an anonymous four-element array.
-
- # Gives trouble:
- $pl->xyplot($x, $y, BOX => (0, 0, 100, 200) );
- # What you meant to say was:
- $pl->xyplot($x, $y, BOX => [0, 0, 100, 200] );
-
-=item *
-Too many colors used! (max 15)
-
-
-=back
-
-=head1 AUTHORS
-
-  Doug Hunt <dhunt@ucar.edu>
-  Rafael Laboissiere <rlaboiss@users.sourceforge.net>
-  David Mertens <mertens2@illinois.edu>
-
-=head1 SEE ALSO
-
-perl(1), PDL(1), L<http://www.plplot.org/>
-
-The other common graphics packages include L<PDL::PGPLOT>
-and L<PDL::TriD>.
-
-=cut
-
-EOPM
-
-pp_done();
-
-# Local Variables:
-# mode: cperl
-# End:
@@ -36,13 +36,6 @@ The following issues have been reported with this version of PDL:
     f( scalar($p0 * $p1) x $p2 );
 
 
-- On MS Windows, perl 5.14 (and perhaps later), it is reported that
-  PDL::Graphics::PLplot cannot be sucessfully built as part of the
-  PDL build. It compiles ok, but the resultant binary files are
-  unusable. Workaround is to build PDL first, then build
-  PDL::Graphics::PLplot separately.
-
-
 - Some versions of MinGW gcc (used to compile for win32 perls)
   crash in compilation of large, PP-generated files.  The work-
   around is to disable optimization for those files.  See the
@@ -102,18 +95,26 @@ The following issues have been reported with this version of PDL:
 
 
 - The following SourceForge bugs are outstanding at time of the
-  PDL-2.008 release:
+  PDL-2.012 release:
+
+  389 	not indexed modules
+
+        This is believed to be fixed in this release.
+	As it is an indexer problem, there is no way
+	to be certain without pushing another official
+	release.
 
-  383   gcc/#gfortran 4.9.2 needs -lquadmath
+  384   pdldoc.db is getting invalid paths to files on cygwin
+  383   gcc/gfortran 4.9.2 needs -lquadmath
   382   plplot-5.11.0 comes with libplplot.a but missing libplplotd.a
-  381   rpic/#rim fail to read files with whitespace in the filename
-  380   PDL Install hangs on t/#flexraw_fortran.t
+  381   rpic/rim fail to read files with whitespace in the filename
+  380   PDL Install hangs on t/flexraw_fortran.t
   379   Passing qsort an extra argument causes a segfault
   378   where on dice of pdl bad results
   366   many warnings in t/transform.t with use strict; use warnings;
   364   type promotion in whistogram is based upon the index, not the weight
   354   filter demo list by actually available
-  347   t/#pdl_from_string.t has a failure if BADVAL_NAN=1
+  347   t/pdl_from_string.t has a failure if BADVAL_NAN=1
   346   ExtUtils::F77 dependency causing problems for CPAN install
   343   longlong constructor and display lose digits due to implicit double precision conversions
   340   orover of byte data returns long type
@@ -191,7 +191,6 @@ Example/InlinePdlpp/inlpp_link.pl
 Example/InlinePdlpp/inlppminimal.pl
 Example/PGPLOT/pgplot.pl
 Example/PGPLOT/std_pgplot.pl
-Example/PLplot/refresh.pdl
 Example/Simplex/tsimp2.pl
 Example/Simplex/tsimp_needs_pgplot.pl
 Example/TriD/3dtest.pl
@@ -271,10 +270,6 @@ Graphics/PGPLOT/Window/Makefile.PL
 Graphics/PGPLOT/Window/Window.pm
 Graphics/PGPLOT/Window/Window.xs
 Graphics/PGPLOT/Window/typemap
-Graphics/PLplot/Changes
-Graphics/PLplot/Makefile.PL
-Graphics/PLplot/README
-Graphics/PLplot/plplot.pd
 Graphics/State.pm
 Graphics/TriD/Makefile.PL
 Graphics/TriD/OpenGLQ/Makefile.PL
@@ -768,8 +763,6 @@ t/physical.t
 t/pic_16bit.t
 t/picnorgb.t
 t/picrgb.t
-t/plplot.t
-t/plplot_no_fork.win32
 t/pnm.t
 t/poly.t
 t/polyroots.t
@@ -825,7 +818,6 @@ GENERATED/PDL/Fit/Gaussian.pm            mod=PDL::Fit::Gaussian pd=Lib/Fit/Gauss
 GENERATED/PDL/GIS/Proj.pm                mod=PDL::GIS::Proj pd=Lib/GIS/Proj/Proj.pd (added by pdlpp_mkgen)
 GENERATED/PDL/Graphics/IIS.pm            mod=PDL::Graphics::IIS pd=Graphics/IIS/iis.pd (added by pdlpp_mkgen)
 GENERATED/PDL/Graphics/OpenGLQ.pm        mod=PDL::Graphics::OpenGLQ pd=Graphics/TriD/OpenGLQ/openglq.pd (added by pdlpp_mkgen)
-GENERATED/PDL/Graphics/PLplot.pm         mod=PDL::Graphics::PLplot pd=Graphics/PLplot/plplot.pd (added by pdlpp_mkgen)
 GENERATED/PDL/Graphics/TriD/Rout.pm      mod=PDL::Graphics::TriD::Rout pd=Graphics/TriD/Rout/rout.pd (added by pdlpp_mkgen)
 GENERATED/PDL/GSL/DIFF.pm                mod=PDL::GSL::DIFF pd=Lib/GSL/DIFF/gsl_diff.pd (added by pdlpp_mkgen)
 GENERATED/PDL/GSL/INTEG.pm               mod=PDL::GSL::INTEG pd=Lib/GSL/INTEG/gsl_integ.pd (added by pdlpp_mkgen)
@@ -98,10 +98,6 @@ RCS
 ^Graphics/IIS/IIS\..*
 ^Graphics/PGPLOT/PGPLOT.c
 ^Graphics/PGPLOT/Window/Window.c
-^Graphics/PLplot/OPTIONS!
-^Graphics/PLplot/PLplot.c
-^Graphics/PLplot/PLplot.pm
-^Graphics/PLplot/PLplot.xs
 ^Graphics/TriD/OpenGL/OpenGL.pm
 ^Graphics/TriD/OpenGL/OpenGL.xs
 ^Graphics/TriD/OpenGL/OpenGL\.c$
@@ -35,7 +35,8 @@
          "requires" : {
             "Carp" : "1.2",
             "Devel::CheckLib" : "1.01",
-            "ExtUtils::MakeMaker" : "6.56"
+            "ExtUtils::MakeMaker" : "6.56",
+            "File::Path" : "0"
          }
       },
       "runtime" : {
@@ -77,5 +78,5 @@
       },
       "homepage" : "http://pdl.perl.org/"
    },
-   "version" : "2.008"
+   "version" : "2.012"
 }
@@ -14,6 +14,7 @@ configure_requires:
   Carp: '1.2'
   Devel::CheckLib: '1.01'
   ExtUtils::MakeMaker: '6.56'
+  File::Path: '0'
 dynamic_config: 1
 generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.143240'
 license: unknown
@@ -56,4 +57,4 @@ requires:
 resources:
   bugtracker: http://sourceforge.net/p/pdl/bugs/
   homepage: http://pdl.perl.org/
-version: '2.008'
+version: '2.012'
@@ -445,6 +445,7 @@ my %makefile_hash = (
                 'Devel::CheckLib' => 1.01,
                 'Carp'            => 1.20,    # EU::MM seems to need this not to crash
                 'ExtUtils::MakeMaker' => 6.56,
+                'File::Path'          => 0,
               },
               TEST_REQUIRES => {
                 'CPAN::Meta' => '2.120900',
@@ -1,3 +1,147 @@
+Release Notes for PDL 2.012 -----------------------------
+
+ +---------------------------------------------------------------+
+ | BE WARNED:  This release includes an update to the internal,  |
+ | C-level PDL API for PDL versions 2.007 and earlier.  This     |
+ | will require that you re-build any PP or XS modules.  Do not  |
+ | upgrade or install over an existing PDL installation unless   |
+ | you are prepared to do so!!!                                  |
+ +---------------------------------------------------------------+
+
+General Notes:
+
+ * This is PDL-2.012 it is essentially PDL-2.011 with some
+   fixes for some minor issues that only came to light
+   with a new official release.
+ 
+ * See PDL 2.011 notes below.
+
+
+Highlights:
+
+ * Add package statements so PDL::Lite and PDL::LiteF are
+   indexed correctly
+ 
+ * Give PDL::NiceSlice a non-developer release for indexing
+
+ * Fix build regression that broke ActiveState perl
+   builds for many perl versions and OS platforms.
+
+
+
+Release Notes for PDL 2.011 -----------------------------
+
+ +---------------------------------------------------------------+
+ | BE WARNED:  This release includes an update to the internal,  |
+ | C-level PDL API for PDL versions 2.007 and earlier.  This     |
+ | will require that you re-build any PP or XS modules.  Do not  |
+ | upgrade or install over an existing PDL installation unless   |
+ | you are prepared to do so!!!                                  |
+ +---------------------------------------------------------------+
+
+General Notes:
+
+ * This is PDL-2.011 it is essentially PDL-2.008 with some
+   fixes for some minor issues.
+ 
+ * perl 5.10.x is now the minimum version of perl
+   supported by PDL-2.008 and later.
+
+ * PDL::FFTW is no longer part of the PDL Core.
+   Please use PDL::FFTW3 from CPAN (Dima Kogan)
+   with Alien::FFTW3 support (Craig DeForest)
+
+ * PDL::Graphics::PLplot is no longer included in
+   the PDL core distribution.  Please install from
+   CPAN directly.
+
+ * 50 sf.net bug tickets closed/fixed since PDL-2.007!
+
+ * Partial 64bit indexing support with some fixes
+   to remaining issues.  Full 64bit support for perl
+   modulus operater ('%') is in progress.
+ 
+ * Major clean up and rework of the core PDL
+   computation code, the build process, test suites,
+   and updating to reflect more of the best practices
+   for perl module development.
+ 
+ * The PDL development has moved to github and now
+   has added continuous commit testing via the
+   Travis-CI framework.  The git workflow is now
+   inline with current practices and it is expected
+   that this will allow more contributions and "eyes
+   on the code".
+
+
+Highlights:
+
+ * See PDL 2.008 Highlights below.
+
+
+
+Release Notes for PDL 2.010 -----------------------------
+
+General Notes:
+
+ * Another indexing regression.  Sigh.
+
+
+
+Release Notes for PDL 2.009_01 -----------------------------
+
+ +---------------------------------------------------------------+
+ | BE WARNED:  This release includes an update to the internal,  |
+ | C-level PDL API for PDL versions 2.007 and earlier.  This     |
+ | will require that you re-build any PP or XS modules.  Do not  |
+ | upgrade or install over an existing PDL installation unless   |
+ | you are prepared to do so!!!                                  |
+ +---------------------------------------------------------------+
+
+General Notes:
+
+ * Another quick CPAN developers release
+
+   - It is a snapshot of the current git development tree
+     and everything may not work correctly or have complete
+     documentation.
+
+   - These release notes may not be fully complete.  Please
+     see Changes (from the git log) for full details.
+
+   - All tests may not pass, especially ones corresponding
+     to issues in Known_problems.
+
+   - Manual build/install is possible, but easiest is to
+     use cpanm:
+
+       cpanm --dev PDL
+
+Highlights:
+
+ * Removal of PDL::Graphics::PLplot since exists as separate CPAN distro
+
+
+
+Release Notes for PDL 2.009 -----------------------------
+
+General Notes:
+
+ * This is PDL-2.009. It has tweaks to fix PAUSE/CPAN
+   indexing problems in 2.008.
+ 
+ * Known_problems updated to reflect a seldom seen
+   pdldoc installation problem for certain custom
+   perl configurations on cygwin.  A workaround is
+   known.  Please contact the PDL mailing list if you
+   have this problem.  See the sf.net bug report at
+   http://sourceforge.net/p/pdl/bugs/384/ for more
+   information.
+ 
+ * See Release Notes for PDL 2.008 below for more.
+
+
+
 Release Notes for PDL 2.008 -----------------------------
 
  +---------------------------------------------------------------+
@@ -1,12 +1,6 @@
 What follows is that task list and description of
 the work planned for the future  PDL-2.x releases.
 
-The main goal we are working towards is to have a
-baseline PDL working on *all* PDL OS platforms:
-win32/cygwin, macosx, and linux/unix/bsd systems with
-support for 2-D graphics (via PLplot) and 3-D graphics
-(via OpenGL/TriD).
-
 
 +-------------------------------------------------------+
 |       Candidate Tasks for PDL-2.x Development         |
@@ -137,10 +131,6 @@ support for 2-D graphics (via PLplot) and 3-D graphics
      - needs portable driver (OpenGL)
      - Alien::PGPLOT
      - apply/update RGB color patches to current
-   * PDL::Graphics::PLplot
-     - need portable driver (OpenGL)
-     - Alien::PLplot
-     - need low-level PLplot interface
    * PDL::IO::Browser
      - need curses/ncurses
      - Alien::Curses
@@ -166,7 +156,6 @@ support for 2-D graphics (via PLplot) and 3-D graphics
 +-------------------------------------------------------+
    
    Alien modules for the external PDL dependencies
-   * Alien::PLplot
    * Alien::PROJ4
 
 
@@ -349,20 +338,13 @@ support for 2-D graphics (via PLplot) and 3-D graphics
 +-------------------------------------------------------+
 |                    NEW FEATURES                       |
 +-------------------------------------------------------+
-   
+
    Finish PDL::IO::ENVI module
    * Implement basic writeenvi() routine
    * Add tests and reimplement as a module
    * Add to PDL distribution
 
 
-   Need PLplot and PDL::Graphics::PLplot to build all platforms
-   * MS Windows
-   * Cygwin
-   * Linux/unix
-   * Mac OS X 
-
-   
    Complete Perldl2 shell:
    * Implement remaining perldl features for pdl2
    * Fix Ctrl-C handling for win32 systems
@@ -416,14 +416,6 @@ NOTE: From the cygwin-xfree mailing list:
 
 
 
-
-=================================================================
-                             PLplot
-=================================================================
-TBD
-
-
-
 =================================================================
                                HDF
 =================================================================
@@ -104,11 +104,6 @@ These modules with external dependencies are not yet available
 for cygwin:
 
  PDL::Graphics::IIS
-  
- PDL::Graphics::PLplot  (PLplot and the PDL module support
-                         is not working out of the box.  If
-			 you get plplot built and installed
-			 for cygwin with PDL, let us know!)
 
  PDL::IO::HDF           (HDF4 has not been ported to cygwin
                          but HDF5 is available via the cygwin
@@ -5,10 +5,6 @@ pdl for Debian
   pdl is the perl data language.  Try "man PDL", or , for more man pages,
   "man -k PDL". Html documents are found in /usr/share/doc/pdl/html/.
   
-  For some examples on how to use PDL::Graphics::PLplot for plotting, install
-  libplplot-dev and take a look at the perl/pdl examples in
-  /usr/share/doc/libplplot-dev/examples/perl
-  
   More information can be found at:
   http://pdl.perl.org/
   
@@ -10,7 +10,6 @@ Build-Depends:
  libncurses-dev,
  perl (>= 5.8.0-3),
  debhelper (>= 9),
- libplplot-dev,
  libinline-perl (>= 0.43),
  libgsl0-dev,
  fftw-dev,
@@ -46,7 +45,6 @@ Suggests:
  netpbm | imagemagick,
  libastro-fits-header-perl,
  libinline-perl,
- libplplot-dev,
  doc-base,
  libextutils-f77-perl,
  proj-bin | proj,
@@ -123,19 +123,6 @@
 #       POGL_WINDOW_TYPE => 'x11',      # use X11+GLX for windows
         POGL_WINDOW_TYPE => 'glut',     # use GLUT for windows
 
-## Whether or not to build the PLplot interface module
-#
-# default settings (let PDL build decide whether to build PLPLOT)
-#
-        WITH_PLPLOT          => 0, # Leave it up to PDL to decide
-        WHERE_PLPLOT_LIBS    => undef, # let PDL search for plplot installation
-        WHERE_PLPLOT_INCLUDE => undef, # let PDL search for plplot installation
-        
-# Example manual settings:
-#    WITH_PLPLOT          => 1,                           # Build PLPLOT interface
-#    WHERE_PLPLOT_LIBS    => '/usr/local/plplot/lib',     # PLplot lib dir
-#    WHERE_PLPLOT_INCLUDE => '/usr/local/plplot/include', # PLplot include dir
-
         
 # Whether or not to build the PDL::Slatec module
 # false -> don't use
@@ -123,20 +123,6 @@
 #       POGL_WINDOW_TYPE => 'x11',      # use X11+GLX for windows
         POGL_WINDOW_TYPE => 'glut',     # use GLUT for windows
 
-## Whether or not to build the PLplot interface module
-#
-# default settings (let PDL build decide whether to build PLPLOT)
-#
-        WITH_PLPLOT          => 0, # undef means Leave it up to PDL to decide
-        WHERE_PLPLOT_LIBS    => undef, # let PDL search for plplot installation
-        WHERE_PLPLOT_INCLUDE => undef, # let PDL search for plplot installation
-
-# Example manual settings:
-#    WITH_PLPLOT          => 1,                           # Build PLPLOT interface
-#    WHERE_PLPLOT_LIBS    => '/usr/local/plplot/lib',     # PLplot lib dir
-#    WHERE_PLPLOT_INCLUDE => '/usr/local/plplot/include', # PLplot include dir
-
-
 # Whether or not to build the PDL::Slatec module
 # false -> don't use
 # true -> force use
@@ -6,7 +6,7 @@
 # the result of use_ok or some such.
 
 BEGIN {
-   use Test::More tests => 13;  # 12 WITH_ keys and 1 use_ok test
+   use Test::More tests => 12;  # 11 WITH_ keys and 1 use_ok test
 }
 
 BEGIN {
@@ -1,573 +0,0 @@
-# Before `make install' is performed this script should be runnable with
-# `make test'. After `make install' it should work as `perl test.pl'
-
-use strict;
-use warnings;
-use PDL;
-use PDL::Config;
-use Test::More;
-use File::Temp qw(tempdir);
-use File::Spec;
-
-######################### We start with some black magic to print on failure.
-
-BEGIN{
-  use PDL::Config;
-  if($PDL::Config{WITH_PLPLOT}) {
-    if($^O =~ /mswin/i) {
-      warn "No PLPLOT_LIB env var set - this script will die after the first test if the font files are not found"
-        if !$ENV{PLPLOT_LIB};
-    }
-    plan tests => 37;
-    use_ok( "PDL::Graphics::PLplot" );
-  }
-  else {
-    plan skip_all => "PDL::Graphics::PLplot not installed";
-  }
-}
-
-######################### End of black magic.
-
-# Insert your test code below (better if it prints "ok 13"
-# (correspondingly "not ok 13") depending on the success of chunk 13
-# of the test code):
-
-# Use svg driver because it should always be installed.
-my $dev = 'svg';
-
-my ($pl, $x, $y, $min, $max, $oldwin, $nbins);
-
-
-###
-# Initial test to work around font file brain damage:  for some kinds of
-# PLplot errors, control never returns to us.  FMH.
-#   --CED
-###
-
-my $tmpdir  = tempdir( CLEANUP => 1 );
-unless($^O =~ /mswin/i) { # Causes problems on Windows.
-  my $tmpfile = File::Spec->catfile($tmpdir, "foo.$dev");
-
-# comment this out for testing!!!
-  #my $pid = 0; my $a = 'foo';
-my ($pid,$not_ok);
-  if($pid = fork()) {
-	$a = waitpid($pid,0);
-  } else {
-	sleep 1;
-	$pl = PDL::Graphics::PLplot->new(DEV=>$dev,FILE=>$tmpfile);
-	exit(0);
-  }
-
-  ok( ($not_ok = $? & 0xff )==0 , "PLplot crash test"  );
-  unlink $tmpfile;
-
-  if($not_ok) {
-	printf <<"EOERR" ;
-
-Return value $not_ok; a is $a; pid is $pid
-
-************************************************************************
-* PLplot failed the crash test: it appears to crash its owner process. *
-* This is probably due to a misconfiguration of the PLplot libraries.  *
-* Next we\'ll try creating a test window from which will probably dump  *
-* some (hopefully helpful) error messages and then die.                *
-************************************************************************
-
-EOERR
-
-  }
-}
-else { # MS Windows only
-	my $ret = system(qq{"$^X" -Mblib -MPDL -MPDL::Graphics::PLplot -e "$pl = PDL::Graphics::PLplot->new(DEV=>\"xfig\",FILE=>\"foo.xfig\")"});
-	ok( $ret == 0 , "PLplot crash test"  );
-	unlink 'foo.xfig';
-}
-
-my $tmpfile02 = File::Spec->catfile($tmpdir, "test02.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev,
-				  FILE => $tmpfile02,
-				  BACKGROUND => [255,255,255]);
-isa_ok( $pl, "PDL::Graphics::PLplot" ) or die;
-
-$x  = sequence(10);
-$y  = $x**2;
-$pl->xyplot($x, $y,
-	    BOX => [-5,10,0,200],
-	    PLOTTYPE => 'LINE');
-$pl->close;
-ok (-s $tmpfile02 > 0, "Simple line plot");
-
-my $tmpfile02a = File::Spec->catfile($tmpdir, "test02a.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev,
-				  FILE => $tmpfile02a,
-				  LINEWIDTH => 10,
-				  BACKGROUND => [255,255,255]);
-$pl->xyplot($x, $y,
-	    BOX => [-5,10,0,200],
-	    PLOTTYPE => 'LINE');
-$pl->close;
-ok (-s $tmpfile02a > 0, "Simple line plot with LINEWIDTH specified");
-
-my $tmpfile03 = File::Spec->catfile($tmpdir, "test03.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile03,
-				       BACKGROUND => 'WHITE');
-$pl->xyplot($x, $y, PLOTTYPE => 'POINTS', COLOR => 'BLUEVIOLET', SYMBOL => 1, SYMBOLSIZE => 4);
-$pl->close;
-ok (-s $tmpfile03 > 0, "Symbol plot");
-
-my $tmpfile04 = File::Spec->catfile($tmpdir, "test04.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile04, FRAMECOLOR => 'BLUE');
-$pl->xyplot($x, $y, PLOTTYPE => 'LINEPOINTS', COLOR => [50,230,30]);
-$pl->close;
-ok (-s $tmpfile04 > 0, "Lines and symbols");
-
-$y = sequence(30)+1;
-my $m = (50* (exp(1/$y**2) - 1) * random (30,20))->xchg(0,1);
-my ($mean, $rms) = statsover($m);
-my $x1 = $mean + $rms;
-my $x2 = $mean - $rms;
-my $n  = 500 - exp($y/5);
-
-#$pl = PDL::Graphics::PLplot->new (DEV => "xwin", FILE => "trillian.cosmic.ucar.edu:0");
-
-# Setting text to 1 like this does not work.  text is hard coded in ps.c ;(
-#$pl = PDL::Graphics::PLplot->new (DEV => "psc", FILE => "test05.ps", OPTS => {'text' => '1'});
-
-my $tmpfile05 = File::Spec->catfile($tmpdir, "test05.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile05);
-$pl->xyplot($x1,   $y, COLOR => 'GREEN',
-	               BOX   => [($mean - $rms)->minmax, $y->minmax],
-	               XBOX  => 'bnst', # bottom line, bottom numbers, ticks, subticks
-	               YBOX  => 'bnst', # left line, left numbers, ticks, subticks
-	               TITLE => 'Test statistics plot',
-	               XLAB => 'X label',
-	               YLAB => 'Y label');
-
-$pl->xyplot($x2,   $y, COLOR => 'GREEN');
-$pl->xyplot($mean, $y, COLOR => 'RED');
-$pl->xyplot($n,    $y, COLOR => 'BLUE',
-	               XBOX => 'cmst', # top line, top numbers, ticks, subticks
-	               YBOX => 'cst',  # right line, ticks, subticks
-	               BOX => [0, int(1.1*$n->max), $y->minmax]);
-$pl->text("Count", COLOR => 'PINK',
-	           TEXTPOSITION => ['t', 3, 0.5, 0.5]); # top, 3 units out, string ref. pt in
-                                                        # center of string, middle of axis
-
-$pl->close;
-ok (-s $tmpfile05 > 0, "Sample layer statistics plot");
-
-# test of setting page size.
-my $tmpfile06 = File::Spec->catfile($tmpdir, "test06.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev,
-				       FILE => $tmpfile06,
-				       PAGESIZE => [50,80]);
-$x  = sequence(10);
-$y  = $x**2;
-$pl->xyplot($x, $y, PLOTTYPE => 'LINE');
-$pl->close;
-ok (-s $tmpfile06 > 0, "Setting pagesize");
-
-# test of lines with gaps (plgapline)
-my $tmpfile07 = File::Spec->catfile($tmpdir, "test07.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev,
-				  FILE => $tmpfile07);
-$x  = sequence(10);
-$y  = $x**2;
-$x->inplace->setbadat(5); # insert gap
-$y->inplace->setbadat(5); # insert gap
-$pl->xyplot($x, $y, PLOTTYPE => 'LINE');
-$pl->close;
-ok (-s $tmpfile07 > 0, "Line plot with gaps (plgapline)");
-
-# test of setting JUSTify = 1
-my $tmpfile08 = File::Spec->catfile($tmpdir, "test08.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile08);
-$x  = sequence(10);
-$y  = $x**2;
-$pl->xyplot($x, $y, PLOTTYPE => 'LINEPOINTS', JUST => 1);
-$pl->close;
-ok (-s $tmpfile08 > 0, "Setting JUSTify = 1");
-
-my $tmpfile09 = File::Spec->catfile($tmpdir, "test09.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV  => $dev, FILE => $tmpfile09);
-
-$pl->text("Test string outside of window", TEXTPOSITION => ['T', 1, 0, 0]);
-$pl->text("Test string inside window",     TEXTPOSITION => [0, 0, 0.5, 0.5, 0]);
-$pl->close;
-ok (-s $tmpfile09 > 0, "Printing text inside and outside of plot window");
-
-my $pi = atan2(1,1)*4;
-my $a  = (sequence(20)/20) * 2 * $pi;
-my $b  = sin($a);
-my $c  = cos($a);
-
-# test rainbow point plotting with color key
-my $tmpfile10 = File::Spec->catfile($tmpdir, "test10.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile10);
-$pl->xyplot ($a, $b, SYMBOL => 850, SYMBOLSIZE => 1.5, PALETTE => 'RAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $c);
-$pl->colorkey ($c, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-$pl->colorkey ($c, 'h', VIEWPORT => [0.15, 0.85, 0.92, 0.95]);
-$pl->close;
-ok (-s $tmpfile10 > 0, "Colored symbol plot with key");
-
-# test reverse rainbow point plotting with color key
-my $tmpfile10a = File::Spec->catfile($tmpdir, "test10a.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile10a);
-$pl->xyplot ($a, $b, SYMBOL => 850, SYMBOLSIZE => 1.5, PALETTE => 'REVERSERAINBOW', PLOTTYPE => 'POINTS', COLORMAP => $c);
-$pl->colorkey ($c, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-$pl->colorkey ($c, 'h', VIEWPORT => [0.15, 0.85, 0.92, 0.95]);
-$pl->close;
-ok (-s $tmpfile10a > 0, "Colored symbol plot with key: reverse rainbow");
-
-# Test plot and color key (low level interface)
-plsdev ($dev);
-my $tmpfile11 = File::Spec->catfile($tmpdir, "test11.$dev");
-plsfnam ($tmpfile11);
-plspage (0,0, 600,600, 0,0);
-plinit();
-pladv (0);
-plvsta();
-plwind (0, 1, 0, 1);
-plvpor(0.1,0.85,0.1,0.9);
-
-plwind (0, 10, 0, 100);
-plcol0(1);
-plbox (0, 0, 0, 0, 'BCNST', 'BCNST');
-plpoin($x, $y, 2);
-
-# view port dimensions in normalized device coordinates
-my ($dev_xmin, $dev_xmax, $dev_ymin, $dev_ymax) = plgvpd();
-
-# view port dimensions in world coordinates
-my ($wld_xmin, $wld_xmax, $wld_ymin, $wld_ymax) = plgvpw();
-plvpor(0.86,0.90,0.1,0.9);
-plwind (0, 10, 0, 100);
-plbox (0, 0, 0, 0, '', 'TM');
-plscmap1l (0, PDL->new(0,1), PDL->new(0,360), PDL->new(0.5, 0.5), PDL->new(1,1), pdl []);
-for (my $i=0;$i<10;$i++) {
-  plcol1($i/10);
-  plfill (PDL->new(0,10,10,0), PDL->new($i*10,$i*10,($i+1)*10,($i+1)*10));
-}
-plend1();
-
-ok (-s $tmpfile11 > 0, "Colored symbol plot with key, via low level interface");
-
-ok (sum(pdl(0.1, 0.85, 0.1, 0.9) - pdl($dev_xmin->sclr, $dev_xmax->sclr, $dev_ymin->sclr, $dev_ymax->sclr)) == 0,
-    "plgvpd call works correctly");
-ok (abs(sum(pdl(-0.0001, 10.0001, -0.001, 100.001) - pdl($wld_xmin->sclr, $wld_xmax->sclr, $wld_ymin->sclr, $wld_ymax->sclr))) < 0.000001,
-    "plgvpw call works correctly");
-
-# Test shade plotting (low level interface)
-my $tmpfile12 = File::Spec->catfile($tmpdir, "test12.$dev");
-plsdev ($dev);
-plsfnam ($tmpfile12);
-plspage (0,0, 600,600, 0,0);
-plinit();
-pladv (0);
-plvpor(0.1, 0.9, 0.1, 0.9);
-plwind (-1, 1, -1, 1);
-plpsty(0);
-
-my $nx = 35;
-my $ny = 46;
-$x = (sequence($nx) - ($nx/2))/($nx/2);
-$y = (sequence($ny) - ($ny/2))/(($ny/2) - 1.0);
-my $xv = $x->dummy(1, $y->nelem);
-my $yv = $y->dummy(0, $x->nelem);
-my $z = -sin(7*$xv) * cos (7*$yv) + $xv**2 - $yv**2;
-my $nsteps = 15;
-my ($zmin, $zmax) = $z->minmax;
-my $clevel = ((sequence($nsteps)*(($zmax - $zmin)/($nsteps-1))) + $zmin);
-my $fill_width = 2;
-my $cont_color = 0;
-my $cont_width = 0;
-my $xmap = ((sequence($nx)*(2/($nx-1))) + -1); # map X coords linearly to -1 to 1
-my $ymap = ((sequence($ny)*(2/($ny-1))) + -1);
-my $grid = plAllocGrid ($xmap, $ymap);
-plshades($z, -1, 1, -1, 1,
-         $clevel, $fill_width,
-         $cont_color, $cont_width, 1,
-	 0, \&pltr1, $grid);
-plend1();
-
-ok (-s $tmpfile12 > 0, "3D color plot, low level interface");
-
-# test shade plots with higher level interface.
-my $tmpfile13 = File::Spec->catfile($tmpdir, "test13.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile13);
-$pl->shadeplot ($z, $nsteps, BOX => [-1, 1, -1, 1], PALETTE => 'RAINBOW');
-$pl->colorkey ($z, 'v', VIEWPORT => [0.93, 0.96, 0.15, 0.85]);
-$pl->close;
-ok (-s $tmpfile13 > 0, "3D color plot, high level interface");
-
-# Test histogram plotting (low level interface)
-my $tmpfile14 = File::Spec->catfile($tmpdir, "test14.$dev");
-plsdev ($dev);
-plsfnam ($tmpfile14);
-plspage (0,0, 600,600, 0,0);
-plinit();
-pladv (0);
-plvpor(0.1, 0.9, 0.1, 0.9);
-$x = random(100)*100;
-($min, $max) = $x->minmax;
-$nbins = 15;
-$oldwin = 1; # dont call plenv
-
-plwind ($min, $max, 0, 100);
-plbox (0, 0, 0, 0, 'bcnst', 'bcnst');
-
-plhist ($x, $min, $max, $nbins, $oldwin);
-plend1();
-
-ok (-s $tmpfile14 > 0, "Histogram plotting, low level interface");
-
-# test histograms with higher level interface.
-my $tmpfile15 = File::Spec->catfile($tmpdir, "test15.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile15);
-$pl->histogram ($x, $nbins, BOX => [$min, $max, 0, 100]);
-$pl->close;
-ok (-s $tmpfile15 > 0, "Histogram plotting, high level interface");
-
-# Test multiple plots per page (low level interface)
-my $tmpfile16 = File::Spec->catfile($tmpdir, "test16.$dev");
-plsdev ($dev);
-plsfnam ($tmpfile16);
-plspage (0,0, 300,600, 0,0);
-plssub (1,2);
-plinit();
-pladv (1);
-plvpor(0.1, 0.9, 0.1, 0.9);
-$x = random(100)*100;
-($min, $max) = $x->minmax;
-$nbins = 15;
-$oldwin = 1; # dont call plenv
-plwind ($min, $max, 0, 100);
-plbox (0, 0, 0, 0, 'bcnst', 'bcnst');
-plhist ($x, $min, $max, $nbins, $oldwin);
-
-pladv (2);
-plvpor(0.1, 0.9, 0.1, 0.9);
-$x = random(200)*100;
-($min, $max) = $x->minmax;
-$nbins = 15;
-$oldwin = 1; # dont call plenv
-
-plwind ($min, $max, 0, 100);
-plbox (0, 0, 0, 0, 'bcnst', 'bcnst');
-
-plhist ($x, $min, $max, $nbins, $oldwin);
-
-plend1();
-
-ok (-s $tmpfile16 > 0, "Multiple plots per page, low level interface");
-
-# test multiple pages per plot (high level interface)
-my $tmpfile17 = File::Spec->catfile($tmpdir, "test17.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile17, SUBPAGES => [1,2]);
-$pl->histogram ($x, $nbins, BOX => [$min, $max, 0, 100]);
-$pl->histogram ($x, $nbins, BOX => [$min, $max, 0, 100], SUBPAGE => 2);
-$pl->close;
-ok (-s $tmpfile17 > 0, "Multiple plots per page, high level interface");
-
-my $tmpfile18 = File::Spec->catfile($tmpdir, "test18.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile18);
-$x  = sequence(10);
-$y  = $x**2;
-$pl->xyplot($x, $y, PLOTTYPE => 'LINE', LINESTYLE => 2);
-$pl->close;
-ok (-s $tmpfile18 > 0, "Setting LINESTYLE");
-
-# test setting plot orientation
-my $tmpfile19 = File::Spec->catfile($tmpdir, "test19.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile19, ORIENTATION => 1);
-$x  = sequence(10);
-$y  = $x**2;
-$pl->xyplot($x, $y, PLOTTYPE => 'LINE', LINESTYLE => 2);
-$pl->close;
-ok (-s $tmpfile19 > 0, "Setting plot orientation");
-
-# test symbol plotting
-my $tmpfile20 = File::Spec->catfile($tmpdir, "test20.$dev");
-$pl = PDL::Graphics::PLplot->new (DEV => $dev, FILE => $tmpfile20);
-$pl->setparm (BOX => [0,200,0,200]);
-for (my $x=0;$x<20;$x++) {
-  for (my $y=0;$y<20;$y++) {
-    my $xp = pdl(10*$x);
-    my $yp = pdl(10*$y);
-    $pl->xyplot($xp, $yp, PLOTTYPE => 'POINTS', SYMBOL => 20*$x+$y);
-  }
-}
-$pl->close;
-ok (-s $tmpfile20 > 0, "Symbol plotting");
-
-# test label plotting in multiple subpage plots
-my $tmpfile21 = File::Spec->catfile($tmpdir, "test21.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev,
-				      FILE => $tmpfile21,
-				      PAGESIZE => [500,900],
-				      SUBPAGES => [1,6]);
-my @colors = qw(GREEN BLUE RED BROWN BLACK YELLOW);
-
-for my $i (0..5) {
-
-  my $x  = sequence(100)*0.1;
-  my $y  = sin($x);
-
-  $pl->xyplot($x, $y,
-	      COLOR => $colors[$i],
-	      SUBPAGE => $i+1,
-	      TITLE => "Title $i",
-	      XLAB => "1 to 10",
-	      YLAB => "sin(x)");
-
-}
-
-$pl->close;
-ok (-s $tmpfile21 > 0, "Multiple subpages");
-
-# test bar graphs
-my $tmpfile22 = File::Spec->catfile($tmpdir, "test22.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile22);
-$pl->bargraph([map { sprintf ("2002.%03d", $_) } (1..100)], 100*random(100), COLOR => 'BLUE');
-$pl->close;
-ok (-s $tmpfile22 > 0, "Bar graph");
-
-my $tmpfile23 = File::Spec->catfile($tmpdir, "test23.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile23);
-my @labels = ((map { sprintf ("2001.%03d", $_) } (240..365)), (map { sprintf ("2002.%03d", $_) } (1..100)));
-$pl->bargraph(\@labels, 100*random(scalar(@labels)), COLOR => 'GREEN');
-$pl->close;
-ok (-s $tmpfile23 > 0, "Bar graph part 2");
-
-my $tmpfile23a = File::Spec->catfile($tmpdir, "test23a.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile23a);
-@labels = ((map { sprintf ("2001.%03d", $_) } (240..365)), (map { sprintf ("2002.%03d", $_) } (1..100)));
-$pl->bargraph(\@labels, 100*random(scalar(@labels)), COLOR => 'GREEN', MAXBARLABELS => 30);
-$pl->close;
-ok (-s $tmpfile23a > 0, "Bar graph part 3");
-
-my $tmpfile23b = File::Spec->catfile($tmpdir, "test23b.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile23b);
-@labels = ((map { sprintf ("2001.%03d", $_) } (240..365)), (map { sprintf ("2002.%03d", $_) } (1..100)));
-$pl->bargraph(\@labels, 100*random(scalar(@labels)), COLOR => 'GREEN', TEXTPOSITION => ['tv', 0.5, 0.0, 0.0]);
-$pl->close;
-ok (-s $tmpfile23b > 0, "Bar graph part 4");
-
-my $tmpfile23c = File::Spec->catfile($tmpdir, "test23c.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile23c);
-@labels = ((map { sprintf ("2001.%03d", $_) } (240..365)), (map { sprintf ("2002.%03d", $_) } (1..100)));
-$pl->bargraph(\@labels, 100*random(scalar(@labels)), UNFILLED_BARS => 1, COLOR => 'GREEN', TEXTPOSITION => ['tv', 0.5, 0.0, 0.0]);
-$pl->close;
-ok (-s $tmpfile23c > 0, "Bar graph part 5, unfilled boxes");
-
-my $tmpfile24 = File::Spec->catfile($tmpdir, "test24.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile24);
-$x  = sequence(10);
-$y  = $x**2;
-$pl->xyplot($x, $y, PLOTTYPE => 'LINE', XERRORBAR => ones(10)*0.5, XTICK => 2,  NXSUB => 5,
-                                        YERRORBAR => $y*0.1,       YTICK => 20, NYSUB => 10,
-                                        MINTICKSIZE => 2, MAJTICKSIZE => 3);
-$pl->close;
-ok (-s $tmpfile24 > 0, "Setting error bars and tick size");
-
-my $tmpfile25 = File::Spec->catfile($tmpdir, "test25.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile25);
-$x1  = sequence(20);
-my $y1  = $x1**2;
-
-$x2  = sequence(22);
-my $y2  = sqrt($x2);
-
-my $x3  = sequence(30);
-my $y3  = $x3**3;
-
-my $xs  = [$x1, $x2, $x3];
-my $ys  = [$y1, $y2, $y3];
-
-$pl->stripplots($xs, $ys, PLOTTYPE => 'LINE', TITLE => 'functions', YLAB => ['x**2', 'sqrt(x)', 'x**3']);
-$pl->close;
-ok (-s $tmpfile25 > 0, "Basic stripplots");
-
-my $tmpfile26 = File::Spec->catfile($tmpdir, "test26.$dev");
-$pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $tmpfile26);
-$x1  = sequence(20);
-$y1  = $x1**2;
-
-$x2  = sequence(18);
-$y2  = sqrt($x2);
-
-$x3  = sequence(24);
-$y3  = $x3**3;
-
-my $x4  = sequence(27);
-$a  = ($x4/20) * 2 * $pi;
-my $y4  = sin($a);
-
-$xs  = [$x1, $x2, $x3, $x4];
-$ys  = [$y1, $y2, $y3, $y4];
-$pl->stripplots($xs, $ys, PLOTTYPE => 'LINE', TITLE => 'functions',
-                YLAB => ['x**2', 'sqrt(x)', 'x**3', 'sin(x/20*2pi)'],
-                         COLOR => ['GREEN', 'DEEPSKYBLUE', 'DARKORCHID1', 'DEEPPINK'], XLAB => 'X label');
-$pl->close;
-ok (-s $tmpfile26 > 0, "Multi-color stripplots");
-
-# test opening/closing of more than 100 streams (100 is the max number of plplot streams, close should
-# reuse plplot stream numbers).
-my $count = 0;
-for my $i (1 .. 120) {
-  my $pltfile = File::Spec->catfile($tmpdir, "test27.$dev");
-  my $win = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $pltfile, PAGESIZE => [300, 300]);
-  $win->xyplot(pdl(0,1), pdl(0,1));
-  # print "Stream = ", plgstrm(), " Stream in object = ", $win->{STREAMNUMBER}, "\n";
-  $win->close();
-  if (-s $pltfile > 0) { $count++; unlink $pltfile }
-}
-ok ($count == 120, "Opening/closing of > 100 streams");
-
-
-SKIP: {
-  skip 'Not compiled with POSIX threads', 1 if (($PDL::Config{WITH_POSIX_THREADS} == 0) || ($^O =~/darwin/i));
-
-  my $pltfile = File::Spec->catfile($tmpdir, "test28.$dev");
-  my $pid;
-  if($^O =~ /MSWin32/i) {
-     system "$^X", '-Mblib -e "do \"t/plplot_no_fork.win32\""';
-  }
-  else {
-    if($pid = fork()) {
-      $a = waitpid($pid,0);
-    } else {
-
-      # Breakage seems to be a function of the grid size. For me, 34 did the trick.
-      # You may need to fiddle with it to reproduce trouble, so it's read from the
-      # command-line.
-      my $grid_size = 34;
-
-      # PThreads settings, uncomment to break:
-      set_autopthread_targ($grid_size); # large number to increase likelihood of trouble
-      set_autopthread_size(0);  # zero ensures we get threading
-
-      # Add DEV unless you want it to prompt you:
-      my $pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $pltfile);
-
-      # Some simple sequential data
-      my $xs = sequence($grid_size);
-      my $ys = sequence($grid_size)->transpose;
-
-      # Plot data so that increasing y-values have different colors:
-      $pl->xyplot($xs, $ys, PLOTTYPE => 'POINTS', COLORMAP => $ys);
-
-      $pl->close;
-      exit(0);
-    }
-  }
-
-  # If pthreads are working wrongly, the .svg file is messed up and much larger than usual
-  ok( (-s $pltfile <= 600_000) && (($? & 0xff ) == 0), "Fails to crash with POSIX threads");
-
-}
-
-# Local Variables:
-# mode: cperl
-# End:
@@ -1,31 +0,0 @@
-# This file run by plplot.t (MS Windows only).
-# We can't use fork() with plplot on Win32
-# as the Win32 fork() uses threading, and plplot is not thread-safe.
-# By instead running this separate script for the final test, we avoid the issue.
-use warnings;
-use blib;
-use PDL;
-use PDL::Graphics::PLplot;
-
-my $dev = 'svg';
-
-my $pltfile = "test28.$dev";
-
-my $grid_size = 34;
-
-# PThreads settings, uncomment to break:
-set_autopthread_targ($grid_size); # large number to increase likelihood of trouble
-set_autopthread_size(0);  # zero ensures we get threading
-
-# Add DEV unless you want it to prompt you:
-my $pl = PDL::Graphics::PLplot->new(DEV => $dev, FILE => $pltfile);
-
-# Some simple sequential data
-my $xs = sequence($grid_size);
-my $ys = sequence($grid_size)->transpose;
-
-# Plot data so that increasing y-values have different colors:
-$pl->xyplot($xs, $ys, PLOTTYPE => 'POINTS', COLORMAP => $ys);
-
-$pl->close;
-exit(0);
@@ -134,6 +134,5 @@ Other Options
    This enables building of such extras as:
     a) PDL::IO::GD (needs the gd C library);
     b) PDL::GSL::* modules (needs the gsl C library);
-    c) PDL::Graphics::PLplot (needs the plplot C library);
-    d) PDL::GIS::Proj & PDL::Transform::Proj4 (needs the proj4 C library);
+    c) PDL::GIS::Proj & PDL::Transform::Proj4 (needs the proj4 C library);