Новосибирский институт органической химии им. Н.Н. Ворожцова СО РАН

Лаборатория изучения механизмов органических реакций

mldn-gif


#!/usr/bin/perl -w

die "Usage: $0 [options] IRC.xyz mol*.gif.
$0 -h for help.\n" unless @ARGV;

$label_color = 'xadd8e6';
$line_color  = 'xff0000';
#  xffffff white     #  xffa500 orange              #  x0000ff blue 
#  x000000 black     #  x66cdaa medium aquamarine   #  xdda0dd plum 
#  x404040 gray      #  xcdb5cd thistle 3           #  x9500d3 dark violet
#  xff0000 red       #  xadd8e6 light blue          # xffff00 желтый
$line_style  = 'lines lw 2'; # 'linespoints'
#$smooth = 'smooth csplines'; # ''
$smooth = '';
$no_axes = 'set noborder; set noarrow; set noxtics; set noytics';
#$no_axes = ''; #Раскоментировать, если нужны оси координат
        
use Getopt::Std;

getopts("hp:f", \%opts);

# Если опция -h, печатаем справку
if ($opts{'h'}) {
  $0 =~ s/^.*[\/\\]//;
  print "
Usage: $0 [options] IRC.xyz mol*.gif

Зависимости: Perl, gnuplot, Image Magick

С помощью gnuplot и composite (Image Magick) добавляет график 
координата-энергия на молденовские гифы.

Молден можно запускать без логотипа и лучше с геометрией 4х3.
По умолчанию создается не больше 99 картинок, это можно исправить опцией -j. 
molden -l -geom 800x600 -j 300.
Молден обычно создает одну лишннюю картинку, ее нужно удалить 
(обычно 1-я и 2-я идентичны).

Каждой точке конкатенированного IRC.xyz должен соответствовать свой gif.
В файле IRC.xyz должны присутствовать строки типа 'Energy -54.59304'
(ккординаты и все другое, в принципе, не обязательно).

Опции:
-p <position>  где <position> - положение графика относительно картинки
   t сверху (default)
   b снизу
   r справа
   l слева
   1 в 1-й четверти (сверху слева)
   2 во 2-й (сверху справа)
   3 в 3-й (снизу слева)
   4 в 4-й (снизу справа)
   5 в верхней четверти
   6 в нижней четверти
-f сложить график вдвое (fold up) по вертикали

Некоторые параметры (цвета, например) заданы в начале скрипта, их легко изменить
\n";
  exit;
}

my $IRC_xyz = shift;
open L, '<', $IRC_xyz or die "Can't open $IRC_xyz: $!\n";
$minE = 1e20;
$x = 0;
while (<L>) {
  if (m/Energy (\S+)/) {
    $E = $1;
    $x++;
    push @x, $x;
    $minE = $E if $E < $minE;
    push @E, $E;
  }
}
close L;

@gif = @ARGV;

if ($#x != $#gif) {
  if ($#x == $#gif - 1) {
    shift @gif;
  } else {
    print "Неодинаковое количество точек на графике и молденовских картинок!\n";
    exit;
  }
}

$sizeX = 800; $sizeY = 700;
($sizeX,$sizeY) = `file $gif[0]` =~ /(\d+)\s*x\s*(\d+)/;

$opts{'p'} = 't' unless $opts{'p'};
$geometry = "+0+0";

if ($opts{'p'} eq 't') {
  $sizeY /= 2;
} elsif ($opts{'p'} eq 'b') {
  $sizeY /= 2; $geometry = "+0+$sizeY";
} elsif ($opts{'p'} eq 'r') {
  $sizeX /= 2;
} elsif ($opts{'p'} eq 'l') {
  $sizeX /= 2; $geometry = "+$sizeX+0";
} elsif ($opts{'p'} eq '1') {
  $sizeX /= 2; $sizeY /= 2; 
} elsif ($opts{'p'} eq '3') {
  $sizeX /= 2; $sizeY /= 2; $geometry = "+0+$sizeY";
} elsif ($opts{'p'} eq '2') {
  $sizeX /= 2; $sizeY /= 2; $geometry = "+$sizeX+0";
} elsif ($opts{'p'} eq '4') {
  $sizeX /= 2; $sizeY /= 2; $geometry = "+$sizeX+$sizeY";
} elsif ($opts{'p'} eq '5') {
  $sizeY /= 4;
} elsif ($opts{'p'} eq '6') {
  $sizeY /= 4; my $s = $sizeY*3; $geometry = "+0+$s";
}

open GR, ">g_r_a_f_i_k.tmp";

for ($i=0; $i<=$#x; $i++) {
  $E[$i] = ($E[$i]-$minE)*627.5;
  print GR "$x[$i]  $E[$i]\n";
}
close GR;

for ($i=0; $i<=$#x; $i++) {
  printf "%-10f %-14f %-14s --> ", $x[$i], $E[$i], $gif[$i];
  open GP, "| gnuplot";
  print GP "set terminal gif medium transparent size $sizeX,$sizeY \\
            xffffff $label_color x404040 $line_color\n";
  print GP "set output 'g_r_a_f_i_k.gif'\n";
  print GP "set autoscale; set nokey; $no_axes\n";
  #print GP "set size 2,2\n";
  print GP "set label 'O' at $x[$i],$E[$i] center\n";
  #print GP "set label 'O' at $x[1],$E[1] center font 'Symbol,34'\n";
  print GP "plot 'g_r_a_f_i_k.tmp' $smooth with $line_style";
  close GP;
  fold_up('g_r_a_f_i_k.gif') if $opts{'f'};
  `composite -geometry $geometry g_r_a_f_i_k.gif $gif[$i] G$gif[$i]`;
  (-f "G$gif[$i]") ? (print "G$gif[$i]\n") : (print "Fail\n");
}

unlink 'g_r_a_f_i_k.tmp' if -f 'g_r_a_f_i_k.tmp';
unlink 'g_r_a_f_i_k.gif' if -f 'g_r_a_f_i_k.gif';

sub fold_up {
  my $file = shift;
  system('convert',          '-crop', '50x100%+0+0', $file, "R$file");
  system('convert', '-flop', '-crop', '50x100%+0+0', $file, "L$file");
  system('composite', "R$file", "L$file", $file);
  system('mogrify', '-scale', '200x100%', $file);
  unlink "R$file", "L$file";
}