Index: /branches/czw_branch/20110406/ippTools/src/laptool.c
===================================================================
--- /branches/czw_branch/20110406/ippTools/src/laptool.c	(revision 31338)
+++ /branches/czw_branch/20110406/ippTools/src/laptool.c	(revision 31338)
@@ -0,0 +1,563 @@
+/*
+ * reproctool.c
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "pxtools.h"
+#include "pxdata.h"
+#include "reproctool.h"
+
+
+// Run level
+static bool definerunMode(pxConfig *config);
+static bool pendingrunMode(pxConfig *config);
+static bool updaterunMode(pxConfig *config);
+// Exposure level
+static bool pendingchipexpMode(pxConfig *config);
+static bool pendingquickstackMode(pxConfig *config);
+static bool pendingdiffMode(pxConfig *config);
+static bool pendingfinalstackMode(pxConfig *config);
+static bool updateexpMode(pxConfig *config);
+
+# define MODECASE(caseName, func) \
+  case caseName: \
+  if (!func(config)) { \
+  goto FAIL; \
+  } \
+  break;
+
+int main(int argc, char **argv)
+{
+  psLibInit(NULL);
+
+  pxConfig *config = reproctoolConfig(NULL, argc, argv);
+  if (!config) {
+    psError(PXTOOLS_ERR_CONFIG, false, "failed to configure");
+    goto FAIL;
+  }
+
+  switch (config->mode) {
+    MODECASE(REPROCTOOL_MODE_DEFINERUN,     definerunMode);
+    MODECASE(REPROCTOOL_MODE_PENDINGRUN,    pendingrunMode);
+    MODECASE(REPROCTOOL_MODE_UPDATERUN,     updaterunMode);
+
+    MODECASE(REPROCTOOL_MODE_PENDINGCHIPEXP,   pendingchipexpMode);
+    MODECASE(REPROCTOOL_MODE_PENDINGQUICKSTACK,pendingquickstackMode);
+    MODECASE(REPROCTOOL_MODE_PENDINGDIFF,      pendingdiffMode);
+    MODECASE(REPROCTOOL_MODE_PENDINGFINALSTACK,pendingfinalstackMode);
+    MODECASE(REPROCTOOL_MODE_UPDATEEXP,        updateexpMode);
+  default:
+    psAbort("invalid option (this should not happen)");
+  }
+  psTrace("reproctool", 9, "Attempting to free config\n");
+  psFree(config);
+  pmConfigDone();
+  psLibFinalize();
+  exit(EXIT_SUCCESS);
+
+ FAIL:
+  psErrorStackPrint(stderr, "\n");
+  int exit_status = pxerrorGetExitStatus();
+
+  psFree(config);
+  pmConfigDone();
+  psLibFinalize();
+
+  exit(exit_status);
+}
+
+// Run level
+static bool definerunMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  PXOPT_LOOKUP_STR(projection_cell, config->args, "-projection_cell", true, false);
+  PXOPT_LOOKUP_STR(tess_id,         config->args, "-tess_id",         true, false);
+  PXOPT_LOOKUP_F64(ra,              config->args, "-ra",              true, false);
+  PXOPT_LOOKUP_F64(decl,            config->args, "-decl",            true, false);
+  PXOPT_LOOKUP_F32(radius,          config->args, "-radius",          true, false);
+
+  // Insert the run
+  if (!reprocRunInsert(config->dbh,
+		       NULL,  // re_id
+		       projection_cell,
+		       tess_id,
+		       ra,
+		       decl,
+		       radius,
+		       NULL,  // registered
+		       "new", // state
+		       0      // fault
+		       )) {
+    // rollback
+    if (!psDBRollback(config->dbh)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+    }
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    
+    return false;
+  }
+  psS64 re_id = psDBLastInsertID(config->dbh);
+
+
+  // Find the input exposures
+  psString query = pxDataGet("reproctool_definerun.sql");
+  if (!query) {
+    psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  psString where = NULL;
+  if (!pxspaceAddWhere(config, &where, "rawExp")) {
+    psError(psErrorCodeLast(), false, "pxSpaceAddWhere failed");
+    return(false);
+  }
+  psStringAppend(&query, " %s", where);
+  psFree(where);
+
+  if (!p_psDBRunQuery(config->dbh, query)) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    psFree(query);
+    return(false);
+  }
+  psFree(query);
+
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  if (!psArrayLength(output)) {
+    psTrace("reproctool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return(true);
+  }
+
+
+  // Insert the exposure data
+  for (long i = 0; i < output->n; i++) {
+    psMetadata *row = output->data[i]; // Row from select
+    bool status;
+    reprocExpRow *reExp = reprocExpObjectFromMetadata(row);
+    reExp->re_id = re_id;
+
+    if (!reprocExpInsertObject(config->dbh,reExp)) {
+      if (!psDBRollback(config->dbh)) {
+	psError(PS_ERR_UNKNOWN, false, "database error");
+      }
+      psError(PS_ERR_UNKNOWN, false, "database error");
+      psFree(output);
+      psFree(reExp);
+      return(false);
+    }
+  }
+
+  psFree(output);
+  return(true);  
+}
+
+static bool pendingrunMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+  psmetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-projection_cell", "projection_cell", "==");
+
+  psString query = pxDataGet("reproctool_pendingrun.sql");
+  if (!query) {
+    psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+  if (whereClause) {
+    psStringPrepend(&whereClause, "\n AND ");
+  }
+  
+  psString limitString = NULL;
+  if (limit) {
+    limitString = psDBGenerateLimitSQL(limit);
+    psStringPrepend(&limitString, "\n");
+  }
+
+  if (!p_psDBRunQueryF(config->dbh, query, whereClause, limitString ? limitString : "")) {
+    psError(PXTOOLS_ERR_PROG, false, "database error");
+    psFree(limitString);
+    psFree(query);
+    psFree(whereClause);
+    return(false);
+  }
+  psFree(limitString);
+  psFree(query);
+  psFree(whereClause);
+  
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  if (!psArrayLength(output)) {
+    psTrace("reproctool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return(true);
+  }
+  
+  if (!ippdbPrintMetadatas(stdout, output, "reprocExp", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(output);
+    return(false);
+  }
+
+  psFree(output);
+  return(true);
+  
+}
+static bool updaterunMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  psMetadata *where = psMetadataAlloc();
+  PXOPT_LOOKUP_S64(re_id, config->args, "-re_id", true, false);
+  PXOPT_LOOKUP_S16(fault, config->args, "-fault", false, false);
+  PXOPT_LOOKUP_STR(set_state, config->args, "-set_state", false, false);
+
+  if ((fault == INT16_MAX)&&(!set_state)) {
+    psError(PS_ERR_UNKNOWN, false, "one of -fault or -set_state must be selected");
+    return(false);
+  }
+
+  psMetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+
+  // Set a fault
+  if (fault != INT16_MAX) {
+    // this is fairly dangerous : can set all if the where is not set...
+    if (!pxSetFaultCode(config->dbh, "reprocRun", where, fault, 0)) {
+      psError(PS_ERR_UNKNOWN, false, "failed to set set fault flag");
+      psFree (where);
+      return false;
+    }
+    psFree (where);
+    return(true);
+  }
+
+  // Set the state, and deactivate the exposures if needed.
+
+  if ((strcmp(set_state,"drop") == 0)||
+      (strcmp(set_state,"full") == 0)) {
+    // Deactivate exposures
+
+    psString query = pxDataGet("reproctool_updaterun_deactivate.sql");
+    if (!query) {
+      psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+      return(false);
+    }
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, whereClause, " \n ");
+    if (!p_psDBRunQuery(config->dbh, query)) {
+      psError(PS_ERR_UNKNOWN, false, "database error");
+      psFree(query);
+      return(false);
+    }
+    psFree(query);
+  }
+
+  char *query = "UPDATE reprocRun SET state = '%s' WHERE re_id = %"PRId64;
+  if (!p_psDBRunQueryF(config->dbh, query, state, re_id)) {
+    psError(PS_ERR_UNKNOWN, false,
+	    "failed to change state for re_id %"PRId64, re_id);
+    return(false);
+  }
+
+  return(true);  
+}
+// Exposure level
+static bool pendingchipexpMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+  psmetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-filter", "filter", "==");
+
+  psString query = pxDataGet("reproctool_pendingchipexp.sql");
+  if (!query) {
+    psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+  if (whereClause) {
+    psStringPrepend(&whereClause, "\n AND ");
+  }
+  
+  psString limitString = NULL;
+  if (limit) {
+    limitString = psDBGenerateLimitSQL(limit);
+    psStringPrepend(&limitString, "\n");
+  }
+
+  if (!p_psDBRunQueryF(config->dbh, query, whereClause, limitString ? limitString : "")) {
+    psError(PXTOOLS_ERR_PROG, false, "database error");
+    psFree(limitString);
+    psFree(query);
+    psFree(whereClause);
+    return(false);
+  }
+  psFree(limitString);
+  psFree(query);
+  psFree(whereClause);
+  
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  if (!psArrayLength(output)) {
+    psTrace("reproctool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return(true);
+  }
+  
+  if (!ippdbPrintMetadatas(stdout, output, "reprocExp", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(output);
+    return(false);
+  }
+
+  psFree(output);
+  return(true);
+  
+
+}
+static bool pendingquickstackMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+  psmetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-filter", "filter", "==");
+
+  psString query = pxDataGet("reproctool_pendingquickstack.sql");
+  if (!query) {
+    psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+  if (whereClause) {
+    psStringPrepend(&whereClause, "\n AND ");
+  }
+  
+  psString limitString = NULL;
+  if (limit) {
+    limitString = psDBGenerateLimitSQL(limit);
+    psStringPrepend(&limitString, "\n");
+  }
+
+  if (!p_psDBRunQueryF(config->dbh, query, whereClause, limitString ? limitString : "")) {
+    psError(PXTOOLS_ERR_PROG, false, "database error");
+    psFree(limitString);
+    psFree(query);
+    psFree(whereClause);
+    return(false);
+  }
+  psFree(limitString);
+  psFree(query);
+  psFree(whereClause);
+  
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  if (!psArrayLength(output)) {
+    psTrace("reproctool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return(true);
+  }
+  
+  if (!ippdbPrintMetadatas(stdout, output, "reprocExp", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(output);
+    return(false);
+  }
+
+  psFree(output);
+  return(true);
+  
+
+}
+static bool pendingdiffMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+  psmetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-filter", "filter", "==");
+
+  psString query = pxDataGet("reproctool_pendingdiff.sql");
+  if (!query) {
+    psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+  if (whereClause) {
+    psStringPrepend(&whereClause, "\n AND ");
+  }
+  
+  psString limitString = NULL;
+  if (limit) {
+    limitString = psDBGenerateLimitSQL(limit);
+    psStringPrepend(&limitString, "\n");
+  }
+
+  if (!p_psDBRunQueryF(config->dbh, query, whereClause, limitString ? limitString : "")) {
+    psError(PXTOOLS_ERR_PROG, false, "database error");
+    psFree(limitString);
+    psFree(query);
+    psFree(whereClause);
+    return(false);
+  }
+  psFree(limitString);
+  psFree(query);
+  psFree(whereClause);
+  
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  if (!psArrayLength(output)) {
+    psTrace("reproctool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return(true);
+  }
+  
+  if (!ippdbPrintMetadatas(stdout, output, "reprocExp", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(output);
+    return(false);
+  }
+
+  psFree(output);
+  return(true);
+  
+
+}
+static bool pendingfinalstackMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+  
+  psmetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-filter", "filter", "==");
+
+  psString query = pxDataGet("reproctool_pendingfinalstack.sql");
+  if (!query) {
+    psError(PXTOOL_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+  if (whereClause) {
+    psStringPrepend(&whereClause, "\n AND ");
+  }
+  
+  psString limitString = NULL;
+  if (limit) {
+    limitString = psDBGenerateLimitSQL(limit);
+    psStringPrepend(&limitString, "\n");
+  }
+
+  if (!p_psDBRunQueryF(config->dbh, query, whereClause, limitString ? limitString : "")) {
+    psError(PXTOOLS_ERR_PROG, false, "database error");
+    psFree(limitString);
+    psFree(query);
+    psFree(whereClause);
+    return(false);
+  }
+  psFree(limitString);
+  psFree(query);
+  psFree(whereClause);
+  
+  psArray *output = p_psDBFetchResult(config->dbh);
+  if (!output) {
+    psError(PS_ERR_UNKNOWN, false, "database error");
+    return(false);
+  }
+  if (!psArrayLength(output)) {
+    psTrace("reproctool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return(true);
+  }
+  
+  if (!ippdbPrintMetadatas(stdout, output, "reprocExp", !simple)) {
+    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+    psFree(output);
+    return(false);
+  }
+
+  psFree(output);
+  return(true);
+  
+
+}
+static bool updateexpMode(pxConfig *config)
+{
+  PS_ASSERT_PTR_NON_NULL(config, false);
+
+  psMetadata *where = psMetadataAlloc();
+  PXOPT_LOOKUP_S64(re_id, config->args, "-re_id", true, false);
+  PXOPT_LOOKUP_S64(exp_id, config->args, "-exp_id", true, false);
+  PXOPT_LOOKUP_S64(chip_id, config->args, "-chip_id", false, false);
+
+  PXOPT_LOOKUP_S64(set_chip_id, config->args, "-set_chip_id", false, false);
+  PXOPT_LOOKUP_BOOL(private, config->args, "-private", false, false);
+  PXOPT_LOOKUP_BOOL(active,  config->args, "-active", false, false);
+  PXOPT_LOOKUP_BOOL(inactive, config->args, "-inactive", false, false);
+
+  if (active == inactive) {
+    psError(PS_ERR_UNKNOWN, false, "only one of -active and -inactive may be selected");
+  }
+
+  psMetadata *where = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, where, "-re_id", "re_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-exp_id", "exp_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-chip_id", "chip_id", "==");
+
+  psMetadata *values = psMetadataAlloc();
+  if (set_chip_id) {
+    PXOPT_COPY_S64(config->args, values, "-set_chip_id", "chip_id", "==");
+  }
+  if (private) {
+    PXOPT_COPY_BOOL(config->args, values, "-private", "private", "==");
+  }
+  if (active) {
+    PXOPT_COPY_BOOL(config->args, values, "-active", "active", "==");
+  }
+  if (inactive) {
+    psMetadataAddBool(values, PS_LIST_TAIL, "active", 0, "", false);
+  }
+
+  long rows = psDBUpdateRows(config->dbh,"reprocExp",where,values);
+  if (rows) {
+    return(true);
+  }
+  else {
+    return(false);
+  }  
+}
+
+
+    
+	     
Index: /branches/czw_branch/20110406/ippTools/src/laptool.h
===================================================================
--- /branches/czw_branch/20110406/ippTools/src/laptool.h	(revision 31338)
+++ /branches/czw_branch/20110406/ippTools/src/laptool.h	(revision 31338)
@@ -0,0 +1,25 @@
+/*
+ * reproctool.h
+ */
+
+#ifndef REPROCTOOL_H
+#define REPROCTOOL_H 1
+
+#include "pxtools.h"
+
+typedef enum {
+  REPROCTOOL_MODE_DEFINERUN          = 0x0,
+  REPROCTOOL_MODE_PENDINGRUN,       
+  REPROCTOOL_MODE_PENDINGCHIPEXP,   
+  REPROCTOOL_MODE_PENDINGQUICKSTACK,
+  REPROCTOOL_MODE_PENDINGDIFF,      
+  REPROCTOOL_MODE_PENDINGFINALSTACK,
+  REPROCTOOL_MODE_UPDATERUN,        
+  REPROCTOOL_MODE_UPDATEEXP
+} reproctoolMode;
+
+pxConfig *reproctoolConfig(pxConfig *config, int argc, char **argv);
+
+#endif // REPROCTOOL_H
+
+
Index: /branches/czw_branch/20110406/ippTools/src/laptoolConfig.c
===================================================================
--- /branches/czw_branch/20110406/ippTools/src/laptoolConfig.c	(revision 31338)
+++ /branches/czw_branch/20110406/ippTools/src/laptoolConfig.c	(revision 31338)
@@ -0,0 +1,126 @@
+/*
+ * reproctoolConfig.c
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <stdint.h>
+
+#include <psmodules.h>
+#include "pxtools.h"
+#include "regtool.h"
+
+#define ADD_OPT(TYPE,TARG,NAME,COMMENT,DEFAULT) psMetadataAdd##TYPE(TARG, PS_LIST_TAIL, NAME, 0, COMMENT, DEFAULT)
+
+pxConfig *reproctoolConfig(pxConfig *config, int argc, char **argv)
+{
+  if (!config) {
+    config = pxConfigAlloc();
+  }
+
+  pmConfigReadParamsSet(false);
+
+  // setup site config
+  config->modules = pmConfigRead(&argc, argv, NULL);
+  if (!config->modules) {
+    psError(psErrorCodeLast(), false, "Can't find site configuration");
+    psFree(config);
+    return NULL;
+  }
+
+  // -definerun
+  psMetadata *definerunArgs = psMetadataAlloc();
+  ADD_OPT(Str, definerunArgs, "-projection_cell",             "define the projection cell for this run (required)", NULL);
+  ADD_OPT(Str, definerunArgs, "-tess_id",                     "define the tessellation used (required)", NULL);
+  ADD_OPT(F64, definerunArgs, "-ra",                          "define RA center (required)", NAN);
+  ADD_OPT(F64, definerunArgs, "-decl",                        "define DEC center (required)", NAN);
+  ADD_OPT(F32, definerunArgs, "-radius",                      "define radius from center to consider (required)", NAN);
+
+  // -pendingrun
+  psMetadata *pendingrunArgs = psMetadataAlloc();
+  ADD_OPT(Str, pendingrunArgs, "-projection_cell",            "projection cell to consider", NULL);
+  ADD_OPT(S64, pendingrunArgs, "-re_id",                      "reprocessing run ID", 0);
+  ADD_OPT(U64, pendingrunArgs, "-limit",                      "limit result set to N items", 0);
+  ADD_OPT(Bool,pendingrunArgs, "-simple",                     "use the simple output format", false);
+  
+  // -pendingchipexp
+  psMetadata *pendingchipexpArgs = psMetadataAlloc();
+  ADD_OPT(S64, pendingchipexpArgs, "-re_id",                  "search by reprocessing run ID", 0);
+  ADD_OPT(Str, pendingchipexpArgs, "-filter",                 "search by filter", 0);
+  ADD_OPT(Bool,pendingchipexpArgs, "-simple",                 "use the simple output format", false);
+  
+  // -pendingquickstack
+  psMetadata *pendingquickstackArgs = psMetadataAlloc();
+  ADD_OPT(S64, pendingquickstackArgs, "-re_id",               "search by reprocessing run ID", 0);
+  ADD_OPT(Str, pendingquickstackArgs, "-filter",              "search by filter", 0);
+  ADD_OPT(Bool,pendingquickstackArgs, "-simple",              "use the simple output format", false);
+  
+  // -pendingdiff
+  psMetadata *pendingdiffArgs = psMetadataAlloc();
+  ADD_OPT(S64, pendingdiffArgs, "-re_id",                    "search by reprocessing run ID", 0);
+  ADD_OPT(Str, pendingdiffArgs, "-filter",                   "search by filter", 0);
+  ADD_OPT(Bool,pendingdiffArgs, "-simple",                   "use the simple output format", false);
+  
+  // -pendingfinalstack
+  psMetadata *pendingfinalstackArgs = psMetadataAlloc();
+  ADD_OPT(S64, pendingfinalstackArgs, "-re_id",               "search by reprocessing run ID", 0);
+  ADD_OPT(Str, pendingfinalstackArgs, "-filter",              "search by filter", 0);
+  ADD_OPT(Bool,pendingfinalstackArgs, "-simple",              "use the simple output format", false);
+
+  // -updaterun
+  psMetadata *updaterunArgs = psMetadataAlloc();
+  ADD_OPT(S64, updaterunArgs, "-re_id",                       "search by reprocessing run ID", 0);
+  ADD_OPT(Str, updaterunArgs, "-set_state",                   "set state", NULL);
+  ADD_OPT(S16, updaterunArgs, "-fault",                       "set fault code", INT16_MAX);
+
+  // -updateexp
+  psMetadata *updateexpArgs = psMetadataAlloc();
+  ADD_OPT(S64, updateexpArgs, "-re_id",                       "search by reprocessing run ID", 0);
+  ADD_OPT(S64, updateexpArgs, "-exp_id",                      "search by exposure ID", 0);
+  ADD_OPT(S64, updateexpArgs, "-chip_id",                     "search by chip ID", 0);
+  ADD_OPT(S64, updateexpArgs, "-set_chip_id",                 "set the chip ID", 0);
+  ADD_OPT(Bool,updateexpArgs, "-private",                     "set this exposure as private", 0);
+  ADD_OPT(Bool,updateexpArgs, "-active",                      "set this exposure to active", 0);
+  ADD_OPT(Bool,updateexpArgs, "-inactive",                    "set this exposure to active", 0);
+
+
+  
+  psMetadata *argSets = psMetadataAlloc();
+  psMetadata *modes = psMetadataAlloc();
+
+  PXOPT_ADD_MODE("-definerun",               "", REPROCTOOL_MODE_DEFINERUN,        definerunArgs);
+  PXOPT_ADD_MODE("-pendingrun",              "", REPROCTOOL_MODE_PENDINGRUN,       pendingrunArgs);
+  PXOPT_ADD_MODE("-pendingchipexp",          "", REPROCTOOL_MODE_PENDINGCHIPEXP,   pendingchipexpArgs);
+  PXOPT_ADD_MODE("-pendingquickstack",       "", REPROCTOOL_MODE_PENDINGQUICKSTACK,pendingquickstackArgs);
+  PXOPT_ADD_MODE("-pendingdiff",             "", REPROCTOOL_MODE_PENDINGDIFF,      pendingdiffArgs);
+  PXOPT_ADD_MODE("-pendingfinalstack",       "", REPROCTOOL_MODE_PENDINGFINALSTACK,pendingfinalstackArgs);
+  PXOPT_ADD_MODE("-updaterun",               "", REPROCTOOL_MODE_UPDATERUN,        updaterunArgs);
+  PXOPT_ADD_MODE("-updateexp",               "", REPROCTOOL_MODE_UPDATEEXP,        updateexpArgs);
+
+  if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
+    psError(PS_ERR_UNKNOWN, true, "option parsing failed");
+    psFree(argSets);
+    psFree(modes);
+    psFree(config);
+    return NULL;
+  }
+
+  psFree(argSets);
+  psFree(modes);
+
+  // define Database handle, if used
+  config->dbh = psMemIncrRefCounter(pmConfigDB(config->modules));
+  if (!config->dbh) {
+    psError(PXTOOLS_ERR_SYS, false, "Can't configure database");
+    psFree(config);
+    return NULL;
+  }
+
+  return config;
+}
+
+
+  
