changeset 2628:b7302d17cb23

* renamed mincpik
author Andrew L Janke <a.janke@gmail.com>
date Mon, 12 Mar 2012 14:08:03 +1000
parents 4c97972059c4
children 9d489fbf4e7b
files progs/mincpik/mincpik progs/mincpik/mincpik.in
diffstat 2 files changed, 661 insertions(+), 661 deletions(-) [+]
line wrap: on
line diff
deleted file mode 100755
--- a/progs/mincpik/mincpik
+++ /dev/null
@@ -1,661 +0,0 @@
-#! /usr/bin/env perl
-#
-# Copyright 2009
-# Andrew Janke - a.janke@gmail.com
-# The University of Queensland
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose and without fee is hereby granted,
-# provided that the above copyright notice appear in all copies.  The
-# author and the University make no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
-
-
-use strict;
-use warnings "all";
-use Getopt::Long;
-use Pod::Usage;
-use File::Basename;
-use File::Temp qw/ tempdir /;
-
-my($Help, $Usage, $me, @opt_table, $tmpdir, %opt);
-my(@args, $args, $infile, $outfile, %ordering, $CODE);
-
-# permutation 'matrix' for differing views
-%ordering = (
-   'zspace' => ['yspace', 'xspace'],
-   'yspace' => ['zspace', 'xspace'],
-   'xspace' => ['zspace', 'yspace'],
-   );
-
-$me = &basename($0);
-%opt = (
-   'help' => 0,
-   'man' => 0,
-   'verbose' => 0,
-   'clobber' => 0,
-   'fake' => 0,
-   
-   'scale' => 2,
-   'width' => undef,
-   'bitdepth' => 8,
-   'range' => undef,
-   'image_range' => undef,
-   'auto_range' => 0,
-   'lookup' => undef,
-   
-   'slice' => undef,
-   'dirs' => ['zspace'],
-   
-   'triplanar' => 0,
-   'tilesize' => 250,
-   'title' => 0,
-   'title_text' => undef,
-   'title_size' => 16,
-   'sagittal_offset' => undef,
-   'sagittal_offset_perc' => undef,
-   'orientation' => 'vertical',
-   'anot_bar' => undef,
-   );
-
-# Check arguments
-&GetOptions(
-   'help|?' => \$opt{'help'},
-   'man' => \$opt{'man'},
-   'version' => sub { &print_version_info },
-   'v|verbose' => \$opt{'verbose'},
-   'c|clobber' => \$opt{'clobber'},
-   'f|fake' => \$opt{'fake'},
-   
-   'scale=i' => \$opt{'scale'},
-   'width=i' => \$opt{'width'},
-   'depth=i' => \$opt{'bitdepth'},
-   
-   'title' => \$opt{'title'},
-   'title_text=s' => \$opt{'title_text'},
-   'title_size=i' => \$opt{'title_size'},
-   'anot_bar=s' => \$opt{'anot_bar'},
-   
-   # Image range and lookup table options
-   'range=f{2}' => \@{$opt{'range'}},
-   'image_range=f{2}' => \@{$opt{'image_range'}},
-   'auto_range' => \$opt{'auto_range'},
-   'lookup=s' => \$opt{'lookup'},
-   
-   # Slicing options
-   's|slice=i' => \$opt{'slice'},
-   'z|axial|transverse' => sub { $opt{'dirs'} = ['zspace']; },
-   'y|coronal' => sub { $opt{'dirs'} = ['yspace']; },
-   'x|sagittal' => sub { $opt{'dirs'} = ['xspace']; },
-   
-   # triplanar options
-   't|triplanar' => \$opt{'triplanar'},
-   'tilesize=i' => \$opt{'tilesize'},
-   'sagittal_offset=i' => \$opt{'sagittal_offset'},
-   'sagittal_offset_perc=i' => \$opt{'sagittal_offset_perc'},
-   'vertical' => \$opt{'orientation'},
-   'horizontal' => \$opt{'orientation'},
-   ) or pod2usage(-verbose => 1) && exit;
-
-# handle -man, -help or missing args
-pod2usage(-verbose => 1) if $opt{'help'};
-pod2usage(-exitstatus => 0, -verbose => 2) if $opt{'man'};
-pod2usage(-verbose => 0) && exit if ($#ARGV != 1);
-
-# Check arguments
-#&Getopt::Tabular::SetHelp ($Help, $Usage);
-#&GetOptions (\@opt_table, \@ARGV) || exit 1;
-#die $Usage if ($#ARGV < 0);
-
-# create temporary directory
-$tmpdir = &tempdir( "$me-XXXXXXXX", TMPDIR => 1, CLEANUP => 1 );
-
-# set up file names and do a few checks
-$infile = $ARGV[0];
-$outfile = (defined($ARGV[1])) ? $ARGV[1] : 'PNG:-';
-
-die "$me: Couldn't find $infile\n\n" if (!-e $infile);
-if($outfile ne 'PNG:-' && -e $outfile && !$opt{'clobber'}){
-   die "\n$me: $outfile exists, use -clobber to overwrite\n\n";
-   }
-
-if($opt{'bitdepth'} != 16 && $opt{bitdepth} != 8) {
-   die "\n$me: Invalid bitdepth specified - $opt{bitdepth} instead of 8 or 16\n\n";
-   }
-
-# sanity check
-if($opt{'auto_range'} && @{$opt{'image_range'}}){
-   die "\n$me: only specify one of -auto_range and -image_range (not both)\n\n";
-   }
-
-# warn about -slice and -triplanar
-if(defined($opt{'slice'}) && $opt{'triplanar'}){
-   warn "\n$me: you probably don't want to use both -triplanar and -slice\n\n";
-   } 
-
-# warn about -sagittal_offset and -sagittal_offset_perc
-if(defined($opt{'sagittal_offset'}) && $opt{'sagittal_offset_perc'}){
-   warn "\n$me: only use one of -sagittal_offset -sagittal_offset_perc\n\n";
-   } 
-
-# set up directions for triplanar
-if($opt{'triplanar'}){
-   $opt{'dirs'} = ['zspace', 'xspace', 'yspace'];
-   }
-
-my ($space, $n_slices, $convert_infile, $imgfile,
-    @extract_args, @convert_args,
-    $img_x, $img_y,
-    $img_step_x, $img_step_y, 
-    $img_length_x, $img_length_y,
-    $dim_names, $pipe_args, $dimorder,
-    @mont_files);
-
-# find the 5% to 95% PcT image range if -auto_range
-if($opt{'auto_range'}){
-   my $buf;
-   
-   print STDERR "Getting range of $infile\n" if $opt{'verbose'};
-   
-   chomp($buf = `mincstats -quiet -pctT 5 $infile`);
-   $buf *= 1.0;
-   @{$opt{'image_range'}}[0] = $buf;
-
-   chomp($buf = `mincstats -quiet -pctT 95 $infile`);
-   $buf *= 1.0;
-   @{$opt{'image_range'}}[1] = $buf;
-
-   # a bit of output
-   if($opt{'verbose'}){
-      print STDERR "Using image range of [@{$opt{image_range}}[0]:@{$opt{image_range}}[1]]\n";
-      }
-   }
-
-# foreach slicing direction
-foreach $space (@{$opt{'dirs'}}){
-
-   print STDERR "Doing direction $space\n" if $opt{'verbose'};
-   
-   my($slice);
-   $CODE = "GRAY";
-   
-   # set up the imgfile depending on triplanar and -title
-   if($opt{'triplanar'}){
-      $imgfile = "$tmpdir/trip-$space.png";
-      push(@mont_files, $imgfile);
-      }
-   elsif($opt{'title'}){
-      $imgfile = "$tmpdir/image.png";
-      }
-   else{
-      $imgfile = $outfile;
-      }
-   
-   # Get the info we need
-   $args = "mincinfo ".
-           "-dimlength $space ".
-           "-dimlength $ordering{$space}[0] ".
-           "-dimlength $ordering{$space}[1] ".
-           "-attvalue $ordering{$space}[0]:step ". 
-           "-attvalue $ordering{$space}[1]:step ".
-           "-dimnames ".
-           $infile;
-   ($n_slices, $img_x, $img_y, $img_step_x, $img_step_y, $dim_names) = split("\n", `$args`);
-
-   if(defined($opt{'width'})){ 
-      $opt{'scale'} = $opt{'width'}/abs($img_step_y * $img_y);
-      print STDERR "Auto-scaling width factor: $opt{'scale'}\n" if $opt{'verbose'}; 
-      }
-   $img_length_x = abs(int($img_step_x * $img_x * $opt{'scale'}));
-   $img_length_y = abs(int($img_step_y * $img_y * $opt{'scale'}));
-   
-   # figure out the slice to get
-   $slice = (!defined($opt{'slice'})) ? int($n_slices/2) : $opt{'slice'};
-   
-   # do the sagittal offset (only one of these should be done)
-   if($space eq 'xspace'){
-
-      # slice offset      
-      if(defined($opt{'sagittal_offset'})){
-         $slice += $opt{'sagittal_offset'};
-         }
-
-      # perc offset
-      if(defined($opt{'sagittal_offset_perc'})){
-         $slice += int($n_slices * $opt{'sagittal_offset_perc'} / 100);
-         }
-      }
-   
-   # check we didn't step of the edge
-   if($slice >= $n_slices || $slice < 0){ 
-      die "Slice $slice out of range (0-" . ($n_slices-1) . ")\n\n";
-      }
-   
-   # check if we have a vector_dimension already
-   if($dim_names =~ m/vector_dimension/){
-      $CODE = 'RGB';
-      }
-  
-   # take only the first timepoint if we have a time dimension
-   my @time_res_args = ();
-   if($dim_names =~ m/time/){
-      @time_res_args = ('-dimrange', "time=0,0");
-      }
-    
-   # do the reshaping
-   $dimorder = join(',', $space, @{$ordering{$space}});
-   if($CODE eq 'RGB'){
-      $dimorder .= ',vector_dimension';
-      }
-   @args = ('mincreshape', '-clobber', '-quiet',
-            '-normalize',
-            '+direction',
-            '-dimsize', "$space=-1",
-            '-dimsize', "$ordering{$space}[0]=-1",
-            '-dimsize', "$ordering{$space}[1]=-1",
-            '-dimorder', $dimorder,
-            '-dimrange', "$space=$slice,1",
-            @time_res_args,
-            $infile, "$tmpdir/reshaped.mnc");                  
-   if(scalar(@{$opt{'range'}}) != 0){
-      push(@args, '-valid_range', @{$opt{'range'}}[0], @{$opt{'range'}}[1]);
-      }
-   if(scalar(@{$opt{'image_range'}}) != 0){
-      push(@args, '-image_range', @{$opt{'image_range'}}[0], @{$opt{'image_range'}}[1]);
-      }
-   &do_cmd(@args);
-   
-   # do the lookup if required
-   $convert_infile = "$tmpdir/reshaped.mnc";
-   if($opt{'lookup'}){
-      if($CODE eq 'RGB'){
-         warn "$me: Input is vector-valued already.  No colour lookup done.\n";
-         }
-      else{
-         $convert_infile = "$tmpdir/lookup.mnc";
-         $CODE = 'RGB';
-         &do_cmd('minclookup', '-clobber', '-quiet', 
-                 split(' ', $opt{'lookup'}), 
-                 "$tmpdir/reshaped.mnc", $convert_infile);
-         }
-      }
-
-   # set up mincextract command
-   @extract_args = ('mincextract', $convert_infile,
-                    '-normalize',
-                    ($opt{'bitdepth'} == 16) ? ('-short', '-unsigned') : '-byte');
-   
-   # set up convert arguments
-   # a flip is 'normal' due to the difference between mnc and most image co-ordinates
-   @convert_args = ('convert',
-                    '-depth', $opt{'bitdepth'},
-                    '-flip', 
-                    '-size', $img_y . 'x' . $img_x,
-                    '-geometry', $img_length_y . 'x' . $img_length_x . '!',
-                    "$CODE:-", $imgfile);
-   
-   # check if we are big or little endian for convert's MSB wierdity
-   $pipe_args = '|';
-   if($opt{'bitdepth'} == 16){
-      if(unpack("c",substr(pack("s",1),0,1))){
-         warn "$me: LSB machine, swapping bytes with dd and crossing fingers\n";
-         $pipe_args .= ' dd conv=swab | ';
-         }
-      }
-   
-   &do_cmd(join(' ', @extract_args, $pipe_args, @convert_args));
-   }
-
-# do the triplanar if requested
-if($opt{'triplanar'}){
-   my @orient_args;
-
-   if($opt{'title'}){
-      $imgfile = "$tmpdir/mont.png";
-      }
-   else{
-      $imgfile = $outfile;
-      }
-   
-   if($opt{'orientation'} eq 'vertical'){
-      @orient_args = ('-tile', ('1x' . ($#mont_files + 1)));
-      }
-   else{ # $opt{orientation} eq 'horizontal'
-      @orient_args = ('-tile', (($#mont_files + 1) . 'x1'));
-      }
-   
-   # do the montage
-   &do_cmd('montage',
-           @orient_args, 
-           '-background', 'grey10',
-           '-geometry', "$opt{tilesize}x$opt{tilesize}+1+1",
-           @mont_files, $imgfile);
-   }
-               
-# Add the title
-if($opt{'title'}){
-   
-   # set up the title text
-   if(!defined($opt{'title_text'})){
-      $opt{'title_text'} = &basename($infile);
-      $opt{'title_text'} =~ s/\.mnc$//;
-      }
-     
-#   This really does not work all that well (but should), go figure
-#   &do_cmd('convert', '-box', 'black', 
-#           '-font', '7x13', 
-#           '-fill', 'white',
-#           '-draw', "text 4,12 \"$opt{'title_text'}\"",
-#           $imgfile, $outfile);
-#
-   # use montage instead
-   &do_cmd('montage', 
-           '-geometry', '100x100%',  
-           '-background', 'black',
-           '-fill', 'white',
-           '-label', $opt{'title_text'},
-           '-pointsize', $opt{'title_size'},
-           $imgfile, $outfile);
-   }
-
-# create the annotated bar if required
-if(defined($opt{'anot_bar'})){
-   
-   my($min, $max, $pcode, 
-      $q0, $q1, $q2, $q3, $q4, $bh, $bw, $bb, $ob, 
-      $textbump, $i, @buf);
-   
-   # set up a few constants
-   $textbump = 3;
-   $pcode = '%6g';
-   
-   # text border, other border, height, width
-   $bb = 50;
-   $ob = 25;
-   $bh = $img_length_y - ($ob*2);
-   $bw = int($bh/10);
-   
-   # get range if not defined
-   if(!defined($opt{'image_range'}[0])){
-      print STDERR "Getting image range\n" if $opt{'verbose'};
-      
-      @buf = split(/\n/, `mincstats -min -max -quiet $infile`);
-      @{$opt{'image_range'}}[0] = $buf[0] * 1.0;
-      @{$opt{'image_range'}}[1] = $buf[1] * 1.0;
-      }
-   
-   $min = @{$opt{'image_range'}}[0];
-   $max = @{$opt{'image_range'}}[1];
-   
-   # set up the datafile
-   my(@data) = undef;
-   my($packstring) = '';
-   for($i=0; $i<$bh; $i++){
-      $data[$i] = $i;
-      $packstring .= 'f';
-      }
-   
-   open(FH, ">$tmpdir/tmp-float.raw");
-   for($i=0; $i<$bw; $i++){
-      syswrite(FH, pack($packstring, @data));
-      }
-   close(FH);
-   
-   # make minc file
-   &do_cmd('rawtominc', '-clobber',
-           '-float',
-           '-input', "$tmpdir/tmp-float.raw",
-           '-xstep',  1, '-ystep',  1, '-zstep',  1,
-           '-xstart', 0, '-ystart', 0, '-zstart', 0,
-           '-dimorder', 'xspace,yspace,zspace',
-           "$tmpdir/bar.mnc", $bw, $bh, 1);
-   
-
-   # make .miff bar image (whoa... recursion!)
-   &do_cmd('mincpik', '-clobber',
-           '-scale', 1,
-           (defined($opt{'lookup'})) ? ('-lookup', $opt{'lookup'}) : (),
-           "$tmpdir/bar.mnc", "$tmpdir/bar.png");
-   
-   # set up the text
-   $q0 = sprintf($pcode, $min);
-   $q1 = sprintf($pcode, (($max-$min) * 0.25) + $min);
-   $q2 = sprintf($pcode, (($max-$min) * 0.5)  + $min);
-   $q3 = sprintf($pcode, (($max-$min) * 0.75) + $min);
-   $q4 = sprintf($pcode, $max);
-   
-   
-   # create the bar itself via convert
-   &do_cmd('convert',
-           '-bordercolor', 'white',
-           '-border', $bb,
-
-           # color for all the decorations
-           '-fill', 'black',
-
-           # bar border
-           '-draw', "line " . join(',',  $bb,      $bb,      ($bb+$bw),  $bb     ),
-           '-draw', "line " . join(',',  $bb,     ($bb+$bh), ($bb+$bw), ($bb+$bh)),
-           '-draw', "line " . join(',',  $bb,      $bb,       $bb,      ($bb+$bh)),
-           '-draw', "line " . join(',', ($bb+$bw), $bb,      ($bb+$bw), ($bb+$bh)),
-
-           # 3 ticks at 1/4, 1/2 and 3/4
-           '-draw', "line " . join(',', ($bb+($bw*3/4)), ($bb+($bh*1/4)), ($bb+$bw), ($bb+($bh*1/4))),
-           '-draw', "line " . join(',', ($bb+($bw*3/4)), ($bb+($bh*2/4)), ($bb+$bw), ($bb+($bh*2/4))),
-           '-draw', "line " . join(',', ($bb+($bw*3/4)), ($bb+($bh*3/4)), ($bb+$bw), ($bb+($bh*3/4))),
-
-           # text
-           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*0/4)+$textbump) . " '$q4'",
-           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*1/4)+$textbump) . " '$q3'",
-           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*2/4)+$textbump) . " '$q2'",
-           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*3/4)+$textbump) . " '$q1'",
-           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*4/4)+$textbump) . " '$q0'",
-
-           # finally crop of the extra border
-           '-crop', (($bb*2)+$bw-($bb-$ob)) . "x" . (($bb*2)+$bh-$bb) . "+" . ($bb-$ob) . "+" . ($bb-$ob),
-
-           "$tmpdir/bar.png", $opt{'anot_bar'});
-   }
-
-
-sub do_cmd {
-   print STDERR "@_\n" if $opt{'verbose'};
-   if(!$opt{'fake'}){
-      system(@_) == 0 or die "\n$me: Failed executing @_\n\n";
-      }
-   }
-
-# print version information
-sub print_version_info {
-   my $PACKAGE = '@PACKAGE_NAME@';
-   my $VERSION = '@PACKAGE_VERSION@';
-   my $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@';
-   
-   print STDOUT "\n$PACKAGE version $VERSION\n".
-                "Comments to $PACKAGE_BUGREPORT\n\n";
-   exit 0;
-   }
-
-__END__
-
-=head1 NAME
-
-B<mincpik> - generate images from minc files
-
-=head1 SYNOPSIS
-
-B<mincpik> [options] <infile>.mnc [<image.type>]
-
-mincpik generates image files from MINC volumes using the Imagemagick
-convert utility. Use -help or -man for more information and examples
-
-=head1 DESCRIPTION
-
-B<mincpik> generates image files from MINC volumes using the Imagemagick
-B<convert> utility. For a complete list of output file types see the
-B<convert> man pages.
-
-EXAMPLES:
-To display a default view, axial (z) slicing, middle slice
-using display. (display is part of the Imagemagick package)
-
-   mincpik infile.mnc PNG:- | display -
-
-To generate a PNG file of the 15th coronal slice
-
-   mincpik -slice 15 -coronal infile.mnc outfile.png
-
-To generate a JPG file using the hotmetal lookup table 
-with the image range 0 to 100
-
-   mincpik -lookup '-hotmetal' -image_range 0 100 infile.mnc outfile.jpg
-
-ImageMagick:  http://www.wizards.dupont.com/cristy/ImageMagick.html
-   NB: ImageMagick should be compiled without 16-bit quanta.
-
-Currently if there is a time dimension in the file the image will
-only produced from the first time point
-
-Problems or comments should be sent to: a.janke\@gmail.com
- 
-=head1 OPTIONS
-
-=over 4
-
-=item B<-v>, B<--verbose>
-
-Be noisy when doing things
-
-=item B<--version>
-
-Print version number and exit
-
-=item B<-?>, B<--help>
-
-Dump some quick help output
-
-=item B<--man>
-
-Dump a man page
-
-=item B<-c> B<--clobber>
-
-overwrite the output file if it exists already
-
-=item B<-f> B<--fake>
-
-do a dry run, (echo cmds only). This is usually used in combination with -verbose to echo commands only
-
-=item B<--scale>
-
-scaling factor for resulting image, by default images are output 
-at twice their original resolution
-
-=item B<--width>
-
-autoscale the resulting image to have a fixed image width (in pixels)
-
-=item B<--depth>
-
-bitdepth for resulting image 8 or 16 (MSB machines only!)
-
-=item B<--title>
-
-add a title to the resulting image, if just this option is specified the text used for the title is the name of the input image file.
-
-=item B<--title_text>
-
-use the input string for the title [default: input-filename]. This option must be used in conjunction with -title
-
-=item B<--title_size>
-
-font point size for the title
-
-=item B<--anot_bar>
-
-create an annotated bar to match the image (use height of the output image)
-
-
-=head3 Image range and lookup table options
-   
-=item B<--range>
-
-valid range of values for MINC file
-
-=item B<--image_range>
-
-range of image values to use for pixel intensity
-
-=item B<--auto_range>
-
-automatically determine image range using a 5 and 95% PcT. (histogram)
-
-=item B<--lookup>
-
-arguments to pass to minclookup
-
-
-=head3 Slicing options
-   
-=item B<-s> B<--slice>
-
-slice number to get. (note this is in voxel co-ordinates)
-
-=item B<-z> B<--axial> B<--transverse>
-
-get an axial/transverse (z) slice
-
-=item B<-y> B<--coronal>
-
-get a coronal (y) slice
-
-=item B<-x> B<--sagittal>
-
-get a sagital (x) slice
-
-
-=head3 Triplanar options
-   
-=item B<-t> B<--triplanar>
-
-create a triplanar view of the input file
-
-=item B<--tilesize>
-
-pixel size for each image in a triplanar
-
-=item B<--sagittal_offset>
-
-offset the sagittal slice from the centre
-
-=item B<--sagittal_offset_perc>
-
-offset the sagittal slice by a percentage from the centre
-
-=item B<--vertical>
-
-create a vertical triplanar view (Default)
-
-=item B<--horizontal>
-
-create a horizontal triplanar view
-
-
-=back
-
-=head1 SEE ALSO
-
-convert(1) mincextract(1) display(1)
-
-=head1 AUTHOR
-
-Andrew Janke - a.janke@gmail.com
-
-=head1 COPYRIGHTS
-
-Copyright 2012 by Andrew L Janke
-
-=cuts
-
-
new file mode 100755
--- /dev/null
+++ b/progs/mincpik/mincpik.in
@@ -0,0 +1,661 @@
+#! /usr/bin/env perl
+#
+# Copyright 2009
+# Andrew Janke - a.janke@gmail.com
+# The University of Queensland
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies.  The
+# author and the University make no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+
+
+use strict;
+use warnings "all";
+use Getopt::Long;
+use Pod::Usage;
+use File::Basename;
+use File::Temp qw/ tempdir /;
+
+my($Help, $Usage, $me, @opt_table, $tmpdir, %opt);
+my(@args, $args, $infile, $outfile, %ordering, $CODE);
+
+# permutation 'matrix' for differing views
+%ordering = (
+   'zspace' => ['yspace', 'xspace'],
+   'yspace' => ['zspace', 'xspace'],
+   'xspace' => ['zspace', 'yspace'],
+   );
+
+$me = &basename($0);
+%opt = (
+   'help' => 0,
+   'man' => 0,
+   'verbose' => 0,
+   'clobber' => 0,
+   'fake' => 0,
+   
+   'scale' => 2,
+   'width' => undef,
+   'bitdepth' => 8,
+   'range' => undef,
+   'image_range' => undef,
+   'auto_range' => 0,
+   'lookup' => undef,
+   
+   'slice' => undef,
+   'dirs' => ['zspace'],
+   
+   'triplanar' => 0,
+   'tilesize' => 250,
+   'title' => 0,
+   'title_text' => undef,
+   'title_size' => 16,
+   'sagittal_offset' => undef,
+   'sagittal_offset_perc' => undef,
+   'orientation' => 'vertical',
+   'anot_bar' => undef,
+   );
+
+# Check arguments
+&GetOptions(
+   'help|?' => \$opt{'help'},
+   'man' => \$opt{'man'},
+   'version' => sub { &print_version_info },
+   'v|verbose' => \$opt{'verbose'},
+   'c|clobber' => \$opt{'clobber'},
+   'f|fake' => \$opt{'fake'},
+   
+   'scale=i' => \$opt{'scale'},
+   'width=i' => \$opt{'width'},
+   'depth=i' => \$opt{'bitdepth'},
+   
+   'title' => \$opt{'title'},
+   'title_text=s' => \$opt{'title_text'},
+   'title_size=i' => \$opt{'title_size'},
+   'anot_bar=s' => \$opt{'anot_bar'},
+   
+   # Image range and lookup table options
+   'range=f{2}' => \@{$opt{'range'}},
+   'image_range=f{2}' => \@{$opt{'image_range'}},
+   'auto_range' => \$opt{'auto_range'},
+   'lookup=s' => \$opt{'lookup'},
+   
+   # Slicing options
+   's|slice=i' => \$opt{'slice'},
+   'z|axial|transverse' => sub { $opt{'dirs'} = ['zspace']; },
+   'y|coronal' => sub { $opt{'dirs'} = ['yspace']; },
+   'x|sagittal' => sub { $opt{'dirs'} = ['xspace']; },
+   
+   # triplanar options
+   't|triplanar' => \$opt{'triplanar'},
+   'tilesize=i' => \$opt{'tilesize'},
+   'sagittal_offset=i' => \$opt{'sagittal_offset'},
+   'sagittal_offset_perc=i' => \$opt{'sagittal_offset_perc'},
+   'vertical' => \$opt{'orientation'},
+   'horizontal' => \$opt{'orientation'},
+   ) or pod2usage(-verbose => 1) && exit;
+
+# handle -man, -help or missing args
+pod2usage(-verbose => 1) if $opt{'help'};
+pod2usage(-exitstatus => 0, -verbose => 2) if $opt{'man'};
+pod2usage(-verbose => 0) && exit if ($#ARGV != 1);
+
+# Check arguments
+#&Getopt::Tabular::SetHelp ($Help, $Usage);
+#&GetOptions (\@opt_table, \@ARGV) || exit 1;
+#die $Usage if ($#ARGV < 0);
+
+# create temporary directory
+$tmpdir = &tempdir( "$me-XXXXXXXX", TMPDIR => 1, CLEANUP => 1 );
+
+# set up file names and do a few checks
+$infile = $ARGV[0];
+$outfile = (defined($ARGV[1])) ? $ARGV[1] : 'PNG:-';
+
+die "$me: Couldn't find $infile\n\n" if (!-e $infile);
+if($outfile ne 'PNG:-' && -e $outfile && !$opt{'clobber'}){
+   die "\n$me: $outfile exists, use -clobber to overwrite\n\n";
+   }
+
+if($opt{'bitdepth'} != 16 && $opt{bitdepth} != 8) {
+   die "\n$me: Invalid bitdepth specified - $opt{bitdepth} instead of 8 or 16\n\n";
+   }
+
+# sanity check
+if($opt{'auto_range'} && @{$opt{'image_range'}}){
+   die "\n$me: only specify one of -auto_range and -image_range (not both)\n\n";
+   }
+
+# warn about -slice and -triplanar
+if(defined($opt{'slice'}) && $opt{'triplanar'}){
+   warn "\n$me: you probably don't want to use both -triplanar and -slice\n\n";
+   } 
+
+# warn about -sagittal_offset and -sagittal_offset_perc
+if(defined($opt{'sagittal_offset'}) && $opt{'sagittal_offset_perc'}){
+   warn "\n$me: only use one of -sagittal_offset -sagittal_offset_perc\n\n";
+   } 
+
+# set up directions for triplanar
+if($opt{'triplanar'}){
+   $opt{'dirs'} = ['zspace', 'xspace', 'yspace'];
+   }
+
+my ($space, $n_slices, $convert_infile, $imgfile,
+    @extract_args, @convert_args,
+    $img_x, $img_y,
+    $img_step_x, $img_step_y, 
+    $img_length_x, $img_length_y,
+    $dim_names, $pipe_args, $dimorder,
+    @mont_files);
+
+# find the 5% to 95% PcT image range if -auto_range
+if($opt{'auto_range'}){
+   my $buf;
+   
+   print STDERR "Getting range of $infile\n" if $opt{'verbose'};
+   
+   chomp($buf = `mincstats -quiet -pctT 5 $infile`);
+   $buf *= 1.0;
+   @{$opt{'image_range'}}[0] = $buf;
+
+   chomp($buf = `mincstats -quiet -pctT 95 $infile`);
+   $buf *= 1.0;
+   @{$opt{'image_range'}}[1] = $buf;
+
+   # a bit of output
+   if($opt{'verbose'}){
+      print STDERR "Using image range of [@{$opt{image_range}}[0]:@{$opt{image_range}}[1]]\n";
+      }
+   }
+
+# foreach slicing direction
+foreach $space (@{$opt{'dirs'}}){
+
+   print STDERR "Doing direction $space\n" if $opt{'verbose'};
+   
+   my($slice);
+   $CODE = "GRAY";
+   
+   # set up the imgfile depending on triplanar and -title
+   if($opt{'triplanar'}){
+      $imgfile = "$tmpdir/trip-$space.png";
+      push(@mont_files, $imgfile);
+      }
+   elsif($opt{'title'}){
+      $imgfile = "$tmpdir/image.png";
+      }
+   else{
+      $imgfile = $outfile;
+      }
+   
+   # Get the info we need
+   $args = "mincinfo ".
+           "-dimlength $space ".
+           "-dimlength $ordering{$space}[0] ".
+           "-dimlength $ordering{$space}[1] ".
+           "-attvalue $ordering{$space}[0]:step ". 
+           "-attvalue $ordering{$space}[1]:step ".
+           "-dimnames ".
+           $infile;
+   ($n_slices, $img_x, $img_y, $img_step_x, $img_step_y, $dim_names) = split("\n", `$args`);
+
+   if(defined($opt{'width'})){ 
+      $opt{'scale'} = $opt{'width'}/abs($img_step_y * $img_y);
+      print STDERR "Auto-scaling width factor: $opt{'scale'}\n" if $opt{'verbose'}; 
+      }
+   $img_length_x = abs(int($img_step_x * $img_x * $opt{'scale'}));
+   $img_length_y = abs(int($img_step_y * $img_y * $opt{'scale'}));
+   
+   # figure out the slice to get
+   $slice = (!defined($opt{'slice'})) ? int($n_slices/2) : $opt{'slice'};
+   
+   # do the sagittal offset (only one of these should be done)
+   if($space eq 'xspace'){
+
+      # slice offset      
+      if(defined($opt{'sagittal_offset'})){
+         $slice += $opt{'sagittal_offset'};
+         }
+
+      # perc offset
+      if(defined($opt{'sagittal_offset_perc'})){
+         $slice += int($n_slices * $opt{'sagittal_offset_perc'} / 100);
+         }
+      }
+   
+   # check we didn't step of the edge
+   if($slice >= $n_slices || $slice < 0){ 
+      die "Slice $slice out of range (0-" . ($n_slices-1) . ")\n\n";
+      }
+   
+   # check if we have a vector_dimension already
+   if($dim_names =~ m/vector_dimension/){
+      $CODE = 'RGB';
+      }
+  
+   # take only the first timepoint if we have a time dimension
+   my @time_res_args = ();
+   if($dim_names =~ m/time/){
+      @time_res_args = ('-dimrange', "time=0,0");
+      }
+    
+   # do the reshaping
+   $dimorder = join(',', $space, @{$ordering{$space}});
+   if($CODE eq 'RGB'){
+      $dimorder .= ',vector_dimension';
+      }
+   @args = ('mincreshape', '-clobber', '-quiet',
+            '-normalize',
+            '+direction',
+            '-dimsize', "$space=-1",
+            '-dimsize', "$ordering{$space}[0]=-1",
+            '-dimsize', "$ordering{$space}[1]=-1",
+            '-dimorder', $dimorder,
+            '-dimrange', "$space=$slice,1",
+            @time_res_args,
+            $infile, "$tmpdir/reshaped.mnc");                  
+   if(scalar(@{$opt{'range'}}) != 0){
+      push(@args, '-valid_range', @{$opt{'range'}}[0], @{$opt{'range'}}[1]);
+      }
+   if(scalar(@{$opt{'image_range'}}) != 0){
+      push(@args, '-image_range', @{$opt{'image_range'}}[0], @{$opt{'image_range'}}[1]);
+      }
+   &do_cmd(@args);
+   
+   # do the lookup if required
+   $convert_infile = "$tmpdir/reshaped.mnc";
+   if($opt{'lookup'}){
+      if($CODE eq 'RGB'){
+         warn "$me: Input is vector-valued already.  No colour lookup done.\n";
+         }
+      else{
+         $convert_infile = "$tmpdir/lookup.mnc";
+         $CODE = 'RGB';
+         &do_cmd('minclookup', '-clobber', '-quiet', 
+                 split(' ', $opt{'lookup'}), 
+                 "$tmpdir/reshaped.mnc", $convert_infile);
+         }
+      }
+
+   # set up mincextract command
+   @extract_args = ('mincextract', $convert_infile,
+                    '-normalize',
+                    ($opt{'bitdepth'} == 16) ? ('-short', '-unsigned') : '-byte');
+   
+   # set up convert arguments
+   # a flip is 'normal' due to the difference between mnc and most image co-ordinates
+   @convert_args = ('convert',
+                    '-depth', $opt{'bitdepth'},
+                    '-flip', 
+                    '-size', $img_y . 'x' . $img_x,
+                    '-geometry', $img_length_y . 'x' . $img_length_x . '!',
+                    "$CODE:-", $imgfile);
+   
+   # check if we are big or little endian for convert's MSB wierdity
+   $pipe_args = '|';
+   if($opt{'bitdepth'} == 16){
+      if(unpack("c",substr(pack("s",1),0,1))){
+         warn "$me: LSB machine, swapping bytes with dd and crossing fingers\n";
+         $pipe_args .= ' dd conv=swab | ';
+         }
+      }
+   
+   &do_cmd(join(' ', @extract_args, $pipe_args, @convert_args));
+   }
+
+# do the triplanar if requested
+if($opt{'triplanar'}){
+   my @orient_args;
+
+   if($opt{'title'}){
+      $imgfile = "$tmpdir/mont.png";
+      }
+   else{
+      $imgfile = $outfile;
+      }
+   
+   if($opt{'orientation'} eq 'vertical'){
+      @orient_args = ('-tile', ('1x' . ($#mont_files + 1)));
+      }
+   else{ # $opt{orientation} eq 'horizontal'
+      @orient_args = ('-tile', (($#mont_files + 1) . 'x1'));
+      }
+   
+   # do the montage
+   &do_cmd('montage',
+           @orient_args, 
+           '-background', 'grey10',
+           '-geometry', "$opt{tilesize}x$opt{tilesize}+1+1",
+           @mont_files, $imgfile);
+   }
+               
+# Add the title
+if($opt{'title'}){
+   
+   # set up the title text
+   if(!defined($opt{'title_text'})){
+      $opt{'title_text'} = &basename($infile);
+      $opt{'title_text'} =~ s/\.mnc$//;
+      }
+     
+#   This really does not work all that well (but should), go figure
+#   &do_cmd('convert', '-box', 'black', 
+#           '-font', '7x13', 
+#           '-fill', 'white',
+#           '-draw', "text 4,12 \"$opt{'title_text'}\"",
+#           $imgfile, $outfile);
+#
+   # use montage instead
+   &do_cmd('montage', 
+           '-geometry', '100x100%',  
+           '-background', 'black',
+           '-fill', 'white',
+           '-label', $opt{'title_text'},
+           '-pointsize', $opt{'title_size'},
+           $imgfile, $outfile);
+   }
+
+# create the annotated bar if required
+if(defined($opt{'anot_bar'})){
+   
+   my($min, $max, $pcode, 
+      $q0, $q1, $q2, $q3, $q4, $bh, $bw, $bb, $ob, 
+      $textbump, $i, @buf);
+   
+   # set up a few constants
+   $textbump = 3;
+   $pcode = '%6g';
+   
+   # text border, other border, height, width
+   $bb = 50;
+   $ob = 25;
+   $bh = $img_length_y - ($ob*2);
+   $bw = int($bh/10);
+   
+   # get range if not defined
+   if(!defined($opt{'image_range'}[0])){
+      print STDERR "Getting image range\n" if $opt{'verbose'};
+      
+      @buf = split(/\n/, `mincstats -min -max -quiet $infile`);
+      @{$opt{'image_range'}}[0] = $buf[0] * 1.0;
+      @{$opt{'image_range'}}[1] = $buf[1] * 1.0;
+      }
+   
+   $min = @{$opt{'image_range'}}[0];
+   $max = @{$opt{'image_range'}}[1];
+   
+   # set up the datafile
+   my(@data) = undef;
+   my($packstring) = '';
+   for($i=0; $i<$bh; $i++){
+      $data[$i] = $i;
+      $packstring .= 'f';
+      }
+   
+   open(FH, ">$tmpdir/tmp-float.raw");
+   for($i=0; $i<$bw; $i++){
+      syswrite(FH, pack($packstring, @data));
+      }
+   close(FH);
+   
+   # make minc file
+   &do_cmd('rawtominc', '-clobber',
+           '-float',
+           '-input', "$tmpdir/tmp-float.raw",
+           '-xstep',  1, '-ystep',  1, '-zstep',  1,
+           '-xstart', 0, '-ystart', 0, '-zstart', 0,
+           '-dimorder', 'xspace,yspace,zspace',
+           "$tmpdir/bar.mnc", $bw, $bh, 1);
+   
+
+   # make .miff bar image (whoa... recursion!)
+   &do_cmd('mincpik', '-clobber',
+           '-scale', 1,
+           (defined($opt{'lookup'})) ? ('-lookup', $opt{'lookup'}) : (),
+           "$tmpdir/bar.mnc", "$tmpdir/bar.png");
+   
+   # set up the text
+   $q0 = sprintf($pcode, $min);
+   $q1 = sprintf($pcode, (($max-$min) * 0.25) + $min);
+   $q2 = sprintf($pcode, (($max-$min) * 0.5)  + $min);
+   $q3 = sprintf($pcode, (($max-$min) * 0.75) + $min);
+   $q4 = sprintf($pcode, $max);
+   
+   
+   # create the bar itself via convert
+   &do_cmd('convert',
+           '-bordercolor', 'white',
+           '-border', $bb,
+
+           # color for all the decorations
+           '-fill', 'black',
+
+           # bar border
+           '-draw', "line " . join(',',  $bb,      $bb,      ($bb+$bw),  $bb     ),
+           '-draw', "line " . join(',',  $bb,     ($bb+$bh), ($bb+$bw), ($bb+$bh)),
+           '-draw', "line " . join(',',  $bb,      $bb,       $bb,      ($bb+$bh)),
+           '-draw', "line " . join(',', ($bb+$bw), $bb,      ($bb+$bw), ($bb+$bh)),
+
+           # 3 ticks at 1/4, 1/2 and 3/4
+           '-draw', "line " . join(',', ($bb+($bw*3/4)), ($bb+($bh*1/4)), ($bb+$bw), ($bb+($bh*1/4))),
+           '-draw', "line " . join(',', ($bb+($bw*3/4)), ($bb+($bh*2/4)), ($bb+$bw), ($bb+($bh*2/4))),
+           '-draw', "line " . join(',', ($bb+($bw*3/4)), ($bb+($bh*3/4)), ($bb+$bw), ($bb+($bh*3/4))),
+
+           # text
+           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*0/4)+$textbump) . " '$q4'",
+           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*1/4)+$textbump) . " '$q3'",
+           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*2/4)+$textbump) . " '$q2'",
+           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*3/4)+$textbump) . " '$q1'",
+           '-draw', 'text ' . ($bb+$bw) . ',' . ($bb+($bh*4/4)+$textbump) . " '$q0'",
+
+           # finally crop of the extra border
+           '-crop', (($bb*2)+$bw-($bb-$ob)) . "x" . (($bb*2)+$bh-$bb) . "+" . ($bb-$ob) . "+" . ($bb-$ob),
+
+           "$tmpdir/bar.png", $opt{'anot_bar'});
+   }
+
+
+sub do_cmd {
+   print STDERR "@_\n" if $opt{'verbose'};
+   if(!$opt{'fake'}){
+      system(@_) == 0 or die "\n$me: Failed executing @_\n\n";
+      }
+   }
+
+# print version information
+sub print_version_info {
+   my $PACKAGE = '@PACKAGE_NAME@';
+   my $VERSION = '@PACKAGE_VERSION@';
+   my $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@';
+   
+   print STDOUT "\n$PACKAGE version $VERSION\n".
+                "Comments to $PACKAGE_BUGREPORT\n\n";
+   exit 0;
+   }
+
+__END__
+
+=head1 NAME
+
+B<mincpik> - generate images from minc files
+
+=head1 SYNOPSIS
+
+B<mincpik> [options] <infile>.mnc [<image.type>]
+
+mincpik generates image files from MINC volumes using the Imagemagick
+convert utility. Use -help or -man for more information and examples
+
+=head1 DESCRIPTION
+
+B<mincpik> generates image files from MINC volumes using the Imagemagick
+B<convert> utility. For a complete list of output file types see the
+B<convert> man pages.
+
+EXAMPLES:
+To display a default view, axial (z) slicing, middle slice
+using display. (display is part of the Imagemagick package)
+
+   mincpik infile.mnc PNG:- | display -
+
+To generate a PNG file of the 15th coronal slice
+
+   mincpik -slice 15 -coronal infile.mnc outfile.png
+
+To generate a JPG file using the hotmetal lookup table 
+with the image range 0 to 100
+
+   mincpik -lookup '-hotmetal' -image_range 0 100 infile.mnc outfile.jpg
+
+ImageMagick:  http://www.wizards.dupont.com/cristy/ImageMagick.html
+   NB: ImageMagick should be compiled without 16-bit quanta.
+
+Currently if there is a time dimension in the file the image will
+only produced from the first time point
+
+Problems or comments should be sent to: a.janke\@gmail.com
+ 
+=head1 OPTIONS
+
+=over 4
+
+=item B<-v>, B<--verbose>
+
+Be noisy when doing things
+
+=item B<--version>
+
+Print version number and exit
+
+=item B<-?>, B<--help>
+
+Dump some quick help output
+
+=item B<--man>
+
+Dump a man page
+
+=item B<-c> B<--clobber>
+
+overwrite the output file if it exists already
+
+=item B<-f> B<--fake>
+
+do a dry run, (echo cmds only). This is usually used in combination with -verbose to echo commands only
+
+=item B<--scale>
+
+scaling factor for resulting image, by default images are output 
+at twice their original resolution
+
+=item B<--width>
+
+autoscale the resulting image to have a fixed image width (in pixels)
+
+=item B<--depth>
+
+bitdepth for resulting image 8 or 16 (MSB machines only!)
+
+=item B<--title>
+
+add a title to the resulting image, if just this option is specified the text used for the title is the name of the input image file.
+
+=item B<--title_text>
+
+use the input string for the title [default: input-filename]. This option must be used in conjunction with -title
+
+=item B<--title_size>
+
+font point size for the title
+
+=item B<--anot_bar>
+
+create an annotated bar to match the image (use height of the output image)
+
+
+=head3 Image range and lookup table options
+   
+=item B<--range>
+
+valid range of values for MINC file
+
+=item B<--image_range>
+
+range of image values to use for pixel intensity
+
+=item B<--auto_range>
+
+automatically determine image range using a 5 and 95% PcT. (histogram)
+
+=item B<--lookup>
+
+arguments to pass to minclookup
+
+
+=head3 Slicing options
+   
+=item B<-s> B<--slice>
+
+slice number to get. (note this is in voxel co-ordinates)
+
+=item B<-z> B<--axial> B<--transverse>
+
+get an axial/transverse (z) slice
+
+=item B<-y> B<--coronal>
+
+get a coronal (y) slice
+
+=item B<-x> B<--sagittal>
+
+get a sagital (x) slice
+
+
+=head3 Triplanar options
+   
+=item B<-t> B<--triplanar>
+
+create a triplanar view of the input file
+
+=item B<--tilesize>
+
+pixel size for each image in a triplanar
+
+=item B<--sagittal_offset>
+
+offset the sagittal slice from the centre
+
+=item B<--sagittal_offset_perc>
+
+offset the sagittal slice by a percentage from the centre
+
+=item B<--vertical>
+
+create a vertical triplanar view (Default)
+
+=item B<--horizontal>
+
+create a horizontal triplanar view
+
+
+=back
+
+=head1 SEE ALSO
+
+convert(1) mincextract(1) display(1)
+
+=head1 AUTHOR
+
+Andrew Janke - a.janke@gmail.com
+
+=head1 COPYRIGHTS
+
+Copyright 2012 by Andrew L Janke
+
+=cuts
+
+