#!/bin/bash

# run a bunch of single-processor analysis jobs in parallel.  Lock
# files are used to keep track of how many processors are in use at
# any given time -- this allows for jobs of varying length to be run
# together.
#
# M. Zingale

#----------------------------------------------------------------------------
# user modifiable variables:

# number of parallel tasks to run
NCPUS=8


# pidfile is a lock file that is used to make sure that only one instance
# of this script is working on the current directory
pidfile=process.pid

# set the prefix of the datafile to process
data_prefix=plt

# check suffix -- if this exists, skip the processing for this file
chk_suff=_enuc_slice.png

# set the full name of the analysis routines (must be in the path)
analysis=slice.py


#----------------------------------------------------------------------------
# initialization stuff

# check to make sure that the lock file does not already exist.
if [ -f $pidfile ]; then
  echo 2>&1 "process lock file " $pidfile " already exists"
  exit -1
fi

# create the lock file
echo $$ > $pidfile

# if our process if killed, remove the lock file first
trap '/bin/rm -f $pidfile' EXIT HUP TERM XCPU KILL

# Number of seconds to sleep before checking again.
N=60




#----------------------------------------------------------------------------
# the processing functions
function process_files
{

    # the argument $1 is the name of the datafile

    echo "working on " $1
    root=$(basename $1)
    echo $1 > _process.$root

    if [ -d $1 ]; then

        if [ ! -f $1$chk_suff ]; then
            # do processing
            ${analysis} $1

            # this sleep line is not necessary if the analysis takes any
    	    # measurable amount of time
	    #sleep 1
        fi
    fi   # end test of whether datafile is a file (as it should be)

    rm -f _process.$root
}



#----------------------------------------------------------------------------
# The function freecpus looks counts the _process.XX files to determine
# how many files we are currently processing.  If we are processing <
# NCPUS, return 1 to indicate that there are free CPUs available to
# do more processing.
function freecpus
{
    num=$(ls -l _process.* | wc -l)

    if [ $num -lt $NCPUS ]; then
        return 1
    else
        return 0
    fi
}


#----------------------------------------------------------------------------
# the main loop

# Looping waiting for new datafiles to appear.  We process
# NCPUS files at a time.  We loop over files, waiting for free CPUs.
# When a CPU becomes available, we launch the processing job in the
# background, and move to the next file, again waiting for an available
# CPU.
#
# if you don't want to wait for new files to appear, get rid of the
# outer loop.

#while true
#do

  if [ ! -f $pidfile ]; then
    echo "process: $pidfile has been removed, exiting"
    exit
  fi


  filelist=$(find . -maxdepth 1 -type d -name "${data_prefix}*" -print | sort)

  for file in ${filelist}
  do

      # wait for available CPUS
      freecpus
      while [ $? -eq 0 ]
      do
          sleep 1
          freecpus
      done

      process_files ${file} &

      sleep 1
  done


  # we've processed all of the files.  Sleep a bit and repeat on any
  # newly written files.
  sleep $N
#done
