Index: /trunk/ippTools/src/dettool.c
===================================================================
--- /trunk/ippTools/src/dettool.c	(revision 9941)
+++ /trunk/ippTools/src/dettool.c	(revision 9942)
@@ -33,4 +33,5 @@
 static bool definebytagMode(pxConfig *config);
 static bool definebyqueryMode(pxConfig *config);
+static bool definebydetrunMode(pxConfig *config);
 static bool runsMode(pxConfig *config);
 static bool inputMode(pxConfig *config);
@@ -97,4 +98,5 @@
         MODECASE(DETTOOL_MODE_DEFINEBYTAG,      definebytagMode);
         MODECASE(DETTOOL_MODE_DEFINEBYQUERY,    definebyqueryMode);
+        MODECASE(DETTOOL_MODE_DEFINEBYDETRUN,   definebydetrunMode);
         MODECASE(DETTOOL_MODE_RUNS,             runsMode);
         MODECASE(DETTOOL_MODE_INPUT,            inputMode);
@@ -504,4 +506,299 @@
 
 static bool definebyqueryMode(pxConfig *config)
+{
+    bool status     = false;
+
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // what type of detRun is this?
+    // det_type is required
+    psString det_type = psMetadataLookupStr(&status, config->args, "-det_type");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type");
+        return false;
+    }
+    if (!det_type) {
+        psError(PS_ERR_UNKNOWN, true, "-det_type is required");
+        return false;
+    }
+
+    psMetadata *where = psMetadataAlloc();
+    {
+        bool status = false;
+        psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type");        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type");
+            return false;
+        }
+        if (exp_type) {
+            if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_type", 0, "==", exp_type)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item exp_type");
+                psFree(where);
+                return false;
+            }
+        }
+        // map -inst -> camera
+        psString camera = psMetadataLookupStr(&status, config->args, "-inst");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst");
+            return false;
+        }
+        if (camera) {
+            if (!psMetadataAddStr(where, PS_LIST_TAIL, "camera", 0, "==", camera)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item inst");
+                psFree(where);
+                return false;
+            }
+        }
+        psString telescope = psMetadataLookupStr(&status, config->args, "-telescope");        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope");
+            return false;
+        }
+        if (telescope) {
+            if (!psMetadataAddStr(where, PS_LIST_TAIL, "telescope", 0, "==", telescope)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item telescope");
+                psFree(where);
+                return false;
+            }
+        }
+        psString filter = psMetadataLookupStr(&status, config->args, "-filter");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
+            return false;
+        }
+        if (filter) {
+            if (!psMetadataAddStr(where, PS_LIST_TAIL, "filter", 0, "==", filter)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
+                psFree(where);
+                return false;
+            }
+        }
+        psString uri = psMetadataLookupStr(&status, config->args, "-uri");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
+            return false;
+        }
+        if (uri) {
+            if (!psMetadataAddStr(where, PS_LIST_TAIL, "uri", 0, "==", uri)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+                psFree(where);
+                return false;
+            }
+        }
+    }
+    if (!psListLength(where->list)) {
+        psFree(where);
+        where = NULL;
+    }
+
+    // there is some namespace overlap between the names of the fields we'd
+    // like to search by to setup a detrun and the names of the fields we'd
+    // like to assign values to so I've seperated them but prepending set- to
+    // the assigned values
+
+    // optional
+    psString exp_type = psMetadataLookupStr(&status, config->args, "-set_exp_type");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_type");
+        return false;
+    }
+
+    psString filter = psMetadataLookupStr(&status, config->args, "-set_filter");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_filter");
+        return false;
+    }
+
+    psF32 airmass = psMetadataLookupF32(&status, config->args, "-set_airmass");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_airmass");
+        return false;
+    }
+
+    psF32 exp_time = psMetadataLookupF32(&status, config->args, "-set_exp_time");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_time");
+        return false;
+    }
+
+    psF32 ccd_temp = psMetadataLookupF32(&status, config->args, "-set_ccd_temp");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_ccd_temp");
+        return false;
+    }
+
+    psF64 posang = psMetadataLookupF32(&status, config->args, "-set_posang");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_posang");
+        return false;
+    }
+
+    psString object = psMetadataLookupStr(&status, config->args, "-set_object");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_object");
+        return false;
+    }
+    psTime *registered = NULL;
+    {
+        psString registeredStr = psMetadataLookupStr(&status, config->args, "-set_registered");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_registered");
+            return false;
+        }
+        // pass through NULL as this is an optional field
+        if (registeredStr) {
+            registered = psTimeFromISO(registeredStr, PS_TIME_UTC);
+        } else {
+            registered = NULL;
+        }
+    }
+
+    psTime *use_begin = NULL;
+    {
+        psString use_beginStr = psMetadataLookupStr(&status, config->args, "-set_use_begin");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_use_begin");
+            return false;
+        }
+        // pass through NULL as this is an optional field
+        if (use_beginStr) {
+            use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC);
+        } else {
+            use_begin = NULL;
+        }
+    }
+
+    psTime *use_end = NULL;
+    {
+        psString use_endStr = psMetadataLookupStr(&status, config->args, "-set_use_end");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_use_end");
+            return false;
+        }
+        // pass through NULL as this is an optional field
+        if (use_endStr) {
+            use_end = psTimeFromISO(use_endStr, PS_TIME_UTC);
+        } else {
+            use_end = NULL;
+        }
+    }
+
+    // search for rawDetrendExps with the specified options
+    psArray *detrendExps = rawDetrendExpSelectRowObjects(config->dbh, where, 0);
+    psFree(where);
+    // make sure that we found at least one rawDetrendExp
+    if (!detrendExps) {
+        psError(PS_ERR_UNKNOWN, false, "no rawDetrendExp rows found");
+        return false;
+    }
+
+    // start a transaction so we don't end up with orphaned det_ids
+    if (!psDBTransaction(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(detrendExps);
+        return false;
+    }
+
+    // the first iteration is always 0
+    // XXX det_id
+    detRunInsert(config->dbh,
+            0,
+            0,
+            det_type,
+            "run",
+            exp_type,
+            filter,
+            airmass,
+            exp_time,
+            ccd_temp,
+            posang,
+            object,
+            registered,
+            use_begin,
+            use_end
+        );
+    psFree(registered);
+    psFree(use_begin);
+    psFree(use_end);
+    long det_id = psDBLastInsertID(config->dbh);
+
+    // create new detInputExp row(s) from the rawDetrendExp row(s)
+    psArray *inputExps = psArrayAllocEmpty(psArrayLength(detrendExps));
+    for (long i = 0; i < psArrayLength(detrendExps); i++) {
+        detInputExpRow *inputExp = rawDetrenTodetInputExpRow(
+            detrendExps->data[i],
+            det_id,
+            0 // the first iteration is explicitly 0
+        );
+        psArrayAdd(inputExps, 0, inputExp);
+        psFree(inputExp);
+    }
+
+    psFree(detrendExps);
+
+    // insert detInputExp objects into the database
+    if (!detInputExpInsertObjects(config->dbh, inputExps)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psFree(inputExps);
+        return false;
+    }
+    psFree(inputExps);
+
+    // point of no return for det_id creation
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    bool simple = false;
+    {
+        bool status = false;
+        simple = psMetadataLookupBool(&status, config->args, "-simple");
+        if (!status) {
+            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");
+            return false;
+        }
+    }
+
+    // print the new det_id
+    psArray *detRuns = NULL;
+    {
+        psMetadata *where = psMetadataAlloc();
+        psMetadataAddS32(where, PS_LIST_TAIL, "det_id", 0, "==", det_id);
+        detRuns = psDBSelectRows(config->dbh, "detRun", where, 0);
+        psFree(where);
+    }
+    if (!detRuns) {
+        psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created");
+        return false;
+    }
+    // sanity check results
+    if (psArrayLength(detRuns) != 1) {
+        psAbort(config->argv[0], "found more then one detRun matching det_id %ld(this should not happen)", det_id);
+        return false;
+    }
+
+    // convert det_id to a string externaly
+    if (!convertDetIdToStr(detRuns)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to convert det_id to a string");
+        psFree(detRuns);
+        return false;
+    }
+
+    // negative simple so the default is true
+    if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(detRuns);
+        return false;
+    }
+    psFree(detRuns);
+
+    return true;
+}
+
+static bool definebydetrunMode(pxConfig *config)
 {
     bool status     = false;
Index: /trunk/ippTools/src/dettool.h
===================================================================
--- /trunk/ippTools/src/dettool.h	(revision 9941)
+++ /trunk/ippTools/src/dettool.h	(revision 9942)
@@ -28,4 +28,5 @@
     DETTOOL_MODE_DEFINEBYTAG,
     DETTOOL_MODE_DEFINEBYQUERY,
+    DETTOOL_MODE_DEFINEBYDETRUN,
     DETTOOL_MODE_RUNS,
     DETTOOL_MODE_INPUT,
Index: /trunk/ippTools/src/dettoolConfig.c
===================================================================
--- /trunk/ippTools/src/dettoolConfig.c	(revision 9941)
+++ /trunk/ippTools/src/dettoolConfig.c	(revision 9942)
@@ -127,4 +127,41 @@
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-simple",  0,
             "use the simple output format", false);
