Index: branches/eam_branches/ipp-20100823/ippTools/src/difftool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/difftool.c	(revision 29232)
+++ branches/eam_branches/ipp-20100823/ippTools/src/difftool.c	(revision 29324)
@@ -1237,4 +1237,6 @@
     PXOPT_COPY_STR(config->args, stackWhere, "-stack_label", "stackRun.label", "==");
 
+    PXOPT_LOOKUP_BOOL(bothways, config->args, "-bothways", false);
+
     PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false); // required option
     PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false); // option
@@ -1498,6 +1500,6 @@
         // ok we've got one create the diffRun
         diffRunRow *run = diffRunRowAlloc(
-                0,          // ID
-                "reg",      // state
+                0,	      // ID
+                "reg",	      // state
                 workdir,
                 label,
@@ -1505,16 +1507,16 @@
                 dist_group,
                 reduction,
-                NULL,       // dvodb
+                NULL,	      // dvodb
                 registered,
                 tess_id,
-                false,                  // bothways
-                true,                   // exposure
-                0,       // magicked
-		NULL, // software version
-		0,    // mask stat npix
-		NAN,    // static
-		NAN,    // dynamic
-		NAN,    // magic
-		NAN,    // advisory
+                bothways,     // bothways (default is false)
+                true,	      // exposure
+                0,	      // magicked
+		NULL,	      // software version
+		0,	      // mask stat npix
+		NAN,	      // static
+		NAN,	      // dynamic
+		NAN,	      // magic
+		NAN,	      // advisory
                 IPP_DIFF_MODE_WARP_STACK,
                 note
@@ -1647,4 +1649,6 @@
     PXOPT_COPY_STR(config->args,   selectWhere, "-comment",            "inputRawExp.comment",        "LIKE");
 
+    PXOPT_LOOKUP_BOOL(not_bothways, config->args, "-not-bothways", false);
+
     // Haversine formula for great circle distance
     PXOPT_COPY_F32(config->args, selectWhere, "-distance",
@@ -1866,5 +1870,5 @@
                                           registered,
                                           tess_id,
-                                          true,  // bothways
+                                          !not_bothways,  // bothways (default is true, ie not_bothways is false)
                                           true,  // exposure
                                           false, // magicked
@@ -1949,307 +1953,318 @@
 
 static bool definestackstackMode(pxConfig *config) {
-  PS_ASSERT_PTR_NON_NULL(config, false);
-
-  psMetadata *stack1Where = psMetadataAlloc();
-  psMetadata *stack2Where = psMetadataAlloc();
-
-  PXOPT_COPY_STR(config->args, stack1Where, "-tess_id", "stackRun.tess_id", "==");
-  PXOPT_COPY_STR(config->args, stack2Where, "-tess_id", "stackRun.tess_id", "==");
-  PXOPT_COPY_STR(config->args, stack1Where, "-filter", "stackRun.filter", "==");
-  PXOPT_COPY_STR(config->args, stack2Where, "-filter", "stackRun.filter", "==");
-  PXOPT_COPY_STR(config->args, stack1Where, "-skycell_id", "stackRun.skycell_id", "==");
-  PXOPT_COPY_STR(config->args, stack2Where, "-skycell_id", "stackRun.skycell_id", "==");
-  PXOPT_COPY_STR(config->args, stack1Where, "-input_label", "stackRun.label","==");
-  PXOPT_COPY_STR(config->args, stack2Where, "-template_label", "stackRun.label","==");
-  PXOPT_COPY_F32(config->args, stack1Where, "-good_frac", "stackSumSkyfile.good_frac", ">=");
-  PXOPT_COPY_F32(config->args, stack2Where, "-good_frac", "stackSumSkyfile.good_frac", ">=");
-
-  PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false); // required option
-  PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false); // option
-  PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false); // option
-  PXOPT_LOOKUP_TIME(registered, config->args, "-set_registered", false, false);
-  PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
-  PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
-  PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
-
-  PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
-  PXOPT_LOOKUP_BOOL(reRun, config->args, "-rerun", false);
-  PXOPT_LOOKUP_BOOL(newTemplates,config->args,"-new-templates", false);
-
-  PXOPT_LOOKUP_BOOL(available, config->args, "-available", false);
-  PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
-
-  if (!(label)) {
-    PXOPT_LOOKUP_STR(label,config->args, "-input_label",true,false);
-  }
-
-  // Organize the config information into queries.
-  psString stack1Query = NULL;
-  psString stack2Query = NULL;
-
-  if (psListLength(stack1Where->list)) {
-    psString whereClause = psDBGenerateWhereConditionSQL(stack1Where, NULL);
-    psStringAppend(&stack1Query, "\n AND %s", whereClause);
-    psFree(whereClause);
-  } else {
-    stack1Query = psStringCopy("\n");
-  }
-  psFree(stack1Where);
-
-  if (psListLength(stack2Where->list)) {
-    psString whereClause = psDBGenerateWhereConditionSQL(stack2Where, NULL);
-    psStringAppend(&stack2Query, "\n AND %s", whereClause);
-    psFree(whereClause);
-  } else {
-    stack2Query = psStringCopy("\n");
-  }
-  psFree(stack2Where);
-
-  // don't queue for stacks that have already been diffed unless requested
-  psString diffQuery = NULL;
-  if (! (reRun || newTemplates) ) {
-    psStringAppend(&diffQuery, "\n AND diffExp.diff_id IS NULL");
-  } else {
-    diffQuery = psStringCopy("\n");
-  }
-
-  // find the distinct set of data_groups and filters
-  psString query = pxDataGet("difftool_definestackstack_part0.sql");
-  if (!query) {
-    psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
-    return(false);
-  }
-  psTrace("difftool",1,query,stack2Query,stack1Query,diffQuery,stack1Query);
-/*   exit(10); */
-
-  if (!psDBTransaction(config->dbh)) {
-    psError(PS_ERR_UNKNOWN, false, "database error");
-    return(false);
-  }
-
-  if (!p_psDBRunQueryF(config->dbh, query, stack2Query, stack1Query, diffQuery, stack1Query)) {
-    psError(PS_ERR_UNKNOWN, false, "database error");
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *stack1Where = psMetadataAlloc();
+    psMetadata *stack2Where = psMetadataAlloc();
+
+    PXOPT_COPY_STR(config->args, stack1Where, "-tess_id", "stackRun.tess_id", "==");
+    PXOPT_COPY_STR(config->args, stack2Where, "-tess_id", "stackRun.tess_id", "==");
+    PXOPT_COPY_STR(config->args, stack1Where, "-filter", "stackRun.filter", "==");
+    PXOPT_COPY_STR(config->args, stack2Where, "-filter", "stackRun.filter", "==");
+    PXOPT_COPY_STR(config->args, stack1Where, "-skycell_id", "stackRun.skycell_id", "==");
+    PXOPT_COPY_STR(config->args, stack2Where, "-skycell_id", "stackRun.skycell_id", "==");
+    PXOPT_COPY_STR(config->args, stack1Where, "-input_label", "stackRun.label","==");
+    PXOPT_COPY_STR(config->args, stack2Where, "-template_label", "stackRun.label","==");
+    PXOPT_COPY_F32(config->args, stack1Where, "-good_frac", "stackSumSkyfile.good_frac", ">=");
+    PXOPT_COPY_F32(config->args, stack2Where, "-good_frac", "stackSumSkyfile.good_frac", ">=");
+
+    PXOPT_LOOKUP_STR(workdir, config->args, "-set_workdir", true, false); // required option
+    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false); // option
+    PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false); // option
+    PXOPT_LOOKUP_TIME(registered, config->args, "-set_registered", false, false);
+    PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
+    PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
+    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
+
+    PXOPT_LOOKUP_BOOL(bothways, config->args, "-bothways", false);
+
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(reRun, config->args, "-rerun", false);
+    PXOPT_LOOKUP_BOOL(newTemplates,config->args,"-new-templates", false);
+
+    PXOPT_LOOKUP_BOOL(available, config->args, "-available", false);
+    PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
+
+    if (!(label)) {
+	PXOPT_LOOKUP_STR(label,config->args, "-input_label",true,false);
+    }
+
+    // Organize the config information into queries.
+    psString stack1Query = NULL;
+    psString stack2Query = NULL;
+
+    if (psListLength(stack1Where->list)) {
+	psString whereClause = psDBGenerateWhereConditionSQL(stack1Where, NULL);
+	psStringAppend(&stack1Query, "\n AND %s", whereClause);
+	psFree(whereClause);
+    } else {
+	stack1Query = psStringCopy("\n");
+    }
+    psFree(stack1Where);
+
+    if (psListLength(stack2Where->list)) {
+	psString whereClause = psDBGenerateWhereConditionSQL(stack2Where, NULL);
+	psStringAppend(&stack2Query, "\n AND %s", whereClause);
+	psFree(whereClause);
+    } else {
+	stack2Query = psStringCopy("\n");
+    }
+    psFree(stack2Where);
+
+  
+    // don't queue for stacks that have already been diffed unless requested
+    psString diffQuery0 = NULL;
+    psString diffQuery1 = NULL;
+    if (! (reRun || newTemplates) ) {
+	psStringAppend(&diffQuery0, "\n AND diffExp.diff_id IS NULL");
+	psStringAppend(&diffQuery1, "\n AND n_diff = 0");
+    } else {
+	diffQuery0 = psStringCopy("\n");
+	diffQuery1 = psStringCopy("\n");
+    }
+
+    // find the distinct set of data_groups and filters
+    psString query = pxDataGet("difftool_definestackstack_part0.sql");
+    if (!query) {
+	psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+	return(false);
+    }
+    psTrace("difftool",1,query,stack2Query,stack1Query,diffQuery0,stack1Query);
+
+    if (!psDBTransaction(config->dbh)) {
+	psError(PS_ERR_UNKNOWN, false, "database error");
+	return(false);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, stack2Query, stack1Query, diffQuery0, stack1Query)) {
+	psError(PS_ERR_UNKNOWN, false, "database error");
+	psFree(query);
+	if (!psDBRollback(config->dbh)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	}
+	return false;
+    }
+
     psFree(query);
