Index: /trunk/ppShutter/.cvsignore
===================================================================
--- /trunk/ppShutter/.cvsignore	(revision 8901)
+++ /trunk/ppShutter/.cvsignore	(revision 8901)
@@ -0,0 +1,11 @@
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+compile
+config.log
+config.status
+configure
+depcomp
+install-sh
+missing
Index: /trunk/ppShutter/Makefile.am
===================================================================
--- /trunk/ppShutter/Makefile.am	(revision 8901)
+++ /trunk/ppShutter/Makefile.am	(revision 8901)
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES = *~ core core.*
Index: /trunk/ppShutter/autogen.sh
===================================================================
--- /trunk/ppShutter/autogen.sh	(revision 8901)
+++ /trunk/ppShutter/autogen.sh	(revision 8901)
@@ -0,0 +1,103 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+PROJECT=ppMerge
+TEST_TYPE=-f
+# change this to be a unique filename in the top level dir
+FILE=autogen.sh
+
+DIE=0
+
+LIBTOOLIZE=libtoolize
+ACLOCAL=aclocal
+AUTOHEADER=autoheader
+AUTOMAKE=automake
+AUTOCONF=autoconf
+
+#($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
+#        echo
+#        echo "You must have $LIBTOOlIZE installed to compile $PROJECT."
+#        echo "Download the appropriate package for your distribution,"
+#        echo "or get the source tarball at http://ftp.gnu.org/gnu/libtool/"
+#        DIE=1
+#}
+
+($ACLOCAL --version) < /dev/null > /dev/null 2>&1 || {
+        echo
+        echo "You must have $ACLOCAL installed to compile $PROJECT."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/"
+        DIE=1
+}
+
+($AUTOHEADER --version) < /dev/null > /dev/null 2>&1 || {
+        echo
+        echo "You must have $AUTOHEADER installed to compile $PROJECT."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/"
+        DIE=1
+}
+
+($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
+        echo
+        echo "You must have $AUTOMAKE installed to compile $PROJECT."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/"
+        DIE=1
+}
+
+($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || {
+        echo
+        echo "You must have $AUTOCONF installed to compile $PROJECT."
+        echo "Download the appropriate package for your distribution,"
+        echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/"
+        DIE=1
+}
+
+if test "$DIE" -eq 1; then
+        exit 1
+fi
+
+test $TEST_TYPE $FILE || {
+        echo "You must run this script in the top-level $PROJECT directory"
+        exit 1
+}
+
+if test -z "$*"; then
+        echo "I am going to run ./configure with no arguments - if you wish "
+        echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+#$LIBTOOLIZE --copy --force || echo "$LIBTOOlIZE failed"
+$ACLOCAL || echo "$ACLOCAL failed"
+$AUTOHEADER || echo "$AUTOHEADER failed"
+$AUTOMAKE --add-missing --force-missing --copy || echo "$AUTOMAKE failed"
+$AUTOCONF || echo "$AUTOCONF failed"
+
+cd $ORIGDIR
+
+run_configure=true
+for arg in $*; do
+    case $arg in
+        --no-configure)
+            run_configure=false
+            ;;
+        *)
+            ;;
+    esac
+done
+
+if $run_configure; then
+    $srcdir/configure --enable-maintainer-mode "$@"
+    echo
+    echo "Now type 'make' to compile $PROJECT."
+else
+    echo
+    echo "Now run 'configure' and 'make' to compile $PROJECT."
+fi
Index: /trunk/ppShutter/configure.ac
===================================================================
--- /trunk/ppShutter/configure.ac	(revision 8901)
+++ /trunk/ppShutter/configure.ac	(revision 8901)
@@ -0,0 +1,56 @@
+AC_PREREQ(2.59)
+
+AC_INIT([ppShutter], [0.0.1], [eugene@ifa.hawaii.edu])
+AC_CONFIG_SRCDIR([src])
+
+AM_INIT_AUTOMAKE([1.6 foreign dist-bzip2])
+AM_CONFIG_HEADER([src/config.h])
+AM_MAINTAINER_MODE
+
+AC_LANG(C)
+AC_GNU_SOURCE
+AC_PROG_CC
+AC_PROG_INSTALL
+dnl AC_PROG_LIBTOOL
+
+dnl enable largefile supports
+AC_SYS_LARGEFILE
+
+ppShutter_CFLAGS="-Wall -Werror -std=c99"
+ppShutter_LDFLAGS=""
+
+dnl handle debug building
+AC_ARG_ENABLE(optimize,
+  [AS_HELP_STRING(--enable-optimize,enable compiler optimization)],
+  [AC_MSG_RESULT(compile optimization enabled)
+   CFLAGS="${CFLAGS=} -O2"],
+  [AC_MSG_RESULT([compile optimization disabled])
+   CFLAGS="${CFLAGS=} -O0 -g"]
+)
+
+dnl handle path coverage checking
+AC_ARG_ENABLE(coverage,
+  [AS_HELP_STRING(--enable-coverage,enable path coverage checking)],
+  [AC_MSG_RESULT(path coverage enabled)
+   CFLAGS="${CFLAGS=} -fprofile-arcs -ftest-coverage -pg"]
+)
+
+PKG_CHECK_MODULES([PSLIB], [pslib >= 0.12.99]) 
+PKG_CHECK_MODULES([PSMODULE], [psmodules >= 0.12.99]) 
+
+dnl handle profiler building
+AC_ARG_ENABLE(profile,
+  [AS_HELP_STRING(--enable-profile,enable compiler profiler information inclusion)],
+  [AC_MSG_RESULT(compile optimization enabled)
+  ppShutter_CFLAGS="${ppShutter_CFLAGS} -g -pg"
+  ppShutter_LDFLAGS="${ppShutter_LDFLAGS} -pg -Wl,--start-group -Wl,-Bstatic"]
+  )
+  
+AC_SUBST([ppShutter_CFLAGS])
+AC_SUBST([ppShutter_LDFLAGS])
+
+AC_CONFIG_FILES([
+  Makefile
+  src/Makefile
+])
+AC_OUTPUT
Index: /trunk/ppShutter/src/.cvsignore
===================================================================
--- /trunk/ppShutter/src/.cvsignore	(revision 8901)
+++ /trunk/ppShutter/src/.cvsignore	(revision 8901)
@@ -0,0 +1,7 @@
+.deps
+Makefile
+Makefile.in
+ppMerge
+config.h
+config.h.in
+stamp-h1
Index: /trunk/ppShutter/src/Makefile.am
===================================================================
--- /trunk/ppShutter/src/Makefile.am	(revision 8901)
+++ /trunk/ppShutter/src/Makefile.am	(revision 8901)
@@ -0,0 +1,19 @@
+bin_PROGRAMS = ppShutter
+
+ppShutter_CFLAGS += $(PPSTATS_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
+ppShutter_LDFLAGS += $(PPSTATS_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) -Wl,-Bdynamic
+
+ppShutter_SOURCES =		\
+	ppShutter.c		
+
+#noinst_HEADERS =		\
+#	ppShutter.h
+
+CLEANFILES = *~
+
+clean-local:
+	-rm -f TAGS
+
+# Tags for emacs
+tags:
+	etags `find . -name \*.[ch] -print`
Index: /trunk/ppShutter/src/ppShutter.c
===================================================================
--- /trunk/ppShutter/src/ppShutter.c	(revision 8901)
+++ /trunk/ppShutter/src/ppShutter.c	(revision 8901)
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+
+void usage () {
+
+    fprintf (stderr, "USAGE: ppShutter (output) (input) (input) (input) ...\n");
+    fprintf (stderr, " minimum number of input images: 5\n");
+    exit (1);
+}
+
+// simple test: ppShutter (output) (input) (input) (input) ...
+int main(int argc, char **argv)
+{
+
+    psFits *fits;
+    psRegion fullimage = {0, 0, 0, 0};
+    psRegion region;
+
+    // minimum number of input images: 5
+    if (argc < 7) usage ();
+
+    int Ninput = argc - 2;
+
+    // load the input images (for now, load them all into memory)
+    psArray *files   = psArrayAlloc (Ninput);
+    psArray *headers = psArrayAlloc (Ninput);
+    psArray *images  = psArrayAlloc (Ninput);
+    for (int i = 0; i < Ninput; i++) {
+	fits = psFitsOpen (argv[i-2], "r");
+	files->data[i] = fits;
+
+	psMetadata *header = psFitsReadHeader (NULL, fits);
+	headers->data[i] = header;
+
+	psImage *image = psFitsReadImage (fits, fullimage, 0);
+	images->data[i] = image;
+    }
+
+    // find the exposures times for each input images
+    // need to resort the array based on the exposure times
+    psVector *exptime = psVectorAlloc (Ninput, PS_TYPE_F32);
+    psVector *fluxRef = psVectorAlloc (Ninput, PS_TYPE_F32);
+    psVector *normCts = psVectorAlloc (Ninput, PS_TYPE_F32);
+    for (int i = 0; i < Ninput; i++) {
+	exptime->data.F32[i] = psMetadataLookupF32 (NULL, headers->data[i], "EXPTIME");
+    }
+    psVector *index = psVectorSortIndex (NULL, exptime);
+
+    // use the first image as a coord reference
+    psImage *refimage = images->data[0];
+
+    // statistics used to measure initial parameters
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    // define the reference region
+    region = psRegionForSquare(0.5*refimage->numCols, 0.5*refimage->numRows, 10);
+
+    // first, measure the reference region statistic from each image
+    for (int i = 0; i < Ninput; i++) {
+	psImage *image = images->data[index->data.S32[i]];
+	myStats = psImageStats(myStats, image, NULL, 0);
+	fluxRef->data.F32[i] = myStats->sampleMean;
+    }	
+
+    // define the sample regions
+    int Nsamples = 4;
+    psArray *samples = psArrayAlloc (Nsamples);
+    for (int i = 0; i < 4; i++) {
+	psPlane *coord = psPlaneAlloc ();
+	coord->x = (i % 2) ? 10 : refimage->numCols - 10;
+	coord->y = (i > 1) ? 10 : refimage->numRows - 10;
+	samples->data[i] = coord;
+    }
+
+    // use several regions to make a measurement of dTo 
+    psVector *refOffsetSample = psVectorAlloc (Nsamples, PS_TYPE_F32);
+    for (int j = 0; j < Nsamples; j++) {
+	psPlane *coord = samples->data[j];
+
+	for (int i = 0; i < Ninput; i++) {
+	    psImage *image = images->data[index->data.S32[i]];
+
+	    region = psRegionForSquare(coord->x, coord->y, 10);
+	    region = psRegionForImage(image, region);
+
+	    myStats = psImageStats(myStats, image, NULL, 0);
+	    normCts->data.F32[i] = myStats->sampleMean / fluxRef->data.F32[i];
+	}	
+	
+	pmShutterCorrPars *guess = pmShutterCorrectionGuess (exptime, normCts);
+	pmShutterCorrPars *params = pmShutterCorrectionFullFit (exptime, normCts, guess);
+
+	refOffsetSample->data.F32[j] = params->offref;
+    }
+    myStats = psVectorStats (myStats, refOffsetSample, NULL, NULL, 0);
+    float refOffset = myStats->sampleMean;
+
+    // now run through all pixels in the images and measure the shutter parameters for each pixel
+    psImage *pattern = psImageAlloc (refimage->numCols, refimage->numRows, PS_TYPE_F32);
+    psImage *offset = psImageAlloc (refimage->numCols, refimage->numRows, PS_TYPE_F32);
+
+    for (int ny = 0; ny < refimage->numRows; ny++) {
+	for (int nx = 0; nx < refimage->numCols; nx++) {
+	    for (int i = 0; i < Ninput; i++) {
+		psImage *image = images->data[index->data.S32[i]];
+		normCts->data.F32[i] = image->data.F32[ny][nx] / fluxRef->data.F32[i];
+	    }
+	    pmShutterCorrPars *params = pmShutterCorrectionLinFit (exptime, normCts, refOffset);
+	    pattern->data.F32[ny][nx] = params->scale;
+	    offset->data.F32[ny][nx] = params->offset;
+	}
+    }
+
+    // save the resulting offset image
+    fits = psFitsOpen (argv[1], "w");
+    psFitsWriteImage (fits, NULL, offset, 0, NULL);
+    psFitsClose (fits);
+
+    // save the resulting illumination pattern image
+    fits = psFitsOpen (argv[2], "w");
+    psFitsWriteImage (fits, NULL, pattern, 0, NULL);
+    psFitsClose (fits);
+
+    exit (0);
+}