+ 
+    // -definebydetrun
+    psMetadata *definebydetrunArgs = psMetadataAlloc();
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-det_type",  0,
+            "define the type of detrend run (required)", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-exp_type",  0,
+            "search by exposure type", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-inst",  0,
+            "search by camera", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-telescope",  0,
+            "search by telescope", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-filter",  0,
+            "search by filter", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-uri",  0,
+            "search by URL", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_exp_type",  0,
+        "define exposure type", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_filter",  0,
+        "define filter ", NULL);
+    psMetadataAddF32(definebydetrunArgs, PS_LIST_TAIL, "-set_airmass",  0,
+        "define airmass", NAN);
+    psMetadataAddF32(definebydetrunArgs, PS_LIST_TAIL, "-set_exp_time",  0,
+        "define exposure time", NAN);
+    psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_ccd_temp",  0,
+        "define ccd tempature", NAN);
+    psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_posang",  0,
+        "define rotator position angle", NAN);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_object",  0,
+        "define exposure object", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_registered",  0,
+        "time detrend run was registered", now);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_use_begin",  0,
+        "start of detrend run applicable peroid", NULL);
+    psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_use_end",  0,
+        "end of detrend run applicable peroid", NULL);
+    psMetadataAddBool(definebydetrunArgs, PS_LIST_TAIL, "-simple",  0,
+            "use the simple output format", false);
 
     // -runs
@@ -595,5 +632,6 @@
     PXTOOL_MODE("-pending",         DETTOOL_MODE_PENDING,       pendingArgs);
     PXTOOL_MODE("-definebytag",     DETTOOL_MODE_DEFINEBYTAG,   definebytagArgs);
-    PXTOOL_MODE("-definebyquery",DETTOOL_MODE_DEFINEBYQUERY, definebyqueryArgs);
+    PXTOOL_MODE("-definebyquery",   DETTOOL_MODE_DEFINEBYQUERY, definebyqueryArgs);
+    PXTOOL_MODE("-definebydetrun",  DETTOOL_MODE_DEFINEBYDETRUN, definebydetrunArgs);
     PXTOOL_MODE("-raw",             DETTOOL_MODE_RAW,           rawArgs);
     PXTOOL_MODE("-runs",            DETTOOL_MODE_RUNS,          runsArgs);