-    if (!psDBRollback(config->dbh)) {
-      psError(PS_ERR_UNKNOWN, false, "database error");
-    }
-    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");
-      break;
-    case PS_ERR_DB_SERVER:
-      psError(PXTOOLS_ERR_PROG, false, "database error");
-      break;
-    default:
-      psError(PXTOOLS_ERR_PROG, false, "unknown error");
-      break;
-    }
-    if (!psDBRollback(config->dbh)) {
-      psError(PS_ERR_UNKNOWN, false, "database error");
-    }
-    return false;
-  }
-  if (!psArrayLength(output)) {
-    psTrace("difftool", PS_LOG_INFO, "no rows found");
+
+    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");
+	    break;
+	  case PS_ERR_DB_SERVER:
+	    psError(PXTOOLS_ERR_PROG, false, "database error");
+	    break;
+	  default:
+	    psError(PXTOOLS_ERR_PROG, false, "unknown error");
+	    break;
+	}
+	if (!psDBRollback(config->dbh)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	}
+	return false;
+    }
+    if (!psArrayLength(output)) {
+	psTrace("difftool", PS_LOG_INFO, "no rows found");
+	psFree(output);
+	if (!psDBCommit(config->dbh)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	    return false;
+	}
+	return true;
+    }
+
+    query = pxDataGet("difftool_definestackstack_part1.sql");
+    if (pretend) {
+	// negative simple so the default is true
+	if (!ippdbPrintMetadatas(stdout, output, "diffRunTemp", !simple)) {
+	    psError(PS_ERR_UNKNOWN, false, "failed to print array");
+	    psFree(output);
+	    return false;
+	}
+	psFree(output);
+	return true;
+    }
+
+    psArray *list = psArrayAllocEmpty(16); // List of runs defined, to print
+    for (long i = 0; i < output->n; i++) {
+	psMetadata *row = output->data[i]; // Output row from query
+	bool mdok;                      // Status of MD lookup
+
+	// psMetadataPrint(stderr, row, 1);
+
+	psString tess_id = psMetadataLookupStr(&mdok,row,"INPUT_tess_id");
+	psString this_data_group = psMetadataLookupStr(&mdok,row,"INPUT_data_group");
+	psString this_dist_group = psMetadataLookupStr(&mdok,row,"INPUT_dist_group");
+	psString this_label = psMetadataLookupStr(&mdok,row,"INPUT_label");
+
+	psString this_stack1Query = psStringCopy(stack1Query);
+
+	psString thisWhere = psDBGenerateWhereConditionSQL(row,NULL);
+	psStringSubstitute(&thisWhere,"stackRun.","INPUT_");
+	psStringAppend(&this_stack1Query,"\n AND %s", thisWhere);
+	psFree(thisWhere);
+
+	psTrace("difftool",1, query,stack2Query,this_stack1Query,diffQuery1,this_stack1Query);
+	if (!psDBTransaction(config->dbh)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	    return(false);
+	}
+
+	if (!p_psDBRunQueryF(config->dbh, query, stack2Query, this_stack1Query, diffQuery1, this_stack1Query)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	    psFree(query);
+	    if (!psDBRollback(config->dbh)) {
+		psError(PS_ERR_UNKNOWN, false, "database error");
+	    }
+	    return false;
+	}
+	psFree(this_stack1Query);
+
+	psArray *diff_id_output = p_psDBFetchResult(config->dbh);
+	if (!diff_id_output) {
+	    psErrorCode err = psErrorCodeLast();
+	    switch (err) {
+	      case PS_ERR_DB_CLIENT:
+		psError(PXTOOLS_ERR_SYS, false, "database error");
+		break;
+	      case PS_ERR_DB_SERVER:
+		psError(PXTOOLS_ERR_PROG, false, "database error");
+		break;
+	      default:
+		psError(PXTOOLS_ERR_PROG, false, "unknown error");
+		break;
+	    }
+	    if (!psDBRollback(config->dbh)) {
+		psError(PS_ERR_UNKNOWN, false, "database error");
+	    }
+	    return false;
+	}
+	if (!psArrayLength(diff_id_output)) {
+	    psTrace("difftool", PS_LOG_INFO, "no rows found");
+	    psFree(diff_id_output);
+	    if (!psDBCommit(config->dbh)) {
+		psError(PS_ERR_UNKNOWN, false, "database error");
+		return false;
+	    }
+	    return true;
+	}
+
+	// ok we've got one create the diffRun
+	diffRunRow *run = diffRunRowAlloc(
+	    0,          // ID
+	    "reg",      // state
+	    workdir,
+	    label ? label : this_label,
+	    data_group ? data_group : this_data_group,
+	    dist_group ? dist_group : this_dist_group,
+	    reduction,
+	    NULL,       // dvodb
+	    registered,
+	    tess_id,
+	    bothways,               // bothways
+	    false,                 // exposure
+	    0,       // magicked
+	    NULL, // software version
+	    0,    // mask stat npix
+	    NAN,    // static
+	    NAN,    // dynamic
+	    NAN,    // magic
+	    NAN,    // advisory				     
+	    IPP_DIFF_MODE_STACK_STACK, // diff_mode
+	    note
+	    );
+	// Commit to database
+	if (!diffRunInsertObject(config->dbh, run)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	    psFree(run);
+	    if (!psDBRollback(config->dbh)) {
+		psError(PS_ERR_UNKNOWN, false, "database error");
+	    }
+	    return false;
+	}
+	// diffRunPrintObject(stdout,run,1);
+	run->diff_id = psDBLastInsertID(config->dbh);
+
+	for (long j = 0; j < diff_id_output->n; j++) {
+	    psMetadata *input_row = diff_id_output->data[j]; // Output row from query
+	    bool mdok;
+	    psString in_skycell_id  = psMetadataLookupStr(&mdok,input_row,"skycell_id");
+	    psS64 in_input_stack_id = psMetadataLookupS64(&mdok,input_row,"stack_id");
+	    psS64 in_template_stack_id = psMetadataLookupS64(&mdok,input_row,"max_stack_id");
+	    psString in_tess_id = psMetadataLookupStr(&mdok,input_row,"tess_id");
+	    psTrace("difftool",1,"%s %" PRId64 " %" PRId64 " %s\n",
+		    in_skycell_id, in_input_stack_id, in_template_stack_id, in_tess_id);
+	    diffInputSkyfileRow *input = diffInputSkyfileRowAlloc(
+		run->diff_id,   // ID
+		in_skycell_id,
+		PS_MAX_S64, // warp1_id -> NULL
+		in_input_stack_id, // stack1
+		PS_MAX_S64, // warp2_id -> NULL
+		in_template_stack_id, // stack2
+		in_tess_id,
+		0 // diff_skyfile_id
+		);
+
+	    // Commit to database the input
+	    if (!diffInputSkyfileInsertObject(config->dbh, input)) {
+		psError(PS_ERR_UNKNOWN, false, "database error");
+		psFree(input);
+		if (!psDBRollback(config->dbh)) {
+		    psError(PS_ERR_UNKNOWN, false, "database error");
+		}
+		return false;
+	    }
+
+/*       diffInputSkyfilePrintObject(stdout,input,1); */
+	    psFree(input);
+	}
+
+	if (!setdiffRunState(config, run->diff_id, "new", false)) {
+	    psError(PS_ERR_UNKNOWN, false, "failed to change diffRun.state for diff_id: %" PRId64, run->diff_id);
+	    psFree(stack1Query);
+	    psFree(stack2Query);
+	    psFree(diffQuery0);
+	    psFree(diffQuery1);
+	    psFree(run);
+	    psFree(list);
+	    if (!psDBRollback(config->dbh)) {
+		psError(PS_ERR_UNKNOWN, false, "database error");
+	    }
+	    return false;
+	}
+	psArrayAdd(list, list->n, run);
+	psFree(run);
+    }
+
+    if (!psDBCommit(config->dbh)) {
+	psError(PS_ERR_UNKNOWN, false, "database error");
+	psFree(list);
+	return false;
+    }
+
+    if (!diffRunPrintObjects(stdout, list, !simple)) {
+	psError(PS_ERR_UNKNOWN, false, "failed to print object");
+	psFree(list);
+	return false;
+    }
+
+    psFree(query);
+    psFree(stack1Query);
+    psFree(stack2Query);
+    psFree(diffQuery0);
+    psFree(diffQuery1);
     psFree(output);
