#!/usr/bin/env perl # Plot the surfaces in 3D. # # Copyright Alan C. Evans # Professor of Neurology # McGill University # use strict; use warnings "all"; use List::Util qw( min max ); use File::Temp qw/ tempdir /; my ($gray_left, $gray_right, $white_left, $white_right, $thickness_left, $thickness_right, $output, $lg_title, $rg_title, $ct_title) = @ARGV; unless($output) { print "Usage: $0 lg_title rg_title ct_title\n"; print "Note that none of the inputs may be compressed!\n"; exit(1); } my $tmpdir = tempdir( CLEANUP => 1 ); my $tilesize = 200; my $debug = 0; my $quiet = 1; my @mont_args = (); my @DrawText = ( "-font", "Helvetica" ); my $xpos = 2*$tilesize; my $ypos = 15; # ROW 1: white left hemi surfaces + white top and bottom views push @DrawText, "-annotate 0x0+${xpos}+${ypos} \"CLASP surfaces\""; foreach my $pos ('default', 'left', 'right') { print "Making left white ${pos} surface\n" unless $quiet; make_hemi($white_left, "${tmpdir}/white_left_$pos.rgb", $pos); push(@mont_args, "${tmpdir}/white_left_$pos.rgb"); } foreach my $pos ('top', 'bottom') { print "Making left/right white ${pos} surface\n" unless $quiet; make_surface( $white_left, $white_right, "${tmpdir}/white_${pos}.rgb", $pos ); push(@mont_args, "${tmpdir}/white_${pos}.rgb"); } # ROW 2: white right hemi surfaces + white front and back views $ypos += $tilesize; foreach my $pos ('flipped', 'right', 'left') { print "Making right white ${pos} surface\n" unless $quiet; make_hemi($white_right, "${tmpdir}/white_right_$pos.rgb", $pos); push(@mont_args, "${tmpdir}/white_right_$pos.rgb"); } foreach my $pos ('front', 'back') { print "Making left/right white ${pos} surface\n" unless $quiet; make_surface( $white_left, $white_right, "${tmpdir}/white_${pos}.rgb", $pos ); push(@mont_args, "${tmpdir}/white_${pos}.rgb"); } # ROW 3: gray left hemi surfaces + gray top and bottom views $ypos += $tilesize - 0.10*$tilesize; push @DrawText, "-annotate 0x0+${xpos}+${ypos} \"$lg_title\""; $ypos += 0.10*$tilesize; foreach my $pos ('default', 'left', 'right') { print "Making left gray ${pos} surface\n" unless $quiet; make_hemi($gray_left, "${tmpdir}/gray_left_$pos.rgb", $pos); push(@mont_args, "${tmpdir}/gray_left_$pos.rgb"); } foreach my $pos ('top', 'bottom') { print "Making left/right gray ${pos} surface\n" unless $quiet; make_surface( $gray_left, $gray_right, "${tmpdir}/gray_${pos}.rgb", $pos ); push(@mont_args, "${tmpdir}/gray_${pos}.rgb"); } # ROW 4: gray right hemi surfaces + gray front and back views $ypos += $tilesize - 0.10*$tilesize; push @DrawText, "-annotate 0x0+${xpos}+${ypos} \"$rg_title\""; $ypos += 0.10*$tilesize; foreach my $pos ('flipped', 'right', 'left') { print "Making right gray ${pos} surface\n" unless $quiet; make_hemi($gray_right, "${tmpdir}/gray_right_$pos.rgb", $pos); push(@mont_args, "${tmpdir}/gray_right_$pos.rgb"); } foreach my $pos ('front', 'back') { print "Making left/right gray ${pos} surface\n" unless $quiet; make_surface( $gray_left, $gray_right, "${tmpdir}/gray_${pos}.rgb", $pos ); push(@mont_args, "${tmpdir}/gray_${pos}.rgb"); } my $num_rows = 4; # ROWS 5 - 6: cortical thickness on left and right mid-surfaces if( -e $thickness_left && $thickness_left ne "none" && -e $thickness_right && $thickness_right ne "none" ) { my $mid_left = "${tmpdir}/mid_left.obj"; my $mid_right = "${tmpdir}/mid_right.obj"; my $mid_rms_left = "${tmpdir}/mid_rms_left.txt"; my $mid_rms_right = "${tmpdir}/mid_rms_right.txt"; my $rms_left_min = `sort -n $thickness_left |head -1`; my $rms_right_min = `sort -n $thickness_right |head -1`; my $rms_left_max = `sort -n $thickness_left |tail -1`; my $rms_right_max = `sort -n $thickness_right |tail -1`; chomp( $rms_left_min ); chomp( $rms_right_min ); chomp( $rms_left_max ); chomp( $rms_right_max ); my $rms_min = min( $rms_left_min, $rms_right_min ); my $rms_max = max( $rms_left_max, $rms_right_max ); $ct_title = sprintf( "$ct_title: min %5.2fmm, max %5.2fmm", $rms_min, $rms_max ); my $old_xpos = $xpos; $xpos = 0.85 * $xpos; $ypos += $tilesize; push @DrawText, "-annotate 0x0+${xpos}+${ypos} \"$ct_title\""; $ypos += $tilesize; $xpos = $old_xpos; $num_rows+=2; `average_surfaces $mid_left none none 1 $gray_left $white_left`; `average_surfaces $mid_right none none 1 $gray_right $white_right`; $rms_min = 0.5; $rms_max = 6.0; `colour_object $mid_left $thickness_left $mid_rms_left spectral $rms_min $rms_max`; `colour_object $mid_right $thickness_right $mid_rms_right spectral $rms_min $rms_max`; foreach my $pos ('default', 'left', 'right') { print "Making left mid ${pos} surface\n" unless $quiet; make_hemi($mid_rms_left, "${tmpdir}/mid_left_$pos.rgb", $pos); push(@mont_args, "${tmpdir}/mid_left_$pos.rgb"); } foreach my $pos ('top', 'bottom') { print "Making left/right mid ${pos} surface\n" unless $quiet; make_surface( $mid_rms_left, $mid_rms_right, "${tmpdir}/mid_${pos}.rgb", $pos ); push(@mont_args, "${tmpdir}/mid_${pos}.rgb"); } foreach my $pos ('flipped', 'right', 'left') { print "Making right mid ${pos} surface\n" unless $quiet; make_hemi($mid_rms_right, "${tmpdir}/mid_right_$pos.rgb", $pos); push(@mont_args, "${tmpdir}/mid_right_$pos.rgb"); } foreach my $pos ('front', 'back') { print "Making left/right mid ${pos} surface\n" unless $quiet; make_surface( $mid_rms_left, $mid_rms_right, "${tmpdir}/mid_${pos}.rgb", $pos ); push(@mont_args, "${tmpdir}/mid_${pos}.rgb"); } } # do the montage print "Making montage\n" unless $quiet; my $cmd = "montage -tile 5x${num_rows} -background white " . "-geometry ${tilesize}x${tilesize}+1+1 " . join(' ', @mont_args)." ${tmpdir}/mont.png"; print "$cmd\n" if $debug; `$cmd`; # Add the title print "Adding title\n" unless $quiet; $cmd = "convert -box white -stroke green -pointsize 16 @DrawText ${tmpdir}/mont.png ${output}"; print "$cmd\n" if $debug; `$cmd`; print "Done\n" unless $quiet; # end of function sub make_hemi { my ($surface, $temp_output, $pos) = @_; my $cmd = ""; my $viewdir = ""; if ($pos eq 'default') { $viewdir = "-view 0.77 -0.18 -0.6 0.55 0.6 0.55"; } else { if ($pos eq 'flipped') { $viewdir = "-view -0.77 -0.18 -0.6 -0.55 0.6 0.55"; } else { $viewdir = "-$pos"; } } $cmd = "ray_trace -shadows -output ${temp_output} ${surface} -bg white -crop ${viewdir}"; print "$cmd\n" if $debug; `$cmd`; } sub make_surface { my ($left_hemi, $right_hemi, $temp_output, $pos) = @_; my $cmd = ""; my $viewdir = ""; if ($pos eq 'default') { $viewdir = ""; } else { $viewdir = "-$pos"; } $cmd = "ray_trace -shadows -output ${temp_output} ${left_hemi} ${right_hemi} -bg white -crop ${viewdir}"; print "$cmd\n" if $debug; `$cmd`; }