Index: trunk/ippTools/src/laptool.c
===================================================================
--- trunk/ippTools/src/laptool.c	(revision 32421)
+++ trunk/ippTools/src/laptool.c	(revision 32422)
@@ -30,4 +30,6 @@
 static bool updateexpMode(pxConfig *config);
 
+static bool diffcheckMode(pxConfig *config);
+
 static bool inactiveexpMode(pxConfig *config);
 
@@ -62,4 +64,6 @@
     MODECASE(LAPTOOL_MODE_UPDATEEXP,     updateexpMode);
 
+    MODECASE(LAPTOOL_MODE_DIFFCHECK,     diffcheckMode);
+    
     MODECASE(LAPTOOL_MODE_INACTIVEEXP,   inactiveexpMode);
   default:
@@ -276,4 +280,7 @@
   PXOPT_COPY_STR(config->args, where, "-filter", "rawExp.filter", "==");
 
+  psMetadata *chipWhere = psMetadataAlloc();
+  PXOPT_COPY_S64(config->args, chipWhere, "-seq_id", "lapRun.seq_id", "==");
+  
   // This seems unnecessarily clunky.
   if (!all_obsmode) {
@@ -296,8 +303,13 @@
   }
 
+  psString chipWhereClause = psDBGenerateWhereConditionSQL(chipWhere,NULL);
   if (whereClause) {
     psStringSubstitute(&query,whereClause,"@WHERE@");
   }
+  if (chipWhereClause) {
+    psStringSubstitute(&query,chipWhereClause,"@CHIPWHERE@");
+  }
   psFree(where);
+  psFree(chipWhere);
 
   // Fetch exposures
@@ -755,6 +767,68 @@
 }
 
-
-    
+static bool diffcheckMode(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, "-lap_id", "lapRun.lap_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-exp_id",  "exp_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-chip_id", "chip_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-warp_id", "warp_id", "==");
+  PXOPT_COPY_S64(config->args, where, "-seq_id",  "seq_id", "==");
+  PXOPT_COPY_STR(config->args, where, "-skycell_id", "skycell_id", "==");
+
+  psString query = pxDataGet("laptool_WSdiff_check.sql");
+  if (!query) {
+    psError(PXTOOLS_ERR_SYS, false, "failed to retrieve SQL statement");
+    return(false);
+  }
+  
+  if (psListLength(where->list)) {
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringPrepend(&whereClause, "\n AND ");
+    psStringSubstitute(&query,whereClause,"@WHERE@");
+    psFree(whereClause);
+  }
+
+  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) {
+    psErrorCode err = psErrorCodeLast();
+    switch (err) {
+    case PS_ERR_DB_CLIENT:
+      psError(PXTOOLS_ERR_SYS, false, "database error");
+    case PS_ERR_DB_SERVER:
+      psError(PXTOOLS_ERR_PROG, false, "database error");
+    default:
+      psError(PXTOOLS_ERR_PROG, false, "unknown error %d",err);
+    }
+
+    return false;
+  }
+  if (!psArrayLength(output)) {
+    psTrace("laptool", PS_LOG_INFO, "no rows found");
+    psFree(output);
+    return true;
+  }
+
+  if (psArrayLength(output)) {
+    if (!ippdbPrintMetadatas(stdout, output, "lapRunWarpStackSkycells", !simple)) {
+      psError(PS_ERR_UNKNOWN, false, "failed to print array");
+      psFree(output);
+      return false;
+    }
+  }
+
+  psFree(output);
+  return(true);
+}    
 
 static bool inactiveexpMode(pxConfig *config)
Index: trunk/ippTools/src/laptool.h
===================================================================
--- trunk/ippTools/src/laptool.h	(revision 32421)
+++ trunk/ippTools/src/laptool.h	(revision 32422)
@@ -19,4 +19,5 @@
   LAPTOOL_MODE_STACKS,
   LAPTOOL_MODE_UPDATEEXP,
+  LAPTOOL_MODE_DIFFCHECK,
   LAPTOOL_MODE_INACTIVEEXP
 } laptoolMode;
Index: trunk/ippTools/src/laptoolConfig.c
===================================================================
--- trunk/ippTools/src/laptoolConfig.c	(revision 32421)
+++ trunk/ippTools/src/laptoolConfig.c	(revision 32422)
@@ -132,4 +132,14 @@
   ADD_OPT(Bool,updateexpArgs, "-inactive",                    "set this exposure to active", 0);
 
+  // -diffcheck
+  psMetadata *diffcheckArgs = psMetadataAlloc();
+  ADD_OPT(S64, diffcheckArgs, "-lap_id",                      "search by lap run ID", 0);
+  ADD_OPT(S64, diffcheckArgs, "-exp_id",                      "search by exposure ID", 0);
+  ADD_OPT(S64, diffcheckArgs, "-chip_id",                     "search by chip ID", 0);
+  ADD_OPT(S64, diffcheckArgs, "-warp_id",                     "search by warp ID", 0);
+  ADD_OPT(S64, diffcheckArgs, "-seq_id",                      "search by lap sequence ID", 0);
+  ADD_OPT(Str, diffcheckArgs, "-skycell_id",                  "search by skycell ID", 0);
+  ADD_OPT(Bool, diffcheckArgs, "-simple",                     "use simple output format", 0);
+  
   // -inactiveexp
   psMetadata *inactiveexpArgs = psMetadataAlloc();
@@ -152,4 +162,5 @@
   PXOPT_ADD_MODE("-stacks",                  "", LAPTOOL_MODE_STACKS,           stacksArgs);
   PXOPT_ADD_MODE("-updateexp",               "", LAPTOOL_MODE_UPDATEEXP,        updateexpArgs);
+  PXOPT_ADD_MODE("-diffcheck",               "", LAPTOOL_MODE_DIFFCHECK,        diffcheckArgs);
   PXOPT_ADD_MODE("-inactiveexp",             "", LAPTOOL_MODE_INACTIVEEXP,      inactiveexpArgs);
   