+    psFree(list);
+
     if (!psDBCommit(config->dbh)) {
-      psError(PS_ERR_UNKNOWN, false, "database error");
-      return false;
-    }
-    return true;
-  }
-
-  query = pxDataGet("difftool_definestackstack_part1.sql");
-  if (pretend) {
-    // negative simple so the default is true
-    if (!ippdbPrintMetadatas(stdout, output, "diffRunTemp", !simple)) {
-      psError(PS_ERR_UNKNOWN, false, "failed to print array");
-      psFree(output);
-      return false;
-    }
-    psFree(output);
-    return true;
-  }
-
-  psArray *list = psArrayAllocEmpty(16); // List of runs defined, to print
-  for (long i = 0; i < output->n; i++) {
-    psMetadata *row = output->data[i]; // Output row from query
-    bool mdok;                      // Status of MD lookup
-
-    psString tess_id = psMetadataLookupStr(&mdok,row,"INPUT_tess_id");
-    psString this_data_group = psMetadataLookupStr(&mdok,row,"INPUT_data_group");
-    psString this_dist_group = psMetadataLookupStr(&mdok,row,"INPUT_dist_group");
-    psString this_label = psMetadataLookupStr(&mdok,row,"INPUT_label");
-
-    psString this_stack1Query = psStringCopy(stack1Query);
-
-    psString thisWhere = psDBGenerateWhereConditionSQL(row,NULL);
-    psStringSubstitute(&thisWhere,"stackRun.","INPUT_");
-    psStringAppend(&this_stack1Query,"\n AND %s", thisWhere);
-    psFree(thisWhere);
-
-    psTrace("difftool",1, query,stack2Query,this_stack1Query,diffQuery,this_stack1Query);
-    if (!psDBTransaction(config->dbh)) {
-      psError(PS_ERR_UNKNOWN, false, "database error");
-      return(false);
-    }
-
-    if (!p_psDBRunQueryF(config->dbh, query, stack2Query, this_stack1Query, diffQuery, this_stack1Query)) {
-      psError(PS_ERR_UNKNOWN, false, "database error");
-      psFree(query);
-      if (!psDBRollback(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-      }
-      return false;
-    }
-    psFree(this_stack1Query);
-
-    psArray *diff_id_output = p_psDBFetchResult(config->dbh);
-    if (!diff_id_output) {
-      psErrorCode err = psErrorCodeLast();
-      switch (err) {
-      case PS_ERR_DB_CLIENT:
-        psError(PXTOOLS_ERR_SYS, false, "database error");
-        break;
-      case PS_ERR_DB_SERVER:
-        psError(PXTOOLS_ERR_PROG, false, "database error");
-        break;
-      default:
-        psError(PXTOOLS_ERR_PROG, false, "unknown error");
-        break;
-      }
-      if (!psDBRollback(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-      }
-      return false;
-    }
-    if (!psArrayLength(diff_id_output)) {
-      psTrace("difftool", PS_LOG_INFO, "no rows found");
-      psFree(diff_id_output);
-      if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-      }
-      return true;
-    }
-
-    // ok we've got one create the diffRun
-    diffRunRow *run = diffRunRowAlloc(
-                                      0,          // ID
-                                      "reg",      // state
-                                      workdir,
-                                      label ? label : this_label,
-                                      data_group ? data_group : this_data_group,
-                                      dist_group ? dist_group : this_dist_group,
-                                      reduction,
-                                      NULL,       // dvodb
-                                      registered,
-                                      tess_id,
-                                      false,                 // bothways
-                                      false,                 // exposure
-                                      0,       // magicked
-				      NULL, // software version
-				      0,    // mask stat npix
-				      NAN,    // static
-				      NAN,    // dynamic
-				      NAN,    // magic
-				      NAN,    // advisory				     
-                                      IPP_DIFF_MODE_STACK_STACK, // diff_mode
-                                      note
-                                      );
-    // Commit to database
-    if (!diffRunInsertObject(config->dbh, run)) {
-      psError(PS_ERR_UNKNOWN, false, "database error");
-      psFree(run);
-      if (!psDBRollback(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-      }
-      return false;
-    }
-/*     diffRunPrintObject(stdout,run,1); */
-    run->diff_id = psDBLastInsertID(config->dbh);
-    for (long j = 0; j < diff_id_output->n; j++) {
-      psMetadata *input_row = diff_id_output->data[j]; // Output row from query
-      bool mdok;
-      psString in_skycell_id  = psMetadataLookupStr(&mdok,input_row,"skycell_id");
-      psS64 in_input_stack_id = psMetadataLookupS64(&mdok,input_row,"stack_id");
-      psS64 in_template_stack_id = psMetadataLookupS64(&mdok,input_row,"max_stack_id");
-      psString in_tess_id = psMetadataLookupStr(&mdok,input_row,"tess_id");
-      psTrace("difftool",1,"%s %" PRId64 " %" PRId64 " %s\n",
-              in_skycell_id, in_input_stack_id, in_template_stack_id, in_tess_id);
-      diffInputSkyfileRow *input = diffInputSkyfileRowAlloc(
-                                                            run->diff_id,   // ID
-                                                            in_skycell_id,
-                                                            PS_MAX_S64, // warp1_id -> NULL
-                                                            in_input_stack_id, // stack1
-                                                            PS_MAX_S64, // warp2_id -> NULL
-                                                            in_template_stack_id, // stack2
-                                                            in_tess_id,
-                                                            0 // diff_skyfile_id
-                                                            );
-      // Commit to database the input
-      if (!diffInputSkyfileInsertObject(config->dbh, input)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(input);
-        if (!psDBRollback(config->dbh)) {
-          psError(PS_ERR_UNKNOWN, false, "database error");
-        }
-        return false;
-      }
-
-/*       diffInputSkyfilePrintObject(stdout,input,1); */
-      psFree(input);
-    }
-
-    if (!setdiffRunState(config, run->diff_id, "new", false)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to change diffRun.state for diff_id: %" PRId64, run->diff_id);
-        psFree(stack1Query);
-        psFree(stack2Query);
-        psFree(diffQuery);
-        psFree(run);
-        psFree(list);
-        if (!psDBRollback(config->dbh)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-        }
-        return false;
-    }
-    psArrayAdd(list, list->n, run);
-    psFree(run);
-  }
-
-  if (!psDBCommit(config->dbh)) {
-    psError(PS_ERR_UNKNOWN, false, "database error");
-    psFree(list);
-    return false;
-  }
-
-  if (!diffRunPrintObjects(stdout, list, !simple)) {
-    psError(PS_ERR_UNKNOWN, false, "failed to print object");
-    psFree(list);
-    return false;
-  }
-
-  psFree(query);
-  psFree(stack1Query);
-  psFree(stack2Query);
-  psFree(diffQuery);
-  psFree(output);
-  psFree(list);
-
-    if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(list);
-        return false;
-    }
-
-  return(true);
+	psError(PS_ERR_UNKNOWN, false, "database error");
+	psFree(list);
+	return false;
+    }
+
+    return(true);
 }
 
