Index: trunk/ippTools/src/laptool.c
===================================================================
--- trunk/ippTools/src/laptool.c	(revision 31827)
+++ 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)
