Index: trunk/ppMops/Makefile.am
===================================================================
--- trunk/ppMops/Makefile.am	(revision 24241)
+++ trunk/ppMops/Makefile.am	(revision 24241)
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES = *.pyc *~ core core.*
Index: trunk/ppMops/autogen.sh
===================================================================
--- trunk/ppMops/autogen.sh	(revision 24241)
+++ trunk/ppMops/autogen.sh	(revision 24241)
@@ -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=ppMops
+TEST_TYPE=-f
+# change this to be a unique filename in the top level dir
+FILE=autogen.sh
+
+DIE=0
+
+LIBTOOLIZE=libtoolize
+ACLOCAL="aclocal $ACLOCAL_FLAGS"
+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/ppMops/configure.ac
===================================================================
--- trunk/ppMops/configure.ac	(revision 24241)
+++ trunk/ppMops/configure.ac	(revision 24241)
@@ -0,0 +1,41 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.61)
+
+AC_INIT([ppMops], [0.1.1], [ipp-support@ifa.hawaii.edu])
+AC_CONFIG_SRCDIR([src])
+
+AM_INIT_AUTOMAKE([1.6 foreign dist-bzip2])
+AM_CONFIG_HEADER([src/config.h])
+AM_MAINTAINER_MODE
+
+IPP_STDCFLAGS
+
+AC_LANG(C)
+AC_GNU_SOURCE
+AC_PROG_CC_C99
+AC_PROG_INSTALL
+AC_PROG_LIBTOOL
+AC_SYS_LARGEFILE
+
+PKG_CHECK_MODULES([PSLIB], [pslib >= 1.0.0])
+
+AC_PATH_PROG([ERRORCODES], [psParseErrorCodes], [missing])
+if test "$ERRORCODES" = "missing" ; then
+  AC_MSG_ERROR([psParseErrorCodes is required])
+fi
+
+dnl Set CFLAGS for build
+IPP_STDOPTS
+CFLAGS="${CFLAGS} -Wall -Werror"
+
+IPP_VERSION
+
+AC_SUBST([PPSUB_CFLAGS])
+AC_SUBST([PPSUB_LIBS])
+
+AC_CONFIG_FILES([
+  Makefile
+  src/Makefile
+])
+
+AC_OUTPUT
Index: trunk/ppMops/src/Makefile.am
===================================================================
--- trunk/ppMops/src/Makefile.am	(revision 24241)
+++ trunk/ppMops/src/Makefile.am	(revision 24241)
@@ -0,0 +1,41 @@
+bin_PROGRAMS = ppMops
+
+if HAVE_SVNVERSION
+PPMOPS_VERSION=`$(SVNVERSION) ..`
+else
+PPMOPS_VERSION="UNKNOWN"
+endif
+
+if HAVE_SVN
+PPMOPS_BRANCH=`$(SVN) info .. | $(SED) -n -e '/URL:/ h' -e '/Repository Root:/ { x; H; x; s|Repository Root: \(.*\)\nURL: \1\(.*\)|\2| ; s|^/|| ; s|/[a-zA-Z]*/src.*|| ; p }'`
+PPMOPS_SOURCE=`$(SVN) info | $(SED) -n -e 's/Repository UUID: // p'`
+else
+PPMOPS_BRANCH="UNKNOWN"
+PPMOPS_SOURCE="UNKNOWN"
+endif
+
+# Force recompilation of ppMopsVersion.c, since it gets the version information
+ppMopsVersion.c: ppMopsVersionDefinitions.h
+ppMopsVersionDefinitions.h: ppMopsVersionDefinitions.h.in FORCE
+	-$(RM) ppMopsVersionDefinitions.h
+	$(SED) -e "s|@PPMOPS_VERSION@|\"$(PPMOPS_VERSION)\"|" -e "s|@PPMOPS_BRANCH@|\"$(PPMOPS_BRANCH)\"|" -e "s|@PPMOPS_SOURCE@|\"$(PPMOPS_SOURCE)\"|" ppMopsVersionDefinitions.h.in > ppMopsVersionDefinitions.h
+FORCE: ;
+
+ppMops_CPPFLAGS = $(PSLIB_CFLAGS) $(PPMOPS_CFLAGS)
+ppMops_LDFLAGS  = $(PSLIB_LIBS)   $(PPMOPS_LIBS)
+
+ppMops_SOURCES =		\
+	ppMops.c		\
+	ppMopsVersion.c		\
+	ppMopsData.c			
+
+noinst_HEADERS = \
+	ppMops.h
+
+
+clean-local:
+	-rm -f TAGS
+
+# Tags for emacs
+tags:
+	etags `find . -name \*.[ch] -print`
Index: trunk/ppMops/src/ppMops.c
===================================================================
--- trunk/ppMops/src/ppMops.c	(revision 24241)
+++ trunk/ppMops/src/ppMops.c	(revision 24241)
@@ -0,0 +1,160 @@
+#include <stdio.h>
+#include <pslib.h>
+
+int main(int argc, char *argv[])
+{
+    if (argc != 4) {
+        fprintf(stderr, "Insufficient arguments.\n");
+        fprintf(stderr, "Usage: %s DETECTIONS ASTROMETRY OUTPUT\n", argv[0]);
+        exit(PS_EXIT_CONFIG_ERROR);
+    }
+
+    ppMopsData *data = ppMopsDataAlloc(); // Configuration data
+    data->detections = psStringCopy(argv[1]);
+    data->zp = atof(argv[2]);
+    data->output = psStringCopy(argv[3]);
+
+    psArray *detections = NULL;         // Detections
+    psMetadata *header = NULL;          // Header for detections
+    {
+        psFits *fits = psFitsOpen(data->detections, "r"); // FITS file
+        header = psFitsReadHeader(NULL, fits);
+        if (!header) {
+            psErrorStackPrint("Unable to read header");
+            psFitsClose(fits);
+            psFree(data);
+            exit(PS_EXIT_DATA_ERROR);
+        }
+        if (!psFitsMoveExtName(fits, IN_EXTNAME)) {
+            psErrorStackPrint("Unable to move to extension %s", IN_EXTNAME);
+            psFitsClose(fits);
+            psFree(header);
+            psFree(data);
+            exit(PS_EXIT_DATA_ERROR);
+        }
+        detections = psFitsReadTable(fits);
+        psFitsClose(fits);
+        if (!detections) {
+            psErrorStackPrint("Unable to read detections");
+            psFree(data);
+            psFree(header);
+            exit(PS_EXIT_DATA_ERROR);
+        }
+    }
+
+    // Translate the columns
+    int numRows = detections->n;        // Number of rows
+    psArray *output = psArrayAlloc(numRows); // Output table
+    double plateScale = 0.0;                 // Average plate scale
+    for (int i = 0; i < numRows; i++) {
+        psMetadata *inRow = detections->data[i]; // Input row
+        psMetadata *outRow = output->data[i] = psMetadataAlloc(); // Output row
+
+        double ra = psMetadataLookupF64(NULL, inRow, "RA_PSF");
+        double dec = psMetadataLookupF64(NULL, inRow, "DEC_PSF");
+        double mag = psMetadataLookupF64(NULL, inRow, "PSF_INST_MAG") + data->zp;
+        double magErr = psMetadataLookupF64(NULL, inRow, "PSF_INST_MAG_SIG");
+        double ext = psMetadataLookupF64(NULL, inRow, "EXT_NSIGMA");
+        double xErr = psMetadataLookupF64(NULL, inRow, "X_PSF_SIG");
+        double yErr = psMetadataLookupF64(NULL, inRow, "Y_PSF_SIG");
+        double scale = psMetadataLookupF64(NULL, inRow, "PLTSCALE");
+        double angle = psMetadataLookupF64(NULL, inRow, "POSANGLE");
+        psU32 flags = psMetadataLookupU32(NULL, inRow, "FLAGS");
+
+        plateScale += scale;
+
+        // XXX Not at all sure I've got the angles around the right way here...
+        double cosAngle = cos(angle), sinAngle = sin(angle);
+        double raErr = scale * sqrt(PS_SQR(cosAngle) * PS_SQR(xErr) + PS_SQR(sinAngle) * PS_SQR(yErr));
+        double decErr = scale * sqrt(PS_SQR(sinAngle) * PS_SQR(xErr) + PS_SQR(cosAngle) * PS_SQR(yErr));
+
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "RA_DEG", 0, "Right ascension (degrees)", ra);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "DEC_DEG", 0, "Declination (degrees)", dec);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "RA_SIG", 0, "Right ascension error (degrees)", raErr);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "DEC_SIG", 0, "Declination error (degrees)", decErr);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "MAG", 0, "Magnitude", mag);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "MAG_SIG", 0, "Magnitude error", magErr);
+        psMetadataAddU32(outRow, PS_LIST_TAIL, "FLAGS", 0, "Detection bit flags", flags);
+
+        // The below need fixing
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "STARPSF", 0, "EXT_NSIGMA", ext);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "ANG", 0, "Position angle of trail (degrees)", 0.0);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "ANG_SIG", 0, "Position angle error (degrees)", 0.0);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "LEN", 0, "Length of trail (arcsec)", 0.0);
+        psMetadataAddF64(outRow, PS_LIST_TAIL, "LEN_SIG", 0, "Length error (arcsec)", 0.0);
+    }
+    plateScale /= numRows;
+    psFree(detections);
+
+    // Translate the header
+    psMetadata *outHeader = psMetadataAlloc(); // Output header
+    {
+        double ra = psMetadataLookupF64(NULL, header, "FPA.RA");
+        double dec = psMetadataLookupF64(NULL, header, "FPA.DEC");
+        const char *filter = psMetadataLookupStr(NULL, header, "FPA.FILTER");
+        float exptime = psMetadataLookupF32(NULL, header, "EXPTIME");
+        double angle = psMetadataLookupF64(NULL, header, "FPA.POSANGLE");
+        double alt = psMetadataLookupF64(NULL, header, "FPA.ALT");
+        double az = psMetadataLookupF64(NULL, header, "FPA.AZ");
+        int imageid = psMetadataLookupS32(NULL, header, "IMAGEID");
+
+        float psf = plateScale * 0.5 * (psMetadataLookupF32(NULL, header, "FWHM_MAJ") +
+                                        psMetadataLookupF32(NULL, header, "FWHM_MIN"));
+
+        // XXX This is wrong
+        int fpaid = psMetadataLookupS32(NULL, header, "IMAGEID");
+
+
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "RA", 0, "Right ascension of boresight", ra);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "DEC", 0, "Declination of boresight", dec);
+        psMetadataAddStr(outHeader, PS_LIST_TAIL, "FILTER", 0, "Filter name", filter);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "EXPTIME", 0, "Exposure time (sec)", exptime);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "ROTANGLE", 0, "Rotator position angle", angle);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "TEL_ALT", 0, "Telescope altitude", alt);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "TEL_AZ", 0, "Telescope azimuth", az);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "DIFFIMID", 0, "Difference image identifier", imageid);
+        psMetadataAddF64(outHeader, PS_LIST_TAIL, "FPA_ID", 0, "Exposure identifier", fpaid);
+        psMetadataAddS32(outHeader, PS_LIST_TAIL, "OBSCODE", 0, "IAU Observatory code", OBSERVATORY_CODE);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "LIMITMAG", 0, "Limiting magnitude", LIMITING_MAG);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "STARPSF", 0, "Stellar PSF (arcsec)", psf);
+
+        // These are completely fake
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE1", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE2", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE3", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE4", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE5", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE6", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE7", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE8", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE9", 0, "Detection efficiency (FAKE)", 0.0);
+        psMetadataAddF32(outHeader, PS_LIST_TAIL, "DE10", 0, "Detection efficiency (FAKE)", 0.0);
+    }
+    psFree(header);
+
+    // Write the new table
+    {
+        psFits *fits = psFitsOpen(data->output, "w"); // FITS file
+        if (!fits) {
+            psErrorStackPrint(stderr, "Unable to open %s for writing", data->output);
+            psFree(outHeader);
+            psFree(output);
+            psFree(data);
+            exit(PS_EXIT_SYS_ERROR);
+        }
+        if (!psFitsWriteTable(fits, outHeader, output, OUT_EXTNAME)) {
+            psErrorStackPrint(stderr, "Unable to write table.");
+            psFree(outHeader);
+            psFree(output);
+            psFree(data);
+            exit(PS_EXIT_SYS_ERROR);
+        }
+        psFitsClose(fits);
+    }
+
+    psFree(outHeader);
+    psFree(output);
+    psFree(data);
+
+    return PS_EXIT_SUCCESS;
+}
Index: trunk/ppMops/src/ppMops.h
===================================================================
--- trunk/ppMops/src/ppMops.h	(revision 24241)
+++ trunk/ppMops/src/ppMops.h	(revision 24241)
@@ -0,0 +1,20 @@
+#ifndef PP_MOPS_H
+#define PP_MOPS_H
+
+#include <pslib.h>
+
+#define IN_EXTNAME "SkyChip.psf"                // Extension name for data in input
+#define OBSERVATORY_CODE 566                    // IAU Observatory Code
+#define OUT_EXTNAME "MOPS_TRANSIENT_DETECTIONS" // Extension name for data in output
+
+// Configuration data
+typedef struct {
+    psString detections;                // Detections filename
+    float zp;                           // Magnitude zero point
+    psString output;                    // Output filename
+} ppMopsData;
+
+// Allocator
+ppMopsData *ppMopsDataAlloc(void);
+
+
Index: trunk/ppMops/src/ppMopsData.c
===================================================================
--- trunk/ppMops/src/ppMopsData.c	(revision 24241)
+++ trunk/ppMops/src/ppMopsData.c	(revision 24241)
@@ -0,0 +1,30 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+
+#include "ppMops.h"
+
+static void mopsDataFree(ppMopsData *data)
+{
+    psFree(data->detections);
+    psFree(data->astrometry);
+    psFree(data->output);
+    return;
+}
+
+ppMopsData *ppMopsDataAlloc(void)
+{
+    ppMopsData *data = psAlloc(sizeof(ppMopsData)); // Data to return
+    psMemSetDeallocator(data, (psFreeFunc)mopsDataFree);
+
+    data->detections = NULL;
+    data->astrometry = NULL;
+    data->output = NULL;
+
+    return data;
+}
+
+
Index: trunk/ppMops/src/ppMopsVersionDefinitions.h.in
===================================================================
--- trunk/ppMops/src/ppMopsVersionDefinitions.h.in	(revision 24241)
+++ trunk/ppMops/src/ppMopsVersionDefinitions.h.in	(revision 24241)
@@ -0,0 +1,8 @@
+#ifndef PPSUB_VERSION_DEFINITIONS_H
+#define PPSUB_VERSION_DEFINITIONS_H
+
+#define PPSUB_VERSION @PPSUB_VERSION@ // SVN version
+#define PPSUB_BRANCH  @PPSUB_BRANCH@  // SVN branch
+#define PPSUB_SOURCE  @PPSUB_SOURCE@  // SVN source
+
+#endif
Index: trunk/ppMops/src/ppSubVersion.c
===================================================================
--- trunk/ppMops/src/ppSubVersion.c	(revision 24241)
+++ trunk/ppMops/src/ppSubVersion.c	(revision 24241)
@@ -0,0 +1,127 @@
+/** @file ppSubVersion.c
+ *
+ *  @brief
+ *
+ *  @ingroup ppSub
+ *
+ *  @author IfA
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-18 00:31:20 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <pslib.h>
+#include <psmodules.h>
+#include <ppStats.h>
+#include <psphot.h>
+
+#include "ppSub.h"
+#include "ppSubVersionDefinitions.h"
+
+#ifndef PPSUB_VERSION
+#error "PPSUB_VERSION is not set"
+#endif
+#ifndef PPSUB_BRANCH
+#error "PPSUB_BRANCH is not set"
+#endif
+#ifndef PPSUB_SOURCE
+#error "PPSUB_SOURCE is not set"
+#endif
+
+psString ppSubVersion(void)
+{
+    char *value = NULL;
+    psStringAppend(&value, "%s@%s", PPSUB_BRANCH, PPSUB_VERSION);
+    return value;
+}
+
+psString ppSubSource(void)
+{
+    return psStringCopy(PPSUB_SOURCE);
+}
+
+psString ppSubVersionLong(void)
+{
+    psString version = ppSubVersion();  // Version, to return
+    psString source = ppSubSource();    // Source
+
+    psStringPrepend(&version, "ppSub ");
+    psStringAppend(&version, " from %s, built %s, %s", source, __DATE__, __TIME__);
+    psFree(source);
+
+#ifdef __OPTIMIZE__
+    psStringAppend(&version, " optimised");
+#else
+    psStringAppend(&version, " unoptimised");
+#endif
+
+    return version;
+};
+
+
+bool ppSubVersionHeader(psMetadata *header)
+{
+    PS_ASSERT_METADATA_NON_NULL(header, false);
+
+    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now
+    psString timeString = psTimeToISO(time); // The time in an ISO string
+    psFree(time);
+    psString history = NULL;               // History string
+    psStringAppend(&history, "ppSub at %s", timeString);
+    psFree(timeString);
+    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history);
+    psFree(history);
+
+    psLibVersionHeader(header);
+    psModulesVersionHeader(header);
+    psphotVersionHeader(header);
+    ppStatsVersionHeader(header);
+
+    psString version = ppSubVersion(); // Software version
+    psString source  = ppSubSource();  // Software source
+
+    psStringPrepend(&version, "ppSub version: ");
+    psStringPrepend(&source, "ppSub source: ");
+
+    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, version);
+    psMetadataAddStr(header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, source);
+
+    psFree(version);
+    psFree(source);
+
+    return true;
+}
+
+void ppSubVersionPrint(void)
+{
+    psTime *time = psTimeGetNow(PS_TIME_TAI); // The time now
+    psString timeString = psTimeToISO(time); // The time in an ISO string
+    psFree(time);
+    psLogMsg("ppSub", PS_LOG_INFO, "ppSub at %s", timeString);
+    psFree(timeString);
+
+    psString pslib = psLibVersionLong();// psLib version
+    psString psmodules = psModulesVersionLong(); // psModules version
+    psString psphot = psphotVersionLong(); // psphot version
+    psString ppStats = ppStatsVersionLong(); // ppStats version
+    psString ppSub = ppSubVersionLong(); // ppSub version
+
+    psLogMsg("ppSub", PS_LOG_INFO, "%s", pslib);
+    psLogMsg("ppSub", PS_LOG_INFO, "%s", psmodules);
+    psLogMsg("ppSub", PS_LOG_INFO, "%s", psphot);
+    psLogMsg("ppSub", PS_LOG_INFO, "%s", ppStats);
+    psLogMsg("ppSub", PS_LOG_INFO, "%s", ppSub);
+
+    psFree(pslib);
+    psFree(psmodules);
+    psFree(psphot);
+    psFree(ppStats);
+    psFree(ppSub);
+
+    return;
+}