Index: branches/eam_branches/ipp-20100823/ippTools/src/difftoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/difftoolConfig.c	(revision 29232)
+++ branches/eam_branches/ipp-20100823/ippTools/src/difftoolConfig.c	(revision 29324)
@@ -222,4 +222,5 @@
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-skycell_id", 0, "search by skycell ID", NULL);
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-tess_id", 0, "search by tess ID", NULL);
+    psMetadataAddBool(definewarpstackArgs, PS_LIST_TAIL, "-bothways",  0,          "do the subtraction both ways?", false);
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-filter", 0, "search by filter", NULL);
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-comment", 0, "search by comment (LIKE)", NULL);
@@ -245,4 +246,5 @@
     psMetadataAddS64(definewarpwarpArgs, PS_LIST_TAIL, "-warp_id", 0, "search by warp ID", 0);
     psMetadataAddS64(definewarpwarpArgs, PS_LIST_TAIL, "-exp_id", 0, "search by exposure ID", 0);
+    psMetadataAddBool(definewarpwarpArgs, PS_LIST_TAIL, "-not-bothways",  0, "only do the single-direction subtraction?", false);
     psMetadataAddStr(definewarpwarpArgs, PS_LIST_TAIL, "-filter", 0, "search by filter", NULL);
     psMetadataAddF32(definewarpwarpArgs, PS_LIST_TAIL, "-distance", 0, "limit distance between input and template (deg)", NAN);
@@ -299,4 +301,5 @@
     psMetadataAddStr(definestackstackArgs, PS_LIST_TAIL, "-skycell_id", 0, "search by skycell ID", NULL);
     psMetadataAddStr(definestackstackArgs, PS_LIST_TAIL, "-tess_id", 0, "search by tess ID", NULL);
+    psMetadataAddBool(definestackstackArgs, PS_LIST_TAIL, "-bothways",  0,          "do the subtraction both ways?", false);
     psMetadataAddStr(definestackstackArgs, PS_LIST_TAIL, "-filter", 0, "search by filter", NULL);
     psMetadataAddStr(definestackstackArgs, PS_LIST_TAIL, "-input_label", 0, "search by stack label for input", NULL);
