#!/usr/bin/perl
#
# $Id: povray_condor.pl,v 1.6 2007/02/25 23:46:13 baaden Exp $
#
# Automation script for running povray via Condor
# for details see usage message below
#
# Copyright CNRS
# contributor : Marc Baaden
#
# baaden@smplinux.de
# http://www.baaden.ibpc.fr
#
# This software is governed by the CeCILL  license under French law and
# abiding by the rules of distribution of free software.  You can  use,
# modify and/or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".
#
# As a counterpart to the access to the source code and  rights to copy,
# modify and redistribute granted by the license, users are provided
# only with a limited warranty  and the software's author,  the holder
# of the economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading,  using,  modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean  that it is complicated to manipulate,  and  that  also
# therefore means  that it is reserved for developers  and  experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and,  more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.


########################################################################
# SYSTEM SETTINGS - adapt to your environment

# where the combineppm executable can be found
$combppmexe="/ibpc/matrix/opt/bin/combineppm";

# where the povray excecutable can be found
$povrayexe="/ibpc/matrix/opt/yasara/pov/povray-3.5/povray";

# where the povray include directory is located
$povincdir="/ibpc/matrix/opt/yasara/pov/povray-3.5/include/";

### you shouldn't need to change anything below
########################################################################


# script setup, command line arguments
%arghash=@ARGV;

# get povray filename
$bnam=$arghash{"-p"};

# Get number of slices
$k=$arghash{"-n"};

# Get resolution or set to default
$res=$arghash{"-r"};
if ($res eq "") {$res=1024};

$usage_message='
NAME
        $Id: povray_condor.pl,v 1.6 2007/02/25 23:46:13 baaden Exp $
        Perl script povray_condor.pl MB260207a

SYNOPSIS
        povray_condor.pl -p <povfile> -n <nb_slices> [-r <res>]

        This is a perl script to start rendering of a povray scene
        via condor, splitting the scene into <nb_slices> separate
        pieces and then reconstituting the final image.
        The script requires povray, imagemagick and the tool
        combineppm that can be obtained from [1].
        The script also writes out a timing value to a file using
        <povfile>.timing.<processnumber>. Units are seconds.

OPTIONS
        -p <povfile>
                <povfile> is a povray scene. Do not indicate the
        trailing .pov.

        -n <nb_slices>
                <nb_slices> is the number of slices that the image
        will be divided into. The resolution must be a multiple of
        this number.

        -r <res>
                <res> is the resolution. Just indicate the horizontal
        value, the script will complete. Choices are 320x240, 480x320
        640x480, 1024x768, 1280x1024, 1600x1200. Default is 1024.
        
AUTHOR
        Marc Baaden <baaden@smplinux.de>

REFERENCES
        [1] http://unu.novajo.ca/simple/combineppm.c
';

###
### Command line arguments and initial info
###

# check arguments
if ( $#ARGV <2 || $#ARGV >5 || ($bnam eq "") || $k eq "" ) {
  die "$usage_message";
}

%resolutions=(
   "320" =>  "240",
   "480" =>  "320",
   "640" =>  "480",
   "800" =>  "600",
  "1024" =>  "768",
  "1280" => "1024",
  "1600" => "1200",
);

# Calculate slice size
$width=$res; $height=$resolutions{$res};
$slice=$height/$k; 

printf("Resolution $width x $height, name $bnam.\n");
if($slice != int($slice)) {
  die "Image slices must be integer, choose a different n (<> $k)!\n";
}
print "We use $k slices of $slice.\n";


# CONFIGURATION SETTINGS - some variables for this script

# Name for temporary condor script
$condorpov=".tmp.pov.condor";
$condorcnv=".tmp.cnv.condor";
$condordag=".tmp.dag.condor";
# Name of working directory
$workdir="/tmp/condor_pov_$$";

###
### Setup directory
###

mkdir $workdir;
system("cp $bnam.pov $workdir");

###
### Prepare povray inis
###

$ifil="";
$pfil="";

for ($i = 0 ; $i < $k; $i++ ) {
	$start = $i * $slice+1;
	$end =  ($i +1 ) * $slice;
	$text = sprintf ("+I$bnam.pov +L$povincdir +FP +H$height +W$width -D +SR%d +ER%d +O%s_%0.4d.ppm",$start,$end,$bnam,$i) ;
	print `echo "$text" > $workdir/$i.ini`;
        $ifil .= $i.".ini, ";
	$pfil .= sprintf ("%s_%0.4d.ppm, ",$bnam,$i) ;
}

###
### Prepare Condor script for povray
###

open CONDOR,">$workdir/$condorpov";
print CONDOR ("# TEMPORARY CONDOR SCRIPT
Universe = vanilla
Executable      = $povrayexe
arguments       = \$(Process).ini
getenv          = true
transfer_input_files = $ifil $bnam.pov
should_transfer_files = YES
when_to_transfer_output = ON_EXIT
output          = povray.\$(Process).std
error           = povray.\$(Process).err
log             = povray.overall.log
notify_user     = baaden\@ibpc.fr
notification    = always
queue $k
");
close CONDOR;

###
### Prepare Condor script for combineppm
###

$pwd=`pwd`;
chomp($pwd);

print `(cd $workdir; echo -e "#!/bin/sh\\n./combineppm $bnam | convert - $bnam.png\\nmv $bnam.png $pwd" > combineppm.sh)`;

open CONDOR,">$workdir/$condorcnv";
print CONDOR ("# TEMPORARY CONDOR SCRIPT
Universe = vanilla
Executable      = combineppm.sh
getenv          = true
transfer_input_files = $pfil $combppmexe
should_transfer_files = YES
when_to_transfer_output = ON_EXIT
output          = combineppm.\$(Process).std
error           = combineppm.\$(Process).err
log             = combineppm.overall.log
notify_user     = baaden\@ibpc.fr
notification    = always
queue
");
close CONDOR;

###
### Prepare Condor script for dagman
###

print `(cd $workdir; echo -e "#!/bin/sh\\ndate +%s > beg.tim" > start_timer.sh)`;

$tmp='"\`date +%s\`-\`cat beg.tim\`"';
print `(cd $workdir; echo -e "#!/bin/sh\\necho $tmp|bc > $pwd/$bnam.timing.$$\ncd $pwd\nrm -rf $workdir" > endof_timer.sh; chmod +x *.sh)`;

open CONDOR,">$workdir/$condordag";
print CONDOR ("# TEMPORARY DAGMAN SCRIPT
JOB  povray  $condorpov
SCRIPT PRE povray start_timer.sh
JOB  convert $condorcnv
SCRIPT POST convert endof_timer.sh
PARENT povray CHILD convert
");
close CONDOR;

###
### Submit condor scripts
###

#system("condor_submit $condorpov"); 
#system("condor_submit $condorcnv");
system("(cd $workdir; condor_submit_dag $condordag)");
#system("mv $workdir/$bnam.png ./");

