Changeset 15545
- Timestamp:
- Nov 9, 2007, 11:27:51 AM (19 years ago)
- Location:
- trunk/ippTools/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippTools/src/caltool.c
r15537 r15545 1 1 /* 2 * dettool.c2 * caltool.c 3 3 * 4 * Copyright (C) 2006 Joshua Hoblitt4 * Copyright (C) 2006-2007 Joshua Hoblitt 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify it … … 31 31 32 32 #include "pxtools.h" 33 #include " dettool.h"33 #include "caltool.h" 34 34 35 static bool pendingMode(pxConfig *config); 36 static bool definebytagMode(pxConfig *config); 37 static bool definebyqueryMode(pxConfig *config); 38 static bool definebydetrunMode(pxConfig *config); 35 static bool adddbMode(pxConfig *config); 36 static bool dbsMode(pxConfig *config); 37 static bool addrunMode(pxConfig *config); 39 38 static bool runsMode(pxConfig *config); 40 static bool childlessrunMode(pxConfig *config);41 static bool inputMode(pxConfig *config);42 static bool rawMode(pxConfig *config);43 // processedimfile44 static bool toprocessedimfileMode(pxConfig *config);45 static bool addprocessedimfileMode(pxConfig *config);46 static bool processedimfileMode(pxConfig *config);47 static bool revertprocessedimfileMode(pxConfig *config);48 // processedexp49 static bool toprocessedexpMode(pxConfig *config);50 static bool addprocessedexpMode(pxConfig *config);51 static bool processedexpMode(pxConfig *config);52 static bool revertprocessedexpMode(pxConfig *config);53 // stackedimfile54 static bool tostackedMode(pxConfig *config);55 static bool addstackedMode(pxConfig *config);56 static bool stackedMode(pxConfig *config);57 static bool revertstackedMode(pxConfig *config);58 // normalizedstat59 static bool tonormalizedstatMode(pxConfig *config);60 static bool addnormalizedstatMode(pxConfig *config);61 static bool normalizedstatMode(pxConfig *config);62 static bool revertnormalizedstatMode(pxConfig *config);63 // normalizedimfile64 static bool tonormalizeMode(pxConfig *config);65 static bool addnormalizedimfileMode(pxConfig *config);66 static bool normalizedimfileMode(pxConfig *config);67 static bool revertnormalizedimfileMode(pxConfig *config);68 // normalizedexp69 static bool tonormalizedexpMode(pxConfig *config);70 static bool addnormalizedexpMode(pxConfig *config);71 static bool normalizedexpMode(pxConfig *config);72 static bool revertnormalizedexpMode(pxConfig *config);73 // residimfile74 static bool toresidimfileMode(pxConfig *config);75 static bool addresidimfileMode(pxConfig *config);76 static bool residimfileMode(pxConfig *config);77 static bool revertresidimfileMode(pxConfig *config);78 // residexp79 static bool toresidexpMode(pxConfig *config);80 static bool addresidexpMode(pxConfig *config);81 static bool residexpMode(pxConfig *config);82 static bool revertresidexpMode(pxConfig *config);83 static bool updateresidexpMode(pxConfig *config);84 // detrunsummary85 static bool todetrunsummaryMode(pxConfig *config);86 static bool adddetrunsummaryMode(pxConfig *config);87 static bool detrunsummaryMode(pxConfig *config);88 static bool revertdetrunsummaryMode(pxConfig *config);89 static bool updatedetrunMode(pxConfig *config);90 static bool rerunMode(pxConfig *config);91 // register92 static bool register_detrendMode(pxConfig *config);93 static bool register_detrend_imfileMode(pxConfig *config);94 95 static detNormalizedStatImfileRow *detStackedToDetNormalizedStatImfile(pxConfig *config, detStackedImfileRow *stackedImfile);96 static detNormalizedImfileRow *detNormalizedStatToDetNormalizedmfile(pxConfig *config, detNormalizedStatImfileRow *statImfile);97 static detResidExpRow *mdToDetResidExp(pxConfig *config, psMetadata *row);98 static detRunSummaryRow *mdToDetRunSummary(pxConfig *config, psMetadata *row);99 //static psArray *validDetInputClassIds(pxConfig *config, const char *det_id);100 //static psArray *searchInputImfiles(pxConfig *config, const char *det_id);101 static detInputExpRow *rawDetrenTodetInputExpRow(rawExpRow *rawExp, psS64 det_id, psS32 iteration);102 static psArray *searchRawImfiles(pxConfig *config, psMetadata *where);103 static bool startNewIteration(pxConfig *config, psS64 det_id);104 static psS32 incrementIteration(pxConfig *config, psS64 det_id);105 static bool setDetRunState(pxConfig *config, psS64 det_id, const char *state);106 static bool isValidMode(pxConfig *config, const char *mode);107 39 108 40 # define MODECASE(caseName, func) \ … … 117 49 psLibInit(NULL); 118 50 119 pxConfig *config = dettoolConfig(NULL, argc, argv);51 pxConfig *config = caltoolConfig(NULL, argc, argv); 120 52 if (!config) { 121 53 psError(PXTOOLS_ERR_CONFIG, false, "failed to configure"); … … 124 56 125 57 switch (config->mode) { 126 MODECASE(DETTOOL_MODE_PENDING, pendingMode); 127 MODECASE(DETTOOL_MODE_DEFINEBYTAG, definebytagMode); 128 MODECASE(DETTOOL_MODE_DEFINEBYQUERY, definebyqueryMode); 129 MODECASE(DETTOOL_MODE_DEFINEBYDETRUN, definebydetrunMode); 130 MODECASE(DETTOOL_MODE_RUNS, runsMode); 131 MODECASE(DETTOOL_MODE_CHILDLESSRUN, childlessrunMode); 132 MODECASE(DETTOOL_MODE_INPUT, inputMode); 133 MODECASE(DETTOOL_MODE_RAW, rawMode); 134 // imfile 135 MODECASE(DETTOOL_MODE_TOPROCESSEDIMFILE,toprocessedimfileMode); 136 MODECASE(DETTOOL_MODE_ADDPROCESSEDIMFILE,addprocessedimfileMode); 137 MODECASE(DETTOOL_MODE_PROCESSEDIMFILE, processedimfileMode); 138 MODECASE(DETTOOL_MODE_REVERTPROCESSEDIMFILE, revertprocessedimfileMode); 139 // exp 140 MODECASE(DETTOOL_MODE_TOPROCESSEDEXP, toprocessedexpMode); 141 MODECASE(DETTOOL_MODE_ADDPROCESSEDEXP, addprocessedexpMode); 142 MODECASE(DETTOOL_MODE_PROCESSEDEXP, processedexpMode); 143 MODECASE(DETTOOL_MODE_REVERTPROCESSEDEXP, revertprocessedexpMode); 144 // stacked 145 MODECASE(DETTOOL_MODE_TOSTACKED, tostackedMode); 146 MODECASE(DETTOOL_MODE_ADDSTACKED, addstackedMode); 147 MODECASE(DETTOOL_MODE_STACKED, stackedMode); 148 MODECASE(DETTOOL_MODE_REVERTSTACKED, revertstackedMode); 149 // normalizedstat 150 MODECASE(DETTOOL_MODE_TONORMALIZEDSTAT, tonormalizedstatMode); 151 MODECASE(DETTOOL_MODE_ADDNORMALIZEDSTAT,addnormalizedstatMode); 152 MODECASE(DETTOOL_MODE_NORMALIZEDSTAT, normalizedstatMode); 153 MODECASE(DETTOOL_MODE_REVERTNORMALIZEDSTAT, revertnormalizedstatMode); 154 // normalizedimfile 155 MODECASE(DETTOOL_MODE_TONORMALIZE, tonormalizeMode); 156 MODECASE(DETTOOL_MODE_ADDNORMALIZEDIMFILE,addnormalizedimfileMode); 157 MODECASE(DETTOOL_MODE_NORMALIZEDIMFILE, normalizedimfileMode); 158 MODECASE(DETTOOL_MODE_REVERTNORMALIZEDIMFILE, revertnormalizedimfileMode); 159 // normalizedexp 160 MODECASE(DETTOOL_MODE_TONORMALIZEDEXP, tonormalizedexpMode); 161 MODECASE(DETTOOL_MODE_ADDNORMALIZEDEXP, addnormalizedexpMode); 162 MODECASE(DETTOOL_MODE_NORMALIZEDEXP, normalizedexpMode); 163 MODECASE(DETTOOL_MODE_REVERTNORMALIZEDEXP, revertnormalizedexpMode); 164 // residimfile 165 MODECASE(DETTOOL_MODE_TORESIDIMFILE, toresidimfileMode); 166 MODECASE(DETTOOL_MODE_ADDRESIDIMFILE, addresidimfileMode); 167 MODECASE(DETTOOL_MODE_RESIDIMFILE, residimfileMode); 168 MODECASE(DETTOOL_MODE_REVERTRESIDIMFILE,revertresidimfileMode); 169 // residexp 170 MODECASE(DETTOOL_MODE_TORESIDEXP, toresidexpMode); 171 MODECASE(DETTOOL_MODE_ADDRESIDEXP, addresidexpMode); 172 MODECASE(DETTOOL_MODE_RESIDEXP, residexpMode); 173 MODECASE(DETTOOL_MODE_REVERTRESIDEXP, revertresidexpMode); 174 MODECASE(DETTOOL_MODE_UPDATERESIDEXP, updateresidexpMode); 175 // detrunsummary 176 MODECASE(DETTOOL_MODE_TODETRUNSUMMARY, todetrunsummaryMode); 177 MODECASE(DETTOOL_MODE_ADDDETRUNSUMMARY, adddetrunsummaryMode); 178 MODECASE(DETTOOL_MODE_DETRUNSUMMARY, detrunsummaryMode); 179 MODECASE(DETTOOL_MODE_REVERTDETRUNSUMMARY, revertdetrunsummaryMode); 180 MODECASE(DETTOOL_MODE_UPDATEDETRUN, updatedetrunMode); 181 MODECASE(DETTOOL_MODE_RERUN, rerunMode); 182 // register 183 MODECASE(DETTOOL_MODE_REGISTER_DETREND, register_detrendMode); 184 MODECASE(DETTOOL_MODE_REGISTER_DETREND_IMFILE, register_detrend_imfileMode); 58 MODECASE(CALTOOL_MODE_ADDDB, adddbMode); 59 MODECASE(CALTOOL_MODE_DBS, dbsMode); 60 MODECASE(CALTOOL_MODE_ADDRUN, addrunMode); 61 MODECASE(CALTOOL_MODE_RUNS, runsMode); 185 62 default: 186 63 psAbort("invalid option (this should not happen)"); … … 204 81 } 205 82 206 static bool pendingMode(pxConfig *config)83 static bool adddbMode(pxConfig *config) 207 84 { 208 85 PS_ASSERT_PTR_NON_NULL(config, NULL); 209 86 210 psString query = psStringCopy( 211 "SELECT" 212 " rawExp.*" 213 " FROM rawExp" 214 " LEFT JOIN detInputExp" 215 " ON rawExp.exp_id = detInputExp.exp_id" 216 " WHERE" 217 " detInputExp.exp_id IS NULL" 218 " AND rawExp.object != 'object'" 219 ); 220 221 if (config->where) { 222 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawExp"); 223 psStringAppend(&query, " AND %s", whereClause); 224 psFree(whereClause); 225 } 226 227 if (!p_psDBRunQuery(config->dbh, query)) { 228 psError(PS_ERR_UNKNOWN, false, "database error"); 229 psFree(query); 230 return false; 231 } 232 psFree(query); 233 234 psArray *output = p_psDBFetchResult(config->dbh); 235 if (!output) { 236 psError(PS_ERR_UNKNOWN, false, "database error"); 237 return false; 238 } 239 if (!psArrayLength(output)) { 240 psTrace("dettool", PS_LOG_INFO, "no rows found"); 241 psFree(output); 242 return true; 243 } 244 245 bool simple = false; 246 { 247 bool status = false; 248 simple = psMetadataLookupBool(&status, config->args, "-simple"); 249 if (!status) { 250 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 251 return false; 252 } 253 } 254 255 // negative simple so the default is true 256 if (!ippdbPrintMetadatas(stdout, output, "rawExp", !simple)) { 257 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 258 psFree(output); 259 return false; 260 } 261 262 psFree(output); 263 264 return true; 87 return false; 265 88 } 266 89 267 static bool definebytagMode(pxConfig *config) 90 91 static bool dbsMode(pxConfig *config) 268 92 { 269 bool status = false;93 PS_ASSERT_PTR_NON_NULL(config, NULL); 270 94 271 PS_ASSERT_PTR_NON_NULL(config, false); 272 273 // what type of detRun is this? 274 // det_type is required 275 psString det_type = psMetadataLookupStr(&status, config->args, "-det_type"); 276 if (!status) { 277 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type"); 278 return false; 279 } 280 if (!det_type) { 281 psError(PS_ERR_UNKNOWN, true, "-det_type is required"); 282 return false; 283 } 284 285 // optional 286 psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel"); 287 if (!status) { 288 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel"); 289 return false; 290 } 291 292 psString workdir = psMetadataLookupStr(&status, config->args, "-workdir"); 293 if (!status) { 294 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir"); 295 return false; 296 } 297 if (!workdir) { 298 psError(PS_ERR_UNKNOWN, true, "-workdir is required"); 299 return false; 300 } 301 302 // optional 303 psString mode = psMetadataLookupStr(&status, config->args, "-mode"); 304 if (!status) { 305 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -mode"); 306 return false; 307 } 308 // check mode 309 if (mode && !isValidMode(config, mode)) { 310 psError(PS_ERR_UNKNOWN, false, "invalud mode"); 311 return false; 312 } 313 psString camera = psMetadataLookupStr(&status, config->args, "-inst"); 314 if (!status) { 315 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst"); 316 return false; 317 } 318 319 psString telescope = psMetadataLookupStr(&status, config->args, "-telescope"); 320 if (!status) { 321 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope"); 322 return false; 323 } 324 325 psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type"); 326 if (!status) { 327 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type"); 328 return false; 329 } 330 331 psString filter = psMetadataLookupStr(&status, config->args, "-filter"); 332 if (!status) { 333 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter"); 334 return false; 335 } 336 337 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-airmass_min"); 338 if (!status) { 339 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_min"); 340 return false; 341 } 342 343 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-airmass_max"); 344 if (!status) { 345 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_max"); 346 return false; 347 } 348 349 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-exp_time_min"); 350 if (!status) { 351 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_min"); 352 return false; 353 } 354 355 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-exp_time_max"); 356 if (!status) { 357 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_max"); 358 return false; 359 } 360 361 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-ccd_temp_min"); 362 if (!status) { 363 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_min"); 364 return false; 365 } 366 367 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-ccd_temp_max"); 368 if (!status) { 369 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_max"); 370 return false; 371 } 372 373 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-posang_min"); 374 if (!status) { 375 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_min"); 376 return false; 377 } 378 379 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-posang_max"); 380 if (!status) { 381 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_max"); 382 return false; 383 } 384 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-solang_min"); 385 if (!status) { 386 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_min"); 387 return false; 388 } 389 390 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-solang_max"); 391 if (!status) { 392 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_max"); 393 return false; 394 } 395 396 psTime *registered = NULL; 397 { 398 psString registeredStr = psMetadataLookupStr(&status, config->args, "-registered"); 399 if (!status) { 400 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -registered"); 401 return false; 402 } 403 // pass through NULL as this is an optional field 404 if (registeredStr) { 405 registered = psTimeFromISO(registeredStr, PS_TIME_UTC); 406 if (!registered) { 407 psError(PS_ERR_UNKNOWN, false, "error in time format %s", registeredStr); 408 return false; 409 } 410 } else { 411 registered = NULL; 412 } 413 } 414 415 psTime *time_begin = NULL; 416 { 417 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-time_begin"); 418 if (!status) { 419 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_begin"); 420 return false; 421 } 422 // pass through NULL as this is an optional field 423 if (time_beginStr) { 424 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC); 425 if (!time_begin) { 426 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_beginStr); 427 return false; 428 } 429 } else { 430 time_begin = NULL; 431 } 432 } 433 434 psTime *time_end = NULL; 435 { 436 psString time_endStr = psMetadataLookupStr(&status, config->args, "-time_end"); 437 if (!status) { 438 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_end"); 439 return false; 440 } 441 // pass through NULL as this is an optional field 442 if (time_endStr) { 443 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC); 444 if (!time_end) { 445 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_endStr); 446 return false; 447 } 448 } else { 449 time_end = NULL; 450 } 451 } 452 453 psTime *use_begin = NULL; 454 { 455 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-use_begin"); 456 if (!status) { 457 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_begin"); 458 return false; 459 } 460 // pass through NULL as this is an optional field 461 if (use_beginStr) { 462 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC); 463 if (!use_begin) { 464 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_beginStr); 465 return false; 466 } 467 } else { 468 use_begin = NULL; 469 } 470 } 471 472 psTime *use_end = NULL; 473 { 474 psString use_endStr = psMetadataLookupStr(&status, config->args, "-use_end"); 475 if (!status) { 476 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_end"); 477 return false; 478 } 479 // pass through NULL as this is an optional field 480 if (use_endStr) { 481 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC); 482 if (!use_end) { 483 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_endStr); 484 return false; 485 } 486 } else { 487 use_end = NULL; 488 } 489 } 490 491 psString reduction = psMetadataLookupStr(&status, config->args, "-reduction"); 492 if (!status) { 493 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reduction"); 494 return false; 495 } 496 497 psString label = psMetadataLookupStr(&status, config->args, "-label"); 498 if (!status) { 499 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label"); 500 return false; 501 } 502 503 // we have to support multipe exp_ids 504 psMetadataItem *item = psMetadataLookup(config->args, "-exp_id"); 505 if (!item) { 506 // this shouldn't actually happen when using psArgs 507 psError(PS_ERR_UNKNOWN, true, "-exp_id is required"); 508 return false; 509 } 510 psMetadata *where = psMetadataAlloc(); 511 512 // make sure that -exp_id was parsed correctly 513 // XXX this can be removed someday 514 if (item->type == PS_DATA_METADATA_MULTI) { 515 psListIterator *iter = psListIteratorAlloc(item->data.list, 0, false); 516 psMetadataItem *mItem = NULL; 517 while ((mItem = psListGetAndIncrement(iter))) { 518 psString exp_id = mItem->data.V; 519 // if exp_id is NULL then it means that -exp_id has not been 520 // specified 521 if (!exp_id) { 522 psError(PS_ERR_UNKNOWN, true, 523 "at least one -exp_id is required"); 524 psFree(where); 525 return false; 526 } 527 528 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 529 PS_META_DUPLICATE_OK, "==", exp_id)) { 530 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 531 psFree(iter); 532 psFree(where); 533 return false; 534 } 535 } 536 psFree(iter); 537 } else { 538 psAbort( "-exp_id was not parsed correctly (this should not happen"); 539 } 540 541 if (psListLength(where->list) < 1) { 542 psFree(where); 543 where = NULL; 544 } 545 546 // check that the specified exp_ids actually exist 547 psArray *detrendExps = rawExpSelectRowObjects(config->dbh, where, 0); 548 psFree(where); 549 if (!detrendExps) { 550 psError(PS_ERR_UNKNOWN, false, "no rawExp rows found"); 551 return false; 552 } 553 554 // we should have one rawExp row per exp_id specified 555 if (psListLength(item->data.list) != psArrayLength(detrendExps)) { 556 psAbort( "an -exp_id matched more then one rawExp (this should not happen"); 557 558 } 559 560 // check to see if -filelevel was set on the command line 561 if (!filelevel) { 562 filelevel = psStringCopy(((rawExpRow *)detrendExps->data[0])->filelevel); 563 } 564 565 // start a transaction so we don't end up with childlessed det_ids 566 if (!psDBTransaction(config->dbh)) { 567 psError(PS_ERR_UNKNOWN, false, "database error"); 568 psFree(detrendExps); 569 return false; 570 } 571 572 // the first iteration is always 0 573 // XXX the camera name is set from the first inputExp 574 // XXX det_id 575 detRunInsert(config->dbh, 576 0, 577 0, 578 det_type, 579 mode, 580 "run", 581 filelevel, 582 workdir, 583 camera, 584 telescope, 585 exp_type, 586 reduction, 587 filter, 588 airmass_min, 589 airmass_max, 590 exp_time_min, 591 exp_time_max, 592 ccd_temp_min, 593 ccd_temp_max, 594 posang_min, 595 posang_max, 596 registered, 597 time_begin, 598 time_end, 599 use_begin, 600 use_end, 601 solang_min, 602 solang_max, 603 label, 604 0 // parent 605 ); 606 psFree(registered); 607 psFree(time_begin); 608 psFree(time_end); 609 psFree(use_begin); 610 psFree(use_end); 611 psS64 det_id = psDBLastInsertID(config->dbh); 612 613 // create new detInputExp row(s) from the rawExp row(s) 614 psArray *inputExps = psArrayAllocEmpty(psArrayLength(detrendExps)); 615 for (long i = 0; i < psArrayLength(detrendExps); i++) { 616 detInputExpRow *inputExp = rawDetrenTodetInputExpRow( 617 detrendExps->data[i], 618 det_id, 619 0 // the first iteration is explicitly 0 620 ); 621 psArrayAdd(inputExps, 0, inputExp); 622 psFree(inputExp); 623 } 624 625 psFree(detrendExps); 626 627 // insert detInputExp objects into the database 628 if (!detInputExpInsertObjects(config->dbh, inputExps)) { 629 psError(PS_ERR_UNKNOWN, false, "database error"); 630 // rollback 631 if (!psDBRollback(config->dbh)) { 632 psError(PS_ERR_UNKNOWN, false, "database error"); 633 } 634 psFree(inputExps); 635 return false; 636 } 637 psFree(inputExps); 638 639 // point of no return for det_id creation 640 if (!psDBCommit(config->dbh)) { 641 psError(PS_ERR_UNKNOWN, false, "database error"); 642 return false; 643 } 644 645 bool simple = false; 646 { 647 bool status = false; 648 simple = psMetadataLookupBool(&status, config->args, "-simple"); 649 if (!status) { 650 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 651 return false; 652 } 653 } 654 655 // print the new det_id 656 psArray *detRuns = NULL; 657 { 658 psMetadata *where = psMetadataAlloc(); 659 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id); 660 detRuns = psDBSelectRows(config->dbh, "detRun", where, 0); 661 psFree(where); 662 } 663 if (!detRuns) { 664 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created"); 665 return false; 666 } 667 // sanity check results 668 if (psArrayLength(detRuns) != 1) { 669 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", det_id); 670 return false; 671 } 672 673 if (!convertIdToStr(detRuns)) { 674 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings"); 675 psFree(detRuns); 676 return false; 677 } 678 679 // negative simple so the default is true 680 if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) { 681 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 682 psFree(detRuns); 683 return false; 684 } 685 psFree(detRuns); 686 687 return true; 95 return false; 688 96 } 689 97 690 #if 0 691 // This function is used to convert the det_id from an int, as it is used 692 // internally, to be a string for external use. The rational being that we may 693 // want to change how det_id is generated in the future and don't want to 694 // external programs to become depending on this value being an int. 695 static bool convertDetIdToStr(psArray *mds) 98 99 static bool addrunMode(pxConfig *config) 696 100 { 697 PS_ASSERT_PTR_NON_NULL( mds, false);101 PS_ASSERT_PTR_NON_NULL(config, NULL); 698 102 699 for (long i = 0; i < psArrayLength(mds); i++) { 700 psMetadata *md = mds->data[i]; 701 bool status = false; 702 psS32 det_id = psMetadataLookupS32(&status, md, "det_id"); 703 if (!status) { 704 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for det_id"); 705 return false; 706 } 707 psMetadataRemoveKey(md, "det_id"); 708 psString det_idStr = psDBIntToString((psU64)det_id); 709 psMetadataAddStr(mds->data[i], PS_LIST_HEAD, "det_id", 0, NULL, det_idStr); 710 psFree(det_idStr); 711 } 712 713 return true; 714 } 715 #endif 716 717 static bool definebyqueryMode(pxConfig *config) 718 { 719 bool status = false; 720 721 PS_ASSERT_PTR_NON_NULL(config, false); 722 723 // what type of detRun is this? 724 // det_type is required 725 psString det_type = psMetadataLookupStr(&status, config->args, "-det_type"); 726 if (!status) { 727 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type"); 728 return false; 729 } 730 if (!det_type) { 731 psError(PS_ERR_UNKNOWN, true, "-det_type is required"); 732 return false; 733 } 734 735 // optional 736 psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel"); 737 if (!status) { 738 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel"); 739 return false; 740 } 741 742 psString workdir = psMetadataLookupStr(&status, config->args, "-workdir"); 743 if (!status) { 744 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir"); 745 return false; 746 } 747 if (!workdir) { 748 psError(PS_ERR_UNKNOWN, true, "-workdir is required"); 749 return false; 750 } 751 psString camera = psMetadataLookupStr(&status, config->args, "-inst"); 752 if (!status) { 753 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst"); 754 return false; 755 } 756 if (!camera) { 757 psError(PS_ERR_UNKNOWN, false, "-inst is required"); 758 return false; 759 } 760 761 psMetadata *where = psMetadataAlloc(); 762 { 763 bool status = false; 764 psString exp_type = psMetadataLookupStr(&status, config->args, "-select_exp_type"); 765 if (!status) { 766 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_exp_type"); 767 return false; 768 } 769 if (exp_type) { 770 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_type", 0, "==", exp_type)) { 771 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_type"); 772 psFree(where); 773 return false; 774 } 775 } 776 777 // map -inst -> camera 778 psString camera = psMetadataLookupStr(&status, config->args, "-select_inst"); 779 if (!status) { 780 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_inst"); 781 return false; 782 } 783 if (camera) { 784 if (!psMetadataAddStr(where, PS_LIST_TAIL, "camera", 0, "==", camera)) { 785 psError(PS_ERR_UNKNOWN, false, "failed to add item inst"); 786 psFree(where); 787 return false; 788 } 789 } 790 791 psString telescope = psMetadataLookupStr(&status, config->args, "-select_telescope"); 792 if (!status) { 793 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_telescope"); 794 return false; 795 } 796 if (telescope) { 797 if (!psMetadataAddStr(where, PS_LIST_TAIL, "telescope", 0, "==", telescope)) { 798 psError(PS_ERR_UNKNOWN, false, "failed to add item telescope"); 799 psFree(where); 800 return false; 801 } 802 } 803 804 psString filter = psMetadataLookupStr(&status, config->args, "-select_filter"); 805 if (!status) { 806 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_filter"); 807 return false; 808 } 809 if (filter) { 810 if (!psMetadataAddStr(where, PS_LIST_TAIL, "filter", 0, "==", filter)) { 811 psError(PS_ERR_UNKNOWN, false, "failed to add item filter"); 812 psFree(where); 813 return false; 814 } 815 } 816 817 psString uri = psMetadataLookupStr(&status, config->args, "-select_uri"); 818 if (!status) { 819 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_uri"); 820 return false; 821 } 822 if (uri) { 823 if (!psMetadataAddStr(where, PS_LIST_TAIL, "uri", 0, "==", uri)) { 824 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 825 psFree(where); 826 return false; 827 } 828 } 829 830 psString dateobs_begin = psMetadataLookupStr(&status, config->args, "-select_dateobs_begin"); 831 if (!status) { 832 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_dateobs_begin"); 833 psFree(where); 834 return false; 835 } 836 if (dateobs_begin) { 837 psTime *time = psTimeFromISO(dateobs_begin, PS_TIME_UTC); 838 if (!time) { 839 psError(PS_ERR_UNKNOWN, false, "error in time format %s", dateobs_begin); 840 psFree(time); 841 psFree(where); 842 return false; 843 } 844 if (!psMetadataAddTime(where, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, ">=", time)) { 845 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs"); 846 psFree(time); 847 psFree(where); 848 return false; 849 } 850 psFree(time); 851 } 852 853 psString dateobs_end = psMetadataLookupStr(&status, config->args, "-select_dateobs_end"); 854 if (!status) { 855 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_dateobs_end"); 856 psFree(where); 857 return false; 858 } 859 if (dateobs_end) { 860 psTime *time = psTimeFromISO(dateobs_end, PS_TIME_UTC); 861 if (!time) { 862 psError(PS_ERR_UNKNOWN, false, "error in time format %s", dateobs_end); 863 psFree(time); 864 psFree(where); 865 return false; 866 } 867 if (!psMetadataAddTime(where, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, "<", time)) { 868 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs"); 869 psFree(time); 870 psFree(where); 871 return false; 872 } 873 psFree(time); 874 } 875 876 /** selection based on airmass range **/ 877 psF32 select_airmass_min = psMetadataLookupF32(&status, config->args, "-select_airmass_min"); 878 if (!status) { 879 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_airmass_min"); 880 psFree(where); 881 return false; 882 } 883 if (isfinite(select_airmass_min)) { 884 if (!psMetadataAddF32(where, PS_LIST_TAIL, "airmass", PS_META_DUPLICATE_OK, ">=", select_airmass_min)) { 885 psError(PS_ERR_UNKNOWN, false, "failed to add item airmass"); 886 psFree(where); 887 return false; 888 } 889 } 890 psF32 select_airmass_max = psMetadataLookupF32(&status, config->args, "-select_airmass_max"); 891 if (!status) { 892 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_airmass_max"); 893 psFree(where); 894 return false; 895 } 896 if (isfinite(select_airmass_max)) { 897 if (!psMetadataAddF32(where, PS_LIST_TAIL, "airmass", PS_META_DUPLICATE_OK, "<=", select_airmass_max)) { 898 psError(PS_ERR_UNKNOWN, false, "failed to add item airmass"); 899 psFree(where); 900 return false; 901 } 902 } 903 904 psF32 select_sat_pixel_frac_max = psMetadataLookupF32(&status, config->args, "-select_sat_pixel_frac_max"); 905 if (!status) { 906 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_sat_pixel_frac_max"); 907 psFree(where); 908 return false; 909 } 910 if (isfinite(select_sat_pixel_frac_max)) { 911 if (!psMetadataAddF32(where, PS_LIST_TAIL, "sat_pixel_frac", PS_META_DUPLICATE_OK, "<=", select_sat_pixel_frac_max)) { 912 psError(PS_ERR_UNKNOWN, false, "failed to add item sat_pixel_frac"); 913 psFree(where); 914 return false; 915 } 916 } 917 918 /** selection based on exp_time range **/ 919 psF32 select_exp_time_min = psMetadataLookupF32(&status, config->args, "-select_exp_time_min"); 920 if (!status) { 921 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_exp_time_min"); 922 psFree(where); 923 return false; 924 } 925 if (isfinite(select_exp_time_min)) { 926 if (!psMetadataAddF32(where, PS_LIST_TAIL, "exp_time", PS_META_DUPLICATE_OK, ">=", select_exp_time_min)) { 927 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_time"); 928 psFree(where); 929 return false; 930 } 931 } 932 psF32 select_exp_time_max = psMetadataLookupF32(&status, config->args, "-select_exp_time_max"); 933 if (!status) { 934 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_exp_time_max"); 935 psFree(where); 936 return false; 937 } 938 if (isfinite(select_exp_time_max)) { 939 if (!psMetadataAddF32(where, PS_LIST_TAIL, "exp_time", PS_META_DUPLICATE_OK, "<=", select_exp_time_max)) { 940 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_time"); 941 psFree(where); 942 return false; 943 } 944 } 945 946 /** selection based on ccd_temp range **/ 947 psF32 select_ccd_temp_min = psMetadataLookupF32(&status, config->args, "-select_ccd_temp_min"); 948 if (!status) { 949 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_ccd_temp_min"); 950 psFree(where); 951 return false; 952 } 953 if (isfinite(select_ccd_temp_min)) { 954 if (!psMetadataAddF32(where, PS_LIST_TAIL, "ccd_temp", PS_META_DUPLICATE_OK, ">=", select_ccd_temp_min)) { 955 psError(PS_ERR_UNKNOWN, false, "failed to add item ccd_temp"); 956 psFree(where); 957 return false; 958 } 959 } 960 psF32 select_ccd_temp_max = psMetadataLookupF32(&status, config->args, "-select_ccd_temp_max"); 961 if (!status) { 962 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_ccd_temp_max"); 963 psFree(where); 964 return false; 965 } 966 if (isfinite(select_ccd_temp_max)) { 967 if (!psMetadataAddF32(where, PS_LIST_TAIL, "ccd_temp", PS_META_DUPLICATE_OK, "<=", select_ccd_temp_max)) { 968 psError(PS_ERR_UNKNOWN, false, "failed to add item ccd_temp"); 969 psFree(where); 970 return false; 971 } 972 } 973 974 /** selection based on posang **/ 975 psF32 select_posang_min = psMetadataLookupF32(&status, config->args, "-select_posang_min"); 976 if (!status) { 977 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_posang_min"); 978 psFree(where); 979 return false; 980 } 981 if (isfinite(select_posang_min)) { 982 if (!psMetadataAddF32(where, PS_LIST_TAIL, "posang", PS_META_DUPLICATE_OK, ">=", select_posang_min)) { 983 psError(PS_ERR_UNKNOWN, false, "failed to add item posang"); 984 psFree(where); 985 return false; 986 } 987 } 988 psF32 select_posang_max = psMetadataLookupF32(&status, config->args, "-select_posang_max"); 989 if (!status) { 990 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_posang_max"); 991 psFree(where); 992 return false; 993 } 994 if (isfinite(select_posang_max)) { 995 if (!psMetadataAddF32(where, PS_LIST_TAIL, "posang", PS_META_DUPLICATE_OK, "<=", select_posang_max)) { 996 psError(PS_ERR_UNKNOWN, false, "failed to add item posang"); 997 psFree(where); 998 return false; 999 } 1000 } 1001 1002 /** selection based on solang **/ 1003 psF32 select_solang_min = psMetadataLookupF32(&status, config->args, "-select_solang_min"); 1004 if (!status) { 1005 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_solang_min"); 1006 psFree(where); 1007 return false; 1008 } 1009 if (isfinite(select_solang_min)) { 1010 if (!psMetadataAddF32(where, PS_LIST_TAIL, "solang", PS_META_DUPLICATE_OK, ">=", select_solang_min)) { 1011 psError(PS_ERR_UNKNOWN, false, "failed to add item solang"); 1012 psFree(where); 1013 return false; 1014 } 1015 } 1016 psF32 select_solang_max = psMetadataLookupF32(&status, config->args, "-select_solang_max"); 1017 if (!status) { 1018 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_solang_max"); 1019 psFree(where); 1020 return false; 1021 } 1022 if (isfinite(select_solang_max)) { 1023 if (!psMetadataAddF32(where, PS_LIST_TAIL, "solang", PS_META_DUPLICATE_OK, "<=", select_solang_max)) { 1024 psError(PS_ERR_UNKNOWN, false, "failed to add item solang"); 1025 psFree(where); 1026 return false; 1027 } 1028 } 1029 1030 } 1031 1032 if (!psListLength(where->list)) { 1033 psFree(where); 1034 where = NULL; 1035 } 1036 1037 // there is some namespace overlap between the names of the fields we'd 1038 // like to search by to setup a detrun and the names of the fields we'd 1039 // like to assign values to so I've seperated them but prepending set- to 1040 // the assigned values 1041 1042 // optional 1043 psString mode = psMetadataLookupStr(&status, config->args, "-mode"); 1044 if (!status) { 1045 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -mode"); 1046 return false; 1047 } 1048 // check mode 1049 if (mode && !isValidMode(config, mode)) { 1050 psError(PS_ERR_UNKNOWN, false, "invalud mode"); 1051 return false; 1052 } 1053 1054 psString telescope = psMetadataLookupStr(&status, config->args, "-telescope"); 1055 if (!status) { 1056 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope"); 1057 return false; 1058 } 1059 1060 psString filter = psMetadataLookupStr(&status, config->args, "-filter"); 1061 if (!status) { 1062 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter"); 1063 return false; 1064 } 1065 1066 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-airmass_min"); 1067 if (!status) { 1068 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_min"); 1069 return false; 1070 } 1071 1072 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-airmass_max"); 1073 if (!status) { 1074 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_max"); 1075 return false; 1076 } 1077 1078 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-exp_time_min"); 1079 if (!status) { 1080 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_min"); 1081 return false; 1082 } 1083 1084 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-exp_time_max"); 1085 if (!status) { 1086 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_max"); 1087 return false; 1088 } 1089 1090 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-ccd_temp_min"); 1091 if (!status) { 1092 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_min"); 1093 return false; 1094 } 1095 1096 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-ccd_temp_max"); 1097 if (!status) { 1098 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_max"); 1099 return false; 1100 } 1101 1102 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-posang_min"); 1103 if (!status) { 1104 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_min"); 1105 return false; 1106 } 1107 1108 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-posang_max"); 1109 if (!status) { 1110 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_max"); 1111 return false; 1112 } 1113 1114 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-solang_min"); 1115 if (!status) { 1116 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_min"); 1117 return false; 1118 } 1119 1120 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-solang_max"); 1121 if (!status) { 1122 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_max"); 1123 return false; 1124 } 1125 1126 psTime *registered = NULL; 1127 { 1128 psString registeredStr = psMetadataLookupStr(&status, config->args, "-registered"); 1129 if (!status) { 1130 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -registered"); 1131 return false; 1132 } 1133 // pass through NULL as this is an optional field 1134 if (registeredStr) { 1135 registered = psTimeFromISO(registeredStr, PS_TIME_UTC); 1136 if (!registered) { 1137 psError(PS_ERR_UNKNOWN, false, "error in time format %s", registeredStr); 1138 return false; 1139 } 1140 } else { 1141 registered = NULL; 1142 } 1143 } 1144 1145 psTime *time_begin = NULL; 1146 { 1147 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-time_begin"); 1148 if (!status) { 1149 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_begin"); 1150 return false; 1151 } 1152 // pass through NULL as this is an optional field 1153 if (time_beginStr) { 1154 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC); 1155 if (!time_begin) { 1156 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_beginStr); 1157 return false; 1158 } 1159 } else { 1160 time_begin = NULL; 1161 } 1162 } 1163 1164 psTime *time_end = NULL; 1165 { 1166 psString time_endStr = psMetadataLookupStr(&status, config->args, "-time_end"); 1167 if (!status) { 1168 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_end"); 1169 return false; 1170 } 1171 // pass through NULL as this is an optional field 1172 if (time_endStr) { 1173 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC); 1174 if (!time_end) { 1175 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_endStr); 1176 return false; 1177 } 1178 } else { 1179 time_end = NULL; 1180 } 1181 } 1182 1183 psTime *use_begin = NULL; 1184 { 1185 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-use_begin"); 1186 if (!status) { 1187 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_begin"); 1188 return false; 1189 } 1190 // pass through NULL as this is an optional field 1191 if (use_beginStr) { 1192 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC); 1193 if (!use_begin) { 1194 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_beginStr); 1195 return false; 1196 } 1197 } else { 1198 use_begin = NULL; 1199 } 1200 } 1201 1202 psTime *use_end = NULL; 1203 { 1204 psString use_endStr = psMetadataLookupStr(&status, config->args, "-use_end"); 1205 if (!status) { 1206 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_end"); 1207 return false; 1208 } 1209 // pass through NULL as this is an optional field 1210 if (use_endStr) { 1211 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC); 1212 if (!use_end) { 1213 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_endStr); 1214 return false; 1215 } 1216 } else { 1217 use_end = NULL; 1218 } 1219 } 1220 1221 psString reduction = psMetadataLookupStr(&status, config->args, "-reduction"); 1222 if (!status) { 1223 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reduction"); 1224 return false; 1225 } 1226 1227 psString label = psMetadataLookupStr(&status, config->args, "-label"); 1228 if (!status) { 1229 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label"); 1230 return false; 1231 } 1232 1233 bool simple = psMetadataLookupBool(&status, config->args, "-simple"); 1234 if (!status) { 1235 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 1236 psFree(registered); 1237 psFree(use_begin); 1238 psFree(use_end); 1239 return false; 1240 } 1241 1242 bool pretend = psMetadataLookupBool(&status, config->args, "-pretend"); 1243 if (!status) { 1244 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -pretend"); 1245 psFree(registered); 1246 psFree(use_begin); 1247 psFree(use_end); 1248 return false; 1249 } 1250 1251 // search for rawExps with the specified options 1252 psArray *detrendExps = rawExpSelectRowObjects(config->dbh, where, 0); 1253 psFree(where); 1254 // make sure that we found at least one rawExp 1255 if (!detrendExps) { 1256 psError(PS_ERR_UNKNOWN, false, "database error"); 1257 psFree(registered); 1258 psFree(use_begin); 1259 psFree(use_end); 1260 return false; 1261 } 1262 if (!psArrayLength(detrendExps)) { 1263 psTrace("dettool", PS_LOG_INFO, "no rows found"); 1264 psFree(detrendExps); 1265 psFree(registered); 1266 psFree(use_begin); 1267 psFree(use_end); 1268 return true; 1269 } 1270 1271 // check to see if -filelevel was set on the command line 1272 if (!filelevel) { 1273 filelevel = psStringCopy(((rawExpRow *)detrendExps->data[0])->filelevel); 1274 } 1275 1276 if (pretend) { 1277 // negative simple so the default is true 1278 if (!rawExpPrintObjects(stdout, detrendExps, !simple)) { 1279 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 1280 psFree(detrendExps); 1281 psFree(registered); 1282 psFree(use_begin); 1283 psFree(use_end); 1284 return false; 1285 } 1286 psFree(detrendExps); 1287 psFree(registered); 1288 psFree(use_begin); 1289 psFree(use_end); 1290 return true; 1291 } 1292 1293 // start a transaction so we don't end up with childlessed det_ids 1294 if (!psDBTransaction(config->dbh)) { 1295 psError(PS_ERR_UNKNOWN, false, "database error"); 1296 psFree(detrendExps); 1297 psFree(registered); 1298 psFree(use_begin); 1299 psFree(use_end); 1300 return false; 1301 } 1302 1303 // the first iteration is always 0 1304 // XXX det_id 1305 detRunInsert(config->dbh, 1306 0, // det_id 1307 0, // iteration 1308 det_type, 1309 mode, 1310 "run", // state 1311 filelevel, 1312 workdir, 1313 camera, 1314 telescope, 1315 "NA", 1316 reduction, 1317 filter, 1318 airmass_min, 1319 airmass_max, 1320 exp_time_min, 1321 exp_time_max, 1322 ccd_temp_min, 1323 ccd_temp_max, 1324 posang_min, 1325 posang_max, 1326 registered, 1327 time_begin, 1328 time_end, 1329 use_begin, 1330 use_end, 1331 solang_min, 1332 solang_max, 1333 label, 1334 0 // parent 1335 ); 1336 psFree(registered); 1337 psFree(time_begin); 1338 psFree(time_end); 1339 psFree(use_end); 1340 psFree(use_begin); 1341 psFree(use_end); 1342 psS64 det_id = psDBLastInsertID(config->dbh); 1343 1344 // create new detInputExp row(s) from the rawExp row(s) 1345 psArray *inputExps = psArrayAllocEmpty(psArrayLength(detrendExps)); 1346 for (long i = 0; i < psArrayLength(detrendExps); i++) { 1347 detInputExpRow *inputExp = rawDetrenTodetInputExpRow( 1348 detrendExps->data[i], 1349 det_id, 1350 0 // the first iteration is explicitly 0 1351 ); 1352 psArrayAdd(inputExps, 0, inputExp); 1353 psFree(inputExp); 1354 } 1355 1356 psFree(detrendExps); 1357 1358 // insert detInputExp objects into the database 1359 if (!detInputExpInsertObjects(config->dbh, inputExps)) { 1360 psError(PS_ERR_UNKNOWN, false, "database error"); 1361 // rollback 1362 if (!psDBRollback(config->dbh)) { 1363 psError(PS_ERR_UNKNOWN, false, "database error"); 1364 } 1365 psFree(inputExps); 1366 return false; 1367 } 1368 psFree(inputExps); 1369 1370 // point of no return for det_id creation 1371 if (!psDBCommit(config->dbh)) { 1372 psError(PS_ERR_UNKNOWN, false, "database error"); 1373 return false; 1374 } 1375 1376 1377 // print the new det_id 1378 psArray *detRuns = NULL; 1379 { 1380 psMetadata *where = psMetadataAlloc(); 1381 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id); 1382 detRuns = psDBSelectRows(config->dbh, "detRun", where, 0); 1383 psFree(where); 1384 } 1385 if (!detRuns) { 1386 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created"); 1387 return false; 1388 } 1389 // sanity check results 1390 if (psArrayLength(detRuns) != 1) { 1391 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", det_id); 1392 return false; 1393 } 1394 1395 // convert det_id to a string externaly 1396 if (!convertIdToStr(detRuns)) { 1397 psError(PS_ERR_UNKNOWN, false, "failed to convert det_id to a string"); 1398 psFree(detRuns); 1399 return false; 1400 } 1401 1402 // negative simple so the default is true 1403 if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) { 1404 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 1405 psFree(detRuns); 1406 return false; 1407 } 1408 psFree(detRuns); 1409 1410 return true; 103 return false; 1411 104 } 1412 105 1413 static bool definebydetrunMode(pxConfig *config)1414 {1415 bool status = false;1416 1417 PS_ASSERT_PTR_NON_NULL(config, false);1418 1419 // det_id is the only required input1420 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");1421 if (!status) {1422 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");1423 return false;1424 }1425 if (!det_id) {1426 psError(PS_ERR_UNKNOWN, true, "-det_id is required");1427 return false;1428 }1429 1430 // lookup the detRun that we will be basing this one on1431 psArray *detRuns = NULL;1432 {1433 psMetadata *where = psMetadataAlloc();1434 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", (psS64)atoll(det_id));1435 detRuns = detRunSelectRowObjects(config->dbh, where, 0);1436 psFree(where);1437 }1438 if (!detRuns) {1439 psError(PS_ERR_UNKNOWN, false, "database error");1440 return false;1441 }1442 // sanity check the result... we should have only found one det_id1443 if (psArrayLength(detRuns) != 1) {1444 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", (psS64)atoll(det_id));1445 return false; // unreachable1446 }1447 1448 // pull the detRun object out the result array1449 detRunRow *detRun = psMemIncrRefCounter(detRuns->data[0]);1450 1451 // discard the resultarray1452 psFree(detRuns);1453 1454 // set the det_id to 0/NULL so the database can assign it1455 detRun->det_id = 0;1456 1457 // reset the iteration to 01458 detRun->iteration = 0;1459 1460 // reset the state to "run"1461 psFree(detRun->state);1462 detRun->state = psStringCopy("run");1463 1464 // walk through the optional values and update the detRun as required1465 psString det_type = psMetadataLookupStr(&status, config->args, "-set_det_type");1466 if (!status) {1467 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_det_type");1468 return false;1469 }1470 if (det_type) {1471 psFree(detRun->det_type);1472 detRun->det_type = psStringCopy(det_type);1473 }1474 1475 psString mode = psMetadataLookupStr(&status, config->args, "-set_mode");1476 if (!status) {1477 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_mode");1478 return false;1479 }1480 // check mode1481 if (mode && !isValidMode(config, mode)) {1482 psError(PS_ERR_UNKNOWN, false, "invalud mode");1483 return false;1484 }1485 if (mode) {1486 psFree(detRun->mode);1487 detRun->mode = psStringCopy(mode);1488 }1489 1490 psString camera = psMetadataLookupStr(&status, config->args, "-set_inst");1491 if (!status) {1492 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_inst");1493 return false;1494 }1495 if (camera) {1496 psFree(detRun->camera);1497 detRun->camera = psStringCopy(camera);1498 }1499 1500 psString telescope = psMetadataLookupStr(&status, config->args, "-set_telescope");1501 if (!status) {1502 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_telescope");1503 return false;1504 }1505 if (telescope) {1506 psFree(detRun->telescope);1507 detRun->telescope = psStringCopy(telescope);1508 }1509 1510 psString exp_type = psMetadataLookupStr(&status, config->args, "-set_exp_type");1511 if (!status) {1512 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_type");1513 return false;1514 }1515 if (exp_type) {1516 psFree(detRun->exp_type);1517 detRun->exp_type = psStringCopy(exp_type);1518 }1519 1520 psString filelevel = psMetadataLookupStr(&status, config->args, "-set_filelevel");1521 if (!status) {1522 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_filelevel");1523 return false;1524 }1525 if (filelevel) {1526 psFree(detRun->filelevel);1527 detRun->filelevel = psStringCopy(filelevel);1528 }1529 1530 psString workdir = psMetadataLookupStr(&status, config->args, "-set_workdir");1531 if (!status) {1532 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_workdir");1533 return false;1534 }1535 if (workdir) {1536 psFree(detRun->workdir);1537 detRun->workdir = psStringCopy(workdir);1538 }1539 1540 psString filter = psMetadataLookupStr(&status, config->args, "-set_filter");1541 if (!status) {1542 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_filter");1543 return false;1544 }1545 if (filter) {1546 psFree(detRun->filter);1547 detRun->filter = psStringCopy(filter);1548 }1549 1550 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-set_airmass_min");1551 if (!status) {1552 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_airmass_min");1553 return false;1554 }1555 if (!isnan(airmass_min)) {1556 detRun->airmass_min = airmass_min;1557 }1558 1559 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-set_airmass_max");1560 if (!status) {1561 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_airmass_max");1562 return false;1563 }1564 if (!isnan(airmass_max)) {1565 detRun->airmass_max = airmass_max;1566 }1567 1568 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-set_exp_time_min");1569 if (!status) {1570 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_time_min");1571 return false;1572 }1573 if (!isnan(exp_time_min)) {1574 detRun->exp_time_min = exp_time_min;1575 }1576 1577 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-set_exp_time_max");1578 if (!status) {1579 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_time_max");1580 return false;1581 }1582 if (!isnan(exp_time_max)) {1583 detRun->exp_time_max = exp_time_max;1584 }1585 1586 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-set_ccd_temp_min");1587 if (!status) {1588 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_ccd_temp_min");1589 return false;1590 }1591 if (!isnan(ccd_temp_min)) {1592 detRun->ccd_temp_min = ccd_temp_min;1593 }1594 1595 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-set_ccd_temp_max");1596 if (!status) {1597 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_ccd_temp_max");1598 return false;1599 }1600 if (!isnan(ccd_temp_max)) {1601 detRun->ccd_temp_max = ccd_temp_max;1602 }1603 1604 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-set_posang_min");1605 if (!status) {1606 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_posang_min");1607 return false;1608 }1609 if (!isnan(posang_min)) {1610 detRun->posang_min = posang_min;1611 }1612 1613 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-set_posang_max");1614 if (!status) {1615 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_posang_max");1616 return false;1617 }1618 if (!isnan(posang_max)) {1619 detRun->posang_max = posang_max;1620 }1621 1622 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-set_solang_min");1623 if (!status) {1624 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_solang_min");1625 return false;1626 }1627 if (!isnan(solang_min)) {1628 detRun->solang_min = solang_min;1629 }1630 1631 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-set_solang_max");1632 if (!status) {1633 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_solang_max");1634 return false;1635 }1636 if (!isnan(solang_max)) {1637 detRun->solang_max = solang_max;1638 }1639 1640 psString label = psMetadataLookupStr(&status, config->args, "-set_label");1641 if (!status) {1642 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_label");1643 return false;1644 }1645 if (label) {1646 detRun->label = label;1647 }1648 1649 psTime *registered = NULL;1650 {1651 psString registeredStr = psMetadataLookupStr(&status, config->args, "-set_registered");1652 if (!status) {1653 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_registered");1654 return false;1655 }1656 // pass through NULL as this is an optional field1657 if (registeredStr) {1658 psFree(detRun->registered);1659 registered = psTimeFromISO(registeredStr, PS_TIME_UTC);1660 detRun->registered = psMemIncrRefCounter(registered);1661 psFree(registered);1662 }1663 }1664 1665 psTime *time_begin = NULL;1666 {1667 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-set_time_begin");1668 if (!status) {1669 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_time_begin");1670 return false;1671 }1672 // pass through NULL as this is an optional field1673 if (time_beginStr) {1674 psFree(detRun->time_begin);1675 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC);1676 detRun->time_begin = psMemIncrRefCounter(time_begin);1677 psFree(time_begin);1678 }1679 }1680 1681 psTime *time_end = NULL;1682 {1683 psString time_endStr = psMetadataLookupStr(&status, config->args, "-set_time_end");1684 if (!status) {1685 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_time_end");1686 return false;1687 }1688 // pass through NULL as this is an optional field1689 if (time_endStr) {1690 psFree(detRun->time_end);1691 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC);1692 detRun->time_end = psMemIncrRefCounter(time_end);1693 psFree(time_end);1694 }1695 }1696 1697 psTime *use_begin = NULL;1698 {1699 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-set_use_begin");1700 if (!status) {1701 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_use_begin");1702 return false;1703 }1704 // pass through NULL as this is an optional field1705 if (use_beginStr) {1706 psFree(detRun->use_begin);1707 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC);1708 detRun->use_begin = psMemIncrRefCounter(use_begin);1709 psFree(use_begin);1710 }1711 }1712 1713 psTime *use_end = NULL;1714 {1715 psString use_endStr = psMetadataLookupStr(&status, config->args, "-set_use_end");1716 if (!status) {1717 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_use_end");1718 return false;1719 }1720 // pass through NULL as this is an optional field1721 if (use_endStr) {1722 psFree(detRun->use_end);1723 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC);1724 detRun->use_end = psMemIncrRefCounter(use_end);1725 psFree(use_end);1726 }1727 }1728 1729 psString reduction = psMetadataLookupStr(&status, config->args, "-set_reduction");1730 if (!status) {1731 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_reduction");1732 return false;1733 }1734 if (reduction) {1735 psFree(detRun->reduction);1736 detRun->reduction = psStringCopy(reduction);1737 }1738 1739 // create a metadata to restrict detInputExp's be in in the specified range1740 1741 psMetadata *time_filter = psMetadataAlloc();1742 1743 {1744 psString timeStr = psMetadataLookupStr(&status, config->args, "-filter_input_begin");1745 if (!status) {1746 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter_input_begin");1747 return false;1748 }1749 // pass through NULL as this is an optional field1750 if (timeStr) {1751 psTime *time = psTimeFromISO(timeStr, PS_TIME_UTC);1752 if (!psMetadataAddTime(time_filter, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, ">=", time)) {1753 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");1754 psFree(time);1755 psFree(time_filter);1756 return false;1757 }1758 psFree(time);1759 }1760 }1761 1762 {1763 psString timeStr = psMetadataLookupStr(&status, config->args, "-filter_input_end");1764 if (!status) {1765 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter_input_end");1766 return false;1767 }1768 // pass through NULL as this is an optional field1769 if (timeStr) {1770 psTime *time = psTimeFromISO(timeStr, PS_TIME_UTC);1771 if (!psMetadataAddTime(time_filter, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, "<", time)) {1772 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs");1773 psFree(time);1774 psFree(time_filter);1775 return false;1776 }1777 psFree(time);1778 }1779 }1780 1781 1782 // start a transaction so we don't end up with childlessed det_ids1783 if (!psDBTransaction(config->dbh)) {1784 psError(PS_ERR_UNKNOWN, false, "database error");1785 psFree(time_filter);1786 psFree(detRun);1787 return false;1788 }1789 1790 if (!detRunInsertObject(config->dbh, detRun)) {1791 psError(PS_ERR_UNKNOWN, false, "database error");1792 // rollback1793 if (!psDBRollback(config->dbh)) {1794 psError(PS_ERR_UNKNOWN, false, "database error");1795 }1796 psFree(time_filter);1797 psFree(detRun);1798 return false;1799 }1800 psFree(detRun);1801 1802 // get the det_id1803 psS64 newDet_id = psDBLastInsertID(config->dbh);1804 1805 psString query = psStringCopy(1806 "INSERT INTO detInputExp"1807 " SELECT"1808 " %d,"1809 " 0,"1810 " detResidExp.exp_id,"1811 " detResidExp.accept"1812 " FROM detResidExp"1813 " JOIN rawExp"1814 " USING(exp_id)"1815 " WHERE det_id = %d"1816 );1817 1818 if (time_filter->list->n) {1819 psString whereClause = psDBGenerateWhereConditionSQL(time_filter, "rawExp");1820 psStringAppend(&query, " AND %s", whereClause);1821 psFree(whereClause);1822 }1823 psFree(time_filter);1824 1825 if (!p_psDBRunQuery(config->dbh, query, (psS64)newDet_id, (psS64)atoll(det_id))) {1826 psError(PS_ERR_UNKNOWN, false, "database error");1827 psFree(query);1828 return false;1829 }1830 psFree(query);1831 1832 // point of no return for det_id creation1833 if (!psDBCommit(config->dbh)) {1834 psError(PS_ERR_UNKNOWN, false, "database error");1835 return false;1836 }1837 1838 bool simple = false;1839 {1840 bool status = false;1841 simple = psMetadataLookupBool(&status, config->args, "-simple");1842 if (!status) {1843 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");1844 return false;1845 }1846 }1847 1848 // print the new det_id1849 psArray *newDetRuns = NULL;1850 {1851 psMetadata *where = psMetadataAlloc();1852 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", newDet_id);1853 newDetRuns = psDBSelectRows(config->dbh, "detRun", where, 0);1854 psFree(where);1855 }1856 if (!newDetRuns) {1857 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created");1858 return false;1859 }1860 // sanity check the result... we should have only found one det_id1861 if (psArrayLength(newDetRuns) != 1) {1862 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", newDet_id);1863 return false; // unreachable1864 }1865 1866 // convert det_id to a string externaly1867 if (!convertIdToStr(detRuns)) {1868 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings");1869 psFree(detRuns);1870 return false;1871 }1872 1873 // negative simple so the default is true1874 if (!ippdbPrintMetadatas(stdout, newDetRuns, "detRun", !simple)) {1875 psError(PS_ERR_UNKNOWN, false, "failed to print array");1876 psFree(newDetRuns);1877 return false;1878 }1879 psFree(newDetRuns);1880 1881 return true;1882 }1883 106 1884 107 static bool runsMode(pxConfig *config) 1885 108 { 1886 PS_ASSERT_PTR_NON_NULL(config, false);1887 1888 // XXX fix the hard coding of the table name1889 psArray *runs = psDBSelectRows(config->dbh, "detRun", config->where, 0);1890 if (!runs) {1891 psError(PS_ERR_UNKNOWN, false, "database error");1892 return false;1893 }1894 1895 if (!psArrayLength(runs)) {1896 psTrace("dettool", PS_LOG_INFO, "no rows found");1897 psFree(runs);1898 return true;1899 }1900 1901 // convert det_id to a string externaly1902 if (!convertIdToStr(runs)) {1903 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings");1904 psFree(runs);1905 return false;1906 }1907 1908 bool simple = false;1909 {1910 bool status = false;1911 simple = psMetadataLookupBool(&status, config->args, "-simple");1912 if (!status) {1913 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");1914 return false;1915 }1916 }1917 1918 // negative simple so the default is true1919 if (!ippdbPrintMetadatas(stdout, runs, "detRun", !simple)) {1920 psError(PS_ERR_UNKNOWN, false, "failed to print array");1921 psFree(runs);1922 return false;1923 }1924 1925 psFree(runs);1926 1927 return true;1928 }1929 1930 static bool childlessrunMode(pxConfig *config)1931 {1932 PS_ASSERT_PTR_NON_NULL(config, false);1933 1934 bool status = false;1935 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");1936 if (!status) {1937 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");1938 return false;1939 }1940 1941 psString query = psStringCopy(1942 "SELECT DISTINCT\n"1943 " detRun.*\n"1944 " FROM detRun\n"1945 " LEFT JOIN detRun as foo\n"1946 " ON foo.parent = detRun.det_id\n"1947 " WHERE\n"1948 " detRun.state = 'stop'\n"1949 " AND detRun.mode = 'master'\n"1950 " AND foo.det_id IS NULL\n"1951 );1952 1953 if (config->where) {1954 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detRun");1955 psStringAppend(&query, " AND %s", whereClause);1956 psFree(whereClause);1957 }1958 1959 // treat limit == 0 as "no limit"1960 if (limit) {1961 psString limitString = psDBGenerateLimitSQL(limit);1962 psStringAppend(&query, " %s", limitString);1963 psFree(limitString);1964 }1965 1966 if (!p_psDBRunQuery(config->dbh, query)) {1967 psError(PS_ERR_UNKNOWN, false, "database error");1968 psFree(query);1969 return false;1970 }1971 psFree(query);1972 1973 psArray *output = p_psDBFetchResult(config->dbh);1974 if (!output) {1975 psError(PS_ERR_UNKNOWN, false, "database error");1976 return false;1977 }1978 if (!psArrayLength(output)) {1979 psTrace("dettool", PS_LOG_INFO, "no rows found");1980 psFree(output);1981 return true;1982 }1983 1984 // convert det_id to a string externaly1985 if (!convertIdToStr(output)) {1986 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings");1987 psFree(output);1988 return false;1989 }1990 1991 bool simple = false;1992 {1993 bool status = false;1994 simple = psMetadataLookupBool(&status, config->args, "-simple");1995 if (!status) {1996 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");1997 psFree(output);1998 return false;1999 }2000 }2001 2002 // negative simple so the default is true2003 if (!ippdbPrintMetadatas(stdout, output, "detRun", !simple)) {2004 psError(PS_ERR_UNKNOWN, false, "failed to print array");2005 psFree(output);2006 return false;2007 }2008 2009 psFree(output);2010 2011 return true;2012 }2013 2014 static detInputExpRow *rawDetrenTodetInputExpRow(rawExpRow *rawExp, psS64 det_id, psS32 iteration)2015 {2016 PS_ASSERT_PTR_NON_NULL(rawExp, NULL);2017 2018 return detInputExpRowAlloc(2019 det_id,2020 iteration,2021 rawExp->exp_id,2022 true // use2023 );2024 }2025 2026 static bool inputMode(pxConfig *config)2027 {2028 PS_ASSERT_PTR_NON_NULL(config, false);2029 2030 // select detInputExp.*2031 // select rawExp.*2032 // by:2033 // exp_id2034 2035 psString query = psStringCopy(2036 "SELECT DISTINCT *"2037 " FROM detInputExp"2038 " JOIN rawExp"2039 " USING(exp_id)"2040 );2041 2042 if (config->where) {2043 psString whereClause = psDBGenerateWhereSQL(config->where, "detInputExp");2044 psStringAppend(&query, " %s", whereClause);2045 psFree(whereClause);2046 }2047 2048 if (!p_psDBRunQuery(config->dbh, query)) {2049 psError(PS_ERR_UNKNOWN, false, "database error");2050 psFree(query);2051 return false;2052 }2053 psFree(query);2054 2055 psArray *output = p_psDBFetchResult(config->dbh);2056 if (!output) {2057 psError(PS_ERR_UNKNOWN, false, "database error");2058 return false;2059 }2060 if (!psArrayLength(output)) {2061 psTrace("dettool", PS_LOG_INFO, "no rows found");2062 psFree(output);2063 return true;2064 }2065 2066 bool simple = false;2067 {2068 bool status = false;2069 simple = psMetadataLookupBool(&status, config->args, "-simple");2070 if (!status) {2071 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2072 return false;2073 }2074 }2075 2076 // negative simple so the default is true2077 if (!ippdbPrintMetadatas(stdout, output, "detInputExp", !simple)) {2078 psError(PS_ERR_UNKNOWN, false, "failed to print array");2079 psFree(output);2080 return false;2081 }2082 2083 psFree(output);2084 2085 return true;2086 }2087 2088 static bool rawMode(pxConfig *config)2089 {2090 PS_ASSERT_PTR_NON_NULL(config, false);2091 2092 psString query = pxDataGet("dettool_raw.sql");2093 if (!query) {2094 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");2095 return false;2096 }2097 2098 if (config->where) {2099 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawImfile");2100 psStringAppend(&query, " AND %s", whereClause);2101 psFree(whereClause);2102 }2103 2104 if (!p_psDBRunQuery(config->dbh, query)) {2105 psError(PS_ERR_UNKNOWN, false, "database error");2106 psFree(query);2107 return false;2108 }2109 psFree(query);2110 2111 psArray *output = p_psDBFetchResult(config->dbh);2112 if (!output) {2113 psError(PS_ERR_UNKNOWN, false, "database error");2114 return false;2115 }2116 if (!psArrayLength(output)) {2117 psTrace("dettool", PS_LOG_INFO, "no rows found");2118 psFree(output);2119 return true;2120 }2121 2122 bool simple = false;2123 {2124 bool status = false;2125 simple = psMetadataLookupBool(&status, config->args, "-simple");2126 if (!status) {2127 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2128 return false;2129 }2130 }2131 2132 // negative simple so the default is true2133 if (!ippdbPrintMetadatas(stdout, output, "rawImfile", !simple)) {2134 psError(PS_ERR_UNKNOWN, false, "failed to print array");2135 psFree(output);2136 return false;2137 }2138 2139 psFree(output);2140 2141 return true;2142 }2143 2144 static bool toprocessedimfileMode(pxConfig *config)2145 {2146 PS_ASSERT_PTR_NON_NULL(config, false);2147 2148 bool status = false;2149 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");2150 if (!status) {2151 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");2152 return false;2153 }2154 2155 psString query = pxDataGet("dettool_toprocessedimfile.sql");2156 if (!query) {2157 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");2158 return false;2159 }2160 2161 if (config->where) {2162 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawImfile");2163 psStringAppend(&query, " AND %s", whereClause);2164 psFree(whereClause);2165 }2166 2167 // treat limit == 0 as "no limit"2168 if (limit) {2169 psString limitString = psDBGenerateLimitSQL(limit);2170 psStringAppend(&query, " %s", limitString);2171 psFree(limitString);2172 }2173 2174 if (!p_psDBRunQuery(config->dbh, query)) {2175 psError(PS_ERR_UNKNOWN, false, "database error");2176 psFree(query);2177 return false;2178 }2179 psFree(query);2180 2181 psArray *output = p_psDBFetchResult(config->dbh);2182 if (!output) {2183 psError(PS_ERR_UNKNOWN, false, "database error");2184 return false;2185 }2186 if (!psArrayLength(output)) {2187 psTrace("dettool", PS_LOG_INFO, "no rows found");2188 psFree(output);2189 return true;2190 }2191 2192 bool simple = false;2193 {2194 bool status = false;2195 simple = psMetadataLookupBool(&status, config->args, "-simple");2196 if (!status) {2197 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2198 return false;2199 }2200 }2201 2202 // negative simple so the default is true2203 if (!ippdbPrintMetadatas(stdout, output, "detPendingProcessedImfile", !simple)) {2204 psError(PS_ERR_UNKNOWN, false, "failed to print array");2205 psFree(output);2206 return false;2207 }2208 2209 psFree(output);2210 2211 return true;2212 }2213 2214 static psArray *searchRawImfiles(pxConfig *config, psMetadata *where)2215 {2216 109 PS_ASSERT_PTR_NON_NULL(config, NULL); 2217 110 2218 // use the default where if "where" is NULL 2219 if (!where) { 2220 where = config->where; 2221 } 2222 2223 // select exp_ids from detInputExp matching det_idp 2224 // where query should be pre-generated 2225 psArray *detInputExp = 2226 detInputExpSelectRowObjects(config->dbh, where, 0); 2227 if (!detInputExp) { 2228 psError(PS_ERR_UNKNOWN, false, "no rawExp rows found"); 2229 return NULL; 2230 } 2231 2232 // generate where query with just the exp_ids 2233 psMetadata *where_exp_ids = psMetadataAlloc(); 2234 for (long i = 0; i < psArrayLength(detInputExp); i++) { 2235 detInputExpRow *row = detInputExp->data[i]; 2236 if (!psMetadataAddS64(where_exp_ids, PS_LIST_TAIL, "exp_id", 2237 PS_META_DUPLICATE_OK, "==", row->exp_id) 2238 ) { 2239 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 2240 psFree(detInputExp); 2241 psFree(where_exp_ids); 2242 return NULL; 2243 } 2244 } 2245 psFree(detInputExp); 2246 2247 // select rawImfiles with matching exp_ids 2248 psArray *rawImfiles = 2249 rawImfileSelectRowObjects(config->dbh, where_exp_ids, 0); 2250 psFree(where_exp_ids); 2251 if (!rawImfiles) { 2252 psError(PS_ERR_UNKNOWN, false, "no rawImfile rows found"); 2253 return NULL; 2254 } 2255 2256 return rawImfiles; 111 return false; 2257 112 } 2258 2259 static bool addprocessedimfileMode(pxConfig *config)2260 {2261 PS_ASSERT_PTR_NON_NULL(config, false);2262 2263 // det_id, exp_id, class_id, uri, recipe, -bg, -bg_stdev2264 // are required2265 bool status = false;2266 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");2267 if (!status) {2268 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");2269 return false;2270 }2271 if (!det_id) {2272 psError(PS_ERR_UNKNOWN, true, "-det_id is required");2273 return false;2274 }2275 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");2276 if (!status) {2277 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");2278 return false;2279 }2280 if (!exp_id) {2281 psError(PS_ERR_UNKNOWN, true, "-exp_id is required");2282 return false;2283 }2284 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id");2285 if (!status) {2286 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id");2287 return false;2288 }2289 if (!class_id) {2290 psError(PS_ERR_UNKNOWN, true, "-class_id is required");2291 return false;2292 }2293 psString uri = psMetadataLookupStr(&status, config->args, "-uri");2294 if (!status) {2295 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri");2296 return false;2297 }2298 if (!uri) {2299 psError(PS_ERR_UNKNOWN, true, "-uri is required");2300 return false;2301 }2302 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");2303 if (!status) {2304 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");2305 return false;2306 }2307 if (!recipe) {2308 psError(PS_ERR_UNKNOWN, true, "-recip is required");2309 return false;2310 }2311 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");2312 if (!status) {2313 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");2314 return false;2315 }2316 //if (isnan(bg)) {2317 //psError(PS_ERR_UNKNOWN, true, "-bg is required");2318 //return false;2319 //}2320 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");2321 if (!status) {2322 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");2323 return false;2324 }2325 //if (isnan(bg_stdev)) {2326 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");2327 // return false;2328 //}2329 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");2330 if (!status) {2331 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");2332 return false;2333 }2334 2335 // optional2336 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0");2337 if (!status) {2338 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0");2339 return false;2340 }2341 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1");2342 if (!status) {2343 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1");2344 return false;2345 }2346 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2");2347 if (!status) {2348 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2");2349 return false;2350 }2351 2352 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");2353 if (!status) {2354 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");2355 return false;2356 }2357 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");2358 if (!status) {2359 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");2360 return false;2361 }2362 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");2363 if (!status) {2364 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");2365 return false;2366 }2367 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");2368 if (!status) {2369 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");2370 return false;2371 }2372 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");2373 if (!status) {2374 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");2375 return false;2376 }2377 2378 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");2379 if (!status) {2380 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");2381 return false;2382 }2383 2384 // find the matching rawImfile by exp_id/class_id2385 psMetadata *where = psMetadataAlloc();2386 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) {2387 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");2388 psFree(where);2389 return false;2390 }2391 if (!psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==", class_id)) {2392 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");2393 psFree(where);2394 return false;2395 }2396 2397 // default values2398 psS16 code = psMetadataLookupS16(&status, config->args, "-code");2399 if (!status) {2400 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");2401 return false;2402 }2403 2404 psArray *rawImfiles = rawImfileSelectRowObjects(config->dbh, where, 0);2405 psFree(where);2406 if (!rawImfiles) {2407 psError(PS_ERR_UNKNOWN, false, "no rawImfile rows found ");2408 return false;2409 }2410 2411 2412 // create a new detProcessedImfile object2413 detProcessedImfileRow *detRow = detProcessedImfileRowAlloc(2414 (psS64)atoll(det_id),2415 (psS64)atoll(exp_id),2416 class_id,2417 uri,2418 recipe,2419 bg,2420 bg_stdev,2421 bg_mean_stdev,2422 fringe_0,2423 fringe_1,2424 fringe_2,2425 user_1,2426 user_2,2427 user_3,2428 user_4,2429 user_5,2430 path_base,2431 code2432 );2433 psFree(rawImfiles);2434 2435 // insert the new row into the detProcessedImfile table2436 if (!detProcessedImfileInsertObject(config->dbh, detRow)) {2437 psError(PS_ERR_UNKNOWN, false, "database error");2438 psFree(detRow);2439 return false;2440 }2441 2442 psFree(detRow);2443 2444 return true;2445 }2446 2447 static bool toprocessedexpMode(pxConfig *config)2448 {2449 PS_ASSERT_PTR_NON_NULL(config, false);2450 2451 bool status = false;2452 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");2453 if (!status) {2454 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");2455 return false;2456 }2457 2458 psString query = pxDataGet("dettool_toprocessedexp.sql");2459 if (!query) {2460 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");2461 return false;2462 }2463 2464 // XXX does it make sense to accept any search params?2465 #if 02466 if (config->where) {2467 psString whereClause = psDBGenerateWhereConditionSQL(config->where);2468 psStringAppend(&query, " AND %s", whereClause);2469 psFree(whereClause);2470 }2471 #endif2472 2473 // treat limit == 0 as "no limit"2474 if (limit) {2475 psString limitString = psDBGenerateLimitSQL(limit);2476 psStringAppend(&query, " %s", limitString);2477 psFree(limitString);2478 }2479 2480 if (!p_psDBRunQuery(config->dbh, query)) {2481 psError(PS_ERR_UNKNOWN, false, "database error");2482 psFree(query);2483 return false;2484 }2485 psFree(query);2486 2487 psArray *output = p_psDBFetchResult(config->dbh);2488 if (!output) {2489 psError(PS_ERR_UNKNOWN, false, "database error");2490 return false;2491 }2492 if (!psArrayLength(output)) {2493 psTrace("dettool", PS_LOG_INFO, "no rows found");2494 psFree(output);2495 return true;2496 }2497 2498 bool simple = false;2499 {2500 bool status = false;2501 simple = psMetadataLookupBool(&status, config->args, "-simple");2502 if (!status) {2503 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2504 return false;2505 }2506 }2507 2508 // negative simple so the default is true2509 if (!ippdbPrintMetadatas(stdout, output, "detPendingProcessedExp", !simple)) {2510 psError(PS_ERR_UNKNOWN, false, "failed to print array");2511 psFree(output);2512 return false;2513 }2514 2515 psFree(output);2516 2517 return true;2518 }2519 2520 static bool addprocessedexpMode(pxConfig *config)2521 {2522 PS_ASSERT_PTR_NON_NULL(config, false);2523 2524 // det_id, exp_id, recip, -bg, -bg_stdev2525 // are required2526 bool status = false;2527 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");2528 if (!status) {2529 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");2530 return false;2531 }2532 if (!det_id) {2533 psError(PS_ERR_UNKNOWN, true, "-det_id is required");2534 return false;2535 }2536 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");2537 if (!status) {2538 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");2539 return false;2540 }2541 if (!exp_id) {2542 psError(PS_ERR_UNKNOWN, true, "-exp_id is required");2543 return false;2544 }2545 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");2546 if (!status) {2547 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");2548 return false;2549 }2550 if (!recipe) {2551 psError(PS_ERR_UNKNOWN, true, "-recip is required");2552 return false;2553 }2554 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");2555 if (!status) {2556 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");2557 return false;2558 }2559 //if (isnan(bg)) {2560 // psError(PS_ERR_UNKNOWN, true, "-bg is required");2561 // return false;2562 //}2563 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");2564 if (!status) {2565 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");2566 return false;2567 }2568 //if (isnan(bg_stdev)) {2569 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");2570 // return false;2571 //}2572 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");2573 if (!status) {2574 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");2575 return false;2576 }2577 // optional2578 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0");2579 if (!status) {2580 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0");2581 return false;2582 }2583 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1");2584 if (!status) {2585 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1");2586 return false;2587 }2588 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2");2589 if (!status) {2590 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2");2591 return false;2592 }2593 2594 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");2595 if (!status) {2596 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");2597 return false;2598 }2599 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");2600 if (!status) {2601 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");2602 return false;2603 }2604 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");2605 if (!status) {2606 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");2607 return false;2608 }2609 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");2610 if (!status) {2611 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");2612 return false;2613 }2614 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");2615 if (!status) {2616 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");2617 return false;2618 }2619 2620 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");2621 if (!status) {2622 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");2623 return false;2624 }2625 2626 // default values2627 psS16 code = psMetadataLookupS16(&status, config->args, "-code");2628 if (!status) {2629 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");2630 return false;2631 }2632 2633 psString query = psStringCopy(2634 " SELECT DISTINCT"2635 " detProcessedImfile.det_id,"2636 " detRun.iteration,"2637 " detRun.det_type,"2638 " detProcessedImfile.exp_id"2639 " FROM detRun"2640 " JOIN detInputExp"2641 " ON detRun.det_id = detInputExp.det_id"2642 " AND detRun.iteration = detInputExp.iteration"2643 " JOIN rawExp"2644 " ON detInputExp.exp_id = rawExp.exp_id"2645 " JOIN detProcessedImfile"2646 " ON detInputExp.det_id = detProcessedImfile.det_id"2647 " AND detInputExp.exp_id = detProcessedImfile.exp_id"2648 " LEFT JOIN detProcessedExp"2649 " ON detInputExp.det_id = detProcessedExp.det_id"2650 " AND detProcessedImfile.exp_id= detProcessedExp.exp_id"2651 " LEFT JOIN rawImfile"2652 " ON detInputExp.exp_id = rawImfile.exp_id"2653 " AND detProcessedImfile.class_id = rawImfile.class_id"2654 " WHERE"2655 " detRun.state = 'run'"2656 " AND detRun.mode = 'master'"2657 " AND detProcessedExp.det_id IS NULL"2658 " AND detProcessedExp.exp_id IS NULL"2659 " AND detInputExp.include = 1"2660 " AND detRun.det_id = %s"2661 " AND detProcessedImfile.exp_id = '%s'"2662 " GROUP BY"2663 " detProcessedImfile.class_id,"2664 " rawImfile.class_id,"2665 " detRun.det_id"2666 " HAVING"2667 " COUNT(detProcessedImfile.class_id) = COUNT(rawImfile.class_id)"2668 );2669 2670 if (!p_psDBRunQuery(config->dbh, query, det_id, exp_id)) {2671 psError(PS_ERR_UNKNOWN, false, "database error");2672 psFree(query);2673 return false;2674 }2675 psFree(query);2676 2677 psArray *output = p_psDBFetchResult(config->dbh);2678 if (!output) {2679 psError(PS_ERR_UNKNOWN, false, "database error");2680 return false;2681 }2682 if (!psArrayLength(output)) {2683 psTrace("dettool", PS_LOG_INFO, "no rows found");2684 psFree(output);2685 return true;2686 }2687 psFree(output);2688 2689 // create a new detProcessedImfile object2690 detProcessedExpRow *detRow = detProcessedExpRowAlloc(2691 (psS64)atoll(det_id),2692 (psS64)atoll(exp_id),2693 recipe,2694 bg,2695 bg_stdev,2696 bg_mean_stdev,2697 fringe_0,2698 fringe_1,2699 fringe_2,2700 user_1,2701 user_2,2702 user_3,2703 user_4,2704 user_5,2705 path_base,2706 code2707 );2708 2709 // insert the new row into the detProcessedImfile table2710 if (!detProcessedExpInsertObject(config->dbh, detRow)) {2711 psError(PS_ERR_UNKNOWN, false, "database error");2712 psFree(detRow);2713 return false;2714 }2715 2716 psFree(detRow);2717 2718 return true;2719 }2720 2721 static bool processedexpMode(pxConfig *config)2722 {2723 PS_ASSERT_PTR_NON_NULL(config, false);2724 2725 bool status = false;2726 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");2727 if (!status) {2728 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");2729 return false;2730 }2731 2732 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");2733 if (!status) {2734 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");2735 return false;2736 }2737 2738 psString query = psStringCopy("SELECT * FROM detProcessedExp");2739 2740 if (config->where) {2741 psString whereClause = psDBGenerateWhereSQL(config->where, NULL);2742 psStringAppend(&query, " %s", whereClause);2743 psFree(whereClause);2744 }2745 2746 if (faulted) {2747 // list only faulted rows2748 psStringAppend(&query, " %s", "AND detProcessedExp.fault != 0");2749 } else {2750 // don't list faulted rows2751 psStringAppend(&query, " %s", "AND detProcessedExp.fault = 0");2752 }2753 2754 // treat limit == 0 as "no limit"2755 if (limit) {2756 psString limitString = psDBGenerateLimitSQL(limit);2757 psStringAppend(&query, " %s", limitString);2758 psFree(limitString);2759 }2760 2761 if (!p_psDBRunQuery(config->dbh, query)) {2762 psError(PS_ERR_UNKNOWN, false, "database error");2763 psFree(query);2764 return false;2765 }2766 psFree(query);2767 2768 psArray *output = p_psDBFetchResult(config->dbh);2769 if (!output) {2770 psError(PS_ERR_UNKNOWN, false, "database error");2771 return false;2772 }2773 if (!psArrayLength(output)) {2774 psTrace("dettool", PS_LOG_INFO, "no rows found");2775 psFree(output);2776 return true;2777 }2778 2779 bool simple = false;2780 {2781 bool status = false;2782 simple = psMetadataLookupBool(&status, config->args, "-simple");2783 if (!status) {2784 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2785 return false;2786 }2787 }2788 2789 // negative simple so the default is true2790 if (!ippdbPrintMetadatas(stdout, output, "detProcessedExp", !simple)) {2791 psError(PS_ERR_UNKNOWN, false, "failed to print array");2792 psFree(output);2793 return false;2794 }2795 2796 psFree(output);2797 2798 return true;2799 }2800 2801 2802 static bool revertprocessedexpMode(pxConfig *config)2803 {2804 PS_ASSERT_PTR_NON_NULL(config, false);2805 2806 psString query = pxDataGet("dettool_revertprocessedexp.sql");2807 if (!query) {2808 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");2809 return false;2810 }2811 2812 if (config->where) {2813 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detProcessedExp");2814 psStringAppend(&query, " AND %s", whereClause);2815 psFree(whereClause);2816 }2817 2818 if (!p_psDBRunQuery(config->dbh, query)) {2819 psError(PS_ERR_UNKNOWN, false, "database error");2820 psFree(query);2821 return false;2822 }2823 psFree(query);2824 2825 if (psDBAffectedRows(config->dbh) < 1) {2826 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");2827 return false;2828 }2829 2830 return true;2831 }2832 2833 2834 static bool tostackedMode(pxConfig *config)2835 {2836 PS_ASSERT_PTR_NON_NULL(config, false);2837 2838 bool status = false;2839 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");2840 if (!status) {2841 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");2842 return false;2843 }2844 2845 psString query = pxDataGet("dettool_tostacked.sql");2846 if (!query) {2847 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");2848 return false;2849 }2850 2851 // XXX does it make sense to accept any search params?2852 #if 02853 if (config->where) {2854 psString whereClause = psDBGenerateWhereConditionSQL(config->where);2855 psStringAppend(&query, " AND %s", whereClause);2856 psFree(whereClause);2857 }2858 #endif2859 2860 // treat limit == 0 as "no limit"2861 if (limit) {2862 psString limitString = psDBGenerateLimitSQL(limit);2863 psStringAppend(&query, " %s", limitString);2864 psFree(limitString);2865 }2866 2867 if (!p_psDBRunQuery(config->dbh, query)) {2868 psError(PS_ERR_UNKNOWN, false, "database error");2869 psFree(query);2870 return false;2871 }2872 psFree(query);2873 2874 psArray *output = p_psDBFetchResult(config->dbh);2875 if (!output) {2876 psError(PS_ERR_UNKNOWN, false, "database error");2877 return false;2878 }2879 if (!psArrayLength(output)) {2880 psTrace("dettool", PS_LOG_INFO, "no rows found");2881 psFree(output);2882 return true;2883 }2884 2885 bool simple = false;2886 {2887 bool status = false;2888 simple = psMetadataLookupBool(&status, config->args, "-simple");2889 if (!status) {2890 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2891 return false;2892 }2893 }2894 2895 // negative simple so the default is true2896 if (!ippdbPrintMetadatas(stdout, output, "detPendingStackedImfile", !simple)) {2897 psError(PS_ERR_UNKNOWN, false, "failed to print array");2898 psFree(output);2899 return false;2900 }2901 2902 psFree(output);2903 2904 return true;2905 }2906 2907 static bool processedimfileMode(pxConfig *config)2908 {2909 PS_ASSERT_PTR_NON_NULL(config, false);2910 2911 char *value = NULL;2912 bool status = false;2913 2914 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");2915 if (!status) {2916 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");2917 return false;2918 }2919 2920 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");2921 if (!status) {2922 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");2923 return false;2924 }2925 2926 psString query = psStringCopy(2927 " SELECT DISTINCT"2928 " detRun.det_type,"2929 " rawExp.exp_time,"2930 " detProcessedImfile.*"2931 " FROM detProcessedImfile"2932 " JOIN detRun"2933 " USING(det_id)"2934 " JOIN detInputExp"2935 " ON detRun.det_id = detInputExp.det_id"2936 " AND detRun.iteration = detInputExp.iteration"2937 " AND detProcessedImfile.exp_id = detInputExp.exp_id"2938 " JOIN rawExp"2939 " ON rawExp.exp_id = detProcessedImfile.exp_id"2940 " WHERE"2941 );2942 // NOTE the above WHERE is completed with the following line:2943 2944 // add the two required restrictions: detRun.state and detRun.mode2945 if ((value = psMetadataLookupStr(&status, config->args, "-select_state"))) {2946 psStringAppend(&query, " detRun.state = '%s'", value);2947 } else {2948 psStringAppend(&query, " detRun.state = 'run'");2949 }2950 if ((value = psMetadataLookupStr(&status, config->args, "-select_mode"))) {2951 psStringAppend(&query, " AND detRun.mode = '%s'", value);2952 } else {2953 psStringAppend(&query, " AND detRun.mode = 'master'");2954 }2955 2956 if (config->where) {2957 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detProcessedImfile");2958 psStringAppend(&query, " AND %s", whereClause);2959 psFree(whereClause);2960 }2961 2962 {2963 bool status = false;2964 bool included = psMetadataLookupBool(&status, config->args, "-included");2965 if (!status) {2966 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");2967 return false;2968 }2969 // restrict search to included imfiles2970 if (included) {2971 psStringAppend(&query, " AND detInputExp.include = 1");2972 }2973 }2974 2975 if (faulted) {2976 // list only faulted rows2977 psStringAppend(&query, " %s", "AND detProcessedImfile.fault != 0");2978 } else {2979 // don't list faulted rows2980 psStringAppend(&query, " %s", "AND detProcessedImfile.fault = 0");2981 }2982 2983 // treat limit == 0 as "no limit"2984 if (limit) {2985 psString limitString = psDBGenerateLimitSQL(limit);2986 psStringAppend(&query, " %s", limitString);2987 psFree(limitString);2988 }2989 2990 if (!p_psDBRunQuery(config->dbh, query)) {2991 psError(PS_ERR_UNKNOWN, false, "database error");2992 psFree(query);2993 return false;2994 }2995 psFree(query);2996 2997 psArray *output = p_psDBFetchResult(config->dbh);2998 if (!output) {2999 psError(PS_ERR_UNKNOWN, false, "database error");3000 return false;3001 }3002 if (!psArrayLength(output)) {3003 psTrace("dettool", PS_LOG_INFO, "no rows found");3004 psFree(output);3005 return true;3006 }3007 3008 bool simple = false;3009 {3010 bool status = false;3011 simple = psMetadataLookupBool(&status, config->args, "-simple");3012 if (!status) {3013 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");3014 return false;3015 }3016 }3017 3018 // negative simple so the default is true3019 if (!ippdbPrintMetadatas(stdout, output, "rawImfile", !simple)) {3020 psError(PS_ERR_UNKNOWN, false, "failed to print array");3021 psFree(output);3022 return false;3023 }3024 3025 psFree(output);3026 3027 return true;3028 }3029 3030 3031 static bool revertprocessedimfileMode(pxConfig *config)3032 {3033 PS_ASSERT_PTR_NON_NULL(config, false);3034 3035 psString query = pxDataGet("dettool_revertprocessedimfile.sql");3036 if (!query) {3037 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");3038 return false;3039 }3040 3041 if (config->where) {3042 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detProcessedImfile");3043 psStringAppend(&query, " AND %s", whereClause);3044 psFree(whereClause);3045 }3046 3047 if (!p_psDBRunQuery(config->dbh, query)) {3048 psError(PS_ERR_UNKNOWN, false, "database error");3049 psFree(query);3050 return false;3051 }3052 psFree(query);3053 3054 if (psDBAffectedRows(config->dbh) < 1) {3055 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");3056 return false;3057 }3058 3059 return true;3060 }3061 3062 3063 static bool addstackedMode(pxConfig *config)3064 {3065 PS_ASSERT_PTR_NON_NULL(config, false);3066 3067 // det_id, class_id, uri, & recipe are required3068 bool status = false;3069 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");3070 if (!status) {3071 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");3072 return false;3073 }3074 if (!det_id) {3075 psError(PS_ERR_UNKNOWN, true, "-det_id is required");3076 return false;3077 }3078 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id");3079 if (!status) {3080 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id");3081 return false;3082 }3083 if (!class_id) {3084 psError(PS_ERR_UNKNOWN, true, "-class_id is required");3085 return false;3086 }3087 psString uri = psMetadataLookupStr(&status, config->args, "-uri");3088 if (!status) {3089 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri");3090 return false;3091 }3092 if (!uri) {3093 psError(PS_ERR_UNKNOWN, true, "-uri is required");3094 return false;3095 }3096 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");3097 if (!status) {3098 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");3099 return false;3100 }3101 if (!recipe) {3102 psError(PS_ERR_UNKNOWN, true, "-recip is required");3103 return false;3104 }3105 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");3106 if (!status) {3107 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");3108 return false;3109 }3110 //if (isnan(bg)) {3111 // psError(PS_ERR_UNKNOWN, true, "-bg is required");3112 // return false;3113 //}3114 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");3115 if (!status) {3116 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");3117 return false;3118 }3119 //if (isnan(bg_stdev)) {3120 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");3121 // return false;3122 //}3123 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");3124 if (!status) {3125 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");3126 return false;3127 }3128 3129 // optional values3130 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");3131 if (!status) {3132 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");3133 return false;3134 }3135 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");3136 if (!status) {3137 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");3138 return false;3139 }3140 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");3141 if (!status) {3142 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");3143 return false;3144 }3145 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");3146 if (!status) {3147 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");3148 return false;3149 }3150 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");3151 if (!status) {3152 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");3153 return false;3154 }3155 3156 // default values3157 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");3158 if (!status) {3159 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");3160 return false;3161 }3162 3163 psS16 code = psMetadataLookupS16(&status, config->args, "-code");3164 if (!status) {3165 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");3166 return false;3167 }3168 3169 // correlate the class_id against the input exposure(s)3170 3171 // we have to generate our own where clause as we want to search only by the3172 // det_id3173 psMetadata *where = psMetadataAlloc();3174 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==",3175 (psS64)atoll(det_id))) {3176 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");3177 psFree(where);3178 return false;3179 }3180 3181 psArray *rawImfiles = searchRawImfiles(config, where);3182 psFree(where);3183 3184 bool valid_class_id = false;3185 if (rawImfiles) {3186 for (long i = 0; i < psArrayLength(rawImfiles); i++) {3187 if (strcmp(class_id, ((rawImfileRow *)rawImfiles->data[i])->class_id) == 0) {3188 valid_class_id = true;3189 break;3190 }3191 }3192 psFree(rawImfiles);3193 }3194 3195 if (!valid_class_id) {3196 psError(PS_ERR_UNKNOWN, true,3197 "class_id can not be correlated with the input exposures");3198 return false;3199 }3200 3201 // create a new detStackedImfile object3202 detStackedImfileRow *stackedImfile = detStackedImfileRowAlloc(3203 (psS64)atoll(det_id),3204 iteration,3205 class_id,3206 uri,3207 recipe,3208 bg,3209 bg_stdev,3210 bg_mean_stdev,3211 user_1,3212 user_2,3213 user_3,3214 user_4,3215 user_5,3216 code3217 );3218 3219 // insert the new row into the detProcessedImfile table3220 if (!detStackedImfileInsertObject(config->dbh, stackedImfile)) {3221 psError(PS_ERR_UNKNOWN, false, "database error");3222 psFree(stackedImfile);3223 return false;3224 }3225 3226 psFree(stackedImfile);3227 3228 return true;3229 }3230 3231 static bool stackedMode(pxConfig *config)3232 {3233 PS_ASSERT_PTR_NON_NULL(config, false);3234 3235 bool status = false;3236 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");3237 if (!status) {3238 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");3239 return false;3240 }3241 3242 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");3243 if (!status) {3244 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");3245 return false;3246 }3247 3248 // select detStackedImfile.*3249 // by:3250 // where det_id, iteration, class_id is not in detNormalizedImfile3251 3252 psString query = psStringCopy(3253 "SELECT"3254 " detStackedImfile.*"3255 " FROM detStackedImfile"3256 " JOIN detRun"3257 " USING(det_id, iteration)"3258 " WHERE"3259 " detRun.state = 'run'"3260 " AND detRun.mode = 'master'"3261 );3262 3263 if (config->where) {3264 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detStackedImfile");3265 psStringAppend(&query, " AND %s", whereClause);3266 psFree(whereClause);3267 }3268 3269 if (faulted) {3270 // list only faulted rows3271 psStringAppend(&query, " %s", "AND detStackedImfile.fault != 0");3272 } else {3273 // don't list faulted rows3274 psStringAppend(&query, " %s", "AND detStackedImfile.fault = 0");3275 }3276 3277 // treat limit == 0 as "no limit"3278 if (limit) {3279 psString limitString = psDBGenerateLimitSQL(limit);3280 psStringAppend(&query, " %s", limitString);3281 psFree(limitString);3282 }3283 3284 if (!p_psDBRunQuery(config->dbh, query)) {3285 psError(PS_ERR_UNKNOWN, false, "database error");3286 psFree(query);3287 return false;3288 }3289 psFree(query);3290 3291 psArray *output = p_psDBFetchResult(config->dbh);3292 if (!output) {3293 psError(PS_ERR_UNKNOWN, false, "database error");3294 return false;3295 }3296 if (!psArrayLength(output)) {3297 psTrace("dettool", PS_LOG_INFO, "no rows found");3298 psFree(output);3299 return true;3300 }3301 3302 bool simple = false;3303 {3304 bool status = false;3305 simple = psMetadataLookupBool(&status, config->args, "-simple");3306 if (!status) {3307 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");3308 psFree(output);3309 return false;3310 }3311 }3312 3313 // negative simple so the default is true3314 if (!ippdbPrintMetadatas(stdout, output, "rawImfile", !simple)) {3315 psError(PS_ERR_UNKNOWN, false, "failed to print array");3316 psFree(output);3317 return false;3318 }3319 3320 psFree(output);3321 3322 return true;3323 }3324 3325 3326 static bool revertstackedMode(pxConfig *config)3327 {3328 PS_ASSERT_PTR_NON_NULL(config, false);3329 3330 psString query = pxDataGet("dettool_revertstacked.sql");3331 if (!query) {3332 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");3333 return false;3334 }3335 3336 if (config->where) {3337 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detStackedImfile");3338 psStringAppend(&query, " AND %s", whereClause);3339 psFree(whereClause);3340 }3341 3342 if (!p_psDBRunQuery(config->dbh, query)) {3343 psError(PS_ERR_UNKNOWN, false, "database error");3344 psFree(query);3345 return false;3346 }3347 psFree(query);3348 3349 if (psDBAffectedRows(config->dbh) < 1) {3350 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");3351 return false;3352 }3353 3354 return true;3355 }3356 3357 static bool tonormalizedstatMode(pxConfig *config)3358 {3359 PS_ASSERT_PTR_NON_NULL(config, false);3360 3361 bool status = false;3362 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");3363 if (!status) {3364 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");3365 return false;3366 }3367 3368 psString query = pxDataGet("dettool_tonormalizedstat.sql");3369 if (!query) {3370 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");3371 return false;3372 }3373 3374 // XXX does it make sense to accept any search params?3375 #if 03376 if (config->where) {3377 psString whereClause = psDBGenerateWhereConditionSQL(config->where);3378 psStringAppend(&query, " AND %s", whereClause);3379 psFree(whereClause);3380 }3381 #endif3382 3383 // treat limit == 0 as "no limit"3384 if (limit) {3385 psString limitString = psDBGenerateLimitSQL(limit);3386 psStringAppend(&query, " %s", limitString);3387 psFree(limitString);3388 }3389 3390 if (!p_psDBRunQuery(config->dbh, query)) {3391 psError(PS_ERR_UNKNOWN, false, "database error");3392 psFree(query);3393 return false;3394 }3395 psFree(query);3396 3397 psArray *output = p_psDBFetchResult(config->dbh);3398 if (!output) {3399 psError(PS_ERR_UNKNOWN, false, "database error");3400 return false;3401 }3402 if (!psArrayLength(output)) {3403 psTrace("dettool", PS_LOG_INFO, "no rows found");3404 psFree(output);3405 return true;3406 }3407 3408 bool simple = false;3409 {3410 bool status = false;3411 simple = psMetadataLookupBool(&status, config->args, "-simple");3412 if (!status) {3413 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");3414 return false;3415 }3416 }3417 3418 // negative simple so the default is true3419 if (!ippdbPrintMetadatas(stdout, output, "detPendingNormStatImfile", !simple)) {3420 psError(PS_ERR_UNKNOWN, false, "failed to print array");3421 psFree(output);3422 return false;3423 }3424 3425 psFree(output);3426 3427 return true;3428 }3429 3430 static bool addnormalizedstatMode(pxConfig *config)3431 {3432 PS_ASSERT_PTR_NON_NULL(config, NULL);3433 3434 // select * from detStackedImfile3435 // by det_id, iteration, class_id3436 // where det_id, iteration, class_id is not in detNormalizedStatImfile3437 psString query = psStringCopy(3438 "SELECT DISTINCT"3439 " detStackedImfile.*"3440 " FROM detStackedImfile"3441 " LEFT JOIN detNormalizedStatImfile"3442 " USING(det_id, iteration, class_id)"3443 " WHERE"3444 " detNormalizedStatImfile.det_id IS NULL"3445 " AND detNormalizedStatImfile.iteration IS NULL"3446 " AND detNormalizedStatImfile.class_id IS NULL"3447 );3448 3449 if (config->where) {3450 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detStackedImfile");3451 psStringAppend(&query, " AND %s", whereClause);3452 psFree(whereClause);3453 }3454 3455 if (!p_psDBRunQuery(config->dbh, query)) {3456 psError(PS_ERR_UNKNOWN, false, "database error");3457 psFree(query);3458 return false;3459 }3460 psFree(query);3461 3462 psArray *output = p_psDBFetchResult(config->dbh);3463 if (!output) {3464 psError(PS_ERR_UNKNOWN, false, "database error");3465 return false;3466 }3467 if (!psArrayLength(output)) {3468 psTrace("dettool", PS_LOG_INFO, "no rows found");3469 psFree(output);3470 return true;3471 }3472 3473 // start a transaction so it's all rows or nothing3474 if (!psDBTransaction(config->dbh)) {3475 psError(PS_ERR_UNKNOWN, false, "database error");3476 psFree(output);3477 return false;3478 }3479 3480 for (long i = 0; i < psArrayLength(output); i++) {3481 psMetadata *row = output->data[i];3482 // convert metadata into a detStackedImfile object3483 detStackedImfileRow *stackedImfile = detStackedImfileObjectFromMetadata(row);3484 // convert detStackedImfile object into a detNormalizedStat object3485 detNormalizedStatImfileRow *stat = detStackedToDetNormalizedStatImfile(config, stackedImfile);3486 psFree(stackedImfile);3487 if (!stat) {3488 if (!psDBRollback(config->dbh)) {3489 psError(PS_ERR_UNKNOWN, false, "database error");3490 }3491 psError(PS_ERR_UNKNOWN, false, "failed to convert detStackedImfile to detNormalizedStatImfile");3492 psFree(output);3493 return false;3494 }3495 // insert detNormlized Stat object into the database3496 if (!detNormalizedStatImfileInsertObject(config->dbh, stat)) {3497 if (!psDBRollback(config->dbh)) {3498 psError(PS_ERR_UNKNOWN, false, "database error");3499 }3500 psError(PS_ERR_UNKNOWN, false, "database error");3501 psFree(stat);3502 psFree(output);3503 }3504 psFree(stat);3505 }3506 3507 psFree(output);3508 3509 if (!psDBCommit(config->dbh)) {3510 psError(PS_ERR_UNKNOWN, false, "database error");3511 return false;3512 }3513 3514 return true;3515 }3516 3517 static detNormalizedStatImfileRow *detStackedToDetNormalizedStatImfile(pxConfig *config, detStackedImfileRow *stackedImfile)3518 {3519 PS_ASSERT_PTR_NON_NULL(config, NULL);3520 PS_ASSERT_PTR_NON_NULL(stackedImfile, NULL);3521 3522 bool status = false;3523 psF32 norm = psMetadataLookupF32(&status, config->args, "-norm");3524 if (!status) {3525 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -norm");3526 return false;3527 }3528 //if (isnan(norm)) {3529 // psError(PS_ERR_UNKNOWN, true, "-norm is required");3530 // return false;3531 //}3532 3533 // default values3534 psS16 code = psMetadataLookupS16(&status, config->args, "-code");3535 if (!status) {3536 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");3537 return false;3538 }3539 3540 return detNormalizedStatImfileRowAlloc(3541 stackedImfile->det_id,3542 stackedImfile->iteration,3543 stackedImfile->class_id,3544 norm,3545 code3546 );3547 }3548 3549 3550 static bool normalizedstatMode(pxConfig *config)3551 {3552 PS_ASSERT_PTR_NON_NULL(config, false);3553 3554 bool status = false;3555 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");3556 if (!status) {3557 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");3558 return false;3559 }3560 3561 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");3562 if (!status) {3563 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");3564 return false;3565 }3566 3567 psString query = pxDataGet("dettool_normalizedstat.sql");3568 if (!query) {3569 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");3570 return false;3571 }3572 3573 if (faulted) {3574 // list only faulted rows3575 psStringAppend(&query, " %s", "WHERE fault != 0");3576 } else {3577 // don't list faulted rows3578 psStringAppend(&query, " %s", "WHERE fault = 0");3579 }3580 3581 if (config->where) {3582 psString whereClause = psDBGenerateWhereConditionSQL(config->where, NULL);3583 psStringAppend(&query, " AND %s", whereClause);3584 psFree(whereClause);3585 }3586 3587 // treat limit == 0 as "no limit"3588 if (limit) {3589 psString limitString = psDBGenerateLimitSQL(limit);3590 psStringAppend(&query, " %s", limitString);3591 psFree(limitString);3592 }3593 3594 if (!p_psDBRunQuery(config->dbh, query)) {3595 psError(PS_ERR_UNKNOWN, false, "database error");3596 psFree(query);3597 return false;3598 }3599 psFree(query);3600 3601 psArray *output = p_psDBFetchResult(config->dbh);3602 if (!output) {3603 psError(PS_ERR_UNKNOWN, false, "database error");3604 return false;3605 }3606 if (!psArrayLength(output)) {3607 psTrace("dettool", PS_LOG_INFO, "no rows found");3608 psFree(output);3609 return true;3610 }3611 3612 bool simple = false;3613 {3614 bool status = false;3615 simple = psMetadataLookupBool(&status, config->args, "-simple");3616 if (!status) {3617 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");3618 psFree(output);3619 return false;3620 }3621 }3622 3623 // negative simple so the default is true3624 if (!ippdbPrintMetadatas(stdout, output, "detNormalizedStatImfile", !simple)) {3625 psError(PS_ERR_UNKNOWN, false, "failed to print array");3626 psFree(output);3627 return false;3628 }3629 3630 psFree(output);3631 3632 return true;3633 }3634 3635 static bool revertnormalizedstatMode(pxConfig *config)3636 {3637 PS_ASSERT_PTR_NON_NULL(config, false);3638 3639 psString query = pxDataGet("dettool_revertnormalizedstat.sql");3640 if (!query) {3641 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");3642 return false;3643 }3644 3645 if (config->where) {3646 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedStatImfile");3647 psStringAppend(&query, " AND %s", whereClause);3648 psFree(whereClause);3649 }3650 3651 if (!p_psDBRunQuery(config->dbh, query)) {3652 psError(PS_ERR_UNKNOWN, false, "database error");3653 psFree(query);3654 return false;3655 }3656 psFree(query);3657 3658 if (psDBAffectedRows(config->dbh) < 1) {3659 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");3660 return false;3661 }3662 3663 return true;3664 }3665 3666 static bool tonormalizeMode(pxConfig *config)3667 {3668 PS_ASSERT_PTR_NON_NULL(config, false);3669 3670 bool status = false;3671 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");3672 if (!status) {3673 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");3674 return false;3675 }3676 3677 // select detNormalizedStatImfile.*3678 // by:3679 // where det_id, iteration, class_id is not in detNormalizedImfile3680 3681 psString query = psStringCopy(3682 "SELECT DISTINCT"3683 " detRun.det_type,"3684 " detRun.workdir,"3685 " rawExp.camera,"3686 " detStackedImfile.uri,"3687 " detNormalizedStatImfile.*"3688 " FROM detRun"3689 " JOIN detStackedImfile"3690 " USING(det_id, iteration)"3691 " JOIN detInputExp"3692 " USING(det_id, iteration)"3693 " JOIN rawExp"3694 " ON detInputExp.exp_id = rawExp.exp_id"3695 " JOIN detNormalizedStatImfile"3696 " ON detStackedImfile.det_id = detNormalizedStatImfile.det_id"3697 " AND detStackedImfile.iteration = detNormalizedStatImfile.iteration"3698 " AND detStackedImfile.class_id = detNormalizedStatImfile.class_id"3699 " LEFT JOIN detNormalizedImfile"3700 " ON detNormalizedStatImfile.det_id = detNormalizedImfile.det_id"3701 " AND detNormalizedStatImfile.iteration = detNormalizedImfile.iteration"3702 " AND detNormalizedStatImfile.class_id = detNormalizedImfile.class_id"3703 " WHERE"3704 " detNormalizedImfile.det_id IS NULL"3705 " AND detNormalizedImfile.iteration IS NULL"3706 " AND detNormalizedImfile.class_id IS NULL"3707 " AND detNormalizedStatImfile.fault = 0"3708 );3709 3710 // XXX does it make sense to accept any search params?3711 #if 03712 if (config->where) {3713 psString whereClause = psDBGenerateWhereConditionSQL(config->where);3714 psStringAppend(&query, " AND %s", whereClause);3715 psFree(whereClause);3716 }3717 #endif3718 3719 // treat limit == 0 as "no limit"3720 if (limit) {3721 psString limitString = psDBGenerateLimitSQL(limit);3722 psStringAppend(&query, " %s", limitString);3723 psFree(limitString);3724 }3725 3726 if (!p_psDBRunQuery(config->dbh, query)) {3727 psError(PS_ERR_UNKNOWN, false, "database error");3728 psFree(query);3729 return false;3730 }3731 psFree(query);3732 3733 psArray *output = p_psDBFetchResult(config->dbh);3734 if (!output) {3735 psError(PS_ERR_UNKNOWN, false, "database error");3736 return false;3737 }3738 if (!psArrayLength(output)) {3739 psTrace("dettool", PS_LOG_INFO, "no rows found");3740 psFree(output);3741 return true;3742 }3743 3744 bool simple = false;3745 {3746 bool status = false;3747 simple = psMetadataLookupBool(&status, config->args, "-simple");3748 if (!status) {3749 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");3750 psFree(output);3751 return false;3752 }3753 }3754 3755 // negative simple so the default is true3756 if (!ippdbPrintMetadatas(stdout, output, "detPendingNormImfile", !simple)) {3757 psError(PS_ERR_UNKNOWN, false, "failed to print array");3758 psFree(output);3759 return false;3760 }3761 3762 psFree(output);3763 3764 return true;3765 }3766 3767 #if 03768 // XXX this function was left in commented as this method may be useful in the3769 // future3770 static psArray *validDetInputClassIds(pxConfig *config, const char *det_id)3771 {3772 PS_ASSERT_PTR_NON_NULL(config, NULL);3773 // det_id is input as a string because the fact that it is an integer3774 // is just a database impliementation detail.3775 PS_ASSERT_PTR_NON_NULL(det_id, NULL);3776 3777 psArray *rawImfiles = searchInputImfiles(config, det_id);3778 if (!rawImfiles) {3779 return NULL;3780 }3781 3782 psArray *valid_class_ids = NULL;3783 {3784 // All this jumping through hoops is so that we end up with unique3785 // values. PP thinks that making multiple passes through this array and3786 // deleting matched elements would end up being more expensive then a3787 // double sort and stagger scheme. JH thinks it would be cheaper to3788 // just do a unqiue sort and delete. So this is really just a cheap3789 // hack to avoid implimenting a unique sort function but at least it's3790 // stable.3791 psHash *hash = psHashAlloc(psArrayLength(rawImfiles));3792 for (long i = 0; i < psArrayLength(rawImfiles); i++) {3793 psHashAdd(hash,3794 ((rawImfileRow *)rawImfiles->data[i])->class_id,3795 ((rawImfileRow *)rawImfiles->data[i])->class_id3796 );3797 }3798 valid_class_ids = psHashToArray(hash);3799 psFree(hash);3800 }3801 psFree(rawImfiles);3802 3803 return valid_class_ids;3804 }3805 3806 static psArray *searchInputImfiles(pxConfig *config, const char *det_id)3807 {3808 PS_ASSERT_PTR_NON_NULL(config, NULL);3809 // det_id is input as a string because the fact that it is an integer3810 // is just a database impliementation detail.3811 PS_ASSERT_PTR_NON_NULL(det_id, NULL);3812 3813 psArray *inputExps = NULL;3814 {3815 psMetadata *where = psMetadataAlloc();3816 if (!psMetadataAddS32(where, PS_LIST_TAIL, "det_id", 0, "==",3817 (psS32)atoi(det_id))) {3818 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");3819 psFree(where);3820 return NULL;3821 }3822 inputExps = detInputExpSelectRowObjects(config->dbh, where, 0);3823 psFree(where);3824 }3825 if (!inputExps) {3826 psError(PS_ERR_UNKNOWN, false, "no detInputExp rows found");3827 return NULL;3828 }3829 3830 // find rawImfiles associated with detInputExps3831 psArray *rawImfiles = NULL;3832 {3833 psMetadata *where = psMetadataAlloc();3834 for (long i = 0; i < psArrayLength(inputExps); i++) {3835 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id",3836 PS_META_DUPLICATE_OK, "==",3837 ((detInputExpRow *)inputExps->data[i])->exp_id)) {3838 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");3839 psFree(inputExps);3840 psFree(where);3841 return NULL;3842 }3843 }3844 psFree(inputExps);3845 rawImfiles = rawImfileSelectRowObjects(config->dbh, where, 0);3846 // XXX this really should be sorted for uniqueness3847 psFree(where);3848 }3849 if (!rawImfiles) {3850 psError(PS_ERR_UNKNOWN, false, "no rawImfile rows found");3851 return NULL;3852 }3853 3854 return rawImfiles;3855 }3856 #endif3857 3858 static bool addnormalizedimfileMode(pxConfig *config)3859 {3860 PS_ASSERT_PTR_NON_NULL(config, false);3861 3862 // make sure that there is a respondoing entry in detNormalizedStatImfile3863 // select * from detNormalizedStatImfile3864 // by det_id, iteration, class_id3865 // where det_id, iteration, class_id is not in detNormalizedImfile3866 psString query = psStringCopy(3867 "SELECT"3868 " detNormalizedStatImfile.*"3869 " FROM detNormalizedStatImfile"3870 " LEFT JOIN detNormalizedImfile"3871 " USING(det_id, iteration, class_id)"3872 " WHERE"3873 " detNormalizedImfile.det_id IS NULL"3874 " AND detNormalizedImfile.iteration IS NULL"3875 " AND detNormalizedImfile.class_id IS NULL"3876 );3877 3878 {3879 // build a query to search by det_id, iteration, class_id3880 psMetadata *where = psMetadataAlloc();3881 bool status = false;3882 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");3883 if (!status) {3884 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");3885 psFree(where);3886 psFree(query);3887 return false;3888 }3889 if (det_id) {3890 if (!psMetadataAddStr(where, PS_LIST_TAIL, "det_id", 0, "==", det_id)) {3891 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");3892 psFree(where);3893 psFree(query);3894 return false;3895 }3896 }3897 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");3898 if (!status) {3899 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");3900 psFree(where);3901 psFree(query);3902 return false;3903 }3904 // always set iteration3905 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) {3906 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");3907 psFree(where);3908 psFree(query);3909 return false;3910 }3911 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id");3912 if (!status) {3913 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id");3914 psFree(where);3915 psFree(query);3916 return false;3917 }3918 if (class_id) {3919 if (!psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==", class_id)) {3920 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");3921 psFree(where);3922 psFree(query);3923 return false;3924 }3925 }3926 3927 // there's not3928 psString whereClause = psDBGenerateWhereConditionSQL(where, "detNormalizedStatImfile");3929 psFree(where);3930 if (whereClause) {3931 psStringAppend(&query, " AND %s", whereClause);3932 psFree(whereClause);3933 }3934 }3935 3936 if (!p_psDBRunQuery(config->dbh, query)) {3937 psError(PS_ERR_UNKNOWN, false, "database error");3938 psFree(query);3939 return false;3940 }3941 psFree(query);3942 3943 psArray *output = p_psDBFetchResult(config->dbh);3944 if (!output) {3945 psError(PS_ERR_UNKNOWN, false, "database error");3946 return false;3947 }3948 if (!psArrayLength(output)) {3949 psTrace("dettool", PS_LOG_INFO, "no rows found");3950 psFree(output);3951 return true;3952 }3953 3954 // start a transaction so it's all rows or nothing3955 if (!psDBTransaction(config->dbh)) {3956 psError(PS_ERR_UNKNOWN, false, "database error");3957 psFree(output);3958 return false;3959 }3960 3961 for (long i = 0; i < psArrayLength(output); i++) {3962 psMetadata *row = output->data[i];3963 // convert metadata into a detNormalizedStatImfile object3964 detNormalizedStatImfileRow *statImfile = detNormalizedStatImfileObjectFromMetadata(row);3965 // convert detNormalizedStatImfile object into a detNormalizedImfile3966 detNormalizedImfileRow *normalizedImfile = detNormalizedStatToDetNormalizedmfile(config, statImfile);3967 psFree(statImfile);3968 if (!normalizedImfile) {3969 if (!psDBRollback(config->dbh)) {3970 psError(PS_ERR_UNKNOWN, false, "database error");3971 }3972 psError(PS_ERR_UNKNOWN, false, "failed to convert detStackedImfile to detNormalizedStatImfile");3973 psFree(output);3974 return false;3975 }3976 // insert detNormlized Stat object into the database3977 if (!detNormalizedImfileInsertObject(config->dbh, normalizedImfile)) {3978 if (!psDBRollback(config->dbh)) {3979 psError(PS_ERR_UNKNOWN, false, "database error");3980 }3981 psError(PS_ERR_UNKNOWN, false, "database error");3982 psFree(normalizedImfile);3983 psFree(output);3984 }3985 psFree(normalizedImfile);3986 }3987 3988 psFree(output);3989 3990 if (!psDBCommit(config->dbh)) {3991 psError(PS_ERR_UNKNOWN, false, "database error");3992 return false;3993 }3994 3995 return true;3996 }3997 3998 3999 static bool normalizedimfileMode(pxConfig *config)4000 {4001 PS_ASSERT_PTR_NON_NULL(config, false);4002 4003 bool status = false;4004 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");4005 if (!status) {4006 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");4007 return false;4008 }4009 4010 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");4011 if (!status) {4012 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");4013 return false;4014 }4015 4016 psString query = psStringCopy(4017 "SELECT"4018 " detNormalizedImfile.*"4019 " FROM detNormalizedImfile"4020 " JOIN detRun"4021 " USING(det_id, iteration)"4022 " WHERE"4023 " detRun.state = 'run'"4024 " AND detRun.mode = 'master'"4025 );4026 4027 if (config->where) {4028 bool status;4029 int iteration = psMetadataLookupS32 (&status, config->where, "iteration");4030 if (status) {4031 psMetadataRemoveKey (config->where, "iteration");4032 psMetadataAddS32 (config->where, PS_LIST_TAIL, "iteration", 0, "==", iteration);4033 }4034 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedImfile");4035 psStringAppend(&query, " AND %s", whereClause);4036 psFree(whereClause);4037 }4038 4039 if (faulted) {4040 // list only faulted rows4041 psStringAppend(&query, " %s", "AND detNormalizedImfile.fault != 0");4042 } else {4043 // don't list faulted rows4044 psStringAppend(&query, " %s", "AND detNormalizedImfile.fault = 0");4045 }4046 4047 // treat limit == 0 as "no limit"4048 if (limit) {4049 psString limitString = psDBGenerateLimitSQL(limit);4050 psStringAppend(&query, " %s", limitString);4051 psFree(limitString);4052 }4053 4054 if (!p_psDBRunQuery(config->dbh, query)) {4055 psError(PS_ERR_UNKNOWN, false, "database error");4056 psFree(query);4057 return false;4058 }4059 psFree(query);4060 4061 psArray *output = p_psDBFetchResult(config->dbh);4062 if (!output) {4063 psError(PS_ERR_UNKNOWN, false, "database error");4064 return false;4065 }4066 if (!psArrayLength(output)) {4067 psTrace("dettool", PS_LOG_INFO, "no rows found");4068 psFree(output);4069 return true;4070 }4071 4072 bool simple = false;4073 {4074 bool status = false;4075 simple = psMetadataLookupBool(&status, config->args, "-simple");4076 if (!status) {4077 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");4078 return false;4079 }4080 }4081 4082 // negative simple so the default is true4083 if (!ippdbPrintMetadatas(stdout, output, "detNormalizedImfile", !simple)) {4084 psError(PS_ERR_UNKNOWN, false, "failed to print array");4085 psFree(output);4086 return false;4087 }4088 4089 psFree(output);4090 4091 return true;4092 }4093 4094 4095 static bool revertnormalizedimfileMode(pxConfig *config)4096 {4097 PS_ASSERT_PTR_NON_NULL(config, false);4098 4099 psString query = pxDataGet("dettool_revertnormalizedimfile.sql");4100 if (!query) {4101 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");4102 return false;4103 }4104 4105 if (config->where) {4106 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedImfile");4107 psStringAppend(&query, " AND %s", whereClause);4108 psFree(whereClause);4109 }4110 4111 if (!p_psDBRunQuery(config->dbh, query)) {4112 psError(PS_ERR_UNKNOWN, false, "database error");4113 psFree(query);4114 return false;4115 }4116 psFree(query);4117 4118 if (psDBAffectedRows(config->dbh) < 1) {4119 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");4120 return false;4121 }4122 4123 return true;4124 }4125 4126 4127 static bool tonormalizedexpMode(pxConfig *config)4128 {4129 PS_ASSERT_PTR_NON_NULL(config, false);4130 4131 bool status = false;4132 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");4133 if (!status) {4134 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");4135 return false;4136 }4137 4138 psString query = pxDataGet("dettool_tonormalizedexp.sql");4139 if (!query) {4140 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");4141 return false;4142 }4143 4144 // XXX does it make sense to accept any search params?4145 #if 04146 if (config->where) {4147 psString whereClause = psDBGenerateWhereConditionSQL(config->where);4148 psStringAppend(&query, " AND %s", whereClause);4149 psFree(whereClause);4150 }4151 #endif4152 4153 // treat limit == 0 as "no limit"4154 if (limit) {4155 psString limitString = psDBGenerateLimitSQL(limit);4156 psStringAppend(&query, " %s", limitString);4157 psFree(limitString);4158 }4159 4160 if (!p_psDBRunQuery(config->dbh, query)) {4161 psError(PS_ERR_UNKNOWN, false, "database error");4162 psFree(query);4163 return false;4164 }4165 psFree(query);4166 4167 psArray *output = p_psDBFetchResult(config->dbh);4168 if (!output) {4169 psError(PS_ERR_UNKNOWN, false, "database error");4170 return false;4171 }4172 if (!psArrayLength(output)) {4173 psTrace("dettool", PS_LOG_INFO, "no rows found");4174 psFree(output);4175 return true;4176 }4177 4178 bool simple = false;4179 {4180 bool status = false;4181 simple = psMetadataLookupBool(&status, config->args, "-simple");4182 if (!status) {4183 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");4184 return false;4185 }4186 }4187 4188 // negative simple so the default is true4189 if (!ippdbPrintMetadatas(stdout, output, "detPendingNormExp", !simple)) {4190 psError(PS_ERR_UNKNOWN, false, "failed to print array");4191 psFree(output);4192 return false;4193 }4194 4195 psFree(output);4196 4197 return true;4198 }4199 4200 static bool addnormalizedexpMode(pxConfig *config)4201 {4202 PS_ASSERT_PTR_NON_NULL(config, false);4203 4204 // det_id, recip, -bg, -bg_stdev4205 // are required4206 bool status = false;4207 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");4208 if (!status) {4209 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");4210 return false;4211 }4212 if (!det_id) {4213 psError(PS_ERR_UNKNOWN, true, "-det_id is required");4214 return false;4215 }4216 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");4217 if (!status) {4218 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");4219 return false;4220 }4221 if (!recipe) {4222 psError(PS_ERR_UNKNOWN, true, "-recip is required");4223 return false;4224 }4225 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");4226 if (!status) {4227 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");4228 return false;4229 }4230 //if (isnan(bg)) {4231 // psError(PS_ERR_UNKNOWN, true, "-bg is required");4232 // return false;4233 //}4234 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");4235 if (!status) {4236 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");4237 return false;4238 }4239 //if (isnan(bg_stdev)) {4240 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");4241 // return false;4242 //}4243 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");4244 if (!status) {4245 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");4246 return false;4247 }4248 4249 // optional4250 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");4251 if (!status) {4252 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");4253 return false;4254 }4255 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");4256 if (!status) {4257 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");4258 return false;4259 }4260 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");4261 if (!status) {4262 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");4263 return false;4264 }4265 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");4266 if (!status) {4267 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");4268 return false;4269 }4270 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");4271 if (!status) {4272 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");4273 return false;4274 }4275 4276 // iteration has a default value4277 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");4278 if (!status) {4279 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); return false;4280 }4281 4282 psS16 code = psMetadataLookupS16(&status, config->args, "-code");4283 if (!status) {4284 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");4285 return false;4286 }4287 4288 // optional4289 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");4290 if (!status) {4291 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");4292 return false;4293 }4294 4295 psString query = pxDataGet("dettool_tonormalizedexp.sql");4296 if (!query) {4297 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");4298 return false;4299 }4300 4301 psStringAppend(&query,4302 "WHERE det_id = %s"4303 " AND iteration = %d", det_id, iteration);4304 4305 4306 if (!p_psDBRunQuery(config->dbh, query)) {4307 psError(PS_ERR_UNKNOWN, false, "database error");4308 psFree(query);4309 return false;4310 }4311 psFree(query);4312 4313 psArray *output = p_psDBFetchResult(config->dbh);4314 if (!output) {4315 psError(PS_ERR_UNKNOWN, false, "database error");4316 return false;4317 }4318 if (!psArrayLength(output)) {4319 psTrace("dettool", PS_LOG_INFO, "no rows found");4320 psFree(output);4321 return true;4322 }4323 psFree(output);4324 4325 // create a new detProcessedImfile object4326 detNormalizedExpRow *detRow = detNormalizedExpRowAlloc(4327 (psS32)atoll(det_id),4328 iteration,4329 recipe,4330 bg,4331 bg_stdev,4332 bg_mean_stdev,4333 user_1,4334 user_2,4335 user_3,4336 user_4,4337 user_5,4338 path_base,4339 code4340 );4341 4342 // insert the new row into the detProcessedImfile table4343 if (!detNormalizedExpInsertObject(config->dbh, detRow)) {4344 psError(PS_ERR_UNKNOWN, false, "database error");4345 psFree(detRow);4346 return false;4347 }4348 4349 psFree(detRow);4350 4351 return true;4352 }4353 4354 4355 static bool normalizedexpMode(pxConfig *config)4356 {4357 PS_ASSERT_PTR_NON_NULL(config, false);4358 4359 bool status = false;4360 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");4361 if (!status) {4362 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");4363 return false;4364 }4365 4366 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");4367 if (!status) {4368 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");4369 return false;4370 }4371 4372 psString query = psStringCopy(4373 "SELECT"4374 " detNormalizedExp.*"4375 " FROM detNormalizedExp"4376 " JOIN detRun"4377 " USING(det_id, iteration)"4378 " WHERE"4379 " detRun.state = 'run'"4380 " AND detRun.mode = 'master'"4381 );4382 4383 if (config->where) {4384 psString whereClause = psDBGenerateWhereSQL(config->where, NULL);4385 psStringAppend(&query, " %s", whereClause);4386 psFree(whereClause);4387 }4388 4389 if (faulted) {4390 // list only faulted rows4391 psStringAppend(&query, " %s", "AND detNormalizedExp.fault != 0");4392 } else {4393 // don't list faulted rows4394 psStringAppend(&query, " %s", "AND detNormalizedExp.fault = 0");4395 }4396 4397 // treat limit == 0 as "no limit"4398 if (limit) {4399 psString limitString = psDBGenerateLimitSQL(limit);4400 psStringAppend(&query, " %s", limitString);4401 psFree(limitString);4402 }4403 4404 if (!p_psDBRunQuery(config->dbh, query)) {4405 psError(PS_ERR_UNKNOWN, false, "database error");4406 psFree(query);4407 return false;4408 }4409 psFree(query);4410 4411 psArray *output = p_psDBFetchResult(config->dbh);4412 if (!output) {4413 psError(PS_ERR_UNKNOWN, false, "database error");4414 return false;4415 }4416 if (!psArrayLength(output)) {4417 psTrace("dettool", PS_LOG_INFO, "no rows found");4418 psFree(output);4419 return true;4420 }4421 4422 bool simple = false;4423 {4424 bool status = false;4425 simple = psMetadataLookupBool(&status, config->args, "-simple");4426 if (!status) {4427 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");4428 return false;4429 }4430 }4431 4432 // negative simple so the default is true4433 if (!ippdbPrintMetadatas(stdout, output, "detNormalizedExp", !simple)) {4434 psError(PS_ERR_UNKNOWN, false, "failed to print array");4435 psFree(output);4436 return false;4437 }4438 4439 psFree(output);4440 4441 return true;4442 }4443 4444 4445 static detNormalizedImfileRow *detNormalizedStatToDetNormalizedmfile(pxConfig *config, detNormalizedStatImfileRow *statImfile)4446 {4447 PS_ASSERT_PTR_NON_NULL(config, NULL);4448 PS_ASSERT_PTR_NON_NULL(statImfile, NULL);4449 4450 bool status = false;4451 psString uri = psMetadataLookupStr(&status, config->args, "-uri");4452 if (!status) {4453 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri");4454 return false;4455 }4456 if (!uri) {4457 psError(PS_ERR_UNKNOWN, true, "-uri is required");4458 return false;4459 }4460 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");4461 if (!status) {4462 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");4463 return false;4464 }4465 //if (isnan(bg)) {4466 // psError(PS_ERR_UNKNOWN, true, "-bg is required");4467 // return false;4468 //}4469 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");4470 if (!status) {4471 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");4472 return false;4473 }4474 //if (isnan(bg_stdev)) {4475 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");4476 // return false;4477 //}4478 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");4479 if (!status) {4480 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");4481 return false;4482 }4483 // optional4484 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");4485 if (!status) {4486 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");4487 return false;4488 }4489 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");4490 if (!status) {4491 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");4492 return false;4493 }4494 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");4495 if (!status) {4496 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");4497 return false;4498 }4499 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");4500 if (!status) {4501 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");4502 return false;4503 }4504 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");4505 if (!status) {4506 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");4507 return false;4508 }4509 4510 // optional4511 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");4512 if (!status) {4513 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");4514 return false;4515 }4516 4517 // default values4518 psS16 code = psMetadataLookupS16(&status, config->args, "-code");4519 if (!status) {4520 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");4521 return false;4522 }4523 4524 return detNormalizedImfileRowAlloc(4525 statImfile->det_id,4526 statImfile->iteration,4527 statImfile->class_id,4528 uri,4529 bg,4530 bg_stdev,4531 bg_mean_stdev,4532 user_1,4533 user_2,4534 user_3,4535 user_4,4536 user_5,4537 path_base,4538 code4539 );4540 }4541 4542 4543 static bool revertnormalizedexpMode(pxConfig *config)4544 {4545 PS_ASSERT_PTR_NON_NULL(config, false);4546 4547 psString query = pxDataGet("dettool_revertnormalizedexp.sql");4548 if (!query) {4549 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");4550 return false;4551 }4552 4553 if (config->where) {4554 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedExp");4555 psStringAppend(&query, " AND %s", whereClause);4556 psFree(whereClause);4557 }4558 4559 if (!p_psDBRunQuery(config->dbh, query)) {4560 psError(PS_ERR_UNKNOWN, false, "database error");4561 psFree(query);4562 return false;4563 }4564 psFree(query);4565 4566 if (psDBAffectedRows(config->dbh) < 1) {4567 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");4568 return false;4569 }4570 4571 return true;4572 }4573 4574 4575 static bool toresidimfileMode(pxConfig *config)4576 {4577 PS_ASSERT_PTR_NON_NULL(config, false);4578 4579 bool status = false;4580 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");4581 if (!status) {4582 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");4583 return false;4584 }4585 4586 psString query = pxDataGet("dettool_toresidimfile.sql");4587 if (!query) {4588 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");4589 return false;4590 }4591 4592 // XXX does it make sense to accept any search params?4593 #if 04594 if (config->where) {4595 psString whereClause = psDBGenerateWhereConditionSQL(config->where);4596 psStringAppend(&query, " AND %s", whereClause);4597 psFree(whereClause);4598 }4599 #endif4600 4601 // treat limit == 0 as "no limit"4602 if (limit) {4603 psString limitString = psDBGenerateLimitSQL(limit);4604 psStringAppend(&query, " %s", limitString);4605 psFree(limitString);4606 }4607 4608 if (!p_psDBRunQuery(config->dbh, query)) {4609 psError(PS_ERR_UNKNOWN, false, "database error");4610 psFree(query);4611 return false;4612 }4613 psFree(query);4614 4615 psArray *output = p_psDBFetchResult(config->dbh);4616 if (!output) {4617 psError(PS_ERR_UNKNOWN, false, "database error");4618 return false;4619 }4620 if (!psArrayLength(output)) {4621 psTrace("dettool", PS_LOG_INFO, "no rows found");4622 psFree(output);4623 return true;4624 }4625 4626 bool simple = false;4627 {4628 bool status = false;4629 simple = psMetadataLookupBool(&status, config->args, "-simple");4630 if (!status) {4631 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");4632 psFree(output);4633 return false;4634 }4635 }4636 4637 // negative simple so the default is true4638 if (!ippdbPrintMetadatas(stdout, output, "detPendingResidImfile", !simple)) {4639 psError(PS_ERR_UNKNOWN, false, "failed to print array");4640 psFree(output);4641 return false;4642 }4643 4644 psFree(output);4645 4646 return true;4647 }4648 4649 4650 static bool addresidimfileMode(pxConfig *config)4651 {4652 PS_ASSERT_PTR_NON_NULL(config, false);4653 4654 bool status = false;4655 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");4656 if (!status) {4657 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");4658 return false;4659 }4660 if (!det_id) {4661 psError(PS_ERR_UNKNOWN, true, "-det_id is required");4662 return false;4663 }4664 4665 // defaults to 04666 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");4667 if (!status) {4668 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");4669 return false;4670 }4671 4672 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id");4673 if (!status) {4674 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id");4675 return false;4676 }4677 if (!class_id) {4678 psError(PS_ERR_UNKNOWN, false, "-class_id is required");4679 return false;4680 }4681 4682 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");4683 if (!status) {4684 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");4685 return false;4686 }4687 if (!exp_id) {4688 psError(PS_ERR_UNKNOWN, true, "-exp_id is required");4689 return false;4690 }4691 psString uri = psMetadataLookupStr(&status, config->args, "-uri");4692 if (!status) {4693 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri");4694 return false;4695 }4696 if (!uri) {4697 psError(PS_ERR_UNKNOWN, true, "-uri is required");4698 return false;4699 }4700 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");4701 if (!status) {4702 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");4703 return false;4704 }4705 if (!recipe) {4706 psError(PS_ERR_UNKNOWN, true, "-recip is required");4707 return false;4708 }4709 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");4710 if (!status) {4711 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");4712 return false;4713 }4714 //if (isnan(bg)) {4715 // psError(PS_ERR_UNKNOWN, true, "-bg is required");4716 // return false;4717 //}4718 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");4719 if (!status) {4720 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");4721 return false;4722 }4723 //if (isnan(bg_stdev)) {4724 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");4725 // return false;4726 //}4727 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");4728 if (!status) {4729 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");4730 return false;4731 }4732 psF64 bg_skewness = psMetadataLookupF64(&status, config->args, "-bg_skewness");4733 if (!status) {4734 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_skewness");4735 return false;4736 }4737 psF64 bg_kurtosis = psMetadataLookupF64(&status, config->args, "-bg_kurtosis");4738 if (!status) {4739 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_kurtosis");4740 return false;4741 }4742 psF64 bin_stdev = psMetadataLookupF64(&status, config->args, "-bin_stdev");4743 if (!status) {4744 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bin_stdev");4745 return false;4746 }4747 4748 // optional4749 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");4750 if (!status) {4751 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");4752 return false;4753 }4754 4755 // optional4756 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0");4757 if (!status) {4758 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0");4759 return false;4760 }4761 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1");4762 if (!status) {4763 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1");4764 return false;4765 }4766 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2");4767 if (!status) {4768 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2");4769 return false;4770 }4771 4772 psF64 fringe_resid_0 = psMetadataLookupF64(&status, config->args, "-fringe_resid_0");4773 if (!status) {4774 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_0");4775 return false;4776 }4777 psF64 fringe_resid_1 = psMetadataLookupF64(&status, config->args, "-fringe_resid_1");4778 if (!status) {4779 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_1");4780 return false;4781 }4782 psF64 fringe_resid_2 = psMetadataLookupF64(&status, config->args, "-fringe_resid_2");4783 if (!status) {4784 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_2");4785 return false;4786 }4787 4788 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");4789 if (!status) {4790 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");4791 return false;4792 }4793 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");4794 if (!status) {4795 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");4796 return false;4797 }4798 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");4799 if (!status) {4800 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");4801 return false;4802 }4803 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");4804 if (!status) {4805 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");4806 return false;4807 }4808 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");4809 if (!status) {4810 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");4811 return false;4812 }4813 4814 // default values4815 psS16 code = psMetadataLookupS16(&status, config->args, "-code");4816 if (!status) {4817 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");4818 return false;4819 }4820 4821 // create a new detResidImfileRow and insert it4822 if (!detResidImfileInsert(4823 config->dbh,4824 (psS64)atoll(det_id),4825 iteration,4826 (psS64)atoll(exp_id),4827 class_id,4828 uri,4829 recipe,4830 bg,4831 bg_stdev,4832 bg_mean_stdev,4833 bg_skewness,4834 bg_kurtosis,4835 bin_stdev,4836 fringe_0,4837 fringe_1,4838 fringe_2,4839 fringe_resid_0,4840 fringe_resid_1,4841 fringe_resid_2,4842 user_1,4843 user_2,4844 user_3,4845 user_4,4846 user_5,4847 path_base,4848 code4849 )) {4850 psError(PS_ERR_UNKNOWN, false, "database error");4851 return false;4852 }4853 4854 return true;4855 }4856 4857 static bool residimfileMode(pxConfig *config)4858 {4859 PS_ASSERT_PTR_NON_NULL(config, false);4860 4861 char *value = NULL;4862 bool status = false;4863 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");4864 if (!status) {4865 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");4866 return false;4867 }4868 4869 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");4870 if (!status) {4871 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");4872 return false;4873 }4874 4875 // select detResidImfile.*4876 // by:4877 // where det_id, iteration, exp_id is not in detResidExp;4878 4879 psString query = psStringCopy(4880 "SELECT"4881 " detRun.det_type,"4882 " detRun.mode,"4883 " detResidImfile.*,"4884 " rawExp.exp_time"4885 " FROM detResidImfile"4886 " JOIN detRun"4887 " USING(det_id, iteration)"4888 " JOIN rawExp"4889 " USING(exp_id)"4890 " WHERE"4891 );4892 // NOTE the above WHERE is completed with the following line:4893 4894 // add the two required restrictions: detRun.state and detRun.mode4895 if ((value = psMetadataLookupStr(&status, config->args, "-select_state"))) {4896 psStringAppend(&query, " detRun.state = '%s'", value);4897 } else {4898 psStringAppend(&query, " detRun.state = 'run'");4899 }4900 4901 if (config->where) {4902 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidImfile");4903 psStringAppend(&query, " AND %s", whereClause);4904 psFree(whereClause);4905 }4906 4907 if (faulted) {4908 // list only faulted rows4909 psStringAppend(&query, " %s", "AND detResidImfile.fault != 0");4910 } else {4911 // don't list faulted rows4912 psStringAppend(&query, " %s", "AND detResidImfile.fault = 0");4913 }4914 4915 // treat limit == 0 as "no limit"4916 if (limit) {4917 psString limitString = psDBGenerateLimitSQL(limit);4918 psStringAppend(&query, " %s", limitString);4919 psFree(limitString);4920 }4921 4922 if (!p_psDBRunQuery(config->dbh, query)) {4923 psError(PS_ERR_UNKNOWN, false, "database error");4924 psFree(query);4925 return false;4926 }4927 psFree(query);4928 4929 psArray *output = p_psDBFetchResult(config->dbh);4930 if (!output) {4931 psError(PS_ERR_UNKNOWN, false, "database error");4932 return false;4933 }4934 if (!psArrayLength(output)) {4935 psTrace("dettool", PS_LOG_INFO, "no rows found");4936 psFree(output);4937 return true;4938 }4939 4940 bool simple = false;4941 {4942 bool status = false;4943 simple = psMetadataLookupBool(&status, config->args, "-simple");4944 if (!status) {4945 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");4946 psFree(output);4947 return false;4948 }4949 }4950 4951 // negative simple so the default is true4952 if (!ippdbPrintMetadatas(stdout, output, "rawResidImfile", !simple)) {4953 psError(PS_ERR_UNKNOWN, false, "failed to print array");4954 psFree(output);4955 return false;4956 }4957 4958 psFree(output);4959 4960 return true;4961 }4962 4963 4964 static bool revertresidimfileMode(pxConfig *config)4965 {4966 PS_ASSERT_PTR_NON_NULL(config, false);4967 4968 psString query = pxDataGet("dettool_revertresidimfile.sql");4969 if (!query) {4970 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");4971 return false;4972 }4973 4974 if (config->where) {4975 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidImfile");4976 psStringAppend(&query, " AND %s", whereClause);4977 psFree(whereClause);4978 }4979 4980 if (!p_psDBRunQuery(config->dbh, query)) {4981 psError(PS_ERR_UNKNOWN, false, "database error");4982 psFree(query);4983 return false;4984 }4985 psFree(query);4986 4987 if (psDBAffectedRows(config->dbh) < 1) {4988 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");4989 return false;4990 }4991 4992 return true;4993 }4994 4995 4996 static bool toresidexpMode(pxConfig *config)4997 {4998 PS_ASSERT_PTR_NON_NULL(config, false);4999 5000 /*5001 which returns a list of exposures for which all component class ids5002 have had residuals created. This list includes the detrend id,5003 iteration, exposure id, detrend type, and whether the exposure was5004 included in the stack for this iteration.5005 */5006 5007 5008 bool status = false;5009 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");5010 if (!status) {5011 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");5012 return false;5013 }5014 5015 psString query = pxDataGet("dettool_toresidexp.sql");5016 if (!query) {5017 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");5018 return false;5019 }5020 5021 // XXX does it make sense to accept any search params?5022 #if 05023 if (config->where) {5024 psString whereClause = psDBGenerateWhereConditionSQL(config->where);5025 psStringAppend(&query, " AND %s", whereClause);5026 psFree(whereClause);5027 }5028 #endif5029 5030 // treat limit == 0 as "no limit"5031 if (limit) {5032 psString limitString = psDBGenerateLimitSQL(limit);5033 psStringAppend(&query, " %s", limitString);5034 psFree(limitString);5035 }5036 5037 if (!p_psDBRunQuery(config->dbh, query)) {5038 psError(PS_ERR_UNKNOWN, false, "database error");5039 psFree(query);5040 return false;5041 }5042 psFree(query);5043 5044 psArray *output = p_psDBFetchResult(config->dbh);5045 if (!output) {5046 psError(PS_ERR_UNKNOWN, false, "database error");5047 return false;5048 }5049 if (!psArrayLength(output)) {5050 psTrace("dettool", PS_LOG_INFO, "no rows found");5051 psFree(output);5052 return true;5053 }5054 5055 bool simple = false;5056 {5057 bool status = false;5058 simple = psMetadataLookupBool(&status, config->args, "-simple");5059 if (!status) {5060 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");5061 return false;5062 }5063 }5064 5065 // negative simple so the default is true5066 if (!ippdbPrintMetadatas(stdout, output, "detPendingResidExp", !simple)) {5067 psError(PS_ERR_UNKNOWN, false, "failed to print array");5068 psFree(output);5069 return false;5070 }5071 5072 psFree(output);5073 5074 return true;5075 }5076 5077 static bool addresidexpMode(pxConfig *config)5078 {5079 PS_ASSERT_PTR_NON_NULL(config, false);5080 5081 /*5082 which returns a list of exposures for which all component class ids5083 have had residuals created. This list includes the detrend id,5084 iteration, exposure id, detrend type, and whether the exposure was5085 included in the stack for this iteration.5086 */5087 5088 5089 // select detRun.det_id5090 // select detRun.iteration5091 // select detRun.det_type5092 // select detInputExp.exp_id5093 // select detInputExp.include5094 // by:5095 // find the current iteration bassed on det_id5096 // find all exp_ids in the current det_id/iteration from detInputExp5097 // compare to detInputExp.imfiles to derResidImfile by class_id5098 // and:5099 // detResidImfile.{det_id, iteration, exp_id} is not in detResidExp5100 5101 psString query = pxDataGet("dettool_toresidexp.sql");5102 if (!query) {5103 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");5104 return false;5105 }5106 5107 {5108 // build a query to search by det_id, iteration, exp_id5109 psMetadata *where = psMetadataAlloc();5110 bool status = false;5111 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");5112 if (!status) {5113 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");5114 return false;5115 }5116 if (!det_id) {5117 psError(PS_ERR_UNKNOWN, true, "-det_id is required");5118 return false;5119 }5120 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", (psS64)atoll(det_id))) {5121 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");5122 psFree(where);5123 psFree(query);5124 return false;5125 }5126 5127 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");5128 if (!status) {5129 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");5130 psFree(where);5131 psFree(query);5132 return false;5133 }5134 // always set iteration5135 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) {5136 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");5137 psFree(where);5138 psFree(query);5139 return false;5140 }5141 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");5142 if (!status) {5143 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");5144 psFree(where);5145 psFree(query);5146 return false;5147 }5148 if (exp_id) {5149 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) {5150 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");5151 psFree(where);5152 psFree(query);5153 return false;5154 }5155 }5156 5157 // there's not5158 psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);5159 psFree(where);5160 if (whereClause) {5161 psStringAppend(&query, " WHERE %s", whereClause);5162 psFree(whereClause);5163 }5164 }5165 5166 if (!p_psDBRunQuery(config->dbh, query)) {5167 psError(PS_ERR_UNKNOWN, false, "database error");5168 psFree(query);5169 return false;5170 }5171 psFree(query);5172 5173 psArray *output = p_psDBFetchResult(config->dbh);5174 if (!output) {5175 psError(PS_ERR_UNKNOWN, false, "database error");5176 return false;5177 }5178 if (!psArrayLength(output)) {5179 // XXX check psError here5180 psError(PS_ERR_UNKNOWN, false, "no detResidImfile rows found");5181 psFree(output);5182 return false;5183 }5184 5185 // start a transaction so it's all rows or nothing5186 if (!psDBTransaction(config->dbh)) {5187 psError(PS_ERR_UNKNOWN, false, "database error");5188 psFree(output);5189 return false;5190 }5191 5192 for (long i = 0; i < psArrayLength(output); i++) {5193 psMetadata *row = output->data[i];5194 // convert metadata into a detResidExp object5195 detResidExpRow *residExp = mdToDetResidExp(config, row);5196 if (!residExp) {5197 if (!psDBRollback(config->dbh)) {5198 psError(PS_ERR_UNKNOWN, false, "database error");5199 }5200 psError(PS_ERR_UNKNOWN, false, "failed to convert metadata to detResidExp");5201 psFree(output);5202 return false;5203 }5204 // insert detResidExp object into the database5205 if (!detResidExpInsertObject(config->dbh, residExp)) {5206 if (!psDBRollback(config->dbh)) {5207 psError(PS_ERR_UNKNOWN, false, "database error");5208 }5209 psError(PS_ERR_UNKNOWN, false, "database error");5210 psFree(residExp);5211 psFree(output);5212 }5213 psFree(residExp);5214 }5215 5216 psFree(output);5217 5218 if (!psDBCommit(config->dbh)) {5219 psError(PS_ERR_UNKNOWN, false, "database error");5220 return false;5221 }5222 5223 return true;5224 }5225 5226 static detResidExpRow *mdToDetResidExp(pxConfig *config, psMetadata *row)5227 {5228 PS_ASSERT_PTR_NON_NULL(config, NULL);5229 PS_ASSERT_PTR_NON_NULL(row, NULL);5230 5231 bool status = false;5232 // values from row5233 psS64 det_id = psMetadataLookupS64(&status, row, "det_id");5234 if (!status) {5235 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for det_id");5236 return false;5237 }5238 //if (isnan(det_id)) {5239 // psError(PS_ERR_UNKNOWN, true, "det_id is required");5240 // return false;5241 //}5242 psS32 iteration = psMetadataLookupS32(&status, row, "iteration");5243 if (!status) {5244 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for iteration");5245 return false;5246 }5247 psS64 exp_id = psMetadataLookupS64(&status, row, "exp_id");5248 if (!status) {5249 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for exp_id");5250 return false;5251 }5252 if (!exp_id) {5253 psError(PS_ERR_UNKNOWN, true, "exp_id is required");5254 return false;5255 }5256 5257 // values from config5258 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");5259 if (!status) {5260 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");5261 return false;5262 }5263 if (!recipe) {5264 psError(PS_ERR_UNKNOWN, true, "-recip is required");5265 return false;5266 }5267 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");5268 if (!status) {5269 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");5270 return false;5271 }5272 //if (isnan(bg)) {5273 // psError(PS_ERR_UNKNOWN, true, "-bg is required");5274 // return false;5275 //}5276 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");5277 if (!status) {5278 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");5279 return false;5280 }5281 //if (isnan(bg_stdev)) {5282 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");5283 // return false;5284 //}5285 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");5286 if (!status) {5287 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");5288 return false;5289 }5290 psF64 bg_skewness = psMetadataLookupF64(&status, config->args, "-bg_skewness");5291 if (!status) {5292 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_skewness");5293 return false;5294 }5295 psF64 bg_kurtosis = psMetadataLookupF64(&status, config->args, "-bg_kurtosis");5296 if (!status) {5297 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_kurtosis");5298 return false;5299 }5300 psF64 bin_stdev = psMetadataLookupF64(&status, config->args, "-bin_stdev");5301 if (!status) {5302 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bin_stdev");5303 return false;5304 }5305 // optional5306 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0");5307 if (!status) {5308 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0");5309 return false;5310 }5311 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1");5312 if (!status) {5313 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1");5314 return false;5315 }5316 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2");5317 if (!status) {5318 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2");5319 return false;5320 }5321 5322 psF64 fringe_resid_0 = psMetadataLookupF64(&status, config->args, "-fringe_resid_0");5323 if (!status) {5324 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_0");5325 return false;5326 }5327 psF64 fringe_resid_1 = psMetadataLookupF64(&status, config->args, "-fringe_resid_1");5328 if (!status) {5329 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_1");5330 return false;5331 }5332 psF64 fringe_resid_2 = psMetadataLookupF64(&status, config->args, "-fringe_resid_2");5333 if (!status) {5334 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_2");5335 return false;5336 }5337 5338 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");5339 if (!status) {5340 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");5341 return false;5342 }5343 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");5344 if (!status) {5345 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");5346 return false;5347 }5348 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");5349 if (!status) {5350 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");5351 return false;5352 }5353 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");5354 if (!status) {5355 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");5356 return false;5357 }5358 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");5359 if (!status) {5360 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");5361 return false;5362 }5363 5364 // optional5365 bool reject = psMetadataLookupBool(&status, config->args, "-reject");5366 if (!status) {5367 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reject");5368 return false;5369 }5370 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");5371 if (!status) {5372 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");5373 return false;5374 }5375 if (!path_base) {5376 psError(PS_ERR_UNKNOWN, true, "-path_base is required");5377 return false;5378 }5379 5380 // default values5381 psS16 code = psMetadataLookupS16(&status, config->args, "-code");5382 if (!status) {5383 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");5384 return false;5385 }5386 5387 // create a new detResidImfileRow and insert it5388 return detResidExpRowAlloc(5389 det_id,5390 iteration,5391 exp_id,5392 recipe,5393 bg,5394 bg_stdev,5395 bg_mean_stdev,5396 bg_skewness,5397 bg_kurtosis,5398 bin_stdev,5399 fringe_0,5400 fringe_1,5401 fringe_2,5402 fringe_resid_0,5403 fringe_resid_1,5404 fringe_resid_2,5405 user_1,5406 user_2,5407 user_3,5408 user_4,5409 user_5,5410 path_base,5411 !reject,5412 code5413 );5414 }5415 5416 static bool residexpMode(pxConfig *config)5417 {5418 PS_ASSERT_PTR_NON_NULL(config, false);5419 5420 bool status = false;5421 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");5422 if (!status) {5423 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");5424 return false;5425 }5426 5427 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");5428 if (!status) {5429 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");5430 return false;5431 }5432 5433 psString query = psStringCopy(5434 "SELECT"5435 " detRun.mode,"5436 " detResidExp.*,"5437 " detInputExp.include"5438 " FROM detRun"5439 " JOIN detInputExp"5440 " USING(det_id, iteration)"5441 " JOIN detResidExp"5442 " USING(det_id, iteration, exp_id)"5443 " WHERE"5444 " detRun.state = 'run'"5445 );5446 5447 if (config->where) {5448 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidExp");5449 psStringAppend(&query, " AND %s", whereClause);5450 psFree(whereClause);5451 }5452 5453 if (faulted) {5454 // list only faulted rows5455 psStringAppend(&query, " %s", "AND detResidExp.fault != 0");5456 } else {5457 // don't list faulted rows5458 psStringAppend(&query, " %s", "AND detResidExp.fault = 0");5459 }5460 5461 // treat limit == 0 as "no limit"5462 if (limit) {5463 psString limitString = psDBGenerateLimitSQL(limit);5464 psStringAppend(&query, " %s", limitString);5465 psFree(limitString);5466 }5467 5468 if (!p_psDBRunQuery(config->dbh, query)) {5469 psError(PS_ERR_UNKNOWN, false, "database error");5470 psFree(query);5471 return false;5472 }5473 psFree(query);5474 5475 psArray *output = p_psDBFetchResult(config->dbh);5476 if (!output) {5477 psError(PS_ERR_UNKNOWN, false, "database error");5478 return false;5479 }5480 if (!psArrayLength(output)) {5481 psTrace("dettool", PS_LOG_INFO, "no rows found");5482 psFree(output);5483 return true;5484 }5485 5486 bool simple = false;5487 {5488 bool status = false;5489 simple = psMetadataLookupBool(&status, config->args, "-simple");5490 if (!status) {5491 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");5492 return false;5493 }5494 }5495 5496 // negative simple so the default is true5497 if (!ippdbPrintMetadatas(stdout, output, "detResidExp", !simple)) {5498 psError(PS_ERR_UNKNOWN, false, "failed to print array");5499 psFree(output);5500 return false;5501 }5502 5503 psFree(output);5504 5505 return true;5506 }5507 5508 5509 static bool revertresidexpMode(pxConfig *config)5510 {5511 PS_ASSERT_PTR_NON_NULL(config, false);5512 5513 psString query = pxDataGet("dettool_revertresidexp.sql");5514 if (!query) {5515 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");5516 return false;5517 }5518 5519 if (config->where) {5520 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidExp");5521 psStringAppend(&query, " AND %s", whereClause);5522 psFree(whereClause);5523 }5524 5525 if (!p_psDBRunQuery(config->dbh, query)) {5526 psError(PS_ERR_UNKNOWN, false, "database error");5527 psFree(query);5528 return false;5529 }5530 psFree(query);5531 5532 if (psDBAffectedRows(config->dbh) < 1) {5533 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");5534 return false;5535 }5536 5537 return true;5538 }5539 5540 5541 static bool todetrunsummaryMode(pxConfig *config)5542 {5543 PS_ASSERT_PTR_NON_NULL(config, false);5544 5545 bool status = false;5546 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");5547 if (!status) {5548 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");5549 return false;5550 }5551 5552 /* which returns a list of detrend runs (with detrend id, iteration and5553 * detrend type) which have completed all residexps.5554 */5555 5556 psString query = pxDataGet("dettool_todetrunsummary.sql");5557 if (!query) {5558 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");5559 return false;5560 }5561 5562 // XXX does it make sense to accept any search params?5563 #if 05564 if (config->where) {5565 psString whereClause = psDBGenerateWhereConditionSQL(config->where);5566 psStringAppend(&query, " AND %s", whereClause);5567 psFree(whereClause);5568 }5569 #endif5570 5571 // treat limit == 0 as "no limit"5572 if (limit) {5573 psString limitString = psDBGenerateLimitSQL(limit);5574 psStringAppend(&query, " %s", limitString);5575 psFree(limitString);5576 }5577 5578 if (!p_psDBRunQuery(config->dbh, query)) {5579 psError(PS_ERR_UNKNOWN, false, "database error");5580 psFree(query);5581 return false;5582 }5583 psFree(query);5584 5585 psArray *output = p_psDBFetchResult(config->dbh);5586 if (!output) {5587 psError(PS_ERR_UNKNOWN, false, "database error");5588 return false;5589 }5590 if (!psArrayLength(output)) {5591 psTrace("dettool", PS_LOG_INFO, "no rows found");5592 psFree(output);5593 return true;5594 }5595 5596 bool simple = false;5597 {5598 bool status = false;5599 simple = psMetadataLookupBool(&status, config->args, "-simple");5600 if (!status) {5601 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");5602 return false;5603 }5604 }5605 5606 // negative simple so the default is true5607 if (!ippdbPrintMetadatas(stdout, output, "detRejectExp", !simple)) {5608 psError(PS_ERR_UNKNOWN, false, "failed to print array");5609 psFree(output);5610 return false;5611 }5612 5613 psFree(output);5614 5615 return true;5616 }5617 5618 static bool updateresidexpMode(pxConfig *config)5619 {5620 PS_ASSERT_PTR_NON_NULL(config, false);5621 5622 // build a query to search by det_id, iteration, exp_id5623 psMetadata *where = psMetadataAlloc();5624 bool status = false;5625 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");5626 if (!status) {5627 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");5628 psFree(where);5629 return false;5630 }5631 if (det_id) {5632 if (!psMetadataAddStr(where, PS_LIST_TAIL, "det_id", 0, "==", det_id)) {5633 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");5634 psFree(where);5635 return false;5636 }5637 }5638 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");5639 if (!status) {5640 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");5641 psFree(where);5642 return false;5643 }5644 // always where iteration5645 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) {5646 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");5647 psFree(where);5648 return false;5649 }5650 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");5651 if (!status) {5652 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");5653 psFree(where);5654 return false;5655 }5656 if (exp_id) {5657 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) {5658 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");5659 psFree(where);5660 return false;5661 }5662 }5663 5664 // find the values we're going to set5665 // copy everything but det_id, iteration, & exp_id from the args and5666 // remove the '-' prefix5667 psMetadata *set = psMetadataAlloc();5668 psString recipe = psMetadataLookupStr(&status, config->args, "-recip");5669 if (!status) {5670 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");5671 psFree(set);5672 psFree(where);5673 return false;5674 }5675 if (recipe) {5676 if (!psMetadataAddStr(set, PS_LIST_TAIL, "recipe", 0, "==", recipe)) {5677 psError(PS_ERR_UNKNOWN, false, "failed to add item recipe");5678 psFree(set);5679 psFree(where);5680 return false;5681 }5682 }5683 5684 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");5685 if (!status) {5686 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");5687 psFree(set);5688 psFree(where);5689 return false;5690 }5691 if (!isnan(bg)) {5692 if (!psMetadataAddF64(set, PS_LIST_TAIL, "bg", 0, "==", bg)) {5693 psError(PS_ERR_UNKNOWN, false, "failed to add item bg");5694 psFree(set);5695 psFree(where);5696 return false;5697 }5698 }5699 5700 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");5701 if (!status) {5702 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");5703 psFree(set);5704 psFree(where);5705 return false;5706 }5707 if (!isnan(bg_stdev)) {5708 if (!psMetadataAddF64(set, PS_LIST_TAIL, "bg_stdev", 0, "==", bg_stdev)) {5709 psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev");5710 psFree(set);5711 psFree(where);5712 return false;5713 }5714 }5715 5716 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");5717 if (!status) {5718 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");5719 psFree(set);5720 psFree(where);5721 return false;5722 }5723 if (!isnan(bg_mean_stdev)) {5724 if (!psMetadataAddF64(set, PS_LIST_TAIL, "bg_mean_stdev", 0, "==", bg_mean_stdev)) {5725 psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");5726 psFree(set);5727 psFree(where);5728 return false;5729 }5730 }5731 5732 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");5733 if (!status) {5734 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");5735 psFree(set);5736 psFree(where);5737 return false;5738 }5739 if (path_base) {5740 if (!psMetadataAddStr(set, PS_LIST_TAIL, "path_base", 0, "==", path_base)) {5741 psError(PS_ERR_UNKNOWN, false, "failed to add item path_base");5742 psFree(set);5743 psFree(where);5744 return false;5745 }5746 }5747 5748 bool reject = psMetadataLookupBool(&status, config->args, "-reject");5749 if (!status) {5750 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reject");5751 psFree(set);5752 psFree(where);5753 return false;5754 }5755 if (!psMetadataAddBool(set, PS_LIST_TAIL, "accept", 0, "==", !reject)) {5756 psError(PS_ERR_UNKNOWN, false, "failed to add item accept");5757 psFree(set);5758 psFree(where);5759 return false;5760 }5761 5762 long changed = psDBUpdateRows(config->dbh, "detResidExp", where, set);5763 psFree(set);5764 psFree(where);5765 5766 if (changed < 0) {5767 psError(PS_ERR_UNKNOWN, false, "no rows were updated");5768 return false;5769 }5770 5771 return true;5772 }5773 5774 static bool adddetrunsummaryMode(pxConfig *config)5775 {5776 PS_ASSERT_PTR_NON_NULL(config, false);5777 5778 // required5779 bool status = false;5780 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");5781 if (!status) {5782 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");5783 return false;5784 }5785 if (!det_id) {5786 psError(PS_ERR_UNKNOWN, true, "-det_id is required");5787 return false;5788 }5789 5790 // optional5791 bool again = psMetadataLookupBool(&status, config->args, "-again");5792 if (!status) {5793 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -again");5794 return false;5795 }5796 5797 psString query = pxDataGet("dettool_find_completed_runs.sql");5798 if (!query) {5799 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");5800 return false;5801 }5802 5803 {5804 // build a query to search by det_id, iteration, exp_id5805 psMetadata *where = psMetadataAlloc();5806 bool status = false;5807 if (det_id) {5808 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", (psS64)atoll(det_id))) {5809 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");5810 psFree(where);5811 psFree(query);5812 return false;5813 }5814 }5815 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration");5816 if (!status) {5817 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration");5818 psFree(where);5819 psFree(query);5820 return false;5821 }5822 // always set iteration5823 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) {5824 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");5825 psFree(where);5826 psFree(query);5827 return false;5828 }5829 5830 // there's not5831 psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);5832 psFree(where);5833 if (whereClause) {5834 psStringAppend(&query, " WHERE %s", whereClause);5835 psFree(whereClause);5836 }5837 }5838 5839 if (!p_psDBRunQuery(config->dbh, query)) {5840 psError(PS_ERR_UNKNOWN, false, "database error");5841 psFree(query);5842 return false;5843 }5844 psFree(query);5845 5846 psArray *output = p_psDBFetchResult(config->dbh);5847 if (!output) {5848 psError(PS_ERR_UNKNOWN, false, "database error");5849 return false;5850 }5851 if (!psArrayLength(output)) {5852 psTrace("dettool", PS_LOG_INFO, "no rows found");5853 psFree(output);5854 return true;5855 }5856 5857 // start a transaction so it's all rows or nothing5858 if (!psDBTransaction(config->dbh)) {5859 psError(PS_ERR_UNKNOWN, false, "database error");5860 psFree(output);5861 return false;5862 }5863 5864 for (long i = 0; i < psArrayLength(output); i++) {5865 psMetadata *row = output->data[i];5866 // convert metadata into a detResidExp object5867 detRunSummaryRow *runSummary = mdToDetRunSummary(config, row);5868 if (!runSummary) {5869 if (!psDBRollback(config->dbh)) {5870 psError(PS_ERR_UNKNOWN, false, "database error");5871 }5872 psError(PS_ERR_UNKNOWN, false, "failed to convert metadata to detResidExp");5873 psFree(output);5874 return false;5875 }5876 // insert detResidExp object into the database5877 if (!detRunSummaryInsertObject(config->dbh, runSummary)) {5878 if (!psDBRollback(config->dbh)) {5879 psError(PS_ERR_UNKNOWN, false, "database error");5880 }5881 psError(PS_ERR_UNKNOWN, false, "database error");5882 psFree(runSummary);5883 psFree(output);5884 return false;5885 }5886 psFree(runSummary);5887 }5888 5889 psFree(output);5890 5891 // XXX this logic does not deal with the case of -code being set5892 if (again) {5893 if (!startNewIteration(config, (psS64)atoll(det_id))) {5894 if (!psDBRollback(config->dbh)) {5895 psError(PS_ERR_UNKNOWN, false, "database error");5896 }5897 psError(PS_ERR_UNKNOWN, false, "failed to start new iteration");5898 return false;5899 }5900 } else {5901 // set detRun.state to stop5902 if (!setDetRunState(config, (psS64)atoll(det_id), "stop")) {5903 if (!psDBRollback(config->dbh)) {5904 psError(PS_ERR_UNKNOWN, false, "database error");5905 }5906 psError(PS_ERR_UNKNOWN, false, "failed to set detRun.state");5907 return false;5908 }5909 }5910 5911 if (!psDBCommit(config->dbh)) {5912 psError(PS_ERR_UNKNOWN, false, "database error");5913 return false;5914 }5915 return true;5916 }5917 5918 static detRunSummaryRow *mdToDetRunSummary(pxConfig *config, psMetadata *row)5919 {5920 PS_ASSERT_PTR_NON_NULL(config, false);5921 5922 bool status = false;5923 // from row5924 psS64 det_id = psMetadataLookupS64(&status, row, "det_id");5925 if (!status) {5926 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for det_id");5927 return false;5928 }5929 psS32 iteration = psMetadataLookupS32(&status, row, "iteration");5930 if (!status) {5931 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for iteration");5932 return false;5933 }5934 5935 // from config->args5936 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");5937 if (!status) {5938 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");5939 return NULL;5940 }5941 //if (isnan(bg)) {5942 // psError(PS_ERR_UNKNOWN, true, "-bg is required");5943 // return NULL;5944 //}5945 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");5946 if (!status) {5947 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");5948 return NULL;5949 }5950 //if (isnan(bg_stdev)) {5951 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");5952 // return NULL;5953 //}5954 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");5955 if (!status) {5956 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");5957 return NULL;5958 }5959 // optional5960 bool accept = psMetadataLookupBool(&status, config->args, "-accept");5961 if (!status) {5962 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -accept");5963 return NULL;5964 }5965 // default values5966 psS16 code = psMetadataLookupS16(&status, config->args, "-code");5967 if (!status) {5968 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");5969 return false;5970 }5971 5972 return detRunSummaryRowAlloc(5973 det_id,5974 iteration,5975 bg,5976 bg_stdev,5977 bg_mean_stdev,5978 accept,5979 code5980 );5981 }5982 5983 static bool detrunsummaryMode(pxConfig *config)5984 {5985 PS_ASSERT_PTR_NON_NULL(config, false);5986 5987 bool status = false;5988 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");5989 if (!status) {5990 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit");5991 return false;5992 }5993 5994 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");5995 if (!status) {5996 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted");5997 return false;5998 }5999 6000 psString query = psStringCopy(6001 "SELECT DISTINCT\n"6002 " detRunSummary.*,\n"6003 " detRun.det_type,\n"6004 " detRun.mode\n"6005 " FROM detRun\n"6006 " JOIN detRunSummary\n"6007 " USING(det_id, iteration)\n"6008 " WHERE\n"6009 " detRun.state = 'run'\n"6010 );6011 6012 if (config->where) {6013 psString whereClause = psDBGenerateWhereConditionSQL(config->where, NULL);6014 psStringAppend(&query, " AND %s", whereClause);6015 psFree(whereClause);6016 }6017 6018 if (faulted) {6019 // list only faulted rows6020 psStringAppend(&query, " %s", "AND detRunSummary.fault != 0");6021 } else {6022 // don't list faulted rows6023 psStringAppend(&query, " %s", "AND detRunSummary.fault = 0");6024 }6025 6026 // treat limit == 0 as "no limit"6027 if (limit) {6028 psString limitString = psDBGenerateLimitSQL(limit);6029 psStringAppend(&query, " %s", limitString);6030 psFree(limitString);6031 }6032 6033 if (!p_psDBRunQuery(config->dbh, query)) {6034 psError(PS_ERR_UNKNOWN, false, "database error");6035 psFree(query);6036 return false;6037 }6038 psFree(query);6039 6040 psArray *output = p_psDBFetchResult(config->dbh);6041 if (!output) {6042 psError(PS_ERR_UNKNOWN, false, "database error");6043 return false;6044 }6045 if (!psArrayLength(output)) {6046 psTrace("dettool", PS_LOG_INFO, "no rows found");6047 psFree(output);6048 return true;6049 }6050 6051 bool simple = false;6052 {6053 bool status = false;6054 simple = psMetadataLookupBool(&status, config->args, "-simple");6055 if (!status) {6056 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");6057 return false;6058 }6059 }6060 6061 // negative simple so the default is true6062 if (!ippdbPrintMetadatas(stdout, output, "rawDetrendImfile", !simple)) {6063 psError(PS_ERR_UNKNOWN, false, "failed to print array");6064 psFree(output);6065 return false;6066 }6067 6068 psFree(output);6069 6070 return true;6071 }6072 6073 6074 static bool revertdetrunsummaryMode(pxConfig *config)6075 {6076 PS_ASSERT_PTR_NON_NULL(config, false);6077 6078 psString query = pxDataGet("dettool_revertdetrunsummary.sql");6079 if (!query) {6080 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");6081 return false;6082 }6083 6084 if (config->where) {6085 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detRunSummary");6086 psStringAppend(&query, " AND %s", whereClause);6087 psFree(whereClause);6088 }6089 6090 if (!p_psDBRunQuery(config->dbh, query)) {6091 psError(PS_ERR_UNKNOWN, false, "database error");6092 psFree(query);6093 return false;6094 }6095 psFree(query);6096 6097 if (psDBAffectedRows(config->dbh) < 1) {6098 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");6099 return false;6100 }6101 6102 return true;6103 }6104 6105 6106 static bool updatedetrunMode(pxConfig *config)6107 {6108 PS_ASSERT_PTR_NON_NULL(config, false);6109 6110 // det_id is required6111 // XXX this isn't strictly nessicary but not having the det_id complicates6112 // incrementing the iteration number6113 bool status = false;6114 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");6115 if (!status) {6116 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");6117 return false;6118 }6119 if (!det_id) {6120 psError(PS_ERR_UNKNOWN, true, "-det_id is required");6121 return false;6122 }6123 // either -rerun or -state must be specified6124 bool again = psMetadataLookupBool(&status, config->args, "-again");6125 if (!status) {6126 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -again");6127 return false;6128 }6129 psString state = psMetadataLookupStr(&status, config->args, "-state");6130 if (!status) {6131 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -state");6132 return false;6133 }6134 if (!(again || state)) {6135 psError(PS_ERR_UNKNOWN, true, "either -again or -state must be specified");6136 return false;6137 }6138 if (again && state) {6139 psError(PS_ERR_UNKNOWN, true, "either -again or -state must be specified");6140 return false;6141 }6142 6143 if (state) {6144 // set detRun.state to state6145 return setDetRunState(config, (psS64)atoll(det_id), state);6146 }6147 6148 // else6149 // -again6150 if (!startNewIteration(config, (psS64)atoll(det_id))) {6151 psError(PS_ERR_UNKNOWN, false, "failed to start new iteration");6152 return false;6153 }6154 6155 return true;6156 }6157 6158 static bool startNewIteration(pxConfig *config, psS64 det_id)6159 {6160 PS_ASSERT_PTR_NON_NULL(config, false);6161 6162 psString query = pxDataGet("dettool_start_new_iteration.sql");6163 if (!query) {6164 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");6165 return false;6166 }6167 6168 // XXX this query was not restricted by det_id, resulting6169 // in an inconsistent UPDATE below. I added this AND clause6170 // though there may be a cleaner method (EAM 2006.10.08)6171 psStringAppend(&query, " WHERE det_id = %" PRId64 , det_id);6172 6173 if (!p_psDBRunQuery(config->dbh, query)) {6174 psError(PS_ERR_UNKNOWN, false, "database error");6175 psFree(query);6176 return false;6177 }6178 psFree(query);6179 6180 psArray *output = p_psDBFetchResult(config->dbh);6181 if (!output) {6182 psError(PS_ERR_UNKNOWN, false, "database error");6183 return false;6184 }6185 if (!psArrayLength(output)) {6186 psError(PS_ERR_UNKNOWN, false, "det_id %" PRId64 " not found", det_id);6187 psFree(output);6188 return false;6189 }6190 6191 // start a transaction so we don't end up with an incremented iteration6192 // count but no detInputExps6193 if (!psDBTransaction(config->dbh)) {6194 psError(PS_ERR_UNKNOWN, false, "database error");6195 psFree(output);6196 return false;6197 }6198 6199 // up the detRuns iteration count for for the single det_id we are6200 // operating on6201 // XXX this will have to changed in order to support multiple det_ids with6202 // a single invocation of this functions6203 psS32 newIteration = incrementIteration(config, det_id);6204 if (!newIteration) {6205 // rollback6206 if (!psDBRollback(config->dbh)) {6207 psError(PS_ERR_UNKNOWN, false, "database error");6208 }6209 psFree(output);6210 return false;6211 }6212 6213 for (long i = 0; i < psArrayLength(output); i++) {6214 psMetadata *row = output->data[i];6215 bool status = false;6216 psS64 exp_id = psMetadataLookupS64(&status, row, "exp_id");6217 if (!status) {6218 // rollback6219 if (!psDBRollback(config->dbh)) {6220 psError(PS_ERR_UNKNOWN, false, "database error");6221 }6222 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for exp_id");6223 psFree(output);6224 return false;6225 }6226 bool accept = psMetadataLookupBool(&status, row, "accept");6227 if (!status) {6228 // rollback6229 if (!psDBRollback(config->dbh)) {6230 psError(PS_ERR_UNKNOWN, false, "database error");6231 }6232 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for accept");6233 psFree(output);6234 return false;6235 }6236 6237 // detResidExp.include is used to set detInputExp.include6238 if (!detInputExpInsert(6239 config->dbh,6240 det_id,6241 newIteration,6242 exp_id,6243 accept6244 )6245 ) {6246 // rollback6247 if (!psDBRollback(config->dbh)) {6248 psError(PS_ERR_UNKNOWN, false, "database error");6249 }6250 psError(PS_ERR_UNKNOWN, false, "database error");6251 psFree(output);6252 return false;6253 }6254 }6255 6256 psFree(output);6257 6258 // point of no return for det_id creation6259 if (!psDBCommit(config->dbh)) {6260 psError(PS_ERR_UNKNOWN, false, "database error");6261 return false;6262 }6263 6264 return true;6265 }6266 6267 static bool rerunMode(pxConfig *config)6268 {6269 PS_ASSERT_PTR_NON_NULL(config, false);6270 6271 // det_id is required6272 bool status = false;6273 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");6274 if (!status) {6275 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");6276 return false;6277 }6278 if (!det_id) {6279 psError(PS_ERR_UNKNOWN, true, "-det_id is required");6280 return false;6281 }6282 6283 // we have to support multipe exp_ids6284 psMetadataItem *item = psMetadataLookup(config->args, "-exp_id");6285 if (!item) {6286 // this shouldn't actually happen when using psArgs6287 psError(PS_ERR_UNKNOWN, true, "-exp_id is required");6288 return false;6289 }6290 6291 psList *exp_id_list = item->data.list;6292 psMetadata *where = psMetadataAlloc();6293 // make sure that -exp_id was parsed correctly6294 // XXX this can be removed someday6295 if (item->type == PS_DATA_METADATA_MULTI) {6296 psListIterator *iter = psListIteratorAlloc(item->data.list, 0, false);6297 psMetadataItem *mItem = NULL;6298 while ((mItem = psListGetAndIncrement(iter))) {6299 psString exp_id = mItem->data.V;6300 // if exp_id is NULL then it means that -exp_id has not been6301 // specified6302 if (!exp_id) {6303 psError(PS_ERR_UNKNOWN, true,6304 "at least one -exp_id is required");6305 psFree(where);6306 return false;6307 }6308 6309 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id",6310 PS_META_DUPLICATE_OK, "==", exp_id)) {6311 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");6312 psFree(iter);6313 psFree(where);6314 return false;6315 }6316 }6317 psFree(iter);6318 } else {6319 psAbort("-exp_id was not parsed correctly (this should not happen");6320 }6321 6322 // check that the specified exp_ids actually exist in the iteration zero6323 // detInputExp set6324 6325 // add the det_id & iteration == 0 to the where clause6326 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==",6327 (psS64)atoll(det_id))) {6328 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");6329 psFree(where);6330 return false;6331 }6332 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", 0)) {6333 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");6334 psFree(where);6335 return false;6336 }6337 6338 psArray *detrendExps = detInputExpSelectRowObjects(config->dbh, where, 0);6339 psFree(where);6340 if (!detrendExps) {6341 psError(PS_ERR_UNKNOWN, false, "no rawExp rows found");6342 psFree(where);6343 return false;6344 }6345 6346 // build a hash for the valid exp_ids6347 psHash *valid_exp_ids = psHashAlloc(psArrayLength(detrendExps));6348 for (long i = 0; i < psArrayLength(detrendExps); i++) {6349 psString exp_idStr = psDBIntToString(((detInputExpRow *)detrendExps->data[i])->exp_id);6350 psHashAdd(valid_exp_ids, exp_idStr, detrendExps->data[i]);6351 psFree(exp_idStr);6352 }6353 psFree(detrendExps);6354 6355 // start a transaction so we don't end up with an incremented iteration6356 // count but no detInputExps6357 if (!psDBTransaction(config->dbh)) {6358 psError(PS_ERR_UNKNOWN, false, "database error");6359 psFree(valid_exp_ids);6360 return false;6361 }6362 6363 // up the detRuns iteration count6364 psS32 newIteration = incrementIteration(config, (psS64)atoll(det_id));6365 if (!newIteration) {6366 // rollback6367 if (!psDBRollback(config->dbh)) {6368 psError(PS_ERR_UNKNOWN, false, "database error");6369 }6370 psFree(valid_exp_ids);6371 return false;6372 }6373 6374 // check exp_ids and build up an array of new detInputExp rows at the same6375 // time6376 psListIterator *iter = psListIteratorAlloc(exp_id_list, 0, false);6377 psMetadataItem *mItem = NULL;6378 psArray *newInputExps = psArrayAllocEmpty(psListLength(exp_id_list));6379 while ((mItem = psListGetAndIncrement(iter))) {6380 detInputExpRow *inputExp = psHashLookup(valid_exp_ids,6381 (char *)mItem->data.V);6382 if (!inputExp) {6383 // rollback6384 if (!psDBRollback(config->dbh)) {6385 psError(PS_ERR_UNKNOWN, false, "database error");6386 }6387 // invalid exp_id6388 psError(PS_ERR_UNKNOWN, false, "exp_id %s is invalid for det_id %s",6389 (char *)mItem->data.V, det_id);6390 psFree(iter);6391 psFree(valid_exp_ids);6392 return false;6393 }6394 detInputExpRow *newInputExp = detInputExpRowAlloc(6395 (psS64)atoll(det_id),6396 newIteration,6397 inputExp->exp_id,6398 true // use6399 );6400 psArrayAdd(newInputExps, 0, newInputExp);6401 psFree(newInputExp);6402 }6403 psFree(iter);6404 psFree(valid_exp_ids);6405 6406 for (long i = 0; i < psArrayLength(newInputExps); i++) {6407 if (!detInputExpInsertObject(config->dbh, newInputExps->data[i])) {6408 psError(PS_ERR_UNKNOWN, false, "database error");6409 // rollback6410 if (!psDBRollback(config->dbh)) {6411 psError(PS_ERR_UNKNOWN, false, "database error");6412 }6413 psFree(newInputExps);6414 return false;6415 }6416 }6417 psFree(newInputExps);6418 6419 // point of no return for det_id creation6420 if (!psDBCommit(config->dbh)) {6421 psError(PS_ERR_UNKNOWN, false, "database error");6422 return false;6423 }6424 6425 return true;6426 }6427 6428 static bool register_detrendMode(pxConfig *config)6429 {6430 PS_ASSERT_PTR_NON_NULL(config, false);6431 6432 // required options6433 bool status = false;6434 psString det_type = psMetadataLookupStr(&status, config->args, "-det_type");6435 if (!status) {6436 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type");6437 return false;6438 }6439 if (!det_type) {6440 psError(PS_ERR_UNKNOWN, true, "-det_type is required");6441 return false;6442 }6443 6444 psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel");6445 if (!status) {6446 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel");6447 return false;6448 }6449 if (!filelevel) {6450 psError(PS_ERR_UNKNOWN, true, "-filelevel is required");6451 return false;6452 }6453 6454 psString workdir = psMetadataLookupStr(&status, config->args, "-workdir");6455 if (!status) {6456 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir");6457 return false;6458 }6459 6460 psString camera = psMetadataLookupStr(&status, config->args, "-inst");6461 if (!status) {6462 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst");6463 return false;6464 }6465 6466 psString telescope = psMetadataLookupStr(&status, config->args, "-telescope");6467 if (!status) {6468 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope");6469 return false;6470 }6471 6472 psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type");6473 if (!status) {6474 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type");6475 return false;6476 }6477 6478 psString filter = psMetadataLookupStr(&status, config->args, "-filter");6479 if (!status) {6480 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");6481 return false;6482 }6483 6484 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-airmass_min");6485 if (!status) {6486 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_min");6487 return false;6488 }6489 6490 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-airmass_max");6491 if (!status) {6492 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_max");6493 return false;6494 }6495 6496 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-exp_time_min");6497 if (!status) {6498 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_min");6499 return false;6500 }6501 6502 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-exp_time_max");6503 if (!status) {6504 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_max");6505 return false;6506 }6507 6508 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-ccd_temp_min");6509 if (!status) {6510 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_min");6511 return false;6512 }6513 6514 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-ccd_temp_max");6515 if (!status) {6516 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_max");6517 return false;6518 }6519 6520 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-posang_min");6521 if (!status) {6522 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_min");6523 return false;6524 }6525 6526 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-posang_max");6527 if (!status) {6528 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_max");6529 return false;6530 }6531 6532 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-solang_min");6533 if (!status) {6534 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_min");6535 return false;6536 }6537 6538 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-solang_max");6539 if (!status) {6540 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_max");6541 return false;6542 }6543 6544 psTime *registered = NULL;6545 {6546 psString registeredStr = psMetadataLookupStr(&status, config->args, "-registered");6547 if (!status) {6548 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -registered");6549 return false;6550 }6551 // pass through NULL as this is an optional field6552 if (registeredStr) {6553 registered = psTimeFromISO(registeredStr, PS_TIME_UTC);6554 } else {6555 registered = NULL;6556 }6557 }6558 6559 psTime *time_begin = NULL;6560 {6561 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-time_begin");6562 if (!status) {6563 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_begin");6564 return false;6565 }6566 // pass through NULL as this is an optional field6567 if (time_beginStr) {6568 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC);6569 } else {6570 time_begin = NULL;6571 }6572 }6573 6574 psTime *time_end = NULL;6575 {6576 psString time_endStr = psMetadataLookupStr(&status, config->args, "-time_end");6577 if (!status) {6578 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_end");6579 return false;6580 }6581 // pass through NULL as this is an optional field6582 if (time_endStr) {6583 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC);6584 } else {6585 time_end = NULL;6586 }6587 }6588 6589 psTime *use_begin = NULL;6590 {6591 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-use_begin");6592 if (!status) {6593 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_begin");6594 return false;6595 }6596 // pass through NULL as this is an optional field6597 if (use_beginStr) {6598 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC);6599 } else {6600 use_begin = NULL;6601 }6602 }6603 6604 psTime *use_end = NULL;6605 {6606 psString use_endStr = psMetadataLookupStr(&status, config->args, "-use_end");6607 if (!status) {6608 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_end");6609 return false;6610 }6611 // pass through NULL as this is an optional field6612 if (use_endStr) {6613 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC);6614 } else {6615 use_end = NULL;6616 }6617 }6618 6619 psString parent = psMetadataLookupStr(&status, config->args, "-parent");6620 if (!status) {6621 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -parent");6622 return false;6623 }6624 6625 psString label = psMetadataLookupStr(&status, config->args, "-label");6626 if (!status) {6627 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label");6628 return false;6629 }6630 6631 if (!psDBTransaction(config->dbh)) {6632 psError(PS_ERR_UNKNOWN, false, "database error");6633 return false;6634 }6635 6636 if (!detRunInsert(config->dbh,6637 0, // det_id6638 0, // the iteration is fixed at 06639 det_type,6640 "register", // mode6641 "register", // state6642 filelevel,6643 workdir,6644 camera,6645 telescope,6646 exp_type,6647 NULL,6648 filter,6649 airmass_min,6650 airmass_max,6651 exp_time_min,6652 exp_time_max,6653 ccd_temp_min,6654 ccd_temp_max,6655 posang_min,6656 posang_max,6657 registered,6658 time_begin,6659 time_end,6660 use_begin,6661 use_end,6662 solang_min,6663 solang_max,6664 label, // label6665 parent ? (psS64)atoll(parent) : 06666 )) {6667 psError(PS_ERR_UNKNOWN, false, "database error");6668 // rollback6669 if (!psDBRollback(config->dbh)) {6670 psError(PS_ERR_UNKNOWN, false, "database error");6671 }6672 psFree(registered);6673 return false;6674 }6675 psFree(registered);6676 6677 // print the new detRun6678 psS64 det_id = psDBLastInsertID(config->dbh);6679 6680 if (!psDBCommit(config->dbh)) {6681 psError(PS_ERR_UNKNOWN, false, "database error");6682 return false;6683 }6684 6685 psArray *detRuns = NULL;6686 {6687 psMetadata *where = psMetadataAlloc();6688 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id);6689 detRuns = psDBSelectRows(config->dbh, "detRun", where, 0);6690 psFree(where);6691 }6692 if (!detRuns) {6693 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created");6694 return false;6695 }6696 // sanity check results6697 if (psArrayLength(detRuns) != 1) {6698 psAbort("found more then one detRun matching det_id %" PRId64 "(this should not happen)", det_id);6699 return false;6700 }6701 6702 if (!convertIdToStr(detRuns)) {6703 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings");6704 psFree(detRuns);6705 return false;6706 }6707 6708 bool simple = false;6709 {6710 bool status = false;6711 simple = psMetadataLookupBool(&status, config->args, "-simple");6712 if (!status) {6713 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");6714 return false;6715 }6716 }6717 6718 // negative simple so the default is true6719 if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) {6720 psError(PS_ERR_UNKNOWN, false, "failed to print array");6721 psFree(detRuns);6722 return false;6723 }6724 psFree(detRuns);6725 6726 return true;6727 }6728 6729 static bool register_detrend_imfileMode(pxConfig *config)6730 {6731 PS_ASSERT_PTR_NON_NULL(config, false);6732 6733 // required options6734 bool status = false;6735 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");6736 if (!status) {6737 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");6738 return false;6739 }6740 if (!det_id) {6741 psError(PS_ERR_UNKNOWN, true, "-det_id is required");6742 return false;6743 }6744 6745 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id");6746 if (!status) {6747 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id");6748 return false;6749 }6750 if (!class_id) {6751 psError(PS_ERR_UNKNOWN, true, "-class_id is required");6752 return false;6753 }6754 6755 psString uri = psMetadataLookupStr(&status, config->args, "-uri");6756 if (!status) {6757 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri");6758 return false;6759 }6760 if (!uri) {6761 psError(PS_ERR_UNKNOWN, true, "-uri is required");6762 return false;6763 }6764 6765 // everything else is optional6766 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");6767 if (!status) {6768 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");6769 return false;6770 }6771 6772 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");6773 if (!status) {6774 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");6775 return false;6776 }6777 6778 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");6779 if (!status) {6780 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");6781 return false;6782 }6783 6784 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");6785 if (!status) {6786 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");6787 return false;6788 }6789 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");6790 if (!status) {6791 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");6792 return false;6793 }6794 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");6795 if (!status) {6796 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");6797 return false;6798 }6799 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");6800 if (!status) {6801 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");6802 return false;6803 }6804 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");6805 if (!status) {6806 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");6807 return false;6808 }6809 6810 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base");6811 if (!status) {6812 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base");6813 return false;6814 }6815 6816 if (!detRegisteredImfileInsert(config->dbh,6817 (psS64)atoll(det_id),6818 0, // the iteration is fixed at 06819 class_id,6820 uri,6821 bg,6822 bg_stdev,6823 bg_mean_stdev,6824 user_1,6825 user_2,6826 user_3,6827 user_4,6828 user_5,6829 path_base,6830 0 // fault code6831 )) {6832 psError(PS_ERR_UNKNOWN, false, "database error");6833 return false;6834 }6835 6836 return true;6837 }6838 6839 static psS32 incrementIteration(pxConfig *config, psS64 det_id)6840 {6841 // this function returns zero on error6842 PS_ASSERT_PTR_NON_NULL(config, 0);6843 6844 char *query = "UPDATE detRun SET iteration = iteration + 1 WHERE det_id = %" PRId64;6845 if (!p_psDBRunQuery(config->dbh, query, det_id)) {6846 psError(PS_ERR_UNKNOWN, false,6847 "failed to increment iteration for det_id %" PRId64, det_id);6848 return 0;6849 }6850 6851 psMetadata *where = psMetadataAlloc();6852 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id)) {6853 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id");6854 psFree(where);6855 return 0;6856 }6857 6858 psArray *detRuns = detRunSelectRowObjects(config->dbh, where, 0);6859 psFree(where);6860 if (!detRuns) {6861 psError(PS_ERR_UNKNOWN, false, "no detRun rows found");6862 return 0;6863 }6864 6865 // sanity check the database6866 if (psArrayLength(detRuns) != 1) {6867 // this should no happen6868 psAbort( "database query return too many rows (this should not happen");6869 }6870 6871 psS32 newIteration = ((detRunRow *)detRuns->data[0])->iteration;6872 psFree(detRuns);6873 6874 return newIteration;6875 }6876 6877 static bool setDetRunState(pxConfig *config, psS64 det_id, const char *state)6878 {6879 PS_ASSERT_PTR_NON_NULL(config, false);6880 PS_ASSERT_PTR_NON_NULL(state, false);6881 6882 // check that state is a valid string value6883 if (!(6884 (strncmp(state, "run", 4) == 0)6885 || (strncmp(state, "stop", 5) == 0)6886 || (strncmp(state, "drop", 5) == 0)6887 || (strncmp(state, "register", 4) == 0)6888 )6889 ) {6890 psError(PS_ERR_UNKNOWN, false,6891 "invalid detRun state: %s", state);6892 return false;6893 }6894 6895 char *query = "UPDATE detRun SET state = '%s' WHERE det_id = %" PRId64;6896 if (!p_psDBRunQuery(config->dbh, query, state, det_id)) {6897 psError(PS_ERR_UNKNOWN, false,6898 "failed to change state for det_id %" PRId64, det_id);6899 return false;6900 }6901 6902 return true;6903 }6904 6905 static bool isValidMode(pxConfig *config, const char *mode)6906 {6907 PS_ASSERT_PTR_NON_NULL(config, false);6908 PS_ASSERT_PTR_NON_NULL(mode, false);6909 6910 // check that state is a valid string value6911 if (!(6912 (strncmp(mode, "master", 7) == 0)6913 || (strncmp(mode, "verify", 7) == 0)6914 )6915 ) {6916 psError(PS_ERR_UNKNOWN, false,6917 "invalid detRun mode: %s", mode);6918 return false;6919 }6920 6921 return true;6922 } -
trunk/ippTools/src/caltool.h
r15537 r15545 1 1 /* 2 * dettool.c2 * caltool.h 3 3 * 4 * Copyright (C) 2006 Joshua Hoblitt4 * Copyright (C) 2006-2007 Joshua Hoblitt 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify it … … 18 18 */ 19 19 20 #ifdef HAVB_CONFIG_H 21 #include <config.h> 22 #endif 23 24 #include <stdio.h> 25 #include <string.h> 26 #include <stdlib.h> 27 #include <stdint.h> 28 #include <inttypes.h> 29 30 #include <ippdb.h> 20 #ifndef CALTOOL_H 21 #define CALTOOL_H 1 31 22 32 23 #include "pxtools.h" 33 #include "dettool.h"34 24 35 static bool pendingMode(pxConfig *config); 36 static bool definebytagMode(pxConfig *config); 37 static bool definebyqueryMode(pxConfig *config); 38 static bool definebydetrunMode(pxConfig *config); 39 static bool runsMode(pxConfig *config); 40 static bool childlessrunMode(pxConfig *config); 41 static bool inputMode(pxConfig *config); 42 static bool rawMode(pxConfig *config); 43 // processedimfile 44 static bool toprocessedimfileMode(pxConfig *config); 45 static bool addprocessedimfileMode(pxConfig *config); 46 static bool processedimfileMode(pxConfig *config); 47 static bool revertprocessedimfileMode(pxConfig *config); 48 // processedexp 49 static bool toprocessedexpMode(pxConfig *config); 50 static bool addprocessedexpMode(pxConfig *config); 51 static bool processedexpMode(pxConfig *config); 52 static bool revertprocessedexpMode(pxConfig *config); 53 // stackedimfile 54 static bool tostackedMode(pxConfig *config); 55 static bool addstackedMode(pxConfig *config); 56 static bool stackedMode(pxConfig *config); 57 static bool revertstackedMode(pxConfig *config); 58 // normalizedstat 59 static bool tonormalizedstatMode(pxConfig *config); 60 static bool addnormalizedstatMode(pxConfig *config); 61 static bool normalizedstatMode(pxConfig *config); 62 static bool revertnormalizedstatMode(pxConfig *config); 63 // normalizedimfile 64 static bool tonormalizeMode(pxConfig *config); 65 static bool addnormalizedimfileMode(pxConfig *config); 66 static bool normalizedimfileMode(pxConfig *config); 67 static bool revertnormalizedimfileMode(pxConfig *config); 68 // normalizedexp 69 static bool tonormalizedexpMode(pxConfig *config); 70 static bool addnormalizedexpMode(pxConfig *config); 71 static bool normalizedexpMode(pxConfig *config); 72 static bool revertnormalizedexpMode(pxConfig *config); 73 // residimfile 74 static bool toresidimfileMode(pxConfig *config); 75 static bool addresidimfileMode(pxConfig *config); 76 static bool residimfileMode(pxConfig *config); 77 static bool revertresidimfileMode(pxConfig *config); 78 // residexp 79 static bool toresidexpMode(pxConfig *config); 80 static bool addresidexpMode(pxConfig *config); 81 static bool residexpMode(pxConfig *config); 82 static bool revertresidexpMode(pxConfig *config); 83 static bool updateresidexpMode(pxConfig *config); 84 // detrunsummary 85 static bool todetrunsummaryMode(pxConfig *config); 86 static bool adddetrunsummaryMode(pxConfig *config); 87 static bool detrunsummaryMode(pxConfig *config); 88 static bool revertdetrunsummaryMode(pxConfig *config); 89 static bool updatedetrunMode(pxConfig *config); 90 static bool rerunMode(pxConfig *config); 91 // register 92 static bool register_detrendMode(pxConfig *config); 93 static bool register_detrend_imfileMode(pxConfig *config); 25 typedef enum { 26 CALTOOL_MODE_NONE = PXTOOL_MODE_NONE, 27 CALTOOL_MODE_DBS, 28 CALTOOL_MODE_ADDDB, 29 CALTOOL_MODE_ADDRUN, 30 CALTOOL_MODE_RUNS 31 } dettoolMode; 94 32 95 static detNormalizedStatImfileRow *detStackedToDetNormalizedStatImfile(pxConfig *config, detStackedImfileRow *stackedImfile); 96 static detNormalizedImfileRow *detNormalizedStatToDetNormalizedmfile(pxConfig *config, detNormalizedStatImfileRow *statImfile); 97 static detResidExpRow *mdToDetResidExp(pxConfig *config, psMetadata *row); 98 static detRunSummaryRow *mdToDetRunSummary(pxConfig *config, psMetadata *row); 99 //static psArray *validDetInputClassIds(pxConfig *config, const char *det_id); 100 //static psArray *searchInputImfiles(pxConfig *config, const char *det_id); 101 static detInputExpRow *rawDetrenTodetInputExpRow(rawExpRow *rawExp, psS64 det_id, psS32 iteration); 102 static psArray *searchRawImfiles(pxConfig *config, psMetadata *where); 103 static bool startNewIteration(pxConfig *config, psS64 det_id); 104 static psS32 incrementIteration(pxConfig *config, psS64 det_id); 105 static bool setDetRunState(pxConfig *config, psS64 det_id, const char *state); 106 static bool isValidMode(pxConfig *config, const char *mode); 33 pxConfig *caltoolConfig(pxConfig *config, int argc, char **argv); 107 34 108 # define MODECASE(caseName, func) \ 109 case caseName: \ 110 if (!func(config)) { \ 111 goto FAIL; \ 112 } \ 113 break; 114 115 int main(int argc, char **argv) 116 { 117 psLibInit(NULL); 118 119 pxConfig *config = dettoolConfig(NULL, argc, argv); 120 if (!config) { 121 psError(PXTOOLS_ERR_CONFIG, false, "failed to configure"); 122 goto FAIL; 123 } 124 125 switch (config->mode) { 126 MODECASE(DETTOOL_MODE_PENDING, pendingMode); 127 MODECASE(DETTOOL_MODE_DEFINEBYTAG, definebytagMode); 128 MODECASE(DETTOOL_MODE_DEFINEBYQUERY, definebyqueryMode); 129 MODECASE(DETTOOL_MODE_DEFINEBYDETRUN, definebydetrunMode); 130 MODECASE(DETTOOL_MODE_RUNS, runsMode); 131 MODECASE(DETTOOL_MODE_CHILDLESSRUN, childlessrunMode); 132 MODECASE(DETTOOL_MODE_INPUT, inputMode); 133 MODECASE(DETTOOL_MODE_RAW, rawMode); 134 // imfile 135 MODECASE(DETTOOL_MODE_TOPROCESSEDIMFILE,toprocessedimfileMode); 136 MODECASE(DETTOOL_MODE_ADDPROCESSEDIMFILE,addprocessedimfileMode); 137 MODECASE(DETTOOL_MODE_PROCESSEDIMFILE, processedimfileMode); 138 MODECASE(DETTOOL_MODE_REVERTPROCESSEDIMFILE, revertprocessedimfileMode); 139 // exp 140 MODECASE(DETTOOL_MODE_TOPROCESSEDEXP, toprocessedexpMode); 141 MODECASE(DETTOOL_MODE_ADDPROCESSEDEXP, addprocessedexpMode); 142 MODECASE(DETTOOL_MODE_PROCESSEDEXP, processedexpMode); 143 MODECASE(DETTOOL_MODE_REVERTPROCESSEDEXP, revertprocessedexpMode); 144 // stacked 145 MODECASE(DETTOOL_MODE_TOSTACKED, tostackedMode); 146 MODECASE(DETTOOL_MODE_ADDSTACKED, addstackedMode); 147 MODECASE(DETTOOL_MODE_STACKED, stackedMode); 148 MODECASE(DETTOOL_MODE_REVERTSTACKED, revertstackedMode); 149 // normalizedstat 150 MODECASE(DETTOOL_MODE_TONORMALIZEDSTAT, tonormalizedstatMode); 151 MODECASE(DETTOOL_MODE_ADDNORMALIZEDSTAT,addnormalizedstatMode); 152 MODECASE(DETTOOL_MODE_NORMALIZEDSTAT, normalizedstatMode); 153 MODECASE(DETTOOL_MODE_REVERTNORMALIZEDSTAT, revertnormalizedstatMode); 154 // normalizedimfile 155 MODECASE(DETTOOL_MODE_TONORMALIZE, tonormalizeMode); 156 MODECASE(DETTOOL_MODE_ADDNORMALIZEDIMFILE,addnormalizedimfileMode); 157 MODECASE(DETTOOL_MODE_NORMALIZEDIMFILE, normalizedimfileMode); 158 MODECASE(DETTOOL_MODE_REVERTNORMALIZEDIMFILE, revertnormalizedimfileMode); 159 // normalizedexp 160 MODECASE(DETTOOL_MODE_TONORMALIZEDEXP, tonormalizedexpMode); 161 MODECASE(DETTOOL_MODE_ADDNORMALIZEDEXP, addnormalizedexpMode); 162 MODECASE(DETTOOL_MODE_NORMALIZEDEXP, normalizedexpMode); 163 MODECASE(DETTOOL_MODE_REVERTNORMALIZEDEXP, revertnormalizedexpMode); 164 // residimfile 165 MODECASE(DETTOOL_MODE_TORESIDIMFILE, toresidimfileMode); 166 MODECASE(DETTOOL_MODE_ADDRESIDIMFILE, addresidimfileMode); 167 MODECASE(DETTOOL_MODE_RESIDIMFILE, residimfileMode); 168 MODECASE(DETTOOL_MODE_REVERTRESIDIMFILE,revertresidimfileMode); 169 // residexp 170 MODECASE(DETTOOL_MODE_TORESIDEXP, toresidexpMode); 171 MODECASE(DETTOOL_MODE_ADDRESIDEXP, addresidexpMode); 172 MODECASE(DETTOOL_MODE_RESIDEXP, residexpMode); 173 MODECASE(DETTOOL_MODE_REVERTRESIDEXP, revertresidexpMode); 174 MODECASE(DETTOOL_MODE_UPDATERESIDEXP, updateresidexpMode); 175 // detrunsummary 176 MODECASE(DETTOOL_MODE_TODETRUNSUMMARY, todetrunsummaryMode); 177 MODECASE(DETTOOL_MODE_ADDDETRUNSUMMARY, adddetrunsummaryMode); 178 MODECASE(DETTOOL_MODE_DETRUNSUMMARY, detrunsummaryMode); 179 MODECASE(DETTOOL_MODE_REVERTDETRUNSUMMARY, revertdetrunsummaryMode); 180 MODECASE(DETTOOL_MODE_UPDATEDETRUN, updatedetrunMode); 181 MODECASE(DETTOOL_MODE_RERUN, rerunMode); 182 // register 183 MODECASE(DETTOOL_MODE_REGISTER_DETREND, register_detrendMode); 184 MODECASE(DETTOOL_MODE_REGISTER_DETREND_IMFILE, register_detrend_imfileMode); 185 default: 186 psAbort("invalid option (this should not happen)"); 187 } 188 189 psFree(config); 190 pmConfigDone(); 191 psLibFinalize(); 192 193 exit(EXIT_SUCCESS); 194 195 FAIL: 196 psErrorStackPrint(stderr, "\n"); 197 int exit_status = pxerrorGetExitStatus(); 198 199 psFree(config); 200 pmConfigDone(); 201 psLibFinalize(); 202 203 exit(exit_status); 204 } 205 206 static bool pendingMode(pxConfig *config) 207 { 208 PS_ASSERT_PTR_NON_NULL(config, NULL); 209 210 psString query = psStringCopy( 211 "SELECT" 212 " rawExp.*" 213 " FROM rawExp" 214 " LEFT JOIN detInputExp" 215 " ON rawExp.exp_id = detInputExp.exp_id" 216 " WHERE" 217 " detInputExp.exp_id IS NULL" 218 " AND rawExp.object != 'object'" 219 ); 220 221 if (config->where) { 222 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawExp"); 223 psStringAppend(&query, " AND %s", whereClause); 224 psFree(whereClause); 225 } 226 227 if (!p_psDBRunQuery(config->dbh, query)) { 228 psError(PS_ERR_UNKNOWN, false, "database error"); 229 psFree(query); 230 return false; 231 } 232 psFree(query); 233 234 psArray *output = p_psDBFetchResult(config->dbh); 235 if (!output) { 236 psError(PS_ERR_UNKNOWN, false, "database error"); 237 return false; 238 } 239 if (!psArrayLength(output)) { 240 psTrace("dettool", PS_LOG_INFO, "no rows found"); 241 psFree(output); 242 return true; 243 } 244 245 bool simple = false; 246 { 247 bool status = false; 248 simple = psMetadataLookupBool(&status, config->args, "-simple"); 249 if (!status) { 250 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 251 return false; 252 } 253 } 254 255 // negative simple so the default is true 256 if (!ippdbPrintMetadatas(stdout, output, "rawExp", !simple)) { 257 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 258 psFree(output); 259 return false; 260 } 261 262 psFree(output); 263 264 return true; 265 } 266 267 static bool definebytagMode(pxConfig *config) 268 { 269 bool status = false; 270 271 PS_ASSERT_PTR_NON_NULL(config, false); 272 273 // what type of detRun is this? 274 // det_type is required 275 psString det_type = psMetadataLookupStr(&status, config->args, "-det_type"); 276 if (!status) { 277 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type"); 278 return false; 279 } 280 if (!det_type) { 281 psError(PS_ERR_UNKNOWN, true, "-det_type is required"); 282 return false; 283 } 284 285 // optional 286 psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel"); 287 if (!status) { 288 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel"); 289 return false; 290 } 291 292 psString workdir = psMetadataLookupStr(&status, config->args, "-workdir"); 293 if (!status) { 294 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir"); 295 return false; 296 } 297 if (!workdir) { 298 psError(PS_ERR_UNKNOWN, true, "-workdir is required"); 299 return false; 300 } 301 302 // optional 303 psString mode = psMetadataLookupStr(&status, config->args, "-mode"); 304 if (!status) { 305 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -mode"); 306 return false; 307 } 308 // check mode 309 if (mode && !isValidMode(config, mode)) { 310 psError(PS_ERR_UNKNOWN, false, "invalud mode"); 311 return false; 312 } 313 psString camera = psMetadataLookupStr(&status, config->args, "-inst"); 314 if (!status) { 315 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst"); 316 return false; 317 } 318 319 psString telescope = psMetadataLookupStr(&status, config->args, "-telescope"); 320 if (!status) { 321 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope"); 322 return false; 323 } 324 325 psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type"); 326 if (!status) { 327 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type"); 328 return false; 329 } 330 331 psString filter = psMetadataLookupStr(&status, config->args, "-filter"); 332 if (!status) { 333 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter"); 334 return false; 335 } 336 337 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-airmass_min"); 338 if (!status) { 339 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_min"); 340 return false; 341 } 342 343 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-airmass_max"); 344 if (!status) { 345 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_max"); 346 return false; 347 } 348 349 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-exp_time_min"); 350 if (!status) { 351 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_min"); 352 return false; 353 } 354 355 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-exp_time_max"); 356 if (!status) { 357 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_max"); 358 return false; 359 } 360 361 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-ccd_temp_min"); 362 if (!status) { 363 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_min"); 364 return false; 365 } 366 367 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-ccd_temp_max"); 368 if (!status) { 369 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_max"); 370 return false; 371 } 372 373 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-posang_min"); 374 if (!status) { 375 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_min"); 376 return false; 377 } 378 379 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-posang_max"); 380 if (!status) { 381 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_max"); 382 return false; 383 } 384 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-solang_min"); 385 if (!status) { 386 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_min"); 387 return false; 388 } 389 390 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-solang_max"); 391 if (!status) { 392 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_max"); 393 return false; 394 } 395 396 psTime *registered = NULL; 397 { 398 psString registeredStr = psMetadataLookupStr(&status, config->args, "-registered"); 399 if (!status) { 400 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -registered"); 401 return false; 402 } 403 // pass through NULL as this is an optional field 404 if (registeredStr) { 405 registered = psTimeFromISO(registeredStr, PS_TIME_UTC); 406 if (!registered) { 407 psError(PS_ERR_UNKNOWN, false, "error in time format %s", registeredStr); 408 return false; 409 } 410 } else { 411 registered = NULL; 412 } 413 } 414 415 psTime *time_begin = NULL; 416 { 417 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-time_begin"); 418 if (!status) { 419 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_begin"); 420 return false; 421 } 422 // pass through NULL as this is an optional field 423 if (time_beginStr) { 424 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC); 425 if (!time_begin) { 426 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_beginStr); 427 return false; 428 } 429 } else { 430 time_begin = NULL; 431 } 432 } 433 434 psTime *time_end = NULL; 435 { 436 psString time_endStr = psMetadataLookupStr(&status, config->args, "-time_end"); 437 if (!status) { 438 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_end"); 439 return false; 440 } 441 // pass through NULL as this is an optional field 442 if (time_endStr) { 443 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC); 444 if (!time_end) { 445 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_endStr); 446 return false; 447 } 448 } else { 449 time_end = NULL; 450 } 451 } 452 453 psTime *use_begin = NULL; 454 { 455 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-use_begin"); 456 if (!status) { 457 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_begin"); 458 return false; 459 } 460 // pass through NULL as this is an optional field 461 if (use_beginStr) { 462 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC); 463 if (!use_begin) { 464 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_beginStr); 465 return false; 466 } 467 } else { 468 use_begin = NULL; 469 } 470 } 471 472 psTime *use_end = NULL; 473 { 474 psString use_endStr = psMetadataLookupStr(&status, config->args, "-use_end"); 475 if (!status) { 476 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_end"); 477 return false; 478 } 479 // pass through NULL as this is an optional field 480 if (use_endStr) { 481 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC); 482 if (!use_end) { 483 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_endStr); 484 return false; 485 } 486 } else { 487 use_end = NULL; 488 } 489 } 490 491 psString reduction = psMetadataLookupStr(&status, config->args, "-reduction"); 492 if (!status) { 493 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reduction"); 494 return false; 495 } 496 497 psString label = psMetadataLookupStr(&status, config->args, "-label"); 498 if (!status) { 499 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label"); 500 return false; 501 } 502 503 // we have to support multipe exp_ids 504 psMetadataItem *item = psMetadataLookup(config->args, "-exp_id"); 505 if (!item) { 506 // this shouldn't actually happen when using psArgs 507 psError(PS_ERR_UNKNOWN, true, "-exp_id is required"); 508 return false; 509 } 510 psMetadata *where = psMetadataAlloc(); 511 512 // make sure that -exp_id was parsed correctly 513 // XXX this can be removed someday 514 if (item->type == PS_DATA_METADATA_MULTI) { 515 psListIterator *iter = psListIteratorAlloc(item->data.list, 0, false); 516 psMetadataItem *mItem = NULL; 517 while ((mItem = psListGetAndIncrement(iter))) { 518 psString exp_id = mItem->data.V; 519 // if exp_id is NULL then it means that -exp_id has not been 520 // specified 521 if (!exp_id) { 522 psError(PS_ERR_UNKNOWN, true, 523 "at least one -exp_id is required"); 524 psFree(where); 525 return false; 526 } 527 528 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 529 PS_META_DUPLICATE_OK, "==", exp_id)) { 530 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 531 psFree(iter); 532 psFree(where); 533 return false; 534 } 535 } 536 psFree(iter); 537 } else { 538 psAbort( "-exp_id was not parsed correctly (this should not happen"); 539 } 540 541 if (psListLength(where->list) < 1) { 542 psFree(where); 543 where = NULL; 544 } 545 546 // check that the specified exp_ids actually exist 547 psArray *detrendExps = rawExpSelectRowObjects(config->dbh, where, 0); 548 psFree(where); 549 if (!detrendExps) { 550 psError(PS_ERR_UNKNOWN, false, "no rawExp rows found"); 551 return false; 552 } 553 554 // we should have one rawExp row per exp_id specified 555 if (psListLength(item->data.list) != psArrayLength(detrendExps)) { 556 psAbort( "an -exp_id matched more then one rawExp (this should not happen"); 557 558 } 559 560 // check to see if -filelevel was set on the command line 561 if (!filelevel) { 562 filelevel = psStringCopy(((rawExpRow *)detrendExps->data[0])->filelevel); 563 } 564 565 // start a transaction so we don't end up with childlessed det_ids 566 if (!psDBTransaction(config->dbh)) { 567 psError(PS_ERR_UNKNOWN, false, "database error"); 568 psFree(detrendExps); 569 return false; 570 } 571 572 // the first iteration is always 0 573 // XXX the camera name is set from the first inputExp 574 // XXX det_id 575 detRunInsert(config->dbh, 576 0, 577 0, 578 det_type, 579 mode, 580 "run", 581 filelevel, 582 workdir, 583 camera, 584 telescope, 585 exp_type, 586 reduction, 587 filter, 588 airmass_min, 589 airmass_max, 590 exp_time_min, 591 exp_time_max, 592 ccd_temp_min, 593 ccd_temp_max, 594 posang_min, 595 posang_max, 596 registered, 597 time_begin, 598 time_end, 599 use_begin, 600 use_end, 601 solang_min, 602 solang_max, 603 label, 604 0 // parent 605 ); 606 psFree(registered); 607 psFree(time_begin); 608 psFree(time_end); 609 psFree(use_begin); 610 psFree(use_end); 611 psS64 det_id = psDBLastInsertID(config->dbh); 612 613 // create new detInputExp row(s) from the rawExp row(s) 614 psArray *inputExps = psArrayAllocEmpty(psArrayLength(detrendExps)); 615 for (long i = 0; i < psArrayLength(detrendExps); i++) { 616 detInputExpRow *inputExp = rawDetrenTodetInputExpRow( 617 detrendExps->data[i], 618 det_id, 619 0 // the first iteration is explicitly 0 620 ); 621 psArrayAdd(inputExps, 0, inputExp); 622 psFree(inputExp); 623 } 624 625 psFree(detrendExps); 626 627 // insert detInputExp objects into the database 628 if (!detInputExpInsertObjects(config->dbh, inputExps)) { 629 psError(PS_ERR_UNKNOWN, false, "database error"); 630 // rollback 631 if (!psDBRollback(config->dbh)) { 632 psError(PS_ERR_UNKNOWN, false, "database error"); 633 } 634 psFree(inputExps); 635 return false; 636 } 637 psFree(inputExps); 638 639 // point of no return for det_id creation 640 if (!psDBCommit(config->dbh)) { 641 psError(PS_ERR_UNKNOWN, false, "database error"); 642 return false; 643 } 644 645 bool simple = false; 646 { 647 bool status = false; 648 simple = psMetadataLookupBool(&status, config->args, "-simple"); 649 if (!status) { 650 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 651 return false; 652 } 653 } 654 655 // print the new det_id 656 psArray *detRuns = NULL; 657 { 658 psMetadata *where = psMetadataAlloc(); 659 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id); 660 detRuns = psDBSelectRows(config->dbh, "detRun", where, 0); 661 psFree(where); 662 } 663 if (!detRuns) { 664 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created"); 665 return false; 666 } 667 // sanity check results 668 if (psArrayLength(detRuns) != 1) { 669 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", det_id); 670 return false; 671 } 672 673 if (!convertIdToStr(detRuns)) { 674 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings"); 675 psFree(detRuns); 676 return false; 677 } 678 679 // negative simple so the default is true 680 if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) { 681 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 682 psFree(detRuns); 683 return false; 684 } 685 psFree(detRuns); 686 687 return true; 688 } 689 690 #if 0 691 // This function is used to convert the det_id from an int, as it is used 692 // internally, to be a string for external use. The rational being that we may 693 // want to change how det_id is generated in the future and don't want to 694 // external programs to become depending on this value being an int. 695 static bool convertDetIdToStr(psArray *mds) 696 { 697 PS_ASSERT_PTR_NON_NULL(mds, false); 698 699 for (long i = 0; i < psArrayLength(mds); i++) { 700 psMetadata *md = mds->data[i]; 701 bool status = false; 702 psS32 det_id = psMetadataLookupS32(&status, md, "det_id"); 703 if (!status) { 704 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for det_id"); 705 return false; 706 } 707 psMetadataRemoveKey(md, "det_id"); 708 psString det_idStr = psDBIntToString((psU64)det_id); 709 psMetadataAddStr(mds->data[i], PS_LIST_HEAD, "det_id", 0, NULL, det_idStr); 710 psFree(det_idStr); 711 } 712 713 return true; 714 } 715 #endif 716 717 static bool definebyqueryMode(pxConfig *config) 718 { 719 bool status = false; 720 721 PS_ASSERT_PTR_NON_NULL(config, false); 722 723 // what type of detRun is this? 724 // det_type is required 725 psString det_type = psMetadataLookupStr(&status, config->args, "-det_type"); 726 if (!status) { 727 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type"); 728 return false; 729 } 730 if (!det_type) { 731 psError(PS_ERR_UNKNOWN, true, "-det_type is required"); 732 return false; 733 } 734 735 // optional 736 psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel"); 737 if (!status) { 738 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel"); 739 return false; 740 } 741 742 psString workdir = psMetadataLookupStr(&status, config->args, "-workdir"); 743 if (!status) { 744 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir"); 745 return false; 746 } 747 if (!workdir) { 748 psError(PS_ERR_UNKNOWN, true, "-workdir is required"); 749 return false; 750 } 751 psString camera = psMetadataLookupStr(&status, config->args, "-inst"); 752 if (!status) { 753 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst"); 754 return false; 755 } 756 if (!camera) { 757 psError(PS_ERR_UNKNOWN, false, "-inst is required"); 758 return false; 759 } 760 761 psMetadata *where = psMetadataAlloc(); 762 { 763 bool status = false; 764 psString exp_type = psMetadataLookupStr(&status, config->args, "-select_exp_type"); 765 if (!status) { 766 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_exp_type"); 767 return false; 768 } 769 if (exp_type) { 770 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_type", 0, "==", exp_type)) { 771 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_type"); 772 psFree(where); 773 return false; 774 } 775 } 776 777 // map -inst -> camera 778 psString camera = psMetadataLookupStr(&status, config->args, "-select_inst"); 779 if (!status) { 780 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_inst"); 781 return false; 782 } 783 if (camera) { 784 if (!psMetadataAddStr(where, PS_LIST_TAIL, "camera", 0, "==", camera)) { 785 psError(PS_ERR_UNKNOWN, false, "failed to add item inst"); 786 psFree(where); 787 return false; 788 } 789 } 790 791 psString telescope = psMetadataLookupStr(&status, config->args, "-select_telescope"); 792 if (!status) { 793 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_telescope"); 794 return false; 795 } 796 if (telescope) { 797 if (!psMetadataAddStr(where, PS_LIST_TAIL, "telescope", 0, "==", telescope)) { 798 psError(PS_ERR_UNKNOWN, false, "failed to add item telescope"); 799 psFree(where); 800 return false; 801 } 802 } 803 804 psString filter = psMetadataLookupStr(&status, config->args, "-select_filter"); 805 if (!status) { 806 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_filter"); 807 return false; 808 } 809 if (filter) { 810 if (!psMetadataAddStr(where, PS_LIST_TAIL, "filter", 0, "==", filter)) { 811 psError(PS_ERR_UNKNOWN, false, "failed to add item filter"); 812 psFree(where); 813 return false; 814 } 815 } 816 817 psString uri = psMetadataLookupStr(&status, config->args, "-select_uri"); 818 if (!status) { 819 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_uri"); 820 return false; 821 } 822 if (uri) { 823 if (!psMetadataAddStr(where, PS_LIST_TAIL, "uri", 0, "==", uri)) { 824 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 825 psFree(where); 826 return false; 827 } 828 } 829 830 psString dateobs_begin = psMetadataLookupStr(&status, config->args, "-select_dateobs_begin"); 831 if (!status) { 832 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_dateobs_begin"); 833 psFree(where); 834 return false; 835 } 836 if (dateobs_begin) { 837 psTime *time = psTimeFromISO(dateobs_begin, PS_TIME_UTC); 838 if (!time) { 839 psError(PS_ERR_UNKNOWN, false, "error in time format %s", dateobs_begin); 840 psFree(time); 841 psFree(where); 842 return false; 843 } 844 if (!psMetadataAddTime(where, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, ">=", time)) { 845 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs"); 846 psFree(time); 847 psFree(where); 848 return false; 849 } 850 psFree(time); 851 } 852 853 psString dateobs_end = psMetadataLookupStr(&status, config->args, "-select_dateobs_end"); 854 if (!status) { 855 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_dateobs_end"); 856 psFree(where); 857 return false; 858 } 859 if (dateobs_end) { 860 psTime *time = psTimeFromISO(dateobs_end, PS_TIME_UTC); 861 if (!time) { 862 psError(PS_ERR_UNKNOWN, false, "error in time format %s", dateobs_end); 863 psFree(time); 864 psFree(where); 865 return false; 866 } 867 if (!psMetadataAddTime(where, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, "<", time)) { 868 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs"); 869 psFree(time); 870 psFree(where); 871 return false; 872 } 873 psFree(time); 874 } 875 876 /** selection based on airmass range **/ 877 psF32 select_airmass_min = psMetadataLookupF32(&status, config->args, "-select_airmass_min"); 878 if (!status) { 879 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_airmass_min"); 880 psFree(where); 881 return false; 882 } 883 if (isfinite(select_airmass_min)) { 884 if (!psMetadataAddF32(where, PS_LIST_TAIL, "airmass", PS_META_DUPLICATE_OK, ">=", select_airmass_min)) { 885 psError(PS_ERR_UNKNOWN, false, "failed to add item airmass"); 886 psFree(where); 887 return false; 888 } 889 } 890 psF32 select_airmass_max = psMetadataLookupF32(&status, config->args, "-select_airmass_max"); 891 if (!status) { 892 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_airmass_max"); 893 psFree(where); 894 return false; 895 } 896 if (isfinite(select_airmass_max)) { 897 if (!psMetadataAddF32(where, PS_LIST_TAIL, "airmass", PS_META_DUPLICATE_OK, "<=", select_airmass_max)) { 898 psError(PS_ERR_UNKNOWN, false, "failed to add item airmass"); 899 psFree(where); 900 return false; 901 } 902 } 903 904 psF32 select_sat_pixel_frac_max = psMetadataLookupF32(&status, config->args, "-select_sat_pixel_frac_max"); 905 if (!status) { 906 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_sat_pixel_frac_max"); 907 psFree(where); 908 return false; 909 } 910 if (isfinite(select_sat_pixel_frac_max)) { 911 if (!psMetadataAddF32(where, PS_LIST_TAIL, "sat_pixel_frac", PS_META_DUPLICATE_OK, "<=", select_sat_pixel_frac_max)) { 912 psError(PS_ERR_UNKNOWN, false, "failed to add item sat_pixel_frac"); 913 psFree(where); 914 return false; 915 } 916 } 917 918 /** selection based on exp_time range **/ 919 psF32 select_exp_time_min = psMetadataLookupF32(&status, config->args, "-select_exp_time_min"); 920 if (!status) { 921 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_exp_time_min"); 922 psFree(where); 923 return false; 924 } 925 if (isfinite(select_exp_time_min)) { 926 if (!psMetadataAddF32(where, PS_LIST_TAIL, "exp_time", PS_META_DUPLICATE_OK, ">=", select_exp_time_min)) { 927 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_time"); 928 psFree(where); 929 return false; 930 } 931 } 932 psF32 select_exp_time_max = psMetadataLookupF32(&status, config->args, "-select_exp_time_max"); 933 if (!status) { 934 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_exp_time_max"); 935 psFree(where); 936 return false; 937 } 938 if (isfinite(select_exp_time_max)) { 939 if (!psMetadataAddF32(where, PS_LIST_TAIL, "exp_time", PS_META_DUPLICATE_OK, "<=", select_exp_time_max)) { 940 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_time"); 941 psFree(where); 942 return false; 943 } 944 } 945 946 /** selection based on ccd_temp range **/ 947 psF32 select_ccd_temp_min = psMetadataLookupF32(&status, config->args, "-select_ccd_temp_min"); 948 if (!status) { 949 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_ccd_temp_min"); 950 psFree(where); 951 return false; 952 } 953 if (isfinite(select_ccd_temp_min)) { 954 if (!psMetadataAddF32(where, PS_LIST_TAIL, "ccd_temp", PS_META_DUPLICATE_OK, ">=", select_ccd_temp_min)) { 955 psError(PS_ERR_UNKNOWN, false, "failed to add item ccd_temp"); 956 psFree(where); 957 return false; 958 } 959 } 960 psF32 select_ccd_temp_max = psMetadataLookupF32(&status, config->args, "-select_ccd_temp_max"); 961 if (!status) { 962 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_ccd_temp_max"); 963 psFree(where); 964 return false; 965 } 966 if (isfinite(select_ccd_temp_max)) { 967 if (!psMetadataAddF32(where, PS_LIST_TAIL, "ccd_temp", PS_META_DUPLICATE_OK, "<=", select_ccd_temp_max)) { 968 psError(PS_ERR_UNKNOWN, false, "failed to add item ccd_temp"); 969 psFree(where); 970 return false; 971 } 972 } 973 974 /** selection based on posang **/ 975 psF32 select_posang_min = psMetadataLookupF32(&status, config->args, "-select_posang_min"); 976 if (!status) { 977 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_posang_min"); 978 psFree(where); 979 return false; 980 } 981 if (isfinite(select_posang_min)) { 982 if (!psMetadataAddF32(where, PS_LIST_TAIL, "posang", PS_META_DUPLICATE_OK, ">=", select_posang_min)) { 983 psError(PS_ERR_UNKNOWN, false, "failed to add item posang"); 984 psFree(where); 985 return false; 986 } 987 } 988 psF32 select_posang_max = psMetadataLookupF32(&status, config->args, "-select_posang_max"); 989 if (!status) { 990 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_posang_max"); 991 psFree(where); 992 return false; 993 } 994 if (isfinite(select_posang_max)) { 995 if (!psMetadataAddF32(where, PS_LIST_TAIL, "posang", PS_META_DUPLICATE_OK, "<=", select_posang_max)) { 996 psError(PS_ERR_UNKNOWN, false, "failed to add item posang"); 997 psFree(where); 998 return false; 999 } 1000 } 1001 1002 /** selection based on solang **/ 1003 psF32 select_solang_min = psMetadataLookupF32(&status, config->args, "-select_solang_min"); 1004 if (!status) { 1005 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_solang_min"); 1006 psFree(where); 1007 return false; 1008 } 1009 if (isfinite(select_solang_min)) { 1010 if (!psMetadataAddF32(where, PS_LIST_TAIL, "solang", PS_META_DUPLICATE_OK, ">=", select_solang_min)) { 1011 psError(PS_ERR_UNKNOWN, false, "failed to add item solang"); 1012 psFree(where); 1013 return false; 1014 } 1015 } 1016 psF32 select_solang_max = psMetadataLookupF32(&status, config->args, "-select_solang_max"); 1017 if (!status) { 1018 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -select_solang_max"); 1019 psFree(where); 1020 return false; 1021 } 1022 if (isfinite(select_solang_max)) { 1023 if (!psMetadataAddF32(where, PS_LIST_TAIL, "solang", PS_META_DUPLICATE_OK, "<=", select_solang_max)) { 1024 psError(PS_ERR_UNKNOWN, false, "failed to add item solang"); 1025 psFree(where); 1026 return false; 1027 } 1028 } 1029 1030 } 1031 1032 if (!psListLength(where->list)) { 1033 psFree(where); 1034 where = NULL; 1035 } 1036 1037 // there is some namespace overlap between the names of the fields we'd 1038 // like to search by to setup a detrun and the names of the fields we'd 1039 // like to assign values to so I've seperated them but prepending set- to 1040 // the assigned values 1041 1042 // optional 1043 psString mode = psMetadataLookupStr(&status, config->args, "-mode"); 1044 if (!status) { 1045 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -mode"); 1046 return false; 1047 } 1048 // check mode 1049 if (mode && !isValidMode(config, mode)) { 1050 psError(PS_ERR_UNKNOWN, false, "invalud mode"); 1051 return false; 1052 } 1053 1054 psString telescope = psMetadataLookupStr(&status, config->args, "-telescope"); 1055 if (!status) { 1056 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope"); 1057 return false; 1058 } 1059 1060 psString filter = psMetadataLookupStr(&status, config->args, "-filter"); 1061 if (!status) { 1062 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter"); 1063 return false; 1064 } 1065 1066 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-airmass_min"); 1067 if (!status) { 1068 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_min"); 1069 return false; 1070 } 1071 1072 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-airmass_max"); 1073 if (!status) { 1074 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_max"); 1075 return false; 1076 } 1077 1078 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-exp_time_min"); 1079 if (!status) { 1080 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_min"); 1081 return false; 1082 } 1083 1084 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-exp_time_max"); 1085 if (!status) { 1086 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_max"); 1087 return false; 1088 } 1089 1090 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-ccd_temp_min"); 1091 if (!status) { 1092 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_min"); 1093 return false; 1094 } 1095 1096 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-ccd_temp_max"); 1097 if (!status) { 1098 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_max"); 1099 return false; 1100 } 1101 1102 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-posang_min"); 1103 if (!status) { 1104 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_min"); 1105 return false; 1106 } 1107 1108 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-posang_max"); 1109 if (!status) { 1110 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_max"); 1111 return false; 1112 } 1113 1114 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-solang_min"); 1115 if (!status) { 1116 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_min"); 1117 return false; 1118 } 1119 1120 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-solang_max"); 1121 if (!status) { 1122 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_max"); 1123 return false; 1124 } 1125 1126 psTime *registered = NULL; 1127 { 1128 psString registeredStr = psMetadataLookupStr(&status, config->args, "-registered"); 1129 if (!status) { 1130 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -registered"); 1131 return false; 1132 } 1133 // pass through NULL as this is an optional field 1134 if (registeredStr) { 1135 registered = psTimeFromISO(registeredStr, PS_TIME_UTC); 1136 if (!registered) { 1137 psError(PS_ERR_UNKNOWN, false, "error in time format %s", registeredStr); 1138 return false; 1139 } 1140 } else { 1141 registered = NULL; 1142 } 1143 } 1144 1145 psTime *time_begin = NULL; 1146 { 1147 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-time_begin"); 1148 if (!status) { 1149 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_begin"); 1150 return false; 1151 } 1152 // pass through NULL as this is an optional field 1153 if (time_beginStr) { 1154 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC); 1155 if (!time_begin) { 1156 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_beginStr); 1157 return false; 1158 } 1159 } else { 1160 time_begin = NULL; 1161 } 1162 } 1163 1164 psTime *time_end = NULL; 1165 { 1166 psString time_endStr = psMetadataLookupStr(&status, config->args, "-time_end"); 1167 if (!status) { 1168 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_end"); 1169 return false; 1170 } 1171 // pass through NULL as this is an optional field 1172 if (time_endStr) { 1173 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC); 1174 if (!time_end) { 1175 psError(PS_ERR_UNKNOWN, false, "error in time format %s", time_endStr); 1176 return false; 1177 } 1178 } else { 1179 time_end = NULL; 1180 } 1181 } 1182 1183 psTime *use_begin = NULL; 1184 { 1185 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-use_begin"); 1186 if (!status) { 1187 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_begin"); 1188 return false; 1189 } 1190 // pass through NULL as this is an optional field 1191 if (use_beginStr) { 1192 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC); 1193 if (!use_begin) { 1194 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_beginStr); 1195 return false; 1196 } 1197 } else { 1198 use_begin = NULL; 1199 } 1200 } 1201 1202 psTime *use_end = NULL; 1203 { 1204 psString use_endStr = psMetadataLookupStr(&status, config->args, "-use_end"); 1205 if (!status) { 1206 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_end"); 1207 return false; 1208 } 1209 // pass through NULL as this is an optional field 1210 if (use_endStr) { 1211 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC); 1212 if (!use_end) { 1213 psError(PS_ERR_UNKNOWN, false, "error in time format %s", use_endStr); 1214 return false; 1215 } 1216 } else { 1217 use_end = NULL; 1218 } 1219 } 1220 1221 psString reduction = psMetadataLookupStr(&status, config->args, "-reduction"); 1222 if (!status) { 1223 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reduction"); 1224 return false; 1225 } 1226 1227 psString label = psMetadataLookupStr(&status, config->args, "-label"); 1228 if (!status) { 1229 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label"); 1230 return false; 1231 } 1232 1233 bool simple = psMetadataLookupBool(&status, config->args, "-simple"); 1234 if (!status) { 1235 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 1236 psFree(registered); 1237 psFree(use_begin); 1238 psFree(use_end); 1239 return false; 1240 } 1241 1242 bool pretend = psMetadataLookupBool(&status, config->args, "-pretend"); 1243 if (!status) { 1244 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -pretend"); 1245 psFree(registered); 1246 psFree(use_begin); 1247 psFree(use_end); 1248 return false; 1249 } 1250 1251 // search for rawExps with the specified options 1252 psArray *detrendExps = rawExpSelectRowObjects(config->dbh, where, 0); 1253 psFree(where); 1254 // make sure that we found at least one rawExp 1255 if (!detrendExps) { 1256 psError(PS_ERR_UNKNOWN, false, "database error"); 1257 psFree(registered); 1258 psFree(use_begin); 1259 psFree(use_end); 1260 return false; 1261 } 1262 if (!psArrayLength(detrendExps)) { 1263 psTrace("dettool", PS_LOG_INFO, "no rows found"); 1264 psFree(detrendExps); 1265 psFree(registered); 1266 psFree(use_begin); 1267 psFree(use_end); 1268 return true; 1269 } 1270 1271 // check to see if -filelevel was set on the command line 1272 if (!filelevel) { 1273 filelevel = psStringCopy(((rawExpRow *)detrendExps->data[0])->filelevel); 1274 } 1275 1276 if (pretend) { 1277 // negative simple so the default is true 1278 if (!rawExpPrintObjects(stdout, detrendExps, !simple)) { 1279 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 1280 psFree(detrendExps); 1281 psFree(registered); 1282 psFree(use_begin); 1283 psFree(use_end); 1284 return false; 1285 } 1286 psFree(detrendExps); 1287 psFree(registered); 1288 psFree(use_begin); 1289 psFree(use_end); 1290 return true; 1291 } 1292 1293 // start a transaction so we don't end up with childlessed det_ids 1294 if (!psDBTransaction(config->dbh)) { 1295 psError(PS_ERR_UNKNOWN, false, "database error"); 1296 psFree(detrendExps); 1297 psFree(registered); 1298 psFree(use_begin); 1299 psFree(use_end); 1300 return false; 1301 } 1302 1303 // the first iteration is always 0 1304 // XXX det_id 1305 detRunInsert(config->dbh, 1306 0, // det_id 1307 0, // iteration 1308 det_type, 1309 mode, 1310 "run", // state 1311 filelevel, 1312 workdir, 1313 camera, 1314 telescope, 1315 "NA", 1316 reduction, 1317 filter, 1318 airmass_min, 1319 airmass_max, 1320 exp_time_min, 1321 exp_time_max, 1322 ccd_temp_min, 1323 ccd_temp_max, 1324 posang_min, 1325 posang_max, 1326 registered, 1327 time_begin, 1328 time_end, 1329 use_begin, 1330 use_end, 1331 solang_min, 1332 solang_max, 1333 label, 1334 0 // parent 1335 ); 1336 psFree(registered); 1337 psFree(time_begin); 1338 psFree(time_end); 1339 psFree(use_end); 1340 psFree(use_begin); 1341 psFree(use_end); 1342 psS64 det_id = psDBLastInsertID(config->dbh); 1343 1344 // create new detInputExp row(s) from the rawExp row(s) 1345 psArray *inputExps = psArrayAllocEmpty(psArrayLength(detrendExps)); 1346 for (long i = 0; i < psArrayLength(detrendExps); i++) { 1347 detInputExpRow *inputExp = rawDetrenTodetInputExpRow( 1348 detrendExps->data[i], 1349 det_id, 1350 0 // the first iteration is explicitly 0 1351 ); 1352 psArrayAdd(inputExps, 0, inputExp); 1353 psFree(inputExp); 1354 } 1355 1356 psFree(detrendExps); 1357 1358 // insert detInputExp objects into the database 1359 if (!detInputExpInsertObjects(config->dbh, inputExps)) { 1360 psError(PS_ERR_UNKNOWN, false, "database error"); 1361 // rollback 1362 if (!psDBRollback(config->dbh)) { 1363 psError(PS_ERR_UNKNOWN, false, "database error"); 1364 } 1365 psFree(inputExps); 1366 return false; 1367 } 1368 psFree(inputExps); 1369 1370 // point of no return for det_id creation 1371 if (!psDBCommit(config->dbh)) { 1372 psError(PS_ERR_UNKNOWN, false, "database error"); 1373 return false; 1374 } 1375 1376 1377 // print the new det_id 1378 psArray *detRuns = NULL; 1379 { 1380 psMetadata *where = psMetadataAlloc(); 1381 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id); 1382 detRuns = psDBSelectRows(config->dbh, "detRun", where, 0); 1383 psFree(where); 1384 } 1385 if (!detRuns) { 1386 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created"); 1387 return false; 1388 } 1389 // sanity check results 1390 if (psArrayLength(detRuns) != 1) { 1391 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", det_id); 1392 return false; 1393 } 1394 1395 // convert det_id to a string externaly 1396 if (!convertIdToStr(detRuns)) { 1397 psError(PS_ERR_UNKNOWN, false, "failed to convert det_id to a string"); 1398 psFree(detRuns); 1399 return false; 1400 } 1401 1402 // negative simple so the default is true 1403 if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) { 1404 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 1405 psFree(detRuns); 1406 return false; 1407 } 1408 psFree(detRuns); 1409 1410 return true; 1411 } 1412 1413 static bool definebydetrunMode(pxConfig *config) 1414 { 1415 bool status = false; 1416 1417 PS_ASSERT_PTR_NON_NULL(config, false); 1418 1419 // det_id is the only required input 1420 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 1421 if (!status) { 1422 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 1423 return false; 1424 } 1425 if (!det_id) { 1426 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 1427 return false; 1428 } 1429 1430 // lookup the detRun that we will be basing this one on 1431 psArray *detRuns = NULL; 1432 { 1433 psMetadata *where = psMetadataAlloc(); 1434 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", (psS64)atoll(det_id)); 1435 detRuns = detRunSelectRowObjects(config->dbh, where, 0); 1436 psFree(where); 1437 } 1438 if (!detRuns) { 1439 psError(PS_ERR_UNKNOWN, false, "database error"); 1440 return false; 1441 } 1442 // sanity check the result... we should have only found one det_id 1443 if (psArrayLength(detRuns) != 1) { 1444 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", (psS64)atoll(det_id)); 1445 return false; // unreachable 1446 } 1447 1448 // pull the detRun object out the result array 1449 detRunRow *detRun = psMemIncrRefCounter(detRuns->data[0]); 1450 1451 // discard the resultarray 1452 psFree(detRuns); 1453 1454 // set the det_id to 0/NULL so the database can assign it 1455 detRun->det_id = 0; 1456 1457 // reset the iteration to 0 1458 detRun->iteration = 0; 1459 1460 // reset the state to "run" 1461 psFree(detRun->state); 1462 detRun->state = psStringCopy("run"); 1463 1464 // walk through the optional values and update the detRun as required 1465 psString det_type = psMetadataLookupStr(&status, config->args, "-set_det_type"); 1466 if (!status) { 1467 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_det_type"); 1468 return false; 1469 } 1470 if (det_type) { 1471 psFree(detRun->det_type); 1472 detRun->det_type = psStringCopy(det_type); 1473 } 1474 1475 psString mode = psMetadataLookupStr(&status, config->args, "-set_mode"); 1476 if (!status) { 1477 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_mode"); 1478 return false; 1479 } 1480 // check mode 1481 if (mode && !isValidMode(config, mode)) { 1482 psError(PS_ERR_UNKNOWN, false, "invalud mode"); 1483 return false; 1484 } 1485 if (mode) { 1486 psFree(detRun->mode); 1487 detRun->mode = psStringCopy(mode); 1488 } 1489 1490 psString camera = psMetadataLookupStr(&status, config->args, "-set_inst"); 1491 if (!status) { 1492 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_inst"); 1493 return false; 1494 } 1495 if (camera) { 1496 psFree(detRun->camera); 1497 detRun->camera = psStringCopy(camera); 1498 } 1499 1500 psString telescope = psMetadataLookupStr(&status, config->args, "-set_telescope"); 1501 if (!status) { 1502 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_telescope"); 1503 return false; 1504 } 1505 if (telescope) { 1506 psFree(detRun->telescope); 1507 detRun->telescope = psStringCopy(telescope); 1508 } 1509 1510 psString exp_type = psMetadataLookupStr(&status, config->args, "-set_exp_type"); 1511 if (!status) { 1512 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_type"); 1513 return false; 1514 } 1515 if (exp_type) { 1516 psFree(detRun->exp_type); 1517 detRun->exp_type = psStringCopy(exp_type); 1518 } 1519 1520 psString filelevel = psMetadataLookupStr(&status, config->args, "-set_filelevel"); 1521 if (!status) { 1522 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_filelevel"); 1523 return false; 1524 } 1525 if (filelevel) { 1526 psFree(detRun->filelevel); 1527 detRun->filelevel = psStringCopy(filelevel); 1528 } 1529 1530 psString workdir = psMetadataLookupStr(&status, config->args, "-set_workdir"); 1531 if (!status) { 1532 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_workdir"); 1533 return false; 1534 } 1535 if (workdir) { 1536 psFree(detRun->workdir); 1537 detRun->workdir = psStringCopy(workdir); 1538 } 1539 1540 psString filter = psMetadataLookupStr(&status, config->args, "-set_filter"); 1541 if (!status) { 1542 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_filter"); 1543 return false; 1544 } 1545 if (filter) { 1546 psFree(detRun->filter); 1547 detRun->filter = psStringCopy(filter); 1548 } 1549 1550 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-set_airmass_min"); 1551 if (!status) { 1552 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_airmass_min"); 1553 return false; 1554 } 1555 if (!isnan(airmass_min)) { 1556 detRun->airmass_min = airmass_min; 1557 } 1558 1559 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-set_airmass_max"); 1560 if (!status) { 1561 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_airmass_max"); 1562 return false; 1563 } 1564 if (!isnan(airmass_max)) { 1565 detRun->airmass_max = airmass_max; 1566 } 1567 1568 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-set_exp_time_min"); 1569 if (!status) { 1570 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_time_min"); 1571 return false; 1572 } 1573 if (!isnan(exp_time_min)) { 1574 detRun->exp_time_min = exp_time_min; 1575 } 1576 1577 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-set_exp_time_max"); 1578 if (!status) { 1579 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_exp_time_max"); 1580 return false; 1581 } 1582 if (!isnan(exp_time_max)) { 1583 detRun->exp_time_max = exp_time_max; 1584 } 1585 1586 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-set_ccd_temp_min"); 1587 if (!status) { 1588 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_ccd_temp_min"); 1589 return false; 1590 } 1591 if (!isnan(ccd_temp_min)) { 1592 detRun->ccd_temp_min = ccd_temp_min; 1593 } 1594 1595 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-set_ccd_temp_max"); 1596 if (!status) { 1597 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_ccd_temp_max"); 1598 return false; 1599 } 1600 if (!isnan(ccd_temp_max)) { 1601 detRun->ccd_temp_max = ccd_temp_max; 1602 } 1603 1604 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-set_posang_min"); 1605 if (!status) { 1606 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_posang_min"); 1607 return false; 1608 } 1609 if (!isnan(posang_min)) { 1610 detRun->posang_min = posang_min; 1611 } 1612 1613 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-set_posang_max"); 1614 if (!status) { 1615 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_posang_max"); 1616 return false; 1617 } 1618 if (!isnan(posang_max)) { 1619 detRun->posang_max = posang_max; 1620 } 1621 1622 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-set_solang_min"); 1623 if (!status) { 1624 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_solang_min"); 1625 return false; 1626 } 1627 if (!isnan(solang_min)) { 1628 detRun->solang_min = solang_min; 1629 } 1630 1631 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-set_solang_max"); 1632 if (!status) { 1633 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_solang_max"); 1634 return false; 1635 } 1636 if (!isnan(solang_max)) { 1637 detRun->solang_max = solang_max; 1638 } 1639 1640 psString label = psMetadataLookupStr(&status, config->args, "-set_label"); 1641 if (!status) { 1642 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_label"); 1643 return false; 1644 } 1645 if (label) { 1646 detRun->label = label; 1647 } 1648 1649 psTime *registered = NULL; 1650 { 1651 psString registeredStr = psMetadataLookupStr(&status, config->args, "-set_registered"); 1652 if (!status) { 1653 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_registered"); 1654 return false; 1655 } 1656 // pass through NULL as this is an optional field 1657 if (registeredStr) { 1658 psFree(detRun->registered); 1659 registered = psTimeFromISO(registeredStr, PS_TIME_UTC); 1660 detRun->registered = psMemIncrRefCounter(registered); 1661 psFree(registered); 1662 } 1663 } 1664 1665 psTime *time_begin = NULL; 1666 { 1667 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-set_time_begin"); 1668 if (!status) { 1669 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_time_begin"); 1670 return false; 1671 } 1672 // pass through NULL as this is an optional field 1673 if (time_beginStr) { 1674 psFree(detRun->time_begin); 1675 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC); 1676 detRun->time_begin = psMemIncrRefCounter(time_begin); 1677 psFree(time_begin); 1678 } 1679 } 1680 1681 psTime *time_end = NULL; 1682 { 1683 psString time_endStr = psMetadataLookupStr(&status, config->args, "-set_time_end"); 1684 if (!status) { 1685 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_time_end"); 1686 return false; 1687 } 1688 // pass through NULL as this is an optional field 1689 if (time_endStr) { 1690 psFree(detRun->time_end); 1691 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC); 1692 detRun->time_end = psMemIncrRefCounter(time_end); 1693 psFree(time_end); 1694 } 1695 } 1696 1697 psTime *use_begin = NULL; 1698 { 1699 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-set_use_begin"); 1700 if (!status) { 1701 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_use_begin"); 1702 return false; 1703 } 1704 // pass through NULL as this is an optional field 1705 if (use_beginStr) { 1706 psFree(detRun->use_begin); 1707 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC); 1708 detRun->use_begin = psMemIncrRefCounter(use_begin); 1709 psFree(use_begin); 1710 } 1711 } 1712 1713 psTime *use_end = NULL; 1714 { 1715 psString use_endStr = psMetadataLookupStr(&status, config->args, "-set_use_end"); 1716 if (!status) { 1717 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_use_end"); 1718 return false; 1719 } 1720 // pass through NULL as this is an optional field 1721 if (use_endStr) { 1722 psFree(detRun->use_end); 1723 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC); 1724 detRun->use_end = psMemIncrRefCounter(use_end); 1725 psFree(use_end); 1726 } 1727 } 1728 1729 psString reduction = psMetadataLookupStr(&status, config->args, "-set_reduction"); 1730 if (!status) { 1731 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -set_reduction"); 1732 return false; 1733 } 1734 if (reduction) { 1735 psFree(detRun->reduction); 1736 detRun->reduction = psStringCopy(reduction); 1737 } 1738 1739 // create a metadata to restrict detInputExp's be in in the specified range 1740 1741 psMetadata *time_filter = psMetadataAlloc(); 1742 1743 { 1744 psString timeStr = psMetadataLookupStr(&status, config->args, "-filter_input_begin"); 1745 if (!status) { 1746 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter_input_begin"); 1747 return false; 1748 } 1749 // pass through NULL as this is an optional field 1750 if (timeStr) { 1751 psTime *time = psTimeFromISO(timeStr, PS_TIME_UTC); 1752 if (!psMetadataAddTime(time_filter, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, ">=", time)) { 1753 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs"); 1754 psFree(time); 1755 psFree(time_filter); 1756 return false; 1757 } 1758 psFree(time); 1759 } 1760 } 1761 1762 { 1763 psString timeStr = psMetadataLookupStr(&status, config->args, "-filter_input_end"); 1764 if (!status) { 1765 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter_input_end"); 1766 return false; 1767 } 1768 // pass through NULL as this is an optional field 1769 if (timeStr) { 1770 psTime *time = psTimeFromISO(timeStr, PS_TIME_UTC); 1771 if (!psMetadataAddTime(time_filter, PS_LIST_TAIL, "dateobs", PS_META_DUPLICATE_OK, "<", time)) { 1772 psError(PS_ERR_UNKNOWN, false, "failed to add item dateobs"); 1773 psFree(time); 1774 psFree(time_filter); 1775 return false; 1776 } 1777 psFree(time); 1778 } 1779 } 1780 1781 1782 // start a transaction so we don't end up with childlessed det_ids 1783 if (!psDBTransaction(config->dbh)) { 1784 psError(PS_ERR_UNKNOWN, false, "database error"); 1785 psFree(time_filter); 1786 psFree(detRun); 1787 return false; 1788 } 1789 1790 if (!detRunInsertObject(config->dbh, detRun)) { 1791 psError(PS_ERR_UNKNOWN, false, "database error"); 1792 // rollback 1793 if (!psDBRollback(config->dbh)) { 1794 psError(PS_ERR_UNKNOWN, false, "database error"); 1795 } 1796 psFree(time_filter); 1797 psFree(detRun); 1798 return false; 1799 } 1800 psFree(detRun); 1801 1802 // get the det_id 1803 psS64 newDet_id = psDBLastInsertID(config->dbh); 1804 1805 psString query = psStringCopy( 1806 "INSERT INTO detInputExp" 1807 " SELECT" 1808 " %d," 1809 " 0," 1810 " detResidExp.exp_id," 1811 " detResidExp.accept" 1812 " FROM detResidExp" 1813 " JOIN rawExp" 1814 " USING(exp_id)" 1815 " WHERE det_id = %d" 1816 ); 1817 1818 if (time_filter->list->n) { 1819 psString whereClause = psDBGenerateWhereConditionSQL(time_filter, "rawExp"); 1820 psStringAppend(&query, " AND %s", whereClause); 1821 psFree(whereClause); 1822 } 1823 psFree(time_filter); 1824 1825 if (!p_psDBRunQuery(config->dbh, query, (psS64)newDet_id, (psS64)atoll(det_id))) { 1826 psError(PS_ERR_UNKNOWN, false, "database error"); 1827 psFree(query); 1828 return false; 1829 } 1830 psFree(query); 1831 1832 // point of no return for det_id creation 1833 if (!psDBCommit(config->dbh)) { 1834 psError(PS_ERR_UNKNOWN, false, "database error"); 1835 return false; 1836 } 1837 1838 bool simple = false; 1839 { 1840 bool status = false; 1841 simple = psMetadataLookupBool(&status, config->args, "-simple"); 1842 if (!status) { 1843 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 1844 return false; 1845 } 1846 } 1847 1848 // print the new det_id 1849 psArray *newDetRuns = NULL; 1850 { 1851 psMetadata *where = psMetadataAlloc(); 1852 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", newDet_id); 1853 newDetRuns = psDBSelectRows(config->dbh, "detRun", where, 0); 1854 psFree(where); 1855 } 1856 if (!newDetRuns) { 1857 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created"); 1858 return false; 1859 } 1860 // sanity check the result... we should have only found one det_id 1861 if (psArrayLength(newDetRuns) != 1) { 1862 psAbort("found more then one detRun matching det_id %" PRId64 " (this should not happen)", newDet_id); 1863 return false; // unreachable 1864 } 1865 1866 // convert det_id to a string externaly 1867 if (!convertIdToStr(detRuns)) { 1868 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings"); 1869 psFree(detRuns); 1870 return false; 1871 } 1872 1873 // negative simple so the default is true 1874 if (!ippdbPrintMetadatas(stdout, newDetRuns, "detRun", !simple)) { 1875 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 1876 psFree(newDetRuns); 1877 return false; 1878 } 1879 psFree(newDetRuns); 1880 1881 return true; 1882 } 1883 1884 static bool runsMode(pxConfig *config) 1885 { 1886 PS_ASSERT_PTR_NON_NULL(config, false); 1887 1888 // XXX fix the hard coding of the table name 1889 psArray *runs = psDBSelectRows(config->dbh, "detRun", config->where, 0); 1890 if (!runs) { 1891 psError(PS_ERR_UNKNOWN, false, "database error"); 1892 return false; 1893 } 1894 1895 if (!psArrayLength(runs)) { 1896 psTrace("dettool", PS_LOG_INFO, "no rows found"); 1897 psFree(runs); 1898 return true; 1899 } 1900 1901 // convert det_id to a string externaly 1902 if (!convertIdToStr(runs)) { 1903 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings"); 1904 psFree(runs); 1905 return false; 1906 } 1907 1908 bool simple = false; 1909 { 1910 bool status = false; 1911 simple = psMetadataLookupBool(&status, config->args, "-simple"); 1912 if (!status) { 1913 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 1914 return false; 1915 } 1916 } 1917 1918 // negative simple so the default is true 1919 if (!ippdbPrintMetadatas(stdout, runs, "detRun", !simple)) { 1920 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 1921 psFree(runs); 1922 return false; 1923 } 1924 1925 psFree(runs); 1926 1927 return true; 1928 } 1929 1930 static bool childlessrunMode(pxConfig *config) 1931 { 1932 PS_ASSERT_PTR_NON_NULL(config, false); 1933 1934 bool status = false; 1935 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 1936 if (!status) { 1937 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 1938 return false; 1939 } 1940 1941 psString query = psStringCopy( 1942 "SELECT DISTINCT\n" 1943 " detRun.*\n" 1944 " FROM detRun\n" 1945 " LEFT JOIN detRun as foo\n" 1946 " ON foo.parent = detRun.det_id\n" 1947 " WHERE\n" 1948 " detRun.state = 'stop'\n" 1949 " AND detRun.mode = 'master'\n" 1950 " AND foo.det_id IS NULL\n" 1951 ); 1952 1953 if (config->where) { 1954 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detRun"); 1955 psStringAppend(&query, " AND %s", whereClause); 1956 psFree(whereClause); 1957 } 1958 1959 // treat limit == 0 as "no limit" 1960 if (limit) { 1961 psString limitString = psDBGenerateLimitSQL(limit); 1962 psStringAppend(&query, " %s", limitString); 1963 psFree(limitString); 1964 } 1965 1966 if (!p_psDBRunQuery(config->dbh, query)) { 1967 psError(PS_ERR_UNKNOWN, false, "database error"); 1968 psFree(query); 1969 return false; 1970 } 1971 psFree(query); 1972 1973 psArray *output = p_psDBFetchResult(config->dbh); 1974 if (!output) { 1975 psError(PS_ERR_UNKNOWN, false, "database error"); 1976 return false; 1977 } 1978 if (!psArrayLength(output)) { 1979 psTrace("dettool", PS_LOG_INFO, "no rows found"); 1980 psFree(output); 1981 return true; 1982 } 1983 1984 // convert det_id to a string externaly 1985 if (!convertIdToStr(output)) { 1986 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings"); 1987 psFree(output); 1988 return false; 1989 } 1990 1991 bool simple = false; 1992 { 1993 bool status = false; 1994 simple = psMetadataLookupBool(&status, config->args, "-simple"); 1995 if (!status) { 1996 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 1997 psFree(output); 1998 return false; 1999 } 2000 } 2001 2002 // negative simple so the default is true 2003 if (!ippdbPrintMetadatas(stdout, output, "detRun", !simple)) { 2004 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2005 psFree(output); 2006 return false; 2007 } 2008 2009 psFree(output); 2010 2011 return true; 2012 } 2013 2014 static detInputExpRow *rawDetrenTodetInputExpRow(rawExpRow *rawExp, psS64 det_id, psS32 iteration) 2015 { 2016 PS_ASSERT_PTR_NON_NULL(rawExp, NULL); 2017 2018 return detInputExpRowAlloc( 2019 det_id, 2020 iteration, 2021 rawExp->exp_id, 2022 true // use 2023 ); 2024 } 2025 2026 static bool inputMode(pxConfig *config) 2027 { 2028 PS_ASSERT_PTR_NON_NULL(config, false); 2029 2030 // select detInputExp.* 2031 // select rawExp.* 2032 // by: 2033 // exp_id 2034 2035 psString query = psStringCopy( 2036 "SELECT DISTINCT *" 2037 " FROM detInputExp" 2038 " JOIN rawExp" 2039 " USING(exp_id)" 2040 ); 2041 2042 if (config->where) { 2043 psString whereClause = psDBGenerateWhereSQL(config->where, "detInputExp"); 2044 psStringAppend(&query, " %s", whereClause); 2045 psFree(whereClause); 2046 } 2047 2048 if (!p_psDBRunQuery(config->dbh, query)) { 2049 psError(PS_ERR_UNKNOWN, false, "database error"); 2050 psFree(query); 2051 return false; 2052 } 2053 psFree(query); 2054 2055 psArray *output = p_psDBFetchResult(config->dbh); 2056 if (!output) { 2057 psError(PS_ERR_UNKNOWN, false, "database error"); 2058 return false; 2059 } 2060 if (!psArrayLength(output)) { 2061 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2062 psFree(output); 2063 return true; 2064 } 2065 2066 bool simple = false; 2067 { 2068 bool status = false; 2069 simple = psMetadataLookupBool(&status, config->args, "-simple"); 2070 if (!status) { 2071 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2072 return false; 2073 } 2074 } 2075 2076 // negative simple so the default is true 2077 if (!ippdbPrintMetadatas(stdout, output, "detInputExp", !simple)) { 2078 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2079 psFree(output); 2080 return false; 2081 } 2082 2083 psFree(output); 2084 2085 return true; 2086 } 2087 2088 static bool rawMode(pxConfig *config) 2089 { 2090 PS_ASSERT_PTR_NON_NULL(config, false); 2091 2092 psString query = pxDataGet("dettool_raw.sql"); 2093 if (!query) { 2094 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 2095 return false; 2096 } 2097 2098 if (config->where) { 2099 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawImfile"); 2100 psStringAppend(&query, " AND %s", whereClause); 2101 psFree(whereClause); 2102 } 2103 2104 if (!p_psDBRunQuery(config->dbh, query)) { 2105 psError(PS_ERR_UNKNOWN, false, "database error"); 2106 psFree(query); 2107 return false; 2108 } 2109 psFree(query); 2110 2111 psArray *output = p_psDBFetchResult(config->dbh); 2112 if (!output) { 2113 psError(PS_ERR_UNKNOWN, false, "database error"); 2114 return false; 2115 } 2116 if (!psArrayLength(output)) { 2117 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2118 psFree(output); 2119 return true; 2120 } 2121 2122 bool simple = false; 2123 { 2124 bool status = false; 2125 simple = psMetadataLookupBool(&status, config->args, "-simple"); 2126 if (!status) { 2127 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2128 return false; 2129 } 2130 } 2131 2132 // negative simple so the default is true 2133 if (!ippdbPrintMetadatas(stdout, output, "rawImfile", !simple)) { 2134 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2135 psFree(output); 2136 return false; 2137 } 2138 2139 psFree(output); 2140 2141 return true; 2142 } 2143 2144 static bool toprocessedimfileMode(pxConfig *config) 2145 { 2146 PS_ASSERT_PTR_NON_NULL(config, false); 2147 2148 bool status = false; 2149 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 2150 if (!status) { 2151 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 2152 return false; 2153 } 2154 2155 psString query = pxDataGet("dettool_toprocessedimfile.sql"); 2156 if (!query) { 2157 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 2158 return false; 2159 } 2160 2161 if (config->where) { 2162 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawImfile"); 2163 psStringAppend(&query, " AND %s", whereClause); 2164 psFree(whereClause); 2165 } 2166 2167 // treat limit == 0 as "no limit" 2168 if (limit) { 2169 psString limitString = psDBGenerateLimitSQL(limit); 2170 psStringAppend(&query, " %s", limitString); 2171 psFree(limitString); 2172 } 2173 2174 if (!p_psDBRunQuery(config->dbh, query)) { 2175 psError(PS_ERR_UNKNOWN, false, "database error"); 2176 psFree(query); 2177 return false; 2178 } 2179 psFree(query); 2180 2181 psArray *output = p_psDBFetchResult(config->dbh); 2182 if (!output) { 2183 psError(PS_ERR_UNKNOWN, false, "database error"); 2184 return false; 2185 } 2186 if (!psArrayLength(output)) { 2187 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2188 psFree(output); 2189 return true; 2190 } 2191 2192 bool simple = false; 2193 { 2194 bool status = false; 2195 simple = psMetadataLookupBool(&status, config->args, "-simple"); 2196 if (!status) { 2197 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2198 return false; 2199 } 2200 } 2201 2202 // negative simple so the default is true 2203 if (!ippdbPrintMetadatas(stdout, output, "detPendingProcessedImfile", !simple)) { 2204 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2205 psFree(output); 2206 return false; 2207 } 2208 2209 psFree(output); 2210 2211 return true; 2212 } 2213 2214 static psArray *searchRawImfiles(pxConfig *config, psMetadata *where) 2215 { 2216 PS_ASSERT_PTR_NON_NULL(config, NULL); 2217 2218 // use the default where if "where" is NULL 2219 if (!where) { 2220 where = config->where; 2221 } 2222 2223 // select exp_ids from detInputExp matching det_idp 2224 // where query should be pre-generated 2225 psArray *detInputExp = 2226 detInputExpSelectRowObjects(config->dbh, where, 0); 2227 if (!detInputExp) { 2228 psError(PS_ERR_UNKNOWN, false, "no rawExp rows found"); 2229 return NULL; 2230 } 2231 2232 // generate where query with just the exp_ids 2233 psMetadata *where_exp_ids = psMetadataAlloc(); 2234 for (long i = 0; i < psArrayLength(detInputExp); i++) { 2235 detInputExpRow *row = detInputExp->data[i]; 2236 if (!psMetadataAddS64(where_exp_ids, PS_LIST_TAIL, "exp_id", 2237 PS_META_DUPLICATE_OK, "==", row->exp_id) 2238 ) { 2239 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 2240 psFree(detInputExp); 2241 psFree(where_exp_ids); 2242 return NULL; 2243 } 2244 } 2245 psFree(detInputExp); 2246 2247 // select rawImfiles with matching exp_ids 2248 psArray *rawImfiles = 2249 rawImfileSelectRowObjects(config->dbh, where_exp_ids, 0); 2250 psFree(where_exp_ids); 2251 if (!rawImfiles) { 2252 psError(PS_ERR_UNKNOWN, false, "no rawImfile rows found"); 2253 return NULL; 2254 } 2255 2256 return rawImfiles; 2257 } 2258 2259 static bool addprocessedimfileMode(pxConfig *config) 2260 { 2261 PS_ASSERT_PTR_NON_NULL(config, false); 2262 2263 // det_id, exp_id, class_id, uri, recipe, -bg, -bg_stdev 2264 // are required 2265 bool status = false; 2266 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 2267 if (!status) { 2268 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 2269 return false; 2270 } 2271 if (!det_id) { 2272 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 2273 return false; 2274 } 2275 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id"); 2276 if (!status) { 2277 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id"); 2278 return false; 2279 } 2280 if (!exp_id) { 2281 psError(PS_ERR_UNKNOWN, true, "-exp_id is required"); 2282 return false; 2283 } 2284 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id"); 2285 if (!status) { 2286 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id"); 2287 return false; 2288 } 2289 if (!class_id) { 2290 psError(PS_ERR_UNKNOWN, true, "-class_id is required"); 2291 return false; 2292 } 2293 psString uri = psMetadataLookupStr(&status, config->args, "-uri"); 2294 if (!status) { 2295 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri"); 2296 return false; 2297 } 2298 if (!uri) { 2299 psError(PS_ERR_UNKNOWN, true, "-uri is required"); 2300 return false; 2301 } 2302 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 2303 if (!status) { 2304 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 2305 return false; 2306 } 2307 if (!recipe) { 2308 psError(PS_ERR_UNKNOWN, true, "-recip is required"); 2309 return false; 2310 } 2311 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 2312 if (!status) { 2313 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 2314 return false; 2315 } 2316 //if (isnan(bg)) { 2317 //psError(PS_ERR_UNKNOWN, true, "-bg is required"); 2318 //return false; 2319 //} 2320 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 2321 if (!status) { 2322 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 2323 return false; 2324 } 2325 //if (isnan(bg_stdev)) { 2326 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 2327 // return false; 2328 //} 2329 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 2330 if (!status) { 2331 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 2332 return false; 2333 } 2334 2335 // optional 2336 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0"); 2337 if (!status) { 2338 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0"); 2339 return false; 2340 } 2341 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1"); 2342 if (!status) { 2343 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1"); 2344 return false; 2345 } 2346 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2"); 2347 if (!status) { 2348 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2"); 2349 return false; 2350 } 2351 2352 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 2353 if (!status) { 2354 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 2355 return false; 2356 } 2357 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 2358 if (!status) { 2359 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 2360 return false; 2361 } 2362 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 2363 if (!status) { 2364 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 2365 return false; 2366 } 2367 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 2368 if (!status) { 2369 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 2370 return false; 2371 } 2372 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 2373 if (!status) { 2374 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 2375 return false; 2376 } 2377 2378 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 2379 if (!status) { 2380 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 2381 return false; 2382 } 2383 2384 // find the matching rawImfile by exp_id/class_id 2385 psMetadata *where = psMetadataAlloc(); 2386 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) { 2387 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 2388 psFree(where); 2389 return false; 2390 } 2391 if (!psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==", class_id)) { 2392 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 2393 psFree(where); 2394 return false; 2395 } 2396 2397 // default values 2398 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 2399 if (!status) { 2400 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 2401 return false; 2402 } 2403 2404 psArray *rawImfiles = rawImfileSelectRowObjects(config->dbh, where, 0); 2405 psFree(where); 2406 if (!rawImfiles) { 2407 psError(PS_ERR_UNKNOWN, false, "no rawImfile rows found "); 2408 return false; 2409 } 2410 2411 2412 // create a new detProcessedImfile object 2413 detProcessedImfileRow *detRow = detProcessedImfileRowAlloc( 2414 (psS64)atoll(det_id), 2415 (psS64)atoll(exp_id), 2416 class_id, 2417 uri, 2418 recipe, 2419 bg, 2420 bg_stdev, 2421 bg_mean_stdev, 2422 fringe_0, 2423 fringe_1, 2424 fringe_2, 2425 user_1, 2426 user_2, 2427 user_3, 2428 user_4, 2429 user_5, 2430 path_base, 2431 code 2432 ); 2433 psFree(rawImfiles); 2434 2435 // insert the new row into the detProcessedImfile table 2436 if (!detProcessedImfileInsertObject(config->dbh, detRow)) { 2437 psError(PS_ERR_UNKNOWN, false, "database error"); 2438 psFree(detRow); 2439 return false; 2440 } 2441 2442 psFree(detRow); 2443 2444 return true; 2445 } 2446 2447 static bool toprocessedexpMode(pxConfig *config) 2448 { 2449 PS_ASSERT_PTR_NON_NULL(config, false); 2450 2451 bool status = false; 2452 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 2453 if (!status) { 2454 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 2455 return false; 2456 } 2457 2458 psString query = pxDataGet("dettool_toprocessedexp.sql"); 2459 if (!query) { 2460 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 2461 return false; 2462 } 2463 2464 // XXX does it make sense to accept any search params? 2465 #if 0 2466 if (config->where) { 2467 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 2468 psStringAppend(&query, " AND %s", whereClause); 2469 psFree(whereClause); 2470 } 2471 #endif 2472 2473 // treat limit == 0 as "no limit" 2474 if (limit) { 2475 psString limitString = psDBGenerateLimitSQL(limit); 2476 psStringAppend(&query, " %s", limitString); 2477 psFree(limitString); 2478 } 2479 2480 if (!p_psDBRunQuery(config->dbh, query)) { 2481 psError(PS_ERR_UNKNOWN, false, "database error"); 2482 psFree(query); 2483 return false; 2484 } 2485 psFree(query); 2486 2487 psArray *output = p_psDBFetchResult(config->dbh); 2488 if (!output) { 2489 psError(PS_ERR_UNKNOWN, false, "database error"); 2490 return false; 2491 } 2492 if (!psArrayLength(output)) { 2493 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2494 psFree(output); 2495 return true; 2496 } 2497 2498 bool simple = false; 2499 { 2500 bool status = false; 2501 simple = psMetadataLookupBool(&status, config->args, "-simple"); 2502 if (!status) { 2503 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2504 return false; 2505 } 2506 } 2507 2508 // negative simple so the default is true 2509 if (!ippdbPrintMetadatas(stdout, output, "detPendingProcessedExp", !simple)) { 2510 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2511 psFree(output); 2512 return false; 2513 } 2514 2515 psFree(output); 2516 2517 return true; 2518 } 2519 2520 static bool addprocessedexpMode(pxConfig *config) 2521 { 2522 PS_ASSERT_PTR_NON_NULL(config, false); 2523 2524 // det_id, exp_id, recip, -bg, -bg_stdev 2525 // are required 2526 bool status = false; 2527 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 2528 if (!status) { 2529 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 2530 return false; 2531 } 2532 if (!det_id) { 2533 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 2534 return false; 2535 } 2536 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id"); 2537 if (!status) { 2538 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id"); 2539 return false; 2540 } 2541 if (!exp_id) { 2542 psError(PS_ERR_UNKNOWN, true, "-exp_id is required"); 2543 return false; 2544 } 2545 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 2546 if (!status) { 2547 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 2548 return false; 2549 } 2550 if (!recipe) { 2551 psError(PS_ERR_UNKNOWN, true, "-recip is required"); 2552 return false; 2553 } 2554 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 2555 if (!status) { 2556 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 2557 return false; 2558 } 2559 //if (isnan(bg)) { 2560 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 2561 // return false; 2562 //} 2563 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 2564 if (!status) { 2565 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 2566 return false; 2567 } 2568 //if (isnan(bg_stdev)) { 2569 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 2570 // return false; 2571 //} 2572 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 2573 if (!status) { 2574 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 2575 return false; 2576 } 2577 // optional 2578 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0"); 2579 if (!status) { 2580 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0"); 2581 return false; 2582 } 2583 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1"); 2584 if (!status) { 2585 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1"); 2586 return false; 2587 } 2588 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2"); 2589 if (!status) { 2590 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2"); 2591 return false; 2592 } 2593 2594 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 2595 if (!status) { 2596 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 2597 return false; 2598 } 2599 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 2600 if (!status) { 2601 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 2602 return false; 2603 } 2604 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 2605 if (!status) { 2606 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 2607 return false; 2608 } 2609 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 2610 if (!status) { 2611 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 2612 return false; 2613 } 2614 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 2615 if (!status) { 2616 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 2617 return false; 2618 } 2619 2620 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 2621 if (!status) { 2622 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 2623 return false; 2624 } 2625 2626 // default values 2627 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 2628 if (!status) { 2629 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 2630 return false; 2631 } 2632 2633 psString query = psStringCopy( 2634 " SELECT DISTINCT" 2635 " detProcessedImfile.det_id," 2636 " detRun.iteration," 2637 " detRun.det_type," 2638 " detProcessedImfile.exp_id" 2639 " FROM detRun" 2640 " JOIN detInputExp" 2641 " ON detRun.det_id = detInputExp.det_id" 2642 " AND detRun.iteration = detInputExp.iteration" 2643 " JOIN rawExp" 2644 " ON detInputExp.exp_id = rawExp.exp_id" 2645 " JOIN detProcessedImfile" 2646 " ON detInputExp.det_id = detProcessedImfile.det_id" 2647 " AND detInputExp.exp_id = detProcessedImfile.exp_id" 2648 " LEFT JOIN detProcessedExp" 2649 " ON detInputExp.det_id = detProcessedExp.det_id" 2650 " AND detProcessedImfile.exp_id= detProcessedExp.exp_id" 2651 " LEFT JOIN rawImfile" 2652 " ON detInputExp.exp_id = rawImfile.exp_id" 2653 " AND detProcessedImfile.class_id = rawImfile.class_id" 2654 " WHERE" 2655 " detRun.state = 'run'" 2656 " AND detRun.mode = 'master'" 2657 " AND detProcessedExp.det_id IS NULL" 2658 " AND detProcessedExp.exp_id IS NULL" 2659 " AND detInputExp.include = 1" 2660 " AND detRun.det_id = %s" 2661 " AND detProcessedImfile.exp_id = '%s'" 2662 " GROUP BY" 2663 " detProcessedImfile.class_id," 2664 " rawImfile.class_id," 2665 " detRun.det_id" 2666 " HAVING" 2667 " COUNT(detProcessedImfile.class_id) = COUNT(rawImfile.class_id)" 2668 ); 2669 2670 if (!p_psDBRunQuery(config->dbh, query, det_id, exp_id)) { 2671 psError(PS_ERR_UNKNOWN, false, "database error"); 2672 psFree(query); 2673 return false; 2674 } 2675 psFree(query); 2676 2677 psArray *output = p_psDBFetchResult(config->dbh); 2678 if (!output) { 2679 psError(PS_ERR_UNKNOWN, false, "database error"); 2680 return false; 2681 } 2682 if (!psArrayLength(output)) { 2683 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2684 psFree(output); 2685 return true; 2686 } 2687 psFree(output); 2688 2689 // create a new detProcessedImfile object 2690 detProcessedExpRow *detRow = detProcessedExpRowAlloc( 2691 (psS64)atoll(det_id), 2692 (psS64)atoll(exp_id), 2693 recipe, 2694 bg, 2695 bg_stdev, 2696 bg_mean_stdev, 2697 fringe_0, 2698 fringe_1, 2699 fringe_2, 2700 user_1, 2701 user_2, 2702 user_3, 2703 user_4, 2704 user_5, 2705 path_base, 2706 code 2707 ); 2708 2709 // insert the new row into the detProcessedImfile table 2710 if (!detProcessedExpInsertObject(config->dbh, detRow)) { 2711 psError(PS_ERR_UNKNOWN, false, "database error"); 2712 psFree(detRow); 2713 return false; 2714 } 2715 2716 psFree(detRow); 2717 2718 return true; 2719 } 2720 2721 static bool processedexpMode(pxConfig *config) 2722 { 2723 PS_ASSERT_PTR_NON_NULL(config, false); 2724 2725 bool status = false; 2726 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 2727 if (!status) { 2728 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 2729 return false; 2730 } 2731 2732 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 2733 if (!status) { 2734 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 2735 return false; 2736 } 2737 2738 psString query = psStringCopy("SELECT * FROM detProcessedExp"); 2739 2740 if (config->where) { 2741 psString whereClause = psDBGenerateWhereSQL(config->where, NULL); 2742 psStringAppend(&query, " %s", whereClause); 2743 psFree(whereClause); 2744 } 2745 2746 if (faulted) { 2747 // list only faulted rows 2748 psStringAppend(&query, " %s", "AND detProcessedExp.fault != 0"); 2749 } else { 2750 // don't list faulted rows 2751 psStringAppend(&query, " %s", "AND detProcessedExp.fault = 0"); 2752 } 2753 2754 // treat limit == 0 as "no limit" 2755 if (limit) { 2756 psString limitString = psDBGenerateLimitSQL(limit); 2757 psStringAppend(&query, " %s", limitString); 2758 psFree(limitString); 2759 } 2760 2761 if (!p_psDBRunQuery(config->dbh, query)) { 2762 psError(PS_ERR_UNKNOWN, false, "database error"); 2763 psFree(query); 2764 return false; 2765 } 2766 psFree(query); 2767 2768 psArray *output = p_psDBFetchResult(config->dbh); 2769 if (!output) { 2770 psError(PS_ERR_UNKNOWN, false, "database error"); 2771 return false; 2772 } 2773 if (!psArrayLength(output)) { 2774 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2775 psFree(output); 2776 return true; 2777 } 2778 2779 bool simple = false; 2780 { 2781 bool status = false; 2782 simple = psMetadataLookupBool(&status, config->args, "-simple"); 2783 if (!status) { 2784 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2785 return false; 2786 } 2787 } 2788 2789 // negative simple so the default is true 2790 if (!ippdbPrintMetadatas(stdout, output, "detProcessedExp", !simple)) { 2791 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2792 psFree(output); 2793 return false; 2794 } 2795 2796 psFree(output); 2797 2798 return true; 2799 } 2800 2801 2802 static bool revertprocessedexpMode(pxConfig *config) 2803 { 2804 PS_ASSERT_PTR_NON_NULL(config, false); 2805 2806 psString query = pxDataGet("dettool_revertprocessedexp.sql"); 2807 if (!query) { 2808 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 2809 return false; 2810 } 2811 2812 if (config->where) { 2813 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detProcessedExp"); 2814 psStringAppend(&query, " AND %s", whereClause); 2815 psFree(whereClause); 2816 } 2817 2818 if (!p_psDBRunQuery(config->dbh, query)) { 2819 psError(PS_ERR_UNKNOWN, false, "database error"); 2820 psFree(query); 2821 return false; 2822 } 2823 psFree(query); 2824 2825 if (psDBAffectedRows(config->dbh) < 1) { 2826 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 2827 return false; 2828 } 2829 2830 return true; 2831 } 2832 2833 2834 static bool tostackedMode(pxConfig *config) 2835 { 2836 PS_ASSERT_PTR_NON_NULL(config, false); 2837 2838 bool status = false; 2839 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 2840 if (!status) { 2841 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 2842 return false; 2843 } 2844 2845 psString query = pxDataGet("dettool_tostacked.sql"); 2846 if (!query) { 2847 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 2848 return false; 2849 } 2850 2851 // XXX does it make sense to accept any search params? 2852 #if 0 2853 if (config->where) { 2854 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 2855 psStringAppend(&query, " AND %s", whereClause); 2856 psFree(whereClause); 2857 } 2858 #endif 2859 2860 // treat limit == 0 as "no limit" 2861 if (limit) { 2862 psString limitString = psDBGenerateLimitSQL(limit); 2863 psStringAppend(&query, " %s", limitString); 2864 psFree(limitString); 2865 } 2866 2867 if (!p_psDBRunQuery(config->dbh, query)) { 2868 psError(PS_ERR_UNKNOWN, false, "database error"); 2869 psFree(query); 2870 return false; 2871 } 2872 psFree(query); 2873 2874 psArray *output = p_psDBFetchResult(config->dbh); 2875 if (!output) { 2876 psError(PS_ERR_UNKNOWN, false, "database error"); 2877 return false; 2878 } 2879 if (!psArrayLength(output)) { 2880 psTrace("dettool", PS_LOG_INFO, "no rows found"); 2881 psFree(output); 2882 return true; 2883 } 2884 2885 bool simple = false; 2886 { 2887 bool status = false; 2888 simple = psMetadataLookupBool(&status, config->args, "-simple"); 2889 if (!status) { 2890 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2891 return false; 2892 } 2893 } 2894 2895 // negative simple so the default is true 2896 if (!ippdbPrintMetadatas(stdout, output, "detPendingStackedImfile", !simple)) { 2897 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 2898 psFree(output); 2899 return false; 2900 } 2901 2902 psFree(output); 2903 2904 return true; 2905 } 2906 2907 static bool processedimfileMode(pxConfig *config) 2908 { 2909 PS_ASSERT_PTR_NON_NULL(config, false); 2910 2911 char *value = NULL; 2912 bool status = false; 2913 2914 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 2915 if (!status) { 2916 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 2917 return false; 2918 } 2919 2920 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 2921 if (!status) { 2922 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 2923 return false; 2924 } 2925 2926 psString query = psStringCopy( 2927 " SELECT DISTINCT" 2928 " detRun.det_type," 2929 " rawExp.exp_time," 2930 " detProcessedImfile.*" 2931 " FROM detProcessedImfile" 2932 " JOIN detRun" 2933 " USING(det_id)" 2934 " JOIN detInputExp" 2935 " ON detRun.det_id = detInputExp.det_id" 2936 " AND detRun.iteration = detInputExp.iteration" 2937 " AND detProcessedImfile.exp_id = detInputExp.exp_id" 2938 " JOIN rawExp" 2939 " ON rawExp.exp_id = detProcessedImfile.exp_id" 2940 " WHERE" 2941 ); 2942 // NOTE the above WHERE is completed with the following line: 2943 2944 // add the two required restrictions: detRun.state and detRun.mode 2945 if ((value = psMetadataLookupStr(&status, config->args, "-select_state"))) { 2946 psStringAppend(&query, " detRun.state = '%s'", value); 2947 } else { 2948 psStringAppend(&query, " detRun.state = 'run'"); 2949 } 2950 if ((value = psMetadataLookupStr(&status, config->args, "-select_mode"))) { 2951 psStringAppend(&query, " AND detRun.mode = '%s'", value); 2952 } else { 2953 psStringAppend(&query, " AND detRun.mode = 'master'"); 2954 } 2955 2956 if (config->where) { 2957 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detProcessedImfile"); 2958 psStringAppend(&query, " AND %s", whereClause); 2959 psFree(whereClause); 2960 } 2961 2962 { 2963 bool status = false; 2964 bool included = psMetadataLookupBool(&status, config->args, "-included"); 2965 if (!status) { 2966 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 2967 return false; 2968 } 2969 // restrict search to included imfiles 2970 if (included) { 2971 psStringAppend(&query, " AND detInputExp.include = 1"); 2972 } 2973 } 2974 2975 if (faulted) { 2976 // list only faulted rows 2977 psStringAppend(&query, " %s", "AND detProcessedImfile.fault != 0"); 2978 } else { 2979 // don't list faulted rows 2980 psStringAppend(&query, " %s", "AND detProcessedImfile.fault = 0"); 2981 } 2982 2983 // treat limit == 0 as "no limit" 2984 if (limit) { 2985 psString limitString = psDBGenerateLimitSQL(limit); 2986 psStringAppend(&query, " %s", limitString); 2987 psFree(limitString); 2988 } 2989 2990 if (!p_psDBRunQuery(config->dbh, query)) { 2991 psError(PS_ERR_UNKNOWN, false, "database error"); 2992 psFree(query); 2993 return false; 2994 } 2995 psFree(query); 2996 2997 psArray *output = p_psDBFetchResult(config->dbh); 2998 if (!output) { 2999 psError(PS_ERR_UNKNOWN, false, "database error"); 3000 return false; 3001 } 3002 if (!psArrayLength(output)) { 3003 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3004 psFree(output); 3005 return true; 3006 } 3007 3008 bool simple = false; 3009 { 3010 bool status = false; 3011 simple = psMetadataLookupBool(&status, config->args, "-simple"); 3012 if (!status) { 3013 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 3014 return false; 3015 } 3016 } 3017 3018 // negative simple so the default is true 3019 if (!ippdbPrintMetadatas(stdout, output, "rawImfile", !simple)) { 3020 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 3021 psFree(output); 3022 return false; 3023 } 3024 3025 psFree(output); 3026 3027 return true; 3028 } 3029 3030 3031 static bool revertprocessedimfileMode(pxConfig *config) 3032 { 3033 PS_ASSERT_PTR_NON_NULL(config, false); 3034 3035 psString query = pxDataGet("dettool_revertprocessedimfile.sql"); 3036 if (!query) { 3037 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 3038 return false; 3039 } 3040 3041 if (config->where) { 3042 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detProcessedImfile"); 3043 psStringAppend(&query, " AND %s", whereClause); 3044 psFree(whereClause); 3045 } 3046 3047 if (!p_psDBRunQuery(config->dbh, query)) { 3048 psError(PS_ERR_UNKNOWN, false, "database error"); 3049 psFree(query); 3050 return false; 3051 } 3052 psFree(query); 3053 3054 if (psDBAffectedRows(config->dbh) < 1) { 3055 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 3056 return false; 3057 } 3058 3059 return true; 3060 } 3061 3062 3063 static bool addstackedMode(pxConfig *config) 3064 { 3065 PS_ASSERT_PTR_NON_NULL(config, false); 3066 3067 // det_id, class_id, uri, & recipe are required 3068 bool status = false; 3069 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 3070 if (!status) { 3071 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 3072 return false; 3073 } 3074 if (!det_id) { 3075 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 3076 return false; 3077 } 3078 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id"); 3079 if (!status) { 3080 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id"); 3081 return false; 3082 } 3083 if (!class_id) { 3084 psError(PS_ERR_UNKNOWN, true, "-class_id is required"); 3085 return false; 3086 } 3087 psString uri = psMetadataLookupStr(&status, config->args, "-uri"); 3088 if (!status) { 3089 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri"); 3090 return false; 3091 } 3092 if (!uri) { 3093 psError(PS_ERR_UNKNOWN, true, "-uri is required"); 3094 return false; 3095 } 3096 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 3097 if (!status) { 3098 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 3099 return false; 3100 } 3101 if (!recipe) { 3102 psError(PS_ERR_UNKNOWN, true, "-recip is required"); 3103 return false; 3104 } 3105 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 3106 if (!status) { 3107 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 3108 return false; 3109 } 3110 //if (isnan(bg)) { 3111 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 3112 // return false; 3113 //} 3114 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 3115 if (!status) { 3116 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 3117 return false; 3118 } 3119 //if (isnan(bg_stdev)) { 3120 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 3121 // return false; 3122 //} 3123 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 3124 if (!status) { 3125 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 3126 return false; 3127 } 3128 3129 // optional values 3130 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 3131 if (!status) { 3132 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 3133 return false; 3134 } 3135 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 3136 if (!status) { 3137 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 3138 return false; 3139 } 3140 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 3141 if (!status) { 3142 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 3143 return false; 3144 } 3145 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 3146 if (!status) { 3147 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 3148 return false; 3149 } 3150 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 3151 if (!status) { 3152 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 3153 return false; 3154 } 3155 3156 // default values 3157 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 3158 if (!status) { 3159 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); 3160 return false; 3161 } 3162 3163 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 3164 if (!status) { 3165 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 3166 return false; 3167 } 3168 3169 // correlate the class_id against the input exposure(s) 3170 3171 // we have to generate our own where clause as we want to search only by the 3172 // det_id 3173 psMetadata *where = psMetadataAlloc(); 3174 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", 3175 (psS64)atoll(det_id))) { 3176 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 3177 psFree(where); 3178 return false; 3179 } 3180 3181 psArray *rawImfiles = searchRawImfiles(config, where); 3182 psFree(where); 3183 3184 bool valid_class_id = false; 3185 if (rawImfiles) { 3186 for (long i = 0; i < psArrayLength(rawImfiles); i++) { 3187 if (strcmp(class_id, ((rawImfileRow *)rawImfiles->data[i])->class_id) == 0) { 3188 valid_class_id = true; 3189 break; 3190 } 3191 } 3192 psFree(rawImfiles); 3193 } 3194 3195 if (!valid_class_id) { 3196 psError(PS_ERR_UNKNOWN, true, 3197 "class_id can not be correlated with the input exposures"); 3198 return false; 3199 } 3200 3201 // create a new detStackedImfile object 3202 detStackedImfileRow *stackedImfile = detStackedImfileRowAlloc( 3203 (psS64)atoll(det_id), 3204 iteration, 3205 class_id, 3206 uri, 3207 recipe, 3208 bg, 3209 bg_stdev, 3210 bg_mean_stdev, 3211 user_1, 3212 user_2, 3213 user_3, 3214 user_4, 3215 user_5, 3216 code 3217 ); 3218 3219 // insert the new row into the detProcessedImfile table 3220 if (!detStackedImfileInsertObject(config->dbh, stackedImfile)) { 3221 psError(PS_ERR_UNKNOWN, false, "database error"); 3222 psFree(stackedImfile); 3223 return false; 3224 } 3225 3226 psFree(stackedImfile); 3227 3228 return true; 3229 } 3230 3231 static bool stackedMode(pxConfig *config) 3232 { 3233 PS_ASSERT_PTR_NON_NULL(config, false); 3234 3235 bool status = false; 3236 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 3237 if (!status) { 3238 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 3239 return false; 3240 } 3241 3242 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 3243 if (!status) { 3244 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 3245 return false; 3246 } 3247 3248 // select detStackedImfile.* 3249 // by: 3250 // where det_id, iteration, class_id is not in detNormalizedImfile 3251 3252 psString query = psStringCopy( 3253 "SELECT" 3254 " detStackedImfile.*" 3255 " FROM detStackedImfile" 3256 " JOIN detRun" 3257 " USING(det_id, iteration)" 3258 " WHERE" 3259 " detRun.state = 'run'" 3260 " AND detRun.mode = 'master'" 3261 ); 3262 3263 if (config->where) { 3264 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detStackedImfile"); 3265 psStringAppend(&query, " AND %s", whereClause); 3266 psFree(whereClause); 3267 } 3268 3269 if (faulted) { 3270 // list only faulted rows 3271 psStringAppend(&query, " %s", "AND detStackedImfile.fault != 0"); 3272 } else { 3273 // don't list faulted rows 3274 psStringAppend(&query, " %s", "AND detStackedImfile.fault = 0"); 3275 } 3276 3277 // treat limit == 0 as "no limit" 3278 if (limit) { 3279 psString limitString = psDBGenerateLimitSQL(limit); 3280 psStringAppend(&query, " %s", limitString); 3281 psFree(limitString); 3282 } 3283 3284 if (!p_psDBRunQuery(config->dbh, query)) { 3285 psError(PS_ERR_UNKNOWN, false, "database error"); 3286 psFree(query); 3287 return false; 3288 } 3289 psFree(query); 3290 3291 psArray *output = p_psDBFetchResult(config->dbh); 3292 if (!output) { 3293 psError(PS_ERR_UNKNOWN, false, "database error"); 3294 return false; 3295 } 3296 if (!psArrayLength(output)) { 3297 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3298 psFree(output); 3299 return true; 3300 } 3301 3302 bool simple = false; 3303 { 3304 bool status = false; 3305 simple = psMetadataLookupBool(&status, config->args, "-simple"); 3306 if (!status) { 3307 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 3308 psFree(output); 3309 return false; 3310 } 3311 } 3312 3313 // negative simple so the default is true 3314 if (!ippdbPrintMetadatas(stdout, output, "rawImfile", !simple)) { 3315 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 3316 psFree(output); 3317 return false; 3318 } 3319 3320 psFree(output); 3321 3322 return true; 3323 } 3324 3325 3326 static bool revertstackedMode(pxConfig *config) 3327 { 3328 PS_ASSERT_PTR_NON_NULL(config, false); 3329 3330 psString query = pxDataGet("dettool_revertstacked.sql"); 3331 if (!query) { 3332 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 3333 return false; 3334 } 3335 3336 if (config->where) { 3337 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detStackedImfile"); 3338 psStringAppend(&query, " AND %s", whereClause); 3339 psFree(whereClause); 3340 } 3341 3342 if (!p_psDBRunQuery(config->dbh, query)) { 3343 psError(PS_ERR_UNKNOWN, false, "database error"); 3344 psFree(query); 3345 return false; 3346 } 3347 psFree(query); 3348 3349 if (psDBAffectedRows(config->dbh) < 1) { 3350 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 3351 return false; 3352 } 3353 3354 return true; 3355 } 3356 3357 static bool tonormalizedstatMode(pxConfig *config) 3358 { 3359 PS_ASSERT_PTR_NON_NULL(config, false); 3360 3361 bool status = false; 3362 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 3363 if (!status) { 3364 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 3365 return false; 3366 } 3367 3368 psString query = pxDataGet("dettool_tonormalizedstat.sql"); 3369 if (!query) { 3370 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 3371 return false; 3372 } 3373 3374 // XXX does it make sense to accept any search params? 3375 #if 0 3376 if (config->where) { 3377 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 3378 psStringAppend(&query, " AND %s", whereClause); 3379 psFree(whereClause); 3380 } 3381 #endif 3382 3383 // treat limit == 0 as "no limit" 3384 if (limit) { 3385 psString limitString = psDBGenerateLimitSQL(limit); 3386 psStringAppend(&query, " %s", limitString); 3387 psFree(limitString); 3388 } 3389 3390 if (!p_psDBRunQuery(config->dbh, query)) { 3391 psError(PS_ERR_UNKNOWN, false, "database error"); 3392 psFree(query); 3393 return false; 3394 } 3395 psFree(query); 3396 3397 psArray *output = p_psDBFetchResult(config->dbh); 3398 if (!output) { 3399 psError(PS_ERR_UNKNOWN, false, "database error"); 3400 return false; 3401 } 3402 if (!psArrayLength(output)) { 3403 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3404 psFree(output); 3405 return true; 3406 } 3407 3408 bool simple = false; 3409 { 3410 bool status = false; 3411 simple = psMetadataLookupBool(&status, config->args, "-simple"); 3412 if (!status) { 3413 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 3414 return false; 3415 } 3416 } 3417 3418 // negative simple so the default is true 3419 if (!ippdbPrintMetadatas(stdout, output, "detPendingNormStatImfile", !simple)) { 3420 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 3421 psFree(output); 3422 return false; 3423 } 3424 3425 psFree(output); 3426 3427 return true; 3428 } 3429 3430 static bool addnormalizedstatMode(pxConfig *config) 3431 { 3432 PS_ASSERT_PTR_NON_NULL(config, NULL); 3433 3434 // select * from detStackedImfile 3435 // by det_id, iteration, class_id 3436 // where det_id, iteration, class_id is not in detNormalizedStatImfile 3437 psString query = psStringCopy( 3438 "SELECT DISTINCT" 3439 " detStackedImfile.*" 3440 " FROM detStackedImfile" 3441 " LEFT JOIN detNormalizedStatImfile" 3442 " USING(det_id, iteration, class_id)" 3443 " WHERE" 3444 " detNormalizedStatImfile.det_id IS NULL" 3445 " AND detNormalizedStatImfile.iteration IS NULL" 3446 " AND detNormalizedStatImfile.class_id IS NULL" 3447 ); 3448 3449 if (config->where) { 3450 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detStackedImfile"); 3451 psStringAppend(&query, " AND %s", whereClause); 3452 psFree(whereClause); 3453 } 3454 3455 if (!p_psDBRunQuery(config->dbh, query)) { 3456 psError(PS_ERR_UNKNOWN, false, "database error"); 3457 psFree(query); 3458 return false; 3459 } 3460 psFree(query); 3461 3462 psArray *output = p_psDBFetchResult(config->dbh); 3463 if (!output) { 3464 psError(PS_ERR_UNKNOWN, false, "database error"); 3465 return false; 3466 } 3467 if (!psArrayLength(output)) { 3468 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3469 psFree(output); 3470 return true; 3471 } 3472 3473 // start a transaction so it's all rows or nothing 3474 if (!psDBTransaction(config->dbh)) { 3475 psError(PS_ERR_UNKNOWN, false, "database error"); 3476 psFree(output); 3477 return false; 3478 } 3479 3480 for (long i = 0; i < psArrayLength(output); i++) { 3481 psMetadata *row = output->data[i]; 3482 // convert metadata into a detStackedImfile object 3483 detStackedImfileRow *stackedImfile = detStackedImfileObjectFromMetadata(row); 3484 // convert detStackedImfile object into a detNormalizedStat object 3485 detNormalizedStatImfileRow *stat = detStackedToDetNormalizedStatImfile(config, stackedImfile); 3486 psFree(stackedImfile); 3487 if (!stat) { 3488 if (!psDBRollback(config->dbh)) { 3489 psError(PS_ERR_UNKNOWN, false, "database error"); 3490 } 3491 psError(PS_ERR_UNKNOWN, false, "failed to convert detStackedImfile to detNormalizedStatImfile"); 3492 psFree(output); 3493 return false; 3494 } 3495 // insert detNormlized Stat object into the database 3496 if (!detNormalizedStatImfileInsertObject(config->dbh, stat)) { 3497 if (!psDBRollback(config->dbh)) { 3498 psError(PS_ERR_UNKNOWN, false, "database error"); 3499 } 3500 psError(PS_ERR_UNKNOWN, false, "database error"); 3501 psFree(stat); 3502 psFree(output); 3503 } 3504 psFree(stat); 3505 } 3506 3507 psFree(output); 3508 3509 if (!psDBCommit(config->dbh)) { 3510 psError(PS_ERR_UNKNOWN, false, "database error"); 3511 return false; 3512 } 3513 3514 return true; 3515 } 3516 3517 static detNormalizedStatImfileRow *detStackedToDetNormalizedStatImfile(pxConfig *config, detStackedImfileRow *stackedImfile) 3518 { 3519 PS_ASSERT_PTR_NON_NULL(config, NULL); 3520 PS_ASSERT_PTR_NON_NULL(stackedImfile, NULL); 3521 3522 bool status = false; 3523 psF32 norm = psMetadataLookupF32(&status, config->args, "-norm"); 3524 if (!status) { 3525 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -norm"); 3526 return false; 3527 } 3528 //if (isnan(norm)) { 3529 // psError(PS_ERR_UNKNOWN, true, "-norm is required"); 3530 // return false; 3531 //} 3532 3533 // default values 3534 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 3535 if (!status) { 3536 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 3537 return false; 3538 } 3539 3540 return detNormalizedStatImfileRowAlloc( 3541 stackedImfile->det_id, 3542 stackedImfile->iteration, 3543 stackedImfile->class_id, 3544 norm, 3545 code 3546 ); 3547 } 3548 3549 3550 static bool normalizedstatMode(pxConfig *config) 3551 { 3552 PS_ASSERT_PTR_NON_NULL(config, false); 3553 3554 bool status = false; 3555 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 3556 if (!status) { 3557 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 3558 return false; 3559 } 3560 3561 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 3562 if (!status) { 3563 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 3564 return false; 3565 } 3566 3567 psString query = pxDataGet("dettool_normalizedstat.sql"); 3568 if (!query) { 3569 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 3570 return false; 3571 } 3572 3573 if (faulted) { 3574 // list only faulted rows 3575 psStringAppend(&query, " %s", "WHERE fault != 0"); 3576 } else { 3577 // don't list faulted rows 3578 psStringAppend(&query, " %s", "WHERE fault = 0"); 3579 } 3580 3581 if (config->where) { 3582 psString whereClause = psDBGenerateWhereConditionSQL(config->where, NULL); 3583 psStringAppend(&query, " AND %s", whereClause); 3584 psFree(whereClause); 3585 } 3586 3587 // treat limit == 0 as "no limit" 3588 if (limit) { 3589 psString limitString = psDBGenerateLimitSQL(limit); 3590 psStringAppend(&query, " %s", limitString); 3591 psFree(limitString); 3592 } 3593 3594 if (!p_psDBRunQuery(config->dbh, query)) { 3595 psError(PS_ERR_UNKNOWN, false, "database error"); 3596 psFree(query); 3597 return false; 3598 } 3599 psFree(query); 3600 3601 psArray *output = p_psDBFetchResult(config->dbh); 3602 if (!output) { 3603 psError(PS_ERR_UNKNOWN, false, "database error"); 3604 return false; 3605 } 3606 if (!psArrayLength(output)) { 3607 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3608 psFree(output); 3609 return true; 3610 } 3611 3612 bool simple = false; 3613 { 3614 bool status = false; 3615 simple = psMetadataLookupBool(&status, config->args, "-simple"); 3616 if (!status) { 3617 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 3618 psFree(output); 3619 return false; 3620 } 3621 } 3622 3623 // negative simple so the default is true 3624 if (!ippdbPrintMetadatas(stdout, output, "detNormalizedStatImfile", !simple)) { 3625 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 3626 psFree(output); 3627 return false; 3628 } 3629 3630 psFree(output); 3631 3632 return true; 3633 } 3634 3635 static bool revertnormalizedstatMode(pxConfig *config) 3636 { 3637 PS_ASSERT_PTR_NON_NULL(config, false); 3638 3639 psString query = pxDataGet("dettool_revertnormalizedstat.sql"); 3640 if (!query) { 3641 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 3642 return false; 3643 } 3644 3645 if (config->where) { 3646 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedStatImfile"); 3647 psStringAppend(&query, " AND %s", whereClause); 3648 psFree(whereClause); 3649 } 3650 3651 if (!p_psDBRunQuery(config->dbh, query)) { 3652 psError(PS_ERR_UNKNOWN, false, "database error"); 3653 psFree(query); 3654 return false; 3655 } 3656 psFree(query); 3657 3658 if (psDBAffectedRows(config->dbh) < 1) { 3659 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 3660 return false; 3661 } 3662 3663 return true; 3664 } 3665 3666 static bool tonormalizeMode(pxConfig *config) 3667 { 3668 PS_ASSERT_PTR_NON_NULL(config, false); 3669 3670 bool status = false; 3671 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 3672 if (!status) { 3673 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 3674 return false; 3675 } 3676 3677 // select detNormalizedStatImfile.* 3678 // by: 3679 // where det_id, iteration, class_id is not in detNormalizedImfile 3680 3681 psString query = psStringCopy( 3682 "SELECT DISTINCT" 3683 " detRun.det_type," 3684 " detRun.workdir," 3685 " rawExp.camera," 3686 " detStackedImfile.uri," 3687 " detNormalizedStatImfile.*" 3688 " FROM detRun" 3689 " JOIN detStackedImfile" 3690 " USING(det_id, iteration)" 3691 " JOIN detInputExp" 3692 " USING(det_id, iteration)" 3693 " JOIN rawExp" 3694 " ON detInputExp.exp_id = rawExp.exp_id" 3695 " JOIN detNormalizedStatImfile" 3696 " ON detStackedImfile.det_id = detNormalizedStatImfile.det_id" 3697 " AND detStackedImfile.iteration = detNormalizedStatImfile.iteration" 3698 " AND detStackedImfile.class_id = detNormalizedStatImfile.class_id" 3699 " LEFT JOIN detNormalizedImfile" 3700 " ON detNormalizedStatImfile.det_id = detNormalizedImfile.det_id" 3701 " AND detNormalizedStatImfile.iteration = detNormalizedImfile.iteration" 3702 " AND detNormalizedStatImfile.class_id = detNormalizedImfile.class_id" 3703 " WHERE" 3704 " detNormalizedImfile.det_id IS NULL" 3705 " AND detNormalizedImfile.iteration IS NULL" 3706 " AND detNormalizedImfile.class_id IS NULL" 3707 " AND detNormalizedStatImfile.fault = 0" 3708 ); 3709 3710 // XXX does it make sense to accept any search params? 3711 #if 0 3712 if (config->where) { 3713 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 3714 psStringAppend(&query, " AND %s", whereClause); 3715 psFree(whereClause); 3716 } 3717 #endif 3718 3719 // treat limit == 0 as "no limit" 3720 if (limit) { 3721 psString limitString = psDBGenerateLimitSQL(limit); 3722 psStringAppend(&query, " %s", limitString); 3723 psFree(limitString); 3724 } 3725 3726 if (!p_psDBRunQuery(config->dbh, query)) { 3727 psError(PS_ERR_UNKNOWN, false, "database error"); 3728 psFree(query); 3729 return false; 3730 } 3731 psFree(query); 3732 3733 psArray *output = p_psDBFetchResult(config->dbh); 3734 if (!output) { 3735 psError(PS_ERR_UNKNOWN, false, "database error"); 3736 return false; 3737 } 3738 if (!psArrayLength(output)) { 3739 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3740 psFree(output); 3741 return true; 3742 } 3743 3744 bool simple = false; 3745 { 3746 bool status = false; 3747 simple = psMetadataLookupBool(&status, config->args, "-simple"); 3748 if (!status) { 3749 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 3750 psFree(output); 3751 return false; 3752 } 3753 } 3754 3755 // negative simple so the default is true 3756 if (!ippdbPrintMetadatas(stdout, output, "detPendingNormImfile", !simple)) { 3757 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 3758 psFree(output); 3759 return false; 3760 } 3761 3762 psFree(output); 3763 3764 return true; 3765 } 3766 3767 #if 0 3768 // XXX this function was left in commented as this method may be useful in the 3769 // future 3770 static psArray *validDetInputClassIds(pxConfig *config, const char *det_id) 3771 { 3772 PS_ASSERT_PTR_NON_NULL(config, NULL); 3773 // det_id is input as a string because the fact that it is an integer 3774 // is just a database impliementation detail. 3775 PS_ASSERT_PTR_NON_NULL(det_id, NULL); 3776 3777 psArray *rawImfiles = searchInputImfiles(config, det_id); 3778 if (!rawImfiles) { 3779 return NULL; 3780 } 3781 3782 psArray *valid_class_ids = NULL; 3783 { 3784 // All this jumping through hoops is so that we end up with unique 3785 // values. PP thinks that making multiple passes through this array and 3786 // deleting matched elements would end up being more expensive then a 3787 // double sort and stagger scheme. JH thinks it would be cheaper to 3788 // just do a unqiue sort and delete. So this is really just a cheap 3789 // hack to avoid implimenting a unique sort function but at least it's 3790 // stable. 3791 psHash *hash = psHashAlloc(psArrayLength(rawImfiles)); 3792 for (long i = 0; i < psArrayLength(rawImfiles); i++) { 3793 psHashAdd(hash, 3794 ((rawImfileRow *)rawImfiles->data[i])->class_id, 3795 ((rawImfileRow *)rawImfiles->data[i])->class_id 3796 ); 3797 } 3798 valid_class_ids = psHashToArray(hash); 3799 psFree(hash); 3800 } 3801 psFree(rawImfiles); 3802 3803 return valid_class_ids; 3804 } 3805 3806 static psArray *searchInputImfiles(pxConfig *config, const char *det_id) 3807 { 3808 PS_ASSERT_PTR_NON_NULL(config, NULL); 3809 // det_id is input as a string because the fact that it is an integer 3810 // is just a database impliementation detail. 3811 PS_ASSERT_PTR_NON_NULL(det_id, NULL); 3812 3813 psArray *inputExps = NULL; 3814 { 3815 psMetadata *where = psMetadataAlloc(); 3816 if (!psMetadataAddS32(where, PS_LIST_TAIL, "det_id", 0, "==", 3817 (psS32)atoi(det_id))) { 3818 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 3819 psFree(where); 3820 return NULL; 3821 } 3822 inputExps = detInputExpSelectRowObjects(config->dbh, where, 0); 3823 psFree(where); 3824 } 3825 if (!inputExps) { 3826 psError(PS_ERR_UNKNOWN, false, "no detInputExp rows found"); 3827 return NULL; 3828 } 3829 3830 // find rawImfiles associated with detInputExps 3831 psArray *rawImfiles = NULL; 3832 { 3833 psMetadata *where = psMetadataAlloc(); 3834 for (long i = 0; i < psArrayLength(inputExps); i++) { 3835 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 3836 PS_META_DUPLICATE_OK, "==", 3837 ((detInputExpRow *)inputExps->data[i])->exp_id)) { 3838 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 3839 psFree(inputExps); 3840 psFree(where); 3841 return NULL; 3842 } 3843 } 3844 psFree(inputExps); 3845 rawImfiles = rawImfileSelectRowObjects(config->dbh, where, 0); 3846 // XXX this really should be sorted for uniqueness 3847 psFree(where); 3848 } 3849 if (!rawImfiles) { 3850 psError(PS_ERR_UNKNOWN, false, "no rawImfile rows found"); 3851 return NULL; 3852 } 3853 3854 return rawImfiles; 3855 } 3856 #endif 3857 3858 static bool addnormalizedimfileMode(pxConfig *config) 3859 { 3860 PS_ASSERT_PTR_NON_NULL(config, false); 3861 3862 // make sure that there is a respondoing entry in detNormalizedStatImfile 3863 // select * from detNormalizedStatImfile 3864 // by det_id, iteration, class_id 3865 // where det_id, iteration, class_id is not in detNormalizedImfile 3866 psString query = psStringCopy( 3867 "SELECT" 3868 " detNormalizedStatImfile.*" 3869 " FROM detNormalizedStatImfile" 3870 " LEFT JOIN detNormalizedImfile" 3871 " USING(det_id, iteration, class_id)" 3872 " WHERE" 3873 " detNormalizedImfile.det_id IS NULL" 3874 " AND detNormalizedImfile.iteration IS NULL" 3875 " AND detNormalizedImfile.class_id IS NULL" 3876 ); 3877 3878 { 3879 // build a query to search by det_id, iteration, class_id 3880 psMetadata *where = psMetadataAlloc(); 3881 bool status = false; 3882 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 3883 if (!status) { 3884 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 3885 psFree(where); 3886 psFree(query); 3887 return false; 3888 } 3889 if (det_id) { 3890 if (!psMetadataAddStr(where, PS_LIST_TAIL, "det_id", 0, "==", det_id)) { 3891 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 3892 psFree(where); 3893 psFree(query); 3894 return false; 3895 } 3896 } 3897 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 3898 if (!status) { 3899 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); 3900 psFree(where); 3901 psFree(query); 3902 return false; 3903 } 3904 // always set iteration 3905 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) { 3906 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration"); 3907 psFree(where); 3908 psFree(query); 3909 return false; 3910 } 3911 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id"); 3912 if (!status) { 3913 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id"); 3914 psFree(where); 3915 psFree(query); 3916 return false; 3917 } 3918 if (class_id) { 3919 if (!psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==", class_id)) { 3920 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 3921 psFree(where); 3922 psFree(query); 3923 return false; 3924 } 3925 } 3926 3927 // there's not 3928 psString whereClause = psDBGenerateWhereConditionSQL(where, "detNormalizedStatImfile"); 3929 psFree(where); 3930 if (whereClause) { 3931 psStringAppend(&query, " AND %s", whereClause); 3932 psFree(whereClause); 3933 } 3934 } 3935 3936 if (!p_psDBRunQuery(config->dbh, query)) { 3937 psError(PS_ERR_UNKNOWN, false, "database error"); 3938 psFree(query); 3939 return false; 3940 } 3941 psFree(query); 3942 3943 psArray *output = p_psDBFetchResult(config->dbh); 3944 if (!output) { 3945 psError(PS_ERR_UNKNOWN, false, "database error"); 3946 return false; 3947 } 3948 if (!psArrayLength(output)) { 3949 psTrace("dettool", PS_LOG_INFO, "no rows found"); 3950 psFree(output); 3951 return true; 3952 } 3953 3954 // start a transaction so it's all rows or nothing 3955 if (!psDBTransaction(config->dbh)) { 3956 psError(PS_ERR_UNKNOWN, false, "database error"); 3957 psFree(output); 3958 return false; 3959 } 3960 3961 for (long i = 0; i < psArrayLength(output); i++) { 3962 psMetadata *row = output->data[i]; 3963 // convert metadata into a detNormalizedStatImfile object 3964 detNormalizedStatImfileRow *statImfile = detNormalizedStatImfileObjectFromMetadata(row); 3965 // convert detNormalizedStatImfile object into a detNormalizedImfile 3966 detNormalizedImfileRow *normalizedImfile = detNormalizedStatToDetNormalizedmfile(config, statImfile); 3967 psFree(statImfile); 3968 if (!normalizedImfile) { 3969 if (!psDBRollback(config->dbh)) { 3970 psError(PS_ERR_UNKNOWN, false, "database error"); 3971 } 3972 psError(PS_ERR_UNKNOWN, false, "failed to convert detStackedImfile to detNormalizedStatImfile"); 3973 psFree(output); 3974 return false; 3975 } 3976 // insert detNormlized Stat object into the database 3977 if (!detNormalizedImfileInsertObject(config->dbh, normalizedImfile)) { 3978 if (!psDBRollback(config->dbh)) { 3979 psError(PS_ERR_UNKNOWN, false, "database error"); 3980 } 3981 psError(PS_ERR_UNKNOWN, false, "database error"); 3982 psFree(normalizedImfile); 3983 psFree(output); 3984 } 3985 psFree(normalizedImfile); 3986 } 3987 3988 psFree(output); 3989 3990 if (!psDBCommit(config->dbh)) { 3991 psError(PS_ERR_UNKNOWN, false, "database error"); 3992 return false; 3993 } 3994 3995 return true; 3996 } 3997 3998 3999 static bool normalizedimfileMode(pxConfig *config) 4000 { 4001 PS_ASSERT_PTR_NON_NULL(config, false); 4002 4003 bool status = false; 4004 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 4005 if (!status) { 4006 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 4007 return false; 4008 } 4009 4010 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 4011 if (!status) { 4012 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 4013 return false; 4014 } 4015 4016 psString query = psStringCopy( 4017 "SELECT" 4018 " detNormalizedImfile.*" 4019 " FROM detNormalizedImfile" 4020 " JOIN detRun" 4021 " USING(det_id, iteration)" 4022 " WHERE" 4023 " detRun.state = 'run'" 4024 " AND detRun.mode = 'master'" 4025 ); 4026 4027 if (config->where) { 4028 bool status; 4029 int iteration = psMetadataLookupS32 (&status, config->where, "iteration"); 4030 if (status) { 4031 psMetadataRemoveKey (config->where, "iteration"); 4032 psMetadataAddS32 (config->where, PS_LIST_TAIL, "iteration", 0, "==", iteration); 4033 } 4034 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedImfile"); 4035 psStringAppend(&query, " AND %s", whereClause); 4036 psFree(whereClause); 4037 } 4038 4039 if (faulted) { 4040 // list only faulted rows 4041 psStringAppend(&query, " %s", "AND detNormalizedImfile.fault != 0"); 4042 } else { 4043 // don't list faulted rows 4044 psStringAppend(&query, " %s", "AND detNormalizedImfile.fault = 0"); 4045 } 4046 4047 // treat limit == 0 as "no limit" 4048 if (limit) { 4049 psString limitString = psDBGenerateLimitSQL(limit); 4050 psStringAppend(&query, " %s", limitString); 4051 psFree(limitString); 4052 } 4053 4054 if (!p_psDBRunQuery(config->dbh, query)) { 4055 psError(PS_ERR_UNKNOWN, false, "database error"); 4056 psFree(query); 4057 return false; 4058 } 4059 psFree(query); 4060 4061 psArray *output = p_psDBFetchResult(config->dbh); 4062 if (!output) { 4063 psError(PS_ERR_UNKNOWN, false, "database error"); 4064 return false; 4065 } 4066 if (!psArrayLength(output)) { 4067 psTrace("dettool", PS_LOG_INFO, "no rows found"); 4068 psFree(output); 4069 return true; 4070 } 4071 4072 bool simple = false; 4073 { 4074 bool status = false; 4075 simple = psMetadataLookupBool(&status, config->args, "-simple"); 4076 if (!status) { 4077 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 4078 return false; 4079 } 4080 } 4081 4082 // negative simple so the default is true 4083 if (!ippdbPrintMetadatas(stdout, output, "detNormalizedImfile", !simple)) { 4084 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 4085 psFree(output); 4086 return false; 4087 } 4088 4089 psFree(output); 4090 4091 return true; 4092 } 4093 4094 4095 static bool revertnormalizedimfileMode(pxConfig *config) 4096 { 4097 PS_ASSERT_PTR_NON_NULL(config, false); 4098 4099 psString query = pxDataGet("dettool_revertnormalizedimfile.sql"); 4100 if (!query) { 4101 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 4102 return false; 4103 } 4104 4105 if (config->where) { 4106 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedImfile"); 4107 psStringAppend(&query, " AND %s", whereClause); 4108 psFree(whereClause); 4109 } 4110 4111 if (!p_psDBRunQuery(config->dbh, query)) { 4112 psError(PS_ERR_UNKNOWN, false, "database error"); 4113 psFree(query); 4114 return false; 4115 } 4116 psFree(query); 4117 4118 if (psDBAffectedRows(config->dbh) < 1) { 4119 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 4120 return false; 4121 } 4122 4123 return true; 4124 } 4125 4126 4127 static bool tonormalizedexpMode(pxConfig *config) 4128 { 4129 PS_ASSERT_PTR_NON_NULL(config, false); 4130 4131 bool status = false; 4132 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 4133 if (!status) { 4134 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 4135 return false; 4136 } 4137 4138 psString query = pxDataGet("dettool_tonormalizedexp.sql"); 4139 if (!query) { 4140 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 4141 return false; 4142 } 4143 4144 // XXX does it make sense to accept any search params? 4145 #if 0 4146 if (config->where) { 4147 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 4148 psStringAppend(&query, " AND %s", whereClause); 4149 psFree(whereClause); 4150 } 4151 #endif 4152 4153 // treat limit == 0 as "no limit" 4154 if (limit) { 4155 psString limitString = psDBGenerateLimitSQL(limit); 4156 psStringAppend(&query, " %s", limitString); 4157 psFree(limitString); 4158 } 4159 4160 if (!p_psDBRunQuery(config->dbh, query)) { 4161 psError(PS_ERR_UNKNOWN, false, "database error"); 4162 psFree(query); 4163 return false; 4164 } 4165 psFree(query); 4166 4167 psArray *output = p_psDBFetchResult(config->dbh); 4168 if (!output) { 4169 psError(PS_ERR_UNKNOWN, false, "database error"); 4170 return false; 4171 } 4172 if (!psArrayLength(output)) { 4173 psTrace("dettool", PS_LOG_INFO, "no rows found"); 4174 psFree(output); 4175 return true; 4176 } 4177 4178 bool simple = false; 4179 { 4180 bool status = false; 4181 simple = psMetadataLookupBool(&status, config->args, "-simple"); 4182 if (!status) { 4183 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 4184 return false; 4185 } 4186 } 4187 4188 // negative simple so the default is true 4189 if (!ippdbPrintMetadatas(stdout, output, "detPendingNormExp", !simple)) { 4190 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 4191 psFree(output); 4192 return false; 4193 } 4194 4195 psFree(output); 4196 4197 return true; 4198 } 4199 4200 static bool addnormalizedexpMode(pxConfig *config) 4201 { 4202 PS_ASSERT_PTR_NON_NULL(config, false); 4203 4204 // det_id, recip, -bg, -bg_stdev 4205 // are required 4206 bool status = false; 4207 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 4208 if (!status) { 4209 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 4210 return false; 4211 } 4212 if (!det_id) { 4213 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 4214 return false; 4215 } 4216 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 4217 if (!status) { 4218 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 4219 return false; 4220 } 4221 if (!recipe) { 4222 psError(PS_ERR_UNKNOWN, true, "-recip is required"); 4223 return false; 4224 } 4225 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 4226 if (!status) { 4227 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 4228 return false; 4229 } 4230 //if (isnan(bg)) { 4231 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 4232 // return false; 4233 //} 4234 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 4235 if (!status) { 4236 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 4237 return false; 4238 } 4239 //if (isnan(bg_stdev)) { 4240 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 4241 // return false; 4242 //} 4243 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 4244 if (!status) { 4245 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 4246 return false; 4247 } 4248 4249 // optional 4250 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 4251 if (!status) { 4252 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 4253 return false; 4254 } 4255 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 4256 if (!status) { 4257 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 4258 return false; 4259 } 4260 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 4261 if (!status) { 4262 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 4263 return false; 4264 } 4265 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 4266 if (!status) { 4267 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 4268 return false; 4269 } 4270 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 4271 if (!status) { 4272 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 4273 return false; 4274 } 4275 4276 // iteration has a default value 4277 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 4278 if (!status) { 4279 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); return false; 4280 } 4281 4282 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 4283 if (!status) { 4284 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 4285 return false; 4286 } 4287 4288 // optional 4289 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 4290 if (!status) { 4291 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 4292 return false; 4293 } 4294 4295 psString query = pxDataGet("dettool_tonormalizedexp.sql"); 4296 if (!query) { 4297 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 4298 return false; 4299 } 4300 4301 psStringAppend(&query, 4302 "WHERE det_id = %s" 4303 " AND iteration = %d", det_id, iteration); 4304 4305 4306 if (!p_psDBRunQuery(config->dbh, query)) { 4307 psError(PS_ERR_UNKNOWN, false, "database error"); 4308 psFree(query); 4309 return false; 4310 } 4311 psFree(query); 4312 4313 psArray *output = p_psDBFetchResult(config->dbh); 4314 if (!output) { 4315 psError(PS_ERR_UNKNOWN, false, "database error"); 4316 return false; 4317 } 4318 if (!psArrayLength(output)) { 4319 psTrace("dettool", PS_LOG_INFO, "no rows found"); 4320 psFree(output); 4321 return true; 4322 } 4323 psFree(output); 4324 4325 // create a new detProcessedImfile object 4326 detNormalizedExpRow *detRow = detNormalizedExpRowAlloc( 4327 (psS32)atoll(det_id), 4328 iteration, 4329 recipe, 4330 bg, 4331 bg_stdev, 4332 bg_mean_stdev, 4333 user_1, 4334 user_2, 4335 user_3, 4336 user_4, 4337 user_5, 4338 path_base, 4339 code 4340 ); 4341 4342 // insert the new row into the detProcessedImfile table 4343 if (!detNormalizedExpInsertObject(config->dbh, detRow)) { 4344 psError(PS_ERR_UNKNOWN, false, "database error"); 4345 psFree(detRow); 4346 return false; 4347 } 4348 4349 psFree(detRow); 4350 4351 return true; 4352 } 4353 4354 4355 static bool normalizedexpMode(pxConfig *config) 4356 { 4357 PS_ASSERT_PTR_NON_NULL(config, false); 4358 4359 bool status = false; 4360 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 4361 if (!status) { 4362 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 4363 return false; 4364 } 4365 4366 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 4367 if (!status) { 4368 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 4369 return false; 4370 } 4371 4372 psString query = psStringCopy( 4373 "SELECT" 4374 " detNormalizedExp.*" 4375 " FROM detNormalizedExp" 4376 " JOIN detRun" 4377 " USING(det_id, iteration)" 4378 " WHERE" 4379 " detRun.state = 'run'" 4380 " AND detRun.mode = 'master'" 4381 ); 4382 4383 if (config->where) { 4384 psString whereClause = psDBGenerateWhereSQL(config->where, NULL); 4385 psStringAppend(&query, " %s", whereClause); 4386 psFree(whereClause); 4387 } 4388 4389 if (faulted) { 4390 // list only faulted rows 4391 psStringAppend(&query, " %s", "AND detNormalizedExp.fault != 0"); 4392 } else { 4393 // don't list faulted rows 4394 psStringAppend(&query, " %s", "AND detNormalizedExp.fault = 0"); 4395 } 4396 4397 // treat limit == 0 as "no limit" 4398 if (limit) { 4399 psString limitString = psDBGenerateLimitSQL(limit); 4400 psStringAppend(&query, " %s", limitString); 4401 psFree(limitString); 4402 } 4403 4404 if (!p_psDBRunQuery(config->dbh, query)) { 4405 psError(PS_ERR_UNKNOWN, false, "database error"); 4406 psFree(query); 4407 return false; 4408 } 4409 psFree(query); 4410 4411 psArray *output = p_psDBFetchResult(config->dbh); 4412 if (!output) { 4413 psError(PS_ERR_UNKNOWN, false, "database error"); 4414 return false; 4415 } 4416 if (!psArrayLength(output)) { 4417 psTrace("dettool", PS_LOG_INFO, "no rows found"); 4418 psFree(output); 4419 return true; 4420 } 4421 4422 bool simple = false; 4423 { 4424 bool status = false; 4425 simple = psMetadataLookupBool(&status, config->args, "-simple"); 4426 if (!status) { 4427 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 4428 return false; 4429 } 4430 } 4431 4432 // negative simple so the default is true 4433 if (!ippdbPrintMetadatas(stdout, output, "detNormalizedExp", !simple)) { 4434 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 4435 psFree(output); 4436 return false; 4437 } 4438 4439 psFree(output); 4440 4441 return true; 4442 } 4443 4444 4445 static detNormalizedImfileRow *detNormalizedStatToDetNormalizedmfile(pxConfig *config, detNormalizedStatImfileRow *statImfile) 4446 { 4447 PS_ASSERT_PTR_NON_NULL(config, NULL); 4448 PS_ASSERT_PTR_NON_NULL(statImfile, NULL); 4449 4450 bool status = false; 4451 psString uri = psMetadataLookupStr(&status, config->args, "-uri"); 4452 if (!status) { 4453 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri"); 4454 return false; 4455 } 4456 if (!uri) { 4457 psError(PS_ERR_UNKNOWN, true, "-uri is required"); 4458 return false; 4459 } 4460 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 4461 if (!status) { 4462 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 4463 return false; 4464 } 4465 //if (isnan(bg)) { 4466 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 4467 // return false; 4468 //} 4469 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 4470 if (!status) { 4471 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 4472 return false; 4473 } 4474 //if (isnan(bg_stdev)) { 4475 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 4476 // return false; 4477 //} 4478 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 4479 if (!status) { 4480 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 4481 return false; 4482 } 4483 // optional 4484 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 4485 if (!status) { 4486 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 4487 return false; 4488 } 4489 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 4490 if (!status) { 4491 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 4492 return false; 4493 } 4494 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 4495 if (!status) { 4496 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 4497 return false; 4498 } 4499 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 4500 if (!status) { 4501 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 4502 return false; 4503 } 4504 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 4505 if (!status) { 4506 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 4507 return false; 4508 } 4509 4510 // optional 4511 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 4512 if (!status) { 4513 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 4514 return false; 4515 } 4516 4517 // default values 4518 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 4519 if (!status) { 4520 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 4521 return false; 4522 } 4523 4524 return detNormalizedImfileRowAlloc( 4525 statImfile->det_id, 4526 statImfile->iteration, 4527 statImfile->class_id, 4528 uri, 4529 bg, 4530 bg_stdev, 4531 bg_mean_stdev, 4532 user_1, 4533 user_2, 4534 user_3, 4535 user_4, 4536 user_5, 4537 path_base, 4538 code 4539 ); 4540 } 4541 4542 4543 static bool revertnormalizedexpMode(pxConfig *config) 4544 { 4545 PS_ASSERT_PTR_NON_NULL(config, false); 4546 4547 psString query = pxDataGet("dettool_revertnormalizedexp.sql"); 4548 if (!query) { 4549 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 4550 return false; 4551 } 4552 4553 if (config->where) { 4554 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detNormalizedExp"); 4555 psStringAppend(&query, " AND %s", whereClause); 4556 psFree(whereClause); 4557 } 4558 4559 if (!p_psDBRunQuery(config->dbh, query)) { 4560 psError(PS_ERR_UNKNOWN, false, "database error"); 4561 psFree(query); 4562 return false; 4563 } 4564 psFree(query); 4565 4566 if (psDBAffectedRows(config->dbh) < 1) { 4567 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 4568 return false; 4569 } 4570 4571 return true; 4572 } 4573 4574 4575 static bool toresidimfileMode(pxConfig *config) 4576 { 4577 PS_ASSERT_PTR_NON_NULL(config, false); 4578 4579 bool status = false; 4580 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 4581 if (!status) { 4582 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 4583 return false; 4584 } 4585 4586 psString query = pxDataGet("dettool_toresidimfile.sql"); 4587 if (!query) { 4588 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 4589 return false; 4590 } 4591 4592 // XXX does it make sense to accept any search params? 4593 #if 0 4594 if (config->where) { 4595 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 4596 psStringAppend(&query, " AND %s", whereClause); 4597 psFree(whereClause); 4598 } 4599 #endif 4600 4601 // treat limit == 0 as "no limit" 4602 if (limit) { 4603 psString limitString = psDBGenerateLimitSQL(limit); 4604 psStringAppend(&query, " %s", limitString); 4605 psFree(limitString); 4606 } 4607 4608 if (!p_psDBRunQuery(config->dbh, query)) { 4609 psError(PS_ERR_UNKNOWN, false, "database error"); 4610 psFree(query); 4611 return false; 4612 } 4613 psFree(query); 4614 4615 psArray *output = p_psDBFetchResult(config->dbh); 4616 if (!output) { 4617 psError(PS_ERR_UNKNOWN, false, "database error"); 4618 return false; 4619 } 4620 if (!psArrayLength(output)) { 4621 psTrace("dettool", PS_LOG_INFO, "no rows found"); 4622 psFree(output); 4623 return true; 4624 } 4625 4626 bool simple = false; 4627 { 4628 bool status = false; 4629 simple = psMetadataLookupBool(&status, config->args, "-simple"); 4630 if (!status) { 4631 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 4632 psFree(output); 4633 return false; 4634 } 4635 } 4636 4637 // negative simple so the default is true 4638 if (!ippdbPrintMetadatas(stdout, output, "detPendingResidImfile", !simple)) { 4639 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 4640 psFree(output); 4641 return false; 4642 } 4643 4644 psFree(output); 4645 4646 return true; 4647 } 4648 4649 4650 static bool addresidimfileMode(pxConfig *config) 4651 { 4652 PS_ASSERT_PTR_NON_NULL(config, false); 4653 4654 bool status = false; 4655 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 4656 if (!status) { 4657 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 4658 return false; 4659 } 4660 if (!det_id) { 4661 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 4662 return false; 4663 } 4664 4665 // defaults to 0 4666 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 4667 if (!status) { 4668 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); 4669 return false; 4670 } 4671 4672 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id"); 4673 if (!status) { 4674 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id"); 4675 return false; 4676 } 4677 if (!class_id) { 4678 psError(PS_ERR_UNKNOWN, false, "-class_id is required"); 4679 return false; 4680 } 4681 4682 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id"); 4683 if (!status) { 4684 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id"); 4685 return false; 4686 } 4687 if (!exp_id) { 4688 psError(PS_ERR_UNKNOWN, true, "-exp_id is required"); 4689 return false; 4690 } 4691 psString uri = psMetadataLookupStr(&status, config->args, "-uri"); 4692 if (!status) { 4693 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri"); 4694 return false; 4695 } 4696 if (!uri) { 4697 psError(PS_ERR_UNKNOWN, true, "-uri is required"); 4698 return false; 4699 } 4700 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 4701 if (!status) { 4702 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 4703 return false; 4704 } 4705 if (!recipe) { 4706 psError(PS_ERR_UNKNOWN, true, "-recip is required"); 4707 return false; 4708 } 4709 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 4710 if (!status) { 4711 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 4712 return false; 4713 } 4714 //if (isnan(bg)) { 4715 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 4716 // return false; 4717 //} 4718 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 4719 if (!status) { 4720 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 4721 return false; 4722 } 4723 //if (isnan(bg_stdev)) { 4724 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 4725 // return false; 4726 //} 4727 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 4728 if (!status) { 4729 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 4730 return false; 4731 } 4732 psF64 bg_skewness = psMetadataLookupF64(&status, config->args, "-bg_skewness"); 4733 if (!status) { 4734 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_skewness"); 4735 return false; 4736 } 4737 psF64 bg_kurtosis = psMetadataLookupF64(&status, config->args, "-bg_kurtosis"); 4738 if (!status) { 4739 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_kurtosis"); 4740 return false; 4741 } 4742 psF64 bin_stdev = psMetadataLookupF64(&status, config->args, "-bin_stdev"); 4743 if (!status) { 4744 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bin_stdev"); 4745 return false; 4746 } 4747 4748 // optional 4749 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 4750 if (!status) { 4751 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 4752 return false; 4753 } 4754 4755 // optional 4756 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0"); 4757 if (!status) { 4758 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0"); 4759 return false; 4760 } 4761 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1"); 4762 if (!status) { 4763 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1"); 4764 return false; 4765 } 4766 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2"); 4767 if (!status) { 4768 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2"); 4769 return false; 4770 } 4771 4772 psF64 fringe_resid_0 = psMetadataLookupF64(&status, config->args, "-fringe_resid_0"); 4773 if (!status) { 4774 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_0"); 4775 return false; 4776 } 4777 psF64 fringe_resid_1 = psMetadataLookupF64(&status, config->args, "-fringe_resid_1"); 4778 if (!status) { 4779 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_1"); 4780 return false; 4781 } 4782 psF64 fringe_resid_2 = psMetadataLookupF64(&status, config->args, "-fringe_resid_2"); 4783 if (!status) { 4784 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_2"); 4785 return false; 4786 } 4787 4788 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 4789 if (!status) { 4790 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 4791 return false; 4792 } 4793 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 4794 if (!status) { 4795 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 4796 return false; 4797 } 4798 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 4799 if (!status) { 4800 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 4801 return false; 4802 } 4803 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 4804 if (!status) { 4805 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 4806 return false; 4807 } 4808 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 4809 if (!status) { 4810 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 4811 return false; 4812 } 4813 4814 // default values 4815 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 4816 if (!status) { 4817 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 4818 return false; 4819 } 4820 4821 // create a new detResidImfileRow and insert it 4822 if (!detResidImfileInsert( 4823 config->dbh, 4824 (psS64)atoll(det_id), 4825 iteration, 4826 (psS64)atoll(exp_id), 4827 class_id, 4828 uri, 4829 recipe, 4830 bg, 4831 bg_stdev, 4832 bg_mean_stdev, 4833 bg_skewness, 4834 bg_kurtosis, 4835 bin_stdev, 4836 fringe_0, 4837 fringe_1, 4838 fringe_2, 4839 fringe_resid_0, 4840 fringe_resid_1, 4841 fringe_resid_2, 4842 user_1, 4843 user_2, 4844 user_3, 4845 user_4, 4846 user_5, 4847 path_base, 4848 code 4849 )) { 4850 psError(PS_ERR_UNKNOWN, false, "database error"); 4851 return false; 4852 } 4853 4854 return true; 4855 } 4856 4857 static bool residimfileMode(pxConfig *config) 4858 { 4859 PS_ASSERT_PTR_NON_NULL(config, false); 4860 4861 char *value = NULL; 4862 bool status = false; 4863 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 4864 if (!status) { 4865 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 4866 return false; 4867 } 4868 4869 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 4870 if (!status) { 4871 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 4872 return false; 4873 } 4874 4875 // select detResidImfile.* 4876 // by: 4877 // where det_id, iteration, exp_id is not in detResidExp; 4878 4879 psString query = psStringCopy( 4880 "SELECT" 4881 " detRun.det_type," 4882 " detRun.mode," 4883 " detResidImfile.*," 4884 " rawExp.exp_time" 4885 " FROM detResidImfile" 4886 " JOIN detRun" 4887 " USING(det_id, iteration)" 4888 " JOIN rawExp" 4889 " USING(exp_id)" 4890 " WHERE" 4891 ); 4892 // NOTE the above WHERE is completed with the following line: 4893 4894 // add the two required restrictions: detRun.state and detRun.mode 4895 if ((value = psMetadataLookupStr(&status, config->args, "-select_state"))) { 4896 psStringAppend(&query, " detRun.state = '%s'", value); 4897 } else { 4898 psStringAppend(&query, " detRun.state = 'run'"); 4899 } 4900 4901 if (config->where) { 4902 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidImfile"); 4903 psStringAppend(&query, " AND %s", whereClause); 4904 psFree(whereClause); 4905 } 4906 4907 if (faulted) { 4908 // list only faulted rows 4909 psStringAppend(&query, " %s", "AND detResidImfile.fault != 0"); 4910 } else { 4911 // don't list faulted rows 4912 psStringAppend(&query, " %s", "AND detResidImfile.fault = 0"); 4913 } 4914 4915 // treat limit == 0 as "no limit" 4916 if (limit) { 4917 psString limitString = psDBGenerateLimitSQL(limit); 4918 psStringAppend(&query, " %s", limitString); 4919 psFree(limitString); 4920 } 4921 4922 if (!p_psDBRunQuery(config->dbh, query)) { 4923 psError(PS_ERR_UNKNOWN, false, "database error"); 4924 psFree(query); 4925 return false; 4926 } 4927 psFree(query); 4928 4929 psArray *output = p_psDBFetchResult(config->dbh); 4930 if (!output) { 4931 psError(PS_ERR_UNKNOWN, false, "database error"); 4932 return false; 4933 } 4934 if (!psArrayLength(output)) { 4935 psTrace("dettool", PS_LOG_INFO, "no rows found"); 4936 psFree(output); 4937 return true; 4938 } 4939 4940 bool simple = false; 4941 { 4942 bool status = false; 4943 simple = psMetadataLookupBool(&status, config->args, "-simple"); 4944 if (!status) { 4945 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 4946 psFree(output); 4947 return false; 4948 } 4949 } 4950 4951 // negative simple so the default is true 4952 if (!ippdbPrintMetadatas(stdout, output, "rawResidImfile", !simple)) { 4953 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 4954 psFree(output); 4955 return false; 4956 } 4957 4958 psFree(output); 4959 4960 return true; 4961 } 4962 4963 4964 static bool revertresidimfileMode(pxConfig *config) 4965 { 4966 PS_ASSERT_PTR_NON_NULL(config, false); 4967 4968 psString query = pxDataGet("dettool_revertresidimfile.sql"); 4969 if (!query) { 4970 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 4971 return false; 4972 } 4973 4974 if (config->where) { 4975 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidImfile"); 4976 psStringAppend(&query, " AND %s", whereClause); 4977 psFree(whereClause); 4978 } 4979 4980 if (!p_psDBRunQuery(config->dbh, query)) { 4981 psError(PS_ERR_UNKNOWN, false, "database error"); 4982 psFree(query); 4983 return false; 4984 } 4985 psFree(query); 4986 4987 if (psDBAffectedRows(config->dbh) < 1) { 4988 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 4989 return false; 4990 } 4991 4992 return true; 4993 } 4994 4995 4996 static bool toresidexpMode(pxConfig *config) 4997 { 4998 PS_ASSERT_PTR_NON_NULL(config, false); 4999 5000 /* 5001 which returns a list of exposures for which all component class ids 5002 have had residuals created. This list includes the detrend id, 5003 iteration, exposure id, detrend type, and whether the exposure was 5004 included in the stack for this iteration. 5005 */ 5006 5007 5008 bool status = false; 5009 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 5010 if (!status) { 5011 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 5012 return false; 5013 } 5014 5015 psString query = pxDataGet("dettool_toresidexp.sql"); 5016 if (!query) { 5017 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 5018 return false; 5019 } 5020 5021 // XXX does it make sense to accept any search params? 5022 #if 0 5023 if (config->where) { 5024 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 5025 psStringAppend(&query, " AND %s", whereClause); 5026 psFree(whereClause); 5027 } 5028 #endif 5029 5030 // treat limit == 0 as "no limit" 5031 if (limit) { 5032 psString limitString = psDBGenerateLimitSQL(limit); 5033 psStringAppend(&query, " %s", limitString); 5034 psFree(limitString); 5035 } 5036 5037 if (!p_psDBRunQuery(config->dbh, query)) { 5038 psError(PS_ERR_UNKNOWN, false, "database error"); 5039 psFree(query); 5040 return false; 5041 } 5042 psFree(query); 5043 5044 psArray *output = p_psDBFetchResult(config->dbh); 5045 if (!output) { 5046 psError(PS_ERR_UNKNOWN, false, "database error"); 5047 return false; 5048 } 5049 if (!psArrayLength(output)) { 5050 psTrace("dettool", PS_LOG_INFO, "no rows found"); 5051 psFree(output); 5052 return true; 5053 } 5054 5055 bool simple = false; 5056 { 5057 bool status = false; 5058 simple = psMetadataLookupBool(&status, config->args, "-simple"); 5059 if (!status) { 5060 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 5061 return false; 5062 } 5063 } 5064 5065 // negative simple so the default is true 5066 if (!ippdbPrintMetadatas(stdout, output, "detPendingResidExp", !simple)) { 5067 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 5068 psFree(output); 5069 return false; 5070 } 5071 5072 psFree(output); 5073 5074 return true; 5075 } 5076 5077 static bool addresidexpMode(pxConfig *config) 5078 { 5079 PS_ASSERT_PTR_NON_NULL(config, false); 5080 5081 /* 5082 which returns a list of exposures for which all component class ids 5083 have had residuals created. This list includes the detrend id, 5084 iteration, exposure id, detrend type, and whether the exposure was 5085 included in the stack for this iteration. 5086 */ 5087 5088 5089 // select detRun.det_id 5090 // select detRun.iteration 5091 // select detRun.det_type 5092 // select detInputExp.exp_id 5093 // select detInputExp.include 5094 // by: 5095 // find the current iteration bassed on det_id 5096 // find all exp_ids in the current det_id/iteration from detInputExp 5097 // compare to detInputExp.imfiles to derResidImfile by class_id 5098 // and: 5099 // detResidImfile.{det_id, iteration, exp_id} is not in detResidExp 5100 5101 psString query = pxDataGet("dettool_toresidexp.sql"); 5102 if (!query) { 5103 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 5104 return false; 5105 } 5106 5107 { 5108 // build a query to search by det_id, iteration, exp_id 5109 psMetadata *where = psMetadataAlloc(); 5110 bool status = false; 5111 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 5112 if (!status) { 5113 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 5114 return false; 5115 } 5116 if (!det_id) { 5117 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 5118 return false; 5119 } 5120 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", (psS64)atoll(det_id))) { 5121 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 5122 psFree(where); 5123 psFree(query); 5124 return false; 5125 } 5126 5127 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 5128 if (!status) { 5129 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); 5130 psFree(where); 5131 psFree(query); 5132 return false; 5133 } 5134 // always set iteration 5135 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) { 5136 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration"); 5137 psFree(where); 5138 psFree(query); 5139 return false; 5140 } 5141 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id"); 5142 if (!status) { 5143 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id"); 5144 psFree(where); 5145 psFree(query); 5146 return false; 5147 } 5148 if (exp_id) { 5149 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) { 5150 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 5151 psFree(where); 5152 psFree(query); 5153 return false; 5154 } 5155 } 5156 5157 // there's not 5158 psString whereClause = psDBGenerateWhereConditionSQL(where, NULL); 5159 psFree(where); 5160 if (whereClause) { 5161 psStringAppend(&query, " WHERE %s", whereClause); 5162 psFree(whereClause); 5163 } 5164 } 5165 5166 if (!p_psDBRunQuery(config->dbh, query)) { 5167 psError(PS_ERR_UNKNOWN, false, "database error"); 5168 psFree(query); 5169 return false; 5170 } 5171 psFree(query); 5172 5173 psArray *output = p_psDBFetchResult(config->dbh); 5174 if (!output) { 5175 psError(PS_ERR_UNKNOWN, false, "database error"); 5176 return false; 5177 } 5178 if (!psArrayLength(output)) { 5179 // XXX check psError here 5180 psError(PS_ERR_UNKNOWN, false, "no detResidImfile rows found"); 5181 psFree(output); 5182 return false; 5183 } 5184 5185 // start a transaction so it's all rows or nothing 5186 if (!psDBTransaction(config->dbh)) { 5187 psError(PS_ERR_UNKNOWN, false, "database error"); 5188 psFree(output); 5189 return false; 5190 } 5191 5192 for (long i = 0; i < psArrayLength(output); i++) { 5193 psMetadata *row = output->data[i]; 5194 // convert metadata into a detResidExp object 5195 detResidExpRow *residExp = mdToDetResidExp(config, row); 5196 if (!residExp) { 5197 if (!psDBRollback(config->dbh)) { 5198 psError(PS_ERR_UNKNOWN, false, "database error"); 5199 } 5200 psError(PS_ERR_UNKNOWN, false, "failed to convert metadata to detResidExp"); 5201 psFree(output); 5202 return false; 5203 } 5204 // insert detResidExp object into the database 5205 if (!detResidExpInsertObject(config->dbh, residExp)) { 5206 if (!psDBRollback(config->dbh)) { 5207 psError(PS_ERR_UNKNOWN, false, "database error"); 5208 } 5209 psError(PS_ERR_UNKNOWN, false, "database error"); 5210 psFree(residExp); 5211 psFree(output); 5212 } 5213 psFree(residExp); 5214 } 5215 5216 psFree(output); 5217 5218 if (!psDBCommit(config->dbh)) { 5219 psError(PS_ERR_UNKNOWN, false, "database error"); 5220 return false; 5221 } 5222 5223 return true; 5224 } 5225 5226 static detResidExpRow *mdToDetResidExp(pxConfig *config, psMetadata *row) 5227 { 5228 PS_ASSERT_PTR_NON_NULL(config, NULL); 5229 PS_ASSERT_PTR_NON_NULL(row, NULL); 5230 5231 bool status = false; 5232 // values from row 5233 psS64 det_id = psMetadataLookupS64(&status, row, "det_id"); 5234 if (!status) { 5235 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for det_id"); 5236 return false; 5237 } 5238 //if (isnan(det_id)) { 5239 // psError(PS_ERR_UNKNOWN, true, "det_id is required"); 5240 // return false; 5241 //} 5242 psS32 iteration = psMetadataLookupS32(&status, row, "iteration"); 5243 if (!status) { 5244 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for iteration"); 5245 return false; 5246 } 5247 psS64 exp_id = psMetadataLookupS64(&status, row, "exp_id"); 5248 if (!status) { 5249 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for exp_id"); 5250 return false; 5251 } 5252 if (!exp_id) { 5253 psError(PS_ERR_UNKNOWN, true, "exp_id is required"); 5254 return false; 5255 } 5256 5257 // values from config 5258 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 5259 if (!status) { 5260 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 5261 return false; 5262 } 5263 if (!recipe) { 5264 psError(PS_ERR_UNKNOWN, true, "-recip is required"); 5265 return false; 5266 } 5267 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 5268 if (!status) { 5269 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 5270 return false; 5271 } 5272 //if (isnan(bg)) { 5273 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 5274 // return false; 5275 //} 5276 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 5277 if (!status) { 5278 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 5279 return false; 5280 } 5281 //if (isnan(bg_stdev)) { 5282 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 5283 // return false; 5284 //} 5285 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 5286 if (!status) { 5287 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 5288 return false; 5289 } 5290 psF64 bg_skewness = psMetadataLookupF64(&status, config->args, "-bg_skewness"); 5291 if (!status) { 5292 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_skewness"); 5293 return false; 5294 } 5295 psF64 bg_kurtosis = psMetadataLookupF64(&status, config->args, "-bg_kurtosis"); 5296 if (!status) { 5297 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_kurtosis"); 5298 return false; 5299 } 5300 psF64 bin_stdev = psMetadataLookupF64(&status, config->args, "-bin_stdev"); 5301 if (!status) { 5302 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bin_stdev"); 5303 return false; 5304 } 5305 // optional 5306 psF64 fringe_0 = psMetadataLookupF64(&status, config->args, "-fringe_0"); 5307 if (!status) { 5308 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_0"); 5309 return false; 5310 } 5311 psF64 fringe_1 = psMetadataLookupF64(&status, config->args, "-fringe_1"); 5312 if (!status) { 5313 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_1"); 5314 return false; 5315 } 5316 psF64 fringe_2 = psMetadataLookupF64(&status, config->args, "-fringe_2"); 5317 if (!status) { 5318 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_2"); 5319 return false; 5320 } 5321 5322 psF64 fringe_resid_0 = psMetadataLookupF64(&status, config->args, "-fringe_resid_0"); 5323 if (!status) { 5324 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_0"); 5325 return false; 5326 } 5327 psF64 fringe_resid_1 = psMetadataLookupF64(&status, config->args, "-fringe_resid_1"); 5328 if (!status) { 5329 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_1"); 5330 return false; 5331 } 5332 psF64 fringe_resid_2 = psMetadataLookupF64(&status, config->args, "-fringe_resid_2"); 5333 if (!status) { 5334 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -fringe_resid_2"); 5335 return false; 5336 } 5337 5338 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 5339 if (!status) { 5340 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 5341 return false; 5342 } 5343 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 5344 if (!status) { 5345 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 5346 return false; 5347 } 5348 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 5349 if (!status) { 5350 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 5351 return false; 5352 } 5353 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 5354 if (!status) { 5355 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 5356 return false; 5357 } 5358 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 5359 if (!status) { 5360 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 5361 return false; 5362 } 5363 5364 // optional 5365 bool reject = psMetadataLookupBool(&status, config->args, "-reject"); 5366 if (!status) { 5367 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reject"); 5368 return false; 5369 } 5370 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 5371 if (!status) { 5372 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 5373 return false; 5374 } 5375 if (!path_base) { 5376 psError(PS_ERR_UNKNOWN, true, "-path_base is required"); 5377 return false; 5378 } 5379 5380 // default values 5381 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 5382 if (!status) { 5383 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 5384 return false; 5385 } 5386 5387 // create a new detResidImfileRow and insert it 5388 return detResidExpRowAlloc( 5389 det_id, 5390 iteration, 5391 exp_id, 5392 recipe, 5393 bg, 5394 bg_stdev, 5395 bg_mean_stdev, 5396 bg_skewness, 5397 bg_kurtosis, 5398 bin_stdev, 5399 fringe_0, 5400 fringe_1, 5401 fringe_2, 5402 fringe_resid_0, 5403 fringe_resid_1, 5404 fringe_resid_2, 5405 user_1, 5406 user_2, 5407 user_3, 5408 user_4, 5409 user_5, 5410 path_base, 5411 !reject, 5412 code 5413 ); 5414 } 5415 5416 static bool residexpMode(pxConfig *config) 5417 { 5418 PS_ASSERT_PTR_NON_NULL(config, false); 5419 5420 bool status = false; 5421 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 5422 if (!status) { 5423 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 5424 return false; 5425 } 5426 5427 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 5428 if (!status) { 5429 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 5430 return false; 5431 } 5432 5433 psString query = psStringCopy( 5434 "SELECT" 5435 " detRun.mode," 5436 " detResidExp.*," 5437 " detInputExp.include" 5438 " FROM detRun" 5439 " JOIN detInputExp" 5440 " USING(det_id, iteration)" 5441 " JOIN detResidExp" 5442 " USING(det_id, iteration, exp_id)" 5443 " WHERE" 5444 " detRun.state = 'run'" 5445 ); 5446 5447 if (config->where) { 5448 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidExp"); 5449 psStringAppend(&query, " AND %s", whereClause); 5450 psFree(whereClause); 5451 } 5452 5453 if (faulted) { 5454 // list only faulted rows 5455 psStringAppend(&query, " %s", "AND detResidExp.fault != 0"); 5456 } else { 5457 // don't list faulted rows 5458 psStringAppend(&query, " %s", "AND detResidExp.fault = 0"); 5459 } 5460 5461 // treat limit == 0 as "no limit" 5462 if (limit) { 5463 psString limitString = psDBGenerateLimitSQL(limit); 5464 psStringAppend(&query, " %s", limitString); 5465 psFree(limitString); 5466 } 5467 5468 if (!p_psDBRunQuery(config->dbh, query)) { 5469 psError(PS_ERR_UNKNOWN, false, "database error"); 5470 psFree(query); 5471 return false; 5472 } 5473 psFree(query); 5474 5475 psArray *output = p_psDBFetchResult(config->dbh); 5476 if (!output) { 5477 psError(PS_ERR_UNKNOWN, false, "database error"); 5478 return false; 5479 } 5480 if (!psArrayLength(output)) { 5481 psTrace("dettool", PS_LOG_INFO, "no rows found"); 5482 psFree(output); 5483 return true; 5484 } 5485 5486 bool simple = false; 5487 { 5488 bool status = false; 5489 simple = psMetadataLookupBool(&status, config->args, "-simple"); 5490 if (!status) { 5491 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 5492 return false; 5493 } 5494 } 5495 5496 // negative simple so the default is true 5497 if (!ippdbPrintMetadatas(stdout, output, "detResidExp", !simple)) { 5498 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 5499 psFree(output); 5500 return false; 5501 } 5502 5503 psFree(output); 5504 5505 return true; 5506 } 5507 5508 5509 static bool revertresidexpMode(pxConfig *config) 5510 { 5511 PS_ASSERT_PTR_NON_NULL(config, false); 5512 5513 psString query = pxDataGet("dettool_revertresidexp.sql"); 5514 if (!query) { 5515 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 5516 return false; 5517 } 5518 5519 if (config->where) { 5520 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detResidExp"); 5521 psStringAppend(&query, " AND %s", whereClause); 5522 psFree(whereClause); 5523 } 5524 5525 if (!p_psDBRunQuery(config->dbh, query)) { 5526 psError(PS_ERR_UNKNOWN, false, "database error"); 5527 psFree(query); 5528 return false; 5529 } 5530 psFree(query); 5531 5532 if (psDBAffectedRows(config->dbh) < 1) { 5533 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 5534 return false; 5535 } 5536 5537 return true; 5538 } 5539 5540 5541 static bool todetrunsummaryMode(pxConfig *config) 5542 { 5543 PS_ASSERT_PTR_NON_NULL(config, false); 5544 5545 bool status = false; 5546 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 5547 if (!status) { 5548 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 5549 return false; 5550 } 5551 5552 /* which returns a list of detrend runs (with detrend id, iteration and 5553 * detrend type) which have completed all residexps. 5554 */ 5555 5556 psString query = pxDataGet("dettool_todetrunsummary.sql"); 5557 if (!query) { 5558 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 5559 return false; 5560 } 5561 5562 // XXX does it make sense to accept any search params? 5563 #if 0 5564 if (config->where) { 5565 psString whereClause = psDBGenerateWhereConditionSQL(config->where); 5566 psStringAppend(&query, " AND %s", whereClause); 5567 psFree(whereClause); 5568 } 5569 #endif 5570 5571 // treat limit == 0 as "no limit" 5572 if (limit) { 5573 psString limitString = psDBGenerateLimitSQL(limit); 5574 psStringAppend(&query, " %s", limitString); 5575 psFree(limitString); 5576 } 5577 5578 if (!p_psDBRunQuery(config->dbh, query)) { 5579 psError(PS_ERR_UNKNOWN, false, "database error"); 5580 psFree(query); 5581 return false; 5582 } 5583 psFree(query); 5584 5585 psArray *output = p_psDBFetchResult(config->dbh); 5586 if (!output) { 5587 psError(PS_ERR_UNKNOWN, false, "database error"); 5588 return false; 5589 } 5590 if (!psArrayLength(output)) { 5591 psTrace("dettool", PS_LOG_INFO, "no rows found"); 5592 psFree(output); 5593 return true; 5594 } 5595 5596 bool simple = false; 5597 { 5598 bool status = false; 5599 simple = psMetadataLookupBool(&status, config->args, "-simple"); 5600 if (!status) { 5601 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 5602 return false; 5603 } 5604 } 5605 5606 // negative simple so the default is true 5607 if (!ippdbPrintMetadatas(stdout, output, "detRejectExp", !simple)) { 5608 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 5609 psFree(output); 5610 return false; 5611 } 5612 5613 psFree(output); 5614 5615 return true; 5616 } 5617 5618 static bool updateresidexpMode(pxConfig *config) 5619 { 5620 PS_ASSERT_PTR_NON_NULL(config, false); 5621 5622 // build a query to search by det_id, iteration, exp_id 5623 psMetadata *where = psMetadataAlloc(); 5624 bool status = false; 5625 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 5626 if (!status) { 5627 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 5628 psFree(where); 5629 return false; 5630 } 5631 if (det_id) { 5632 if (!psMetadataAddStr(where, PS_LIST_TAIL, "det_id", 0, "==", det_id)) { 5633 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 5634 psFree(where); 5635 return false; 5636 } 5637 } 5638 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 5639 if (!status) { 5640 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); 5641 psFree(where); 5642 return false; 5643 } 5644 // always where iteration 5645 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) { 5646 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration"); 5647 psFree(where); 5648 return false; 5649 } 5650 psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id"); 5651 if (!status) { 5652 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id"); 5653 psFree(where); 5654 return false; 5655 } 5656 if (exp_id) { 5657 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) { 5658 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 5659 psFree(where); 5660 return false; 5661 } 5662 } 5663 5664 // find the values we're going to set 5665 // copy everything but det_id, iteration, & exp_id from the args and 5666 // remove the '-' prefix 5667 psMetadata *set = psMetadataAlloc(); 5668 psString recipe = psMetadataLookupStr(&status, config->args, "-recip"); 5669 if (!status) { 5670 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip"); 5671 psFree(set); 5672 psFree(where); 5673 return false; 5674 } 5675 if (recipe) { 5676 if (!psMetadataAddStr(set, PS_LIST_TAIL, "recipe", 0, "==", recipe)) { 5677 psError(PS_ERR_UNKNOWN, false, "failed to add item recipe"); 5678 psFree(set); 5679 psFree(where); 5680 return false; 5681 } 5682 } 5683 5684 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 5685 if (!status) { 5686 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 5687 psFree(set); 5688 psFree(where); 5689 return false; 5690 } 5691 if (!isnan(bg)) { 5692 if (!psMetadataAddF64(set, PS_LIST_TAIL, "bg", 0, "==", bg)) { 5693 psError(PS_ERR_UNKNOWN, false, "failed to add item bg"); 5694 psFree(set); 5695 psFree(where); 5696 return false; 5697 } 5698 } 5699 5700 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 5701 if (!status) { 5702 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 5703 psFree(set); 5704 psFree(where); 5705 return false; 5706 } 5707 if (!isnan(bg_stdev)) { 5708 if (!psMetadataAddF64(set, PS_LIST_TAIL, "bg_stdev", 0, "==", bg_stdev)) { 5709 psError(PS_ERR_UNKNOWN, false, "failed to add item bg_stdev"); 5710 psFree(set); 5711 psFree(where); 5712 return false; 5713 } 5714 } 5715 5716 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 5717 if (!status) { 5718 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 5719 psFree(set); 5720 psFree(where); 5721 return false; 5722 } 5723 if (!isnan(bg_mean_stdev)) { 5724 if (!psMetadataAddF64(set, PS_LIST_TAIL, "bg_mean_stdev", 0, "==", bg_mean_stdev)) { 5725 psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev"); 5726 psFree(set); 5727 psFree(where); 5728 return false; 5729 } 5730 } 5731 5732 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 5733 if (!status) { 5734 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 5735 psFree(set); 5736 psFree(where); 5737 return false; 5738 } 5739 if (path_base) { 5740 if (!psMetadataAddStr(set, PS_LIST_TAIL, "path_base", 0, "==", path_base)) { 5741 psError(PS_ERR_UNKNOWN, false, "failed to add item path_base"); 5742 psFree(set); 5743 psFree(where); 5744 return false; 5745 } 5746 } 5747 5748 bool reject = psMetadataLookupBool(&status, config->args, "-reject"); 5749 if (!status) { 5750 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reject"); 5751 psFree(set); 5752 psFree(where); 5753 return false; 5754 } 5755 if (!psMetadataAddBool(set, PS_LIST_TAIL, "accept", 0, "==", !reject)) { 5756 psError(PS_ERR_UNKNOWN, false, "failed to add item accept"); 5757 psFree(set); 5758 psFree(where); 5759 return false; 5760 } 5761 5762 long changed = psDBUpdateRows(config->dbh, "detResidExp", where, set); 5763 psFree(set); 5764 psFree(where); 5765 5766 if (changed < 0) { 5767 psError(PS_ERR_UNKNOWN, false, "no rows were updated"); 5768 return false; 5769 } 5770 5771 return true; 5772 } 5773 5774 static bool adddetrunsummaryMode(pxConfig *config) 5775 { 5776 PS_ASSERT_PTR_NON_NULL(config, false); 5777 5778 // required 5779 bool status = false; 5780 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 5781 if (!status) { 5782 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 5783 return false; 5784 } 5785 if (!det_id) { 5786 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 5787 return false; 5788 } 5789 5790 // optional 5791 bool again = psMetadataLookupBool(&status, config->args, "-again"); 5792 if (!status) { 5793 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -again"); 5794 return false; 5795 } 5796 5797 psString query = pxDataGet("dettool_find_completed_runs.sql"); 5798 if (!query) { 5799 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 5800 return false; 5801 } 5802 5803 { 5804 // build a query to search by det_id, iteration, exp_id 5805 psMetadata *where = psMetadataAlloc(); 5806 bool status = false; 5807 if (det_id) { 5808 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", (psS64)atoll(det_id))) { 5809 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 5810 psFree(where); 5811 psFree(query); 5812 return false; 5813 } 5814 } 5815 psS32 iteration = psMetadataLookupS32(&status, config->args, "-iteration"); 5816 if (!status) { 5817 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -iteration"); 5818 psFree(where); 5819 psFree(query); 5820 return false; 5821 } 5822 // always set iteration 5823 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", iteration)) { 5824 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration"); 5825 psFree(where); 5826 psFree(query); 5827 return false; 5828 } 5829 5830 // there's not 5831 psString whereClause = psDBGenerateWhereConditionSQL(where, NULL); 5832 psFree(where); 5833 if (whereClause) { 5834 psStringAppend(&query, " WHERE %s", whereClause); 5835 psFree(whereClause); 5836 } 5837 } 5838 5839 if (!p_psDBRunQuery(config->dbh, query)) { 5840 psError(PS_ERR_UNKNOWN, false, "database error"); 5841 psFree(query); 5842 return false; 5843 } 5844 psFree(query); 5845 5846 psArray *output = p_psDBFetchResult(config->dbh); 5847 if (!output) { 5848 psError(PS_ERR_UNKNOWN, false, "database error"); 5849 return false; 5850 } 5851 if (!psArrayLength(output)) { 5852 psTrace("dettool", PS_LOG_INFO, "no rows found"); 5853 psFree(output); 5854 return true; 5855 } 5856 5857 // start a transaction so it's all rows or nothing 5858 if (!psDBTransaction(config->dbh)) { 5859 psError(PS_ERR_UNKNOWN, false, "database error"); 5860 psFree(output); 5861 return false; 5862 } 5863 5864 for (long i = 0; i < psArrayLength(output); i++) { 5865 psMetadata *row = output->data[i]; 5866 // convert metadata into a detResidExp object 5867 detRunSummaryRow *runSummary = mdToDetRunSummary(config, row); 5868 if (!runSummary) { 5869 if (!psDBRollback(config->dbh)) { 5870 psError(PS_ERR_UNKNOWN, false, "database error"); 5871 } 5872 psError(PS_ERR_UNKNOWN, false, "failed to convert metadata to detResidExp"); 5873 psFree(output); 5874 return false; 5875 } 5876 // insert detResidExp object into the database 5877 if (!detRunSummaryInsertObject(config->dbh, runSummary)) { 5878 if (!psDBRollback(config->dbh)) { 5879 psError(PS_ERR_UNKNOWN, false, "database error"); 5880 } 5881 psError(PS_ERR_UNKNOWN, false, "database error"); 5882 psFree(runSummary); 5883 psFree(output); 5884 return false; 5885 } 5886 psFree(runSummary); 5887 } 5888 5889 psFree(output); 5890 5891 // XXX this logic does not deal with the case of -code being set 5892 if (again) { 5893 if (!startNewIteration(config, (psS64)atoll(det_id))) { 5894 if (!psDBRollback(config->dbh)) { 5895 psError(PS_ERR_UNKNOWN, false, "database error"); 5896 } 5897 psError(PS_ERR_UNKNOWN, false, "failed to start new iteration"); 5898 return false; 5899 } 5900 } else { 5901 // set detRun.state to stop 5902 if (!setDetRunState(config, (psS64)atoll(det_id), "stop")) { 5903 if (!psDBRollback(config->dbh)) { 5904 psError(PS_ERR_UNKNOWN, false, "database error"); 5905 } 5906 psError(PS_ERR_UNKNOWN, false, "failed to set detRun.state"); 5907 return false; 5908 } 5909 } 5910 5911 if (!psDBCommit(config->dbh)) { 5912 psError(PS_ERR_UNKNOWN, false, "database error"); 5913 return false; 5914 } 5915 return true; 5916 } 5917 5918 static detRunSummaryRow *mdToDetRunSummary(pxConfig *config, psMetadata *row) 5919 { 5920 PS_ASSERT_PTR_NON_NULL(config, false); 5921 5922 bool status = false; 5923 // from row 5924 psS64 det_id = psMetadataLookupS64(&status, row, "det_id"); 5925 if (!status) { 5926 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for det_id"); 5927 return false; 5928 } 5929 psS32 iteration = psMetadataLookupS32(&status, row, "iteration"); 5930 if (!status) { 5931 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for iteration"); 5932 return false; 5933 } 5934 5935 // from config->args 5936 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 5937 if (!status) { 5938 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 5939 return NULL; 5940 } 5941 //if (isnan(bg)) { 5942 // psError(PS_ERR_UNKNOWN, true, "-bg is required"); 5943 // return NULL; 5944 //} 5945 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 5946 if (!status) { 5947 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 5948 return NULL; 5949 } 5950 //if (isnan(bg_stdev)) { 5951 // psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required"); 5952 // return NULL; 5953 //} 5954 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 5955 if (!status) { 5956 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 5957 return NULL; 5958 } 5959 // optional 5960 bool accept = psMetadataLookupBool(&status, config->args, "-accept"); 5961 if (!status) { 5962 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -accept"); 5963 return NULL; 5964 } 5965 // default values 5966 psS16 code = psMetadataLookupS16(&status, config->args, "-code"); 5967 if (!status) { 5968 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code"); 5969 return false; 5970 } 5971 5972 return detRunSummaryRowAlloc( 5973 det_id, 5974 iteration, 5975 bg, 5976 bg_stdev, 5977 bg_mean_stdev, 5978 accept, 5979 code 5980 ); 5981 } 5982 5983 static bool detrunsummaryMode(pxConfig *config) 5984 { 5985 PS_ASSERT_PTR_NON_NULL(config, false); 5986 5987 bool status = false; 5988 psU64 limit = psMetadataLookupU64(&status, config->args, "-limit"); 5989 if (!status) { 5990 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -limit"); 5991 return false; 5992 } 5993 5994 bool faulted = psMetadataLookupU64(&status, config->args, "-faulted"); 5995 if (!status) { 5996 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -faulted"); 5997 return false; 5998 } 5999 6000 psString query = psStringCopy( 6001 "SELECT DISTINCT\n" 6002 " detRunSummary.*,\n" 6003 " detRun.det_type,\n" 6004 " detRun.mode\n" 6005 " FROM detRun\n" 6006 " JOIN detRunSummary\n" 6007 " USING(det_id, iteration)\n" 6008 " WHERE\n" 6009 " detRun.state = 'run'\n" 6010 ); 6011 6012 if (config->where) { 6013 psString whereClause = psDBGenerateWhereConditionSQL(config->where, NULL); 6014 psStringAppend(&query, " AND %s", whereClause); 6015 psFree(whereClause); 6016 } 6017 6018 if (faulted) { 6019 // list only faulted rows 6020 psStringAppend(&query, " %s", "AND detRunSummary.fault != 0"); 6021 } else { 6022 // don't list faulted rows 6023 psStringAppend(&query, " %s", "AND detRunSummary.fault = 0"); 6024 } 6025 6026 // treat limit == 0 as "no limit" 6027 if (limit) { 6028 psString limitString = psDBGenerateLimitSQL(limit); 6029 psStringAppend(&query, " %s", limitString); 6030 psFree(limitString); 6031 } 6032 6033 if (!p_psDBRunQuery(config->dbh, query)) { 6034 psError(PS_ERR_UNKNOWN, false, "database error"); 6035 psFree(query); 6036 return false; 6037 } 6038 psFree(query); 6039 6040 psArray *output = p_psDBFetchResult(config->dbh); 6041 if (!output) { 6042 psError(PS_ERR_UNKNOWN, false, "database error"); 6043 return false; 6044 } 6045 if (!psArrayLength(output)) { 6046 psTrace("dettool", PS_LOG_INFO, "no rows found"); 6047 psFree(output); 6048 return true; 6049 } 6050 6051 bool simple = false; 6052 { 6053 bool status = false; 6054 simple = psMetadataLookupBool(&status, config->args, "-simple"); 6055 if (!status) { 6056 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 6057 return false; 6058 } 6059 } 6060 6061 // negative simple so the default is true 6062 if (!ippdbPrintMetadatas(stdout, output, "rawDetrendImfile", !simple)) { 6063 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 6064 psFree(output); 6065 return false; 6066 } 6067 6068 psFree(output); 6069 6070 return true; 6071 } 6072 6073 6074 static bool revertdetrunsummaryMode(pxConfig *config) 6075 { 6076 PS_ASSERT_PTR_NON_NULL(config, false); 6077 6078 psString query = pxDataGet("dettool_revertdetrunsummary.sql"); 6079 if (!query) { 6080 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 6081 return false; 6082 } 6083 6084 if (config->where) { 6085 psString whereClause = psDBGenerateWhereConditionSQL(config->where, "detRunSummary"); 6086 psStringAppend(&query, " AND %s", whereClause); 6087 psFree(whereClause); 6088 } 6089 6090 if (!p_psDBRunQuery(config->dbh, query)) { 6091 psError(PS_ERR_UNKNOWN, false, "database error"); 6092 psFree(query); 6093 return false; 6094 } 6095 psFree(query); 6096 6097 if (psDBAffectedRows(config->dbh) < 1) { 6098 psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row"); 6099 return false; 6100 } 6101 6102 return true; 6103 } 6104 6105 6106 static bool updatedetrunMode(pxConfig *config) 6107 { 6108 PS_ASSERT_PTR_NON_NULL(config, false); 6109 6110 // det_id is required 6111 // XXX this isn't strictly nessicary but not having the det_id complicates 6112 // incrementing the iteration number 6113 bool status = false; 6114 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 6115 if (!status) { 6116 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 6117 return false; 6118 } 6119 if (!det_id) { 6120 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 6121 return false; 6122 } 6123 // either -rerun or -state must be specified 6124 bool again = psMetadataLookupBool(&status, config->args, "-again"); 6125 if (!status) { 6126 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -again"); 6127 return false; 6128 } 6129 psString state = psMetadataLookupStr(&status, config->args, "-state"); 6130 if (!status) { 6131 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -state"); 6132 return false; 6133 } 6134 if (!(again || state)) { 6135 psError(PS_ERR_UNKNOWN, true, "either -again or -state must be specified"); 6136 return false; 6137 } 6138 if (again && state) { 6139 psError(PS_ERR_UNKNOWN, true, "either -again or -state must be specified"); 6140 return false; 6141 } 6142 6143 if (state) { 6144 // set detRun.state to state 6145 return setDetRunState(config, (psS64)atoll(det_id), state); 6146 } 6147 6148 // else 6149 // -again 6150 if (!startNewIteration(config, (psS64)atoll(det_id))) { 6151 psError(PS_ERR_UNKNOWN, false, "failed to start new iteration"); 6152 return false; 6153 } 6154 6155 return true; 6156 } 6157 6158 static bool startNewIteration(pxConfig *config, psS64 det_id) 6159 { 6160 PS_ASSERT_PTR_NON_NULL(config, false); 6161 6162 psString query = pxDataGet("dettool_start_new_iteration.sql"); 6163 if (!query) { 6164 psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement"); 6165 return false; 6166 } 6167 6168 // XXX this query was not restricted by det_id, resulting 6169 // in an inconsistent UPDATE below. I added this AND clause 6170 // though there may be a cleaner method (EAM 2006.10.08) 6171 psStringAppend(&query, " WHERE det_id = %" PRId64 , det_id); 6172 6173 if (!p_psDBRunQuery(config->dbh, query)) { 6174 psError(PS_ERR_UNKNOWN, false, "database error"); 6175 psFree(query); 6176 return false; 6177 } 6178 psFree(query); 6179 6180 psArray *output = p_psDBFetchResult(config->dbh); 6181 if (!output) { 6182 psError(PS_ERR_UNKNOWN, false, "database error"); 6183 return false; 6184 } 6185 if (!psArrayLength(output)) { 6186 psError(PS_ERR_UNKNOWN, false, "det_id %" PRId64 " not found", det_id); 6187 psFree(output); 6188 return false; 6189 } 6190 6191 // start a transaction so we don't end up with an incremented iteration 6192 // count but no detInputExps 6193 if (!psDBTransaction(config->dbh)) { 6194 psError(PS_ERR_UNKNOWN, false, "database error"); 6195 psFree(output); 6196 return false; 6197 } 6198 6199 // up the detRuns iteration count for for the single det_id we are 6200 // operating on 6201 // XXX this will have to changed in order to support multiple det_ids with 6202 // a single invocation of this functions 6203 psS32 newIteration = incrementIteration(config, det_id); 6204 if (!newIteration) { 6205 // rollback 6206 if (!psDBRollback(config->dbh)) { 6207 psError(PS_ERR_UNKNOWN, false, "database error"); 6208 } 6209 psFree(output); 6210 return false; 6211 } 6212 6213 for (long i = 0; i < psArrayLength(output); i++) { 6214 psMetadata *row = output->data[i]; 6215 bool status = false; 6216 psS64 exp_id = psMetadataLookupS64(&status, row, "exp_id"); 6217 if (!status) { 6218 // rollback 6219 if (!psDBRollback(config->dbh)) { 6220 psError(PS_ERR_UNKNOWN, false, "database error"); 6221 } 6222 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for exp_id"); 6223 psFree(output); 6224 return false; 6225 } 6226 bool accept = psMetadataLookupBool(&status, row, "accept"); 6227 if (!status) { 6228 // rollback 6229 if (!psDBRollback(config->dbh)) { 6230 psError(PS_ERR_UNKNOWN, false, "database error"); 6231 } 6232 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for accept"); 6233 psFree(output); 6234 return false; 6235 } 6236 6237 // detResidExp.include is used to set detInputExp.include 6238 if (!detInputExpInsert( 6239 config->dbh, 6240 det_id, 6241 newIteration, 6242 exp_id, 6243 accept 6244 ) 6245 ) { 6246 // rollback 6247 if (!psDBRollback(config->dbh)) { 6248 psError(PS_ERR_UNKNOWN, false, "database error"); 6249 } 6250 psError(PS_ERR_UNKNOWN, false, "database error"); 6251 psFree(output); 6252 return false; 6253 } 6254 } 6255 6256 psFree(output); 6257 6258 // point of no return for det_id creation 6259 if (!psDBCommit(config->dbh)) { 6260 psError(PS_ERR_UNKNOWN, false, "database error"); 6261 return false; 6262 } 6263 6264 return true; 6265 } 6266 6267 static bool rerunMode(pxConfig *config) 6268 { 6269 PS_ASSERT_PTR_NON_NULL(config, false); 6270 6271 // det_id is required 6272 bool status = false; 6273 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 6274 if (!status) { 6275 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 6276 return false; 6277 } 6278 if (!det_id) { 6279 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 6280 return false; 6281 } 6282 6283 // we have to support multipe exp_ids 6284 psMetadataItem *item = psMetadataLookup(config->args, "-exp_id"); 6285 if (!item) { 6286 // this shouldn't actually happen when using psArgs 6287 psError(PS_ERR_UNKNOWN, true, "-exp_id is required"); 6288 return false; 6289 } 6290 6291 psList *exp_id_list = item->data.list; 6292 psMetadata *where = psMetadataAlloc(); 6293 // make sure that -exp_id was parsed correctly 6294 // XXX this can be removed someday 6295 if (item->type == PS_DATA_METADATA_MULTI) { 6296 psListIterator *iter = psListIteratorAlloc(item->data.list, 0, false); 6297 psMetadataItem *mItem = NULL; 6298 while ((mItem = psListGetAndIncrement(iter))) { 6299 psString exp_id = mItem->data.V; 6300 // if exp_id is NULL then it means that -exp_id has not been 6301 // specified 6302 if (!exp_id) { 6303 psError(PS_ERR_UNKNOWN, true, 6304 "at least one -exp_id is required"); 6305 psFree(where); 6306 return false; 6307 } 6308 6309 if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 6310 PS_META_DUPLICATE_OK, "==", exp_id)) { 6311 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id"); 6312 psFree(iter); 6313 psFree(where); 6314 return false; 6315 } 6316 } 6317 psFree(iter); 6318 } else { 6319 psAbort("-exp_id was not parsed correctly (this should not happen"); 6320 } 6321 6322 // check that the specified exp_ids actually exist in the iteration zero 6323 // detInputExp set 6324 6325 // add the det_id & iteration == 0 to the where clause 6326 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", 6327 (psS64)atoll(det_id))) { 6328 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 6329 psFree(where); 6330 return false; 6331 } 6332 if (!psMetadataAddS32(where, PS_LIST_TAIL, "iteration", 0, "==", 0)) { 6333 psError(PS_ERR_UNKNOWN, false, "failed to add item iteration"); 6334 psFree(where); 6335 return false; 6336 } 6337 6338 psArray *detrendExps = detInputExpSelectRowObjects(config->dbh, where, 0); 6339 psFree(where); 6340 if (!detrendExps) { 6341 psError(PS_ERR_UNKNOWN, false, "no rawExp rows found"); 6342 psFree(where); 6343 return false; 6344 } 6345 6346 // build a hash for the valid exp_ids 6347 psHash *valid_exp_ids = psHashAlloc(psArrayLength(detrendExps)); 6348 for (long i = 0; i < psArrayLength(detrendExps); i++) { 6349 psString exp_idStr = psDBIntToString(((detInputExpRow *)detrendExps->data[i])->exp_id); 6350 psHashAdd(valid_exp_ids, exp_idStr, detrendExps->data[i]); 6351 psFree(exp_idStr); 6352 } 6353 psFree(detrendExps); 6354 6355 // start a transaction so we don't end up with an incremented iteration 6356 // count but no detInputExps 6357 if (!psDBTransaction(config->dbh)) { 6358 psError(PS_ERR_UNKNOWN, false, "database error"); 6359 psFree(valid_exp_ids); 6360 return false; 6361 } 6362 6363 // up the detRuns iteration count 6364 psS32 newIteration = incrementIteration(config, (psS64)atoll(det_id)); 6365 if (!newIteration) { 6366 // rollback 6367 if (!psDBRollback(config->dbh)) { 6368 psError(PS_ERR_UNKNOWN, false, "database error"); 6369 } 6370 psFree(valid_exp_ids); 6371 return false; 6372 } 6373 6374 // check exp_ids and build up an array of new detInputExp rows at the same 6375 // time 6376 psListIterator *iter = psListIteratorAlloc(exp_id_list, 0, false); 6377 psMetadataItem *mItem = NULL; 6378 psArray *newInputExps = psArrayAllocEmpty(psListLength(exp_id_list)); 6379 while ((mItem = psListGetAndIncrement(iter))) { 6380 detInputExpRow *inputExp = psHashLookup(valid_exp_ids, 6381 (char *)mItem->data.V); 6382 if (!inputExp) { 6383 // rollback 6384 if (!psDBRollback(config->dbh)) { 6385 psError(PS_ERR_UNKNOWN, false, "database error"); 6386 } 6387 // invalid exp_id 6388 psError(PS_ERR_UNKNOWN, false, "exp_id %s is invalid for det_id %s", 6389 (char *)mItem->data.V, det_id); 6390 psFree(iter); 6391 psFree(valid_exp_ids); 6392 return false; 6393 } 6394 detInputExpRow *newInputExp = detInputExpRowAlloc( 6395 (psS64)atoll(det_id), 6396 newIteration, 6397 inputExp->exp_id, 6398 true // use 6399 ); 6400 psArrayAdd(newInputExps, 0, newInputExp); 6401 psFree(newInputExp); 6402 } 6403 psFree(iter); 6404 psFree(valid_exp_ids); 6405 6406 for (long i = 0; i < psArrayLength(newInputExps); i++) { 6407 if (!detInputExpInsertObject(config->dbh, newInputExps->data[i])) { 6408 psError(PS_ERR_UNKNOWN, false, "database error"); 6409 // rollback 6410 if (!psDBRollback(config->dbh)) { 6411 psError(PS_ERR_UNKNOWN, false, "database error"); 6412 } 6413 psFree(newInputExps); 6414 return false; 6415 } 6416 } 6417 psFree(newInputExps); 6418 6419 // point of no return for det_id creation 6420 if (!psDBCommit(config->dbh)) { 6421 psError(PS_ERR_UNKNOWN, false, "database error"); 6422 return false; 6423 } 6424 6425 return true; 6426 } 6427 6428 static bool register_detrendMode(pxConfig *config) 6429 { 6430 PS_ASSERT_PTR_NON_NULL(config, false); 6431 6432 // required options 6433 bool status = false; 6434 psString det_type = psMetadataLookupStr(&status, config->args, "-det_type"); 6435 if (!status) { 6436 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_type"); 6437 return false; 6438 } 6439 if (!det_type) { 6440 psError(PS_ERR_UNKNOWN, true, "-det_type is required"); 6441 return false; 6442 } 6443 6444 psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel"); 6445 if (!status) { 6446 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel"); 6447 return false; 6448 } 6449 if (!filelevel) { 6450 psError(PS_ERR_UNKNOWN, true, "-filelevel is required"); 6451 return false; 6452 } 6453 6454 psString workdir = psMetadataLookupStr(&status, config->args, "-workdir"); 6455 if (!status) { 6456 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir"); 6457 return false; 6458 } 6459 6460 psString camera = psMetadataLookupStr(&status, config->args, "-inst"); 6461 if (!status) { 6462 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst"); 6463 return false; 6464 } 6465 6466 psString telescope = psMetadataLookupStr(&status, config->args, "-telescope"); 6467 if (!status) { 6468 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope"); 6469 return false; 6470 } 6471 6472 psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type"); 6473 if (!status) { 6474 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type"); 6475 return false; 6476 } 6477 6478 psString filter = psMetadataLookupStr(&status, config->args, "-filter"); 6479 if (!status) { 6480 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter"); 6481 return false; 6482 } 6483 6484 psF32 airmass_min = psMetadataLookupF32(&status, config->args, "-airmass_min"); 6485 if (!status) { 6486 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_min"); 6487 return false; 6488 } 6489 6490 psF32 airmass_max = psMetadataLookupF32(&status, config->args, "-airmass_max"); 6491 if (!status) { 6492 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass_max"); 6493 return false; 6494 } 6495 6496 psF32 exp_time_min = psMetadataLookupF32(&status, config->args, "-exp_time_min"); 6497 if (!status) { 6498 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_min"); 6499 return false; 6500 } 6501 6502 psF32 exp_time_max = psMetadataLookupF32(&status, config->args, "-exp_time_max"); 6503 if (!status) { 6504 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time_max"); 6505 return false; 6506 } 6507 6508 psF32 ccd_temp_min = psMetadataLookupF32(&status, config->args, "-ccd_temp_min"); 6509 if (!status) { 6510 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_min"); 6511 return false; 6512 } 6513 6514 psF32 ccd_temp_max = psMetadataLookupF32(&status, config->args, "-ccd_temp_max"); 6515 if (!status) { 6516 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp_max"); 6517 return false; 6518 } 6519 6520 psF64 posang_min = psMetadataLookupF32(&status, config->args, "-posang_min"); 6521 if (!status) { 6522 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_min"); 6523 return false; 6524 } 6525 6526 psF64 posang_max = psMetadataLookupF32(&status, config->args, "-posang_max"); 6527 if (!status) { 6528 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang_max"); 6529 return false; 6530 } 6531 6532 psF64 solang_min = psMetadataLookupF32(&status, config->args, "-solang_min"); 6533 if (!status) { 6534 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_min"); 6535 return false; 6536 } 6537 6538 psF64 solang_max = psMetadataLookupF32(&status, config->args, "-solang_max"); 6539 if (!status) { 6540 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -solang_max"); 6541 return false; 6542 } 6543 6544 psTime *registered = NULL; 6545 { 6546 psString registeredStr = psMetadataLookupStr(&status, config->args, "-registered"); 6547 if (!status) { 6548 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -registered"); 6549 return false; 6550 } 6551 // pass through NULL as this is an optional field 6552 if (registeredStr) { 6553 registered = psTimeFromISO(registeredStr, PS_TIME_UTC); 6554 } else { 6555 registered = NULL; 6556 } 6557 } 6558 6559 psTime *time_begin = NULL; 6560 { 6561 psString time_beginStr = psMetadataLookupStr(&status, config->args, "-time_begin"); 6562 if (!status) { 6563 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_begin"); 6564 return false; 6565 } 6566 // pass through NULL as this is an optional field 6567 if (time_beginStr) { 6568 time_begin = psTimeFromISO(time_beginStr, PS_TIME_UTC); 6569 } else { 6570 time_begin = NULL; 6571 } 6572 } 6573 6574 psTime *time_end = NULL; 6575 { 6576 psString time_endStr = psMetadataLookupStr(&status, config->args, "-time_end"); 6577 if (!status) { 6578 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -time_end"); 6579 return false; 6580 } 6581 // pass through NULL as this is an optional field 6582 if (time_endStr) { 6583 time_end = psTimeFromISO(time_endStr, PS_TIME_UTC); 6584 } else { 6585 time_end = NULL; 6586 } 6587 } 6588 6589 psTime *use_begin = NULL; 6590 { 6591 psString use_beginStr = psMetadataLookupStr(&status, config->args, "-use_begin"); 6592 if (!status) { 6593 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_begin"); 6594 return false; 6595 } 6596 // pass through NULL as this is an optional field 6597 if (use_beginStr) { 6598 use_begin = psTimeFromISO(use_beginStr, PS_TIME_UTC); 6599 } else { 6600 use_begin = NULL; 6601 } 6602 } 6603 6604 psTime *use_end = NULL; 6605 { 6606 psString use_endStr = psMetadataLookupStr(&status, config->args, "-use_end"); 6607 if (!status) { 6608 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -use_end"); 6609 return false; 6610 } 6611 // pass through NULL as this is an optional field 6612 if (use_endStr) { 6613 use_end = psTimeFromISO(use_endStr, PS_TIME_UTC); 6614 } else { 6615 use_end = NULL; 6616 } 6617 } 6618 6619 psString parent = psMetadataLookupStr(&status, config->args, "-parent"); 6620 if (!status) { 6621 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -parent"); 6622 return false; 6623 } 6624 6625 psString label = psMetadataLookupStr(&status, config->args, "-label"); 6626 if (!status) { 6627 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label"); 6628 return false; 6629 } 6630 6631 if (!psDBTransaction(config->dbh)) { 6632 psError(PS_ERR_UNKNOWN, false, "database error"); 6633 return false; 6634 } 6635 6636 if (!detRunInsert(config->dbh, 6637 0, // det_id 6638 0, // the iteration is fixed at 0 6639 det_type, 6640 "register", // mode 6641 "register", // state 6642 filelevel, 6643 workdir, 6644 camera, 6645 telescope, 6646 exp_type, 6647 NULL, 6648 filter, 6649 airmass_min, 6650 airmass_max, 6651 exp_time_min, 6652 exp_time_max, 6653 ccd_temp_min, 6654 ccd_temp_max, 6655 posang_min, 6656 posang_max, 6657 registered, 6658 time_begin, 6659 time_end, 6660 use_begin, 6661 use_end, 6662 solang_min, 6663 solang_max, 6664 label, // label 6665 parent ? (psS64)atoll(parent) : 0 6666 )) { 6667 psError(PS_ERR_UNKNOWN, false, "database error"); 6668 // rollback 6669 if (!psDBRollback(config->dbh)) { 6670 psError(PS_ERR_UNKNOWN, false, "database error"); 6671 } 6672 psFree(registered); 6673 return false; 6674 } 6675 psFree(registered); 6676 6677 // print the new detRun 6678 psS64 det_id = psDBLastInsertID(config->dbh); 6679 6680 if (!psDBCommit(config->dbh)) { 6681 psError(PS_ERR_UNKNOWN, false, "database error"); 6682 return false; 6683 } 6684 6685 psArray *detRuns = NULL; 6686 { 6687 psMetadata *where = psMetadataAlloc(); 6688 psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id); 6689 detRuns = psDBSelectRows(config->dbh, "detRun", where, 0); 6690 psFree(where); 6691 } 6692 if (!detRuns) { 6693 psError(PS_ERR_UNKNOWN, false, "can't find the detRun we just created"); 6694 return false; 6695 } 6696 // sanity check results 6697 if (psArrayLength(detRuns) != 1) { 6698 psAbort("found more then one detRun matching det_id %" PRId64 "(this should not happen)", det_id); 6699 return false; 6700 } 6701 6702 if (!convertIdToStr(detRuns)) { 6703 psError(PS_ERR_UNKNOWN, false, "failed to convert id fields into a strings"); 6704 psFree(detRuns); 6705 return false; 6706 } 6707 6708 bool simple = false; 6709 { 6710 bool status = false; 6711 simple = psMetadataLookupBool(&status, config->args, "-simple"); 6712 if (!status) { 6713 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple"); 6714 return false; 6715 } 6716 } 6717 6718 // negative simple so the default is true 6719 if (!ippdbPrintMetadatas(stdout, detRuns, "detRun", !simple)) { 6720 psError(PS_ERR_UNKNOWN, false, "failed to print array"); 6721 psFree(detRuns); 6722 return false; 6723 } 6724 psFree(detRuns); 6725 6726 return true; 6727 } 6728 6729 static bool register_detrend_imfileMode(pxConfig *config) 6730 { 6731 PS_ASSERT_PTR_NON_NULL(config, false); 6732 6733 // required options 6734 bool status = false; 6735 psString det_id = psMetadataLookupStr(&status, config->args, "-det_id"); 6736 if (!status) { 6737 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id"); 6738 return false; 6739 } 6740 if (!det_id) { 6741 psError(PS_ERR_UNKNOWN, true, "-det_id is required"); 6742 return false; 6743 } 6744 6745 psString class_id = psMetadataLookupStr(&status, config->args, "-class_id"); 6746 if (!status) { 6747 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id"); 6748 return false; 6749 } 6750 if (!class_id) { 6751 psError(PS_ERR_UNKNOWN, true, "-class_id is required"); 6752 return false; 6753 } 6754 6755 psString uri = psMetadataLookupStr(&status, config->args, "-uri"); 6756 if (!status) { 6757 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri"); 6758 return false; 6759 } 6760 if (!uri) { 6761 psError(PS_ERR_UNKNOWN, true, "-uri is required"); 6762 return false; 6763 } 6764 6765 // everything else is optional 6766 psF64 bg = psMetadataLookupF64(&status, config->args, "-bg"); 6767 if (!status) { 6768 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg"); 6769 return false; 6770 } 6771 6772 psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev"); 6773 if (!status) { 6774 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev"); 6775 return false; 6776 } 6777 6778 psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev"); 6779 if (!status) { 6780 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev"); 6781 return false; 6782 } 6783 6784 psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1"); 6785 if (!status) { 6786 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1"); 6787 return false; 6788 } 6789 psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2"); 6790 if (!status) { 6791 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2"); 6792 return false; 6793 } 6794 psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3"); 6795 if (!status) { 6796 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3"); 6797 return false; 6798 } 6799 psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4"); 6800 if (!status) { 6801 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4"); 6802 return false; 6803 } 6804 psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5"); 6805 if (!status) { 6806 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5"); 6807 return false; 6808 } 6809 6810 psString path_base = psMetadataLookupStr(&status, config->args, "-path_base"); 6811 if (!status) { 6812 psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -path_base"); 6813 return false; 6814 } 6815 6816 if (!detRegisteredImfileInsert(config->dbh, 6817 (psS64)atoll(det_id), 6818 0, // the iteration is fixed at 0 6819 class_id, 6820 uri, 6821 bg, 6822 bg_stdev, 6823 bg_mean_stdev, 6824 user_1, 6825 user_2, 6826 user_3, 6827 user_4, 6828 user_5, 6829 path_base, 6830 0 // fault code 6831 )) { 6832 psError(PS_ERR_UNKNOWN, false, "database error"); 6833 return false; 6834 } 6835 6836 return true; 6837 } 6838 6839 static psS32 incrementIteration(pxConfig *config, psS64 det_id) 6840 { 6841 // this function returns zero on error 6842 PS_ASSERT_PTR_NON_NULL(config, 0); 6843 6844 char *query = "UPDATE detRun SET iteration = iteration + 1 WHERE det_id = %" PRId64; 6845 if (!p_psDBRunQuery(config->dbh, query, det_id)) { 6846 psError(PS_ERR_UNKNOWN, false, 6847 "failed to increment iteration for det_id %" PRId64, det_id); 6848 return 0; 6849 } 6850 6851 psMetadata *where = psMetadataAlloc(); 6852 if (!psMetadataAddS64(where, PS_LIST_TAIL, "det_id", 0, "==", det_id)) { 6853 psError(PS_ERR_UNKNOWN, false, "failed to add item det_id"); 6854 psFree(where); 6855 return 0; 6856 } 6857 6858 psArray *detRuns = detRunSelectRowObjects(config->dbh, where, 0); 6859 psFree(where); 6860 if (!detRuns) { 6861 psError(PS_ERR_UNKNOWN, false, "no detRun rows found"); 6862 return 0; 6863 } 6864 6865 // sanity check the database 6866 if (psArrayLength(detRuns) != 1) { 6867 // this should no happen 6868 psAbort( "database query return too many rows (this should not happen"); 6869 } 6870 6871 psS32 newIteration = ((detRunRow *)detRuns->data[0])->iteration; 6872 psFree(detRuns); 6873 6874 return newIteration; 6875 } 6876 6877 static bool setDetRunState(pxConfig *config, psS64 det_id, const char *state) 6878 { 6879 PS_ASSERT_PTR_NON_NULL(config, false); 6880 PS_ASSERT_PTR_NON_NULL(state, false); 6881 6882 // check that state is a valid string value 6883 if (!( 6884 (strncmp(state, "run", 4) == 0) 6885 || (strncmp(state, "stop", 5) == 0) 6886 || (strncmp(state, "drop", 5) == 0) 6887 || (strncmp(state, "register", 4) == 0) 6888 ) 6889 ) { 6890 psError(PS_ERR_UNKNOWN, false, 6891 "invalid detRun state: %s", state); 6892 return false; 6893 } 6894 6895 char *query = "UPDATE detRun SET state = '%s' WHERE det_id = %" PRId64; 6896 if (!p_psDBRunQuery(config->dbh, query, state, det_id)) { 6897 psError(PS_ERR_UNKNOWN, false, 6898 "failed to change state for det_id %" PRId64, det_id); 6899 return false; 6900 } 6901 6902 return true; 6903 } 6904 6905 static bool isValidMode(pxConfig *config, const char *mode) 6906 { 6907 PS_ASSERT_PTR_NON_NULL(config, false); 6908 PS_ASSERT_PTR_NON_NULL(mode, false); 6909 6910 // check that state is a valid string value 6911 if (!( 6912 (strncmp(mode, "master", 7) == 0) 6913 || (strncmp(mode, "verify", 7) == 0) 6914 ) 6915 ) { 6916 psError(PS_ERR_UNKNOWN, false, 6917 "invalid detRun mode: %s", mode); 6918 return false; 6919 } 6920 6921 return true; 6922 } 35 #endif // CALTOOL_H -
trunk/ippTools/src/caltoolConfig.c
r15537 r15545 1 1 /* 2 * dettoolConfig.c2 * caltoolConfig.c 3 3 * 4 * Copyright (C) 2006 Joshua Hoblitt4 * Copyright (C) 2006-2007 Joshua Hoblitt 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify it … … 25 25 26 26 #include "pxtools.h" 27 #include " dettool.h"27 #include "caltool.h" 28 28 29 pxConfig * dettoolConfig(pxConfig *config, int argc, char **argv)29 pxConfig *caltoolConfig(pxConfig *config, int argc, char **argv) 30 30 { 31 31 if (!config) { … … 47 47 psFree(time); 48 48 49 // -pending 50 psMetadata *pendingArgs = psMetadataAlloc(); 51 psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-exp_id", 0, 52 "search by exposure ID", NULL); 53 psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-exp_type", 0, 54 "search by exposure type", NULL); 55 psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-inst", 0, 56 "search by camera", NULL); 57 psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-telescope", 0, 58 "search by telescope", NULL); 59 psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-filter", 0, 60 "search by filter", NULL); 61 psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-uri", 0, 62 "search by URL", NULL); 63 psMetadataAddBool(pendingArgs, PS_LIST_TAIL, "-simple", 0, 49 // -adddb 50 psMetadata *adddbArgs = psMetadataAlloc(); 51 psMetadataAddStr(adddbArgs, PS_LIST_TAIL, "-dvodb", 0, 52 "define DVO db", NULL); 53 54 // -dbs 55 psMetadata *dbsArgs = psMetadataAlloc(); 56 psMetadataAddU64(dbsArgs, PS_LIST_TAIL, "-limit", 0, 57 "limit result set to N items", 0); 58 psMetadataAddBool(dbsArgs, PS_LIST_TAIL, "-simple", 0, 64 59 "use the simple output format", false); 65 60 66 // -definebytag 67 psMetadata *definebytagArgs = psMetadataAlloc(); 68 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-exp_id", 69 PS_META_DUPLICATE_OK, 70 "include this exposure (multiple OK, required)", NULL); 71 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-det_type", 0, 72 "define the type of detrend run (required)", NULL); 73 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-mode", 0, 74 "define the mode of this detrend run", "master"); 75 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-filelevel", 0, 76 "define filelevel", NULL); 77 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-workdir", 0, 78 "define workdir (required)", NULL); 79 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-inst", 0, 80 "define camera", NULL); 81 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-telescope", 0, 82 "define telescope", NULL); 83 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-exp_type", 0, 84 "define exposure type", NULL); 85 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-filter", 0, 86 "define filter ", NULL); 87 psMetadataAddF32(definebytagArgs, PS_LIST_TAIL, "-airmass_min", 0, 88 "define min airmass", NAN); 89 psMetadataAddF32(definebytagArgs, PS_LIST_TAIL, "-airmass_max", 0, 90 "define max airmass", NAN); 91 psMetadataAddF32(definebytagArgs, PS_LIST_TAIL, "-exp_time_min", 0, 92 "define min exposure time", NAN); 93 psMetadataAddF32(definebytagArgs, PS_LIST_TAIL, "-exp_time_max", 0, 94 "define max exposure time", NAN); 95 psMetadataAddF64(definebytagArgs, PS_LIST_TAIL, "-ccd_temp_min", 0, 96 "define min ccd tempature", NAN); 97 psMetadataAddF64(definebytagArgs, PS_LIST_TAIL, "-ccd_temp_max", 0, 98 "define max ccd tempature", NAN); 99 psMetadataAddF64(definebytagArgs, PS_LIST_TAIL, "-posang_min", 0, 100 "define min rotator position angle", NAN); 101 psMetadataAddF64(definebytagArgs, PS_LIST_TAIL, "-posang_max", 0, 102 "define max rotator position angle", NAN); 103 psMetadataAddF64(definebytagArgs, PS_LIST_TAIL, "-solang_min", 0, 104 "define min solar angle", NAN); 105 psMetadataAddF64(definebytagArgs, PS_LIST_TAIL, "-solang_max", 0, 106 "define max solar angle", NAN); 107 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-registered", 0, 108 "time detrend run was registered", now); 109 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-time_begin", 0, 110 "detrend applyes to exposures taken during this peroid", NULL); 111 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-time_end", 0, 112 "detrend applyes to exposures taken during this peroid", NULL); 113 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-use_begin", 0, 114 "start of detrend run applicable peroid", NULL); 115 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-use_end", 0, 116 "end of detrend run applicable peroid", NULL); 117 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-reduction", 0, 118 "define reduction class for processing", NULL); 119 psMetadataAddStr(definebytagArgs, PS_LIST_TAIL, "-label", 0, 120 "define detrun label", NULL); 121 psMetadataAddBool(definebytagArgs, PS_LIST_TAIL, "-simple", 0, 122 "use the simple output format", false); 123 124 // -definebyquery 125 psMetadata *definebyqueryArgs = psMetadataAlloc(); 126 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-det_type", 0, 127 "define the type of detrend run (required)", NULL); 128 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-mode", 0, 129 "define the mode of this detrend run", "master"); 130 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-filelevel", 0, 131 "define filelevel", NULL); 132 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-workdir", 0, 133 "define workdir (required)", NULL); 134 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-inst", 0, 135 "define camera (required)", NULL); 136 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-telescope", 0, 137 "define telescope", NULL); 138 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-filter", 0, 139 "define filter ", NULL); 140 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-airmass_min", 0, 141 "define min airmass", NAN); 142 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-airmass_max", 0, 143 "define max airmass", NAN); 144 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-exp_time_min", 0, 145 "define min exposure time", NAN); 146 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-exp_time_max", 0, 147 "define max exposure time", NAN); 148 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-ccd_temp_min", 0, 149 "define min ccd tempature", NAN); 150 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-ccd_temp_max", 0, 151 "define max ccd tempature", NAN); 152 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-posang_min", 0, 153 "define min rotator position angle", NAN); 154 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-posang_max", 0, 155 "define max rotator position angle", NAN); 156 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-solang_min", 0, 157 "define min solar angle", NAN); 158 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-solang_max", 0, 159 "define max solar angle", NAN); 160 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-registered", 0, 161 "time detrend run was registered", now); 162 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-time_begin", 0, 163 "detrend applyes to exposures taken during this peroid", NULL); 164 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-time_end", 0, 165 "detrend applyes to exposures taken during this peroid", NULL); 166 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-use_begin", 0, 167 "start of detrend run applicable peroid", NULL); 168 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-use_end", 0, 169 "end of detrend run applicable peroid", NULL); 170 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_exp_type", 0, 171 "search for exp_type", NULL); 172 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_inst", 0, 173 "search for camera", NULL); 174 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_telescope", 0, 175 "search for telescope", NULL); 176 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_filter", 0, 177 "search for filter", NULL); 178 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_uri", 0, 179 "search for uri", NULL); 180 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_dateobs_begin", 0, 181 "search for exposures by time (>=)", NULL); 182 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_dateobs_end", 0, 183 "search for exposures by time (<)", NULL); 184 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_airmass_min", 0, 185 "define min airmass", NAN); 186 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_airmass_max", 0, 187 "define max airmass", NAN); 188 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_sat_pixel_frac_max", 0, 189 "define max fraction of saturated pixels", NAN); 190 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_exp_time_min", 0, 191 "define min exposure time", NAN); 192 psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_exp_time_max", 0, 193 "define max exposure time", NAN); 194 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-select_ccd_temp_min", 0, 195 "define min ccd tempature", NAN); 196 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-select_ccd_temp_max", 0, 197 "define max ccd tempature", NAN); 198 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-select_posang_min", 0, 199 "define min rotator position angle", NAN); 200 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-select_posang_max", 0, 201 "define max rotator position angle", NAN); 202 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-select_solang_min", 0, 203 "define min solar angle", NAN); 204 psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-select_solang_max", 0, 205 "define max solar angle", NAN); 206 psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-pretend", 0, 207 "print the exposures that would be included in the detrend run and exit", false); 208 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-reduction", 0, 209 "define reduction class for processing", NULL); 210 psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-label", 0, 211 "define detrun label", NULL); 212 psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-simple", 0, 213 "use the simple output format", false); 214 215 // -definebydetrun 216 psMetadata *definebydetrunArgs = psMetadataAlloc(); 217 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-det_id", 0, 218 "det ID to base a new detRun on (required)", NULL); 219 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_det_type", 0, 220 "define the type of detrend run", NULL); 221 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_mode", 0, 222 "define the mode of this detrend run", "master"); 223 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_exp_type", 0, 224 "define exposure type", NULL); 225 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_filelevel", 0, 226 "define filelevel", NULL); 227 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_workdir", 0, 228 "define workdir", NULL); 229 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_filter", 0, 230 "define filter ", NULL); 231 psMetadataAddF32(definebydetrunArgs, PS_LIST_TAIL, "-set_airmass_min", 0, 232 "define airmass", NAN); 233 psMetadataAddF32(definebydetrunArgs, PS_LIST_TAIL, "-set_airmass_max", 0, 234 "define airmass", NAN); 235 psMetadataAddF32(definebydetrunArgs, PS_LIST_TAIL, "-set_exp_time_min", 0, 236 "define exposure time", NAN); 237 psMetadataAddF32(definebydetrunArgs, PS_LIST_TAIL, "-set_exp_time_max", 0, 238 "define exposure time", NAN); 239 psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_ccd_temp_min", 0, 240 "define ccd tempature", NAN); 241 psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_ccd_temp_max", 0, 242 "define ccd tempature", NAN); 243 psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_posang_min", 0, 244 "define rotator position angle", NAN); 245 psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_posang_max", 0, 246 "define rotator position angle", NAN); 247 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_registered", 0, 248 "time detrend run was registered", now); 249 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_time_begin", 0, 250 "start of peroid to apply detrend too", NULL); 251 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_time_end", 0, 252 "end of peroid to apply detrend too", NULL); 253 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_use_begin", 0, 254 "start of detrend run applicable peroid", NULL); 255 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_use_end", 0, 256 "end of detrend run applicable peroid", NULL); 257 psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_solang_min", 0, 258 "define solar angle", NAN); 259 psMetadataAddF64(definebydetrunArgs, PS_LIST_TAIL, "-set_solang_max", 0, 260 "define solar angle", NAN); 261 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-filter_input_begin", 0, 262 "filter input detrun exp to be in this peroid", NULL); 263 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-filter_input_end", 0, 264 "filter input detrun exp to be in this peroid", NULL); 265 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_reduction", 0, 266 "define reduction class for processing", NULL); 267 psMetadataAddStr(definebydetrunArgs, PS_LIST_TAIL, "-set_label", 0, 268 "define detrun label", NULL); 269 psMetadataAddBool(definebydetrunArgs, PS_LIST_TAIL, "-simple", 0, 270 "use the simple output format", false); 61 // -addrun 62 psMetadata *addrunArgs = psMetadataAlloc(); 63 psMetadataAddStr(addrunArgs, PS_LIST_TAIL, "-cal_id", 0, 64 "define calibration DB ID", NULL); 65 psMetadataAddF64(addrunArgs, PS_LIST_TAIL, "-user_1", 0, 66 "define user statistic (1)", NAN); 67 psMetadataAddF64(addrunArgs, PS_LIST_TAIL, "-user_2", 0, 68 "define user statistic (2)", NAN); 69 psMetadataAddF64(addrunArgs, PS_LIST_TAIL, "-user_3", 0, 70 "define user statistic (3)", NAN); 71 psMetadataAddF64(addrunArgs, PS_LIST_TAIL, "-user_4", 0, 72 "define user statistic (4)", NAN); 73 psMetadataAddF64(addrunArgs, PS_LIST_TAIL, "-user_5", 0, 74 "define user statistic (5)", NAN); 75 psMetadataAddS16(addrunArgs, PS_LIST_TAIL, "-code", 0, 76 "set fault code", 0); 271 77 272 78 // -runs 273 79 psMetadata *runsArgs = psMetadataAlloc(); 274 psMetadataAddStr(runsArgs, PS_LIST_TAIL, "-det_type", 0, 275 "search for type of detrend run", NULL); 80 psMetadataAddStr(runsArgs, PS_LIST_TAIL, "-cal_id", 0, 81 "search for calibration ID", NULL); 82 psMetadataAddU64(runsArgs, PS_LIST_TAIL, "-limit", 0, 83 "limit result set to N items", 0); 84 psMetadataAddBool(runsArgs, PS_LIST_TAIL, "-faulted", 0, 85 "only return imfiles with a fault status set", false); 276 86 psMetadataAddBool(runsArgs, PS_LIST_TAIL, "-simple", 0, 277 87 "use the simple output format", false); 278 psMetadataAddStr(runsArgs, PS_LIST_TAIL, "-det_id", 0,279 "search for detrend ID", NULL);280 281 // -childlessrun282 psMetadata *childlessrunArgs = psMetadataAlloc();283 psMetadataAddStr(childlessrunArgs, PS_LIST_TAIL, "-det_type", 0,284 "search for type of detrend run", NULL);285 psMetadataAddU64(childlessrunArgs, PS_LIST_TAIL, "-limit", 0,286 "limit result set to N items", 0);287 psMetadataAddBool(childlessrunArgs, PS_LIST_TAIL, "-simple", 0,288 "use the simple output format", false);289 290 // -input291 psMetadata *inputArgs = psMetadataAlloc();292 psMetadataAddStr(inputArgs, PS_LIST_TAIL, "-det_id", 0,293 "search for detrend ID", NULL);294 psMetadataAddS32(inputArgs, PS_LIST_TAIL, "-iteration", 0,295 "define iteration number", 0);296 psMetadataAddStr(inputArgs, PS_LIST_TAIL, "-exp_id", 0,297 "search for exp ID", NULL);298 psMetadataAddBool(inputArgs, PS_LIST_TAIL, "-simple", 0,299 "use the simple output format", false);300 301 // -raw302 psMetadata *rawArgs = psMetadataAlloc();303 psMetadataAddBool(rawArgs, PS_LIST_TAIL, "-simple", 0,304 "use the simple output format", false);305 306 // -toprocessedimfile307 psMetadata *toprocessedimfileArgs = psMetadataAlloc();308 psMetadataAddStr(toprocessedimfileArgs, PS_LIST_TAIL, "-det_id", 0,309 "search for detrend ID", NULL);310 psMetadataAddStr(toprocessedimfileArgs, PS_LIST_TAIL, "-exp_id", 0,311 "search for exp ID", NULL);312 psMetadataAddStr(toprocessedimfileArgs, PS_LIST_TAIL, "-class_id", 0,313 "search for class ID", NULL);314 psMetadataAddU64(toprocessedimfileArgs, PS_LIST_TAIL, "-limit", 0,315 "limit result set to N items", 0);316 psMetadataAddBool(toprocessedimfileArgs, PS_LIST_TAIL, "-simple", 0,317 "use the simple output format", false);318 319 // -addprocessedimfile320 psMetadata *addprocessedimfileArgs = psMetadataAlloc();321 psMetadataAddStr(addprocessedimfileArgs, PS_LIST_TAIL, "-det_id", 0,322 "define detrend ID (required)", NULL);323 psMetadataAddStr(addprocessedimfileArgs, PS_LIST_TAIL, "-exp_id", 0,324 "define exp ID (required)", NULL);325 psMetadataAddStr(addprocessedimfileArgs, PS_LIST_TAIL, "-class_id", 0,326 "define class ID (required)", NULL);327 psMetadataAddStr(addprocessedimfileArgs, PS_LIST_TAIL, "-uri", 0,328 "define URI (required)", NULL);329 psMetadataAddStr(addprocessedimfileArgs, PS_LIST_TAIL, "-recip", 0,330 "define recipe (required)", NULL);331 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-bg", 0,332 "define exposure background (required)", NAN);333 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-bg_stdev", 0,334 "define exposure background stdev (required)", NAN);335 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,336 "define exposure background mean stdev", NAN);337 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-fringe_0", 0,338 "define fringe slope (0th term)", NAN);339 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-fringe_1", 0,340 "define fringe slope (1st term)", NAN);341 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-fringe_2", 0,342 "define fringe slope (2nd term)", NAN);343 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-user_1", 0,344 "define user statistic (1)", NAN);345 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-user_2", 0,346 "define user statistic (2)", NAN);347 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-user_3", 0,348 "define user statistic (3)", NAN);349 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-user_4", 0,350 "define user statistic (4)", NAN);351 psMetadataAddF64(addprocessedimfileArgs, PS_LIST_TAIL, "-user_5", 0,352 "define user statistic (5)", NAN);353 psMetadataAddStr(addprocessedimfileArgs, PS_LIST_TAIL, "-path_base", 0,354 "define base output location", NULL);355 psMetadataAddS16(addprocessedimfileArgs, PS_LIST_TAIL, "-code", 0,356 "set fault code", 0);357 358 // -processedimfile359 psMetadata *processedimfileArgs = psMetadataAlloc();360 psMetadataAddStr(processedimfileArgs, PS_LIST_TAIL, "-det_id", 0,361 "search for detrend ID", NULL);362 psMetadataAddStr(processedimfileArgs, PS_LIST_TAIL, "-exp_id", 0,363 "search for exp ID", NULL);364 psMetadataAddStr(processedimfileArgs, PS_LIST_TAIL, "-class_id", 0,365 "search for class ID", NULL);366 psMetadataAddStr(processedimfileArgs, PS_LIST_TAIL, "-select_state", 0,367 "search for state", NULL);368 psMetadataAddStr(processedimfileArgs, PS_LIST_TAIL, "-select_mode", 0,369 "search for mode", NULL);370 psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-chip", 0,371 "restrict results to completed 'chip' sets", false);372 psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-exp", 0,373 "restrict results to complete 'exposures'", false);374 psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-included", 0,375 "restrict results to exposures 'includeded' in the current iteration", false);376 psMetadataAddU64(processedimfileArgs, PS_LIST_TAIL, "-limit", 0,377 "limit result set to N items", 0);378 psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-faulted", 0,379 "only return imfiles with a fault status set", false);380 psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-simple", 0,381 "use the simple output format", false);382 383 // -revertprocessedimfile384 psMetadata *revertprocessedimfileArgs = psMetadataAlloc();385 psMetadataAddStr(revertprocessedimfileArgs, PS_LIST_TAIL, "-det_id", 0,386 "search for detrend ID (required)", NULL);387 psMetadataAddStr(revertprocessedimfileArgs, PS_LIST_TAIL, "-exp_id", 0,388 "search by exposure ID", NULL);389 psMetadataAddStr(revertprocessedimfileArgs, PS_LIST_TAIL, "-class_id", 0,390 "search by class ID", NULL);391 psMetadataAddS16(revertprocessedimfileArgs, PS_LIST_TAIL, "-code", 0,392 "search by fault code", 0);393 394 // -toprocessedexp395 psMetadata *toprocessedexpArgs = psMetadataAlloc();396 psMetadataAddU64(toprocessedexpArgs, PS_LIST_TAIL, "-limit", 0,397 "limit result set to N items", 0);398 psMetadataAddBool(toprocessedexpArgs, PS_LIST_TAIL, "-simple", 0,399 "use the simple output format", false);400 401 // -addproccessedexp402 psMetadata *addprocessedexpArgs = psMetadataAlloc();403 psMetadataAddStr(addprocessedexpArgs, PS_LIST_TAIL, "-det_id", 0,404 "define detrend ID (required)", NULL);405 psMetadataAddStr(addprocessedexpArgs, PS_LIST_TAIL, "-exp_id", 0,406 "define detrend ID (required)", NULL);407 psMetadataAddStr(addprocessedexpArgs, PS_LIST_TAIL, "-recip", 0,408 "define recipe (required)", NULL);409 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-bg", 0,410 "define exposure background (required)", NAN);411 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-bg_stdev", 0,412 "define exposure background stdev (required)", NAN);413 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,414 "define exposure background mean stdev", NAN);415 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-fringe_0", 0,416 "define fringe slope (0th term)", NAN);417 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-fringe_1", 0,418 "define fringe slope (1st term)", NAN);419 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-fringe_2", 0,420 "define fringe slope (2nd term)", NAN);421 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-user_1", 0,422 "define user statistic (1)", NAN);423 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-user_2", 0,424 "define user statistic (2)", NAN);425 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-user_3", 0,426 "define user statistic (3)", NAN);427 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-user_4", 0,428 "define user statistic (4)", NAN);429 psMetadataAddF64(addprocessedexpArgs, PS_LIST_TAIL, "-user_5", 0,430 "define user statistic (5)", NAN);431 psMetadataAddStr(addprocessedexpArgs, PS_LIST_TAIL, "-path_base", 0,432 "define base output location", NULL);433 psMetadataAddS16(addprocessedexpArgs, PS_LIST_TAIL, "-code", 0,434 "set fault code", 0);435 436 // -proccessedexp437 psMetadata *processedexpArgs = psMetadataAlloc();438 psMetadataAddStr(processedexpArgs, PS_LIST_TAIL, "-det_id", 0,439 "define detrend ID", NULL);440 psMetadataAddStr(processedexpArgs, PS_LIST_TAIL, "-exp_id", 0,441 "define detrend ID", NULL);442 psMetadataAddU64(processedexpArgs, PS_LIST_TAIL, "-limit", 0,443 "limit result set to N items", 0);444 psMetadataAddBool(processedexpArgs, PS_LIST_TAIL, "-faulted", 0,445 "only return imfiles with a fault status set", false);446 psMetadataAddBool(processedexpArgs, PS_LIST_TAIL, "-simple", 0,447 "use the simple output format", false);448 449 // -revertprocessedexp450 psMetadata *revertprocessedexpArgs = psMetadataAlloc();451 psMetadataAddStr(revertprocessedexpArgs, PS_LIST_TAIL, "-det_id", 0,452 "search by detrend ID (required)", NULL);453 psMetadataAddStr(revertprocessedexpArgs, PS_LIST_TAIL, "-exp_id", 0,454 "search by exposure ID", NULL);455 psMetadataAddS16(revertprocessedexpArgs, PS_LIST_TAIL, "-code", 0,456 "search by fault code", 0);457 458 // -tostacked459 psMetadata *tostackedArgs = psMetadataAlloc();460 psMetadataAddU64(tostackedArgs, PS_LIST_TAIL, "-limit", 0,461 "limit result set to N items", 0);462 psMetadataAddBool(tostackedArgs, PS_LIST_TAIL, "-simple", 0,463 "use the simple output format", false);464 465 // -addstacked466 psMetadata *addstackedArgs = psMetadataAlloc();467 psMetadataAddStr(addstackedArgs, PS_LIST_TAIL, "-det_id", 0,468 "define detrend ID (required)", NULL);469 psMetadataAddS32(addstackedArgs, PS_LIST_TAIL, "-iteration", 0,470 "define iteration number", 0);471 psMetadataAddStr(addstackedArgs, PS_LIST_TAIL, "-class_id", 0,472 "define class ID (required)", NULL);473 psMetadataAddStr(addstackedArgs, PS_LIST_TAIL, "-recip", 0,474 "define recipe (required)", NULL);475 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-bg", 0,476 "define exposure background (required)", NAN);477 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-bg_stdev", 0,478 "define exposure background stdev (required)", NAN);479 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,480 "define exposure background mean stdev", NAN);481 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-user_1", 0,482 "define user statistic (1)", NAN);483 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-user_2", 0,484 "define user statistic (2)", NAN);485 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-user_3", 0,486 "define user statistic (3)", NAN);487 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-user_4", 0,488 "define user statistic (4)", NAN);489 psMetadataAddF64(addstackedArgs, PS_LIST_TAIL, "-user_5", 0,490 "define user statistic (5)", NAN);491 psMetadataAddStr(addstackedArgs, PS_LIST_TAIL, "-uri", 0,492 "define URI (required)", NULL);493 psMetadataAddS16(addstackedArgs, PS_LIST_TAIL, "-code", 0,494 "set fault code", 0);495 496 // -stacked497 psMetadata *stackedArgs = psMetadataAlloc();498 psMetadataAddStr(stackedArgs, PS_LIST_TAIL, "-det_id", 0,499 "search for detrend ID", NULL);500 psMetadataAddS32(stackedArgs, PS_LIST_TAIL, "-iteration", 0,501 "search for iteration number", 0);502 psMetadataAddStr(stackedArgs, PS_LIST_TAIL, "-class_id", 0,503 "search for class ID", NULL);504 psMetadataAddStr(stackedArgs, PS_LIST_TAIL, "-recip", 0,505 "search for recipe", NULL);506 psMetadataAddU64(stackedArgs, PS_LIST_TAIL, "-limit", 0,507 "limit result set to N items", 0);508 psMetadataAddBool(stackedArgs, PS_LIST_TAIL, "-faulted", 0,509 "only return imfiles with a fault status set", false);510 psMetadataAddBool(stackedArgs, PS_LIST_TAIL, "-simple", 0,511 "use the simple output format", false);512 513 // -revertstacked514 psMetadata *revertstackedArgs= psMetadataAlloc();515 psMetadataAddStr(revertstackedArgs, PS_LIST_TAIL, "-det_id", 0,516 "search for detrend ID (required)", NULL);517 psMetadataAddS32(revertstackedArgs, PS_LIST_TAIL, "-iteration", 0,518 "search by iteration number", 0);519 psMetadataAddStr(revertstackedArgs, PS_LIST_TAIL, "-class_id", 0,520 "search by class ID", NULL);521 psMetadataAddS16(revertstackedArgs, PS_LIST_TAIL, "-code", 0,522 "search by fault code", 0);523 524 // -tonormalize525 psMetadata *tonormalizeArgs = psMetadataAlloc();526 psMetadataAddU64(tonormalizeArgs, PS_LIST_TAIL, "-limit", 0,527 "limit result set to N items", 0);528 psMetadataAddBool(tonormalizeArgs, PS_LIST_TAIL, "-simple", 0,529 "use the simple output format", false);530 531 // -addnormalizedstat532 psMetadata *addnormstatArgs = psMetadataAlloc();533 psMetadataAddStr(addnormstatArgs, PS_LIST_TAIL, "-det_id", 0,534 "define detrend ID (required)", NULL);535 psMetadataAddS32(addnormstatArgs, PS_LIST_TAIL, "-iteration", 0,536 "define iteration number", 0);537 psMetadataAddStr(addnormstatArgs, PS_LIST_TAIL, "-class_id", 0,538 "define class ID (required)", NULL);539 psMetadataAddF32(addnormstatArgs, PS_LIST_TAIL, "-norm", 0,540 "define normal value (required)", NAN);541 psMetadataAddS16(addnormstatArgs, PS_LIST_TAIL, "-code", 0,542 "set fault code", 0);543 544 // -normalizedstat545 psMetadata *normalizedstatArgs = psMetadataAlloc();546 psMetadataAddStr(normalizedstatArgs, PS_LIST_TAIL, "-det_id", 0,547 "search by detrend ID", NULL);548 psMetadataAddS32(normalizedstatArgs, PS_LIST_TAIL, "-iteration", 0,549 "search by iteration number", 0);550 psMetadataAddStr(normalizedstatArgs, PS_LIST_TAIL, "-class_id", 0,551 "search by class ID", NULL);552 psMetadataAddU64(normalizedstatArgs, PS_LIST_TAIL, "-limit", 0,553 "limit result set to N items", 0);554 psMetadataAddBool(normalizedstatArgs, PS_LIST_TAIL, "-faulted", 0,555 "only return imfiles with a fault status set", false);556 psMetadataAddBool(normalizedstatArgs, PS_LIST_TAIL, "-simple", 0,557 "use the simple output format", false);558 559 // -revertnormalizedstat560 psMetadata *revertnormalizedstatArgs= psMetadataAlloc();561 psMetadataAddStr(revertnormalizedstatArgs, PS_LIST_TAIL, "-det_id", 0,562 "search by detrend ID (required)", NULL);563 psMetadataAddS32(revertnormalizedstatArgs, PS_LIST_TAIL, "-iteration", 0,564 "search by iteration number", 0);565 psMetadataAddStr(revertnormalizedstatArgs, PS_LIST_TAIL, "-class_id", 0,566 "search by class ID", NULL);567 psMetadataAddS16(revertnormalizedstatArgs, PS_LIST_TAIL, "-code", 0,568 "search by fault code", 0);569 570 // -tonormstat571 psMetadata *tonormstatArgs = psMetadataAlloc();572 psMetadataAddU64(tonormstatArgs, PS_LIST_TAIL, "-limit", 0,573 "limit result set to N items", 0);574 psMetadataAddBool(tonormstatArgs, PS_LIST_TAIL, "-simple", 0,575 "use the simple output format", false);576 577 // -addnormalizedimfile578 psMetadata *addnormalizedimfileArgs = psMetadataAlloc();579 psMetadataAddStr(addnormalizedimfileArgs, PS_LIST_TAIL, "-det_id", 0,580 "define detrend ID (required)", NULL);581 psMetadataAddS32(addnormalizedimfileArgs, PS_LIST_TAIL, "-iteration", 0,582 "define iteration number", 0);583 psMetadataAddStr(addnormalizedimfileArgs, PS_LIST_TAIL, "-class_id", 0,584 "define class ID (required)", NULL);585 psMetadataAddStr(addnormalizedimfileArgs, PS_LIST_TAIL, "-uri", 0,586 "define URI (required)", NULL);587 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-bg", 0,588 "define exposure background", NAN);589 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-bg_stdev", 0,590 "define exposure background stdev", NAN);591 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,592 "define exposure background mean stdev", NAN);593 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-user_1", 0,594 "define user statistic (1)", NAN);595 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-user_2", 0,596 "define user statistic (2)", NAN);597 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-user_3", 0,598 "define user statistic (3)", NAN);599 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-user_4", 0,600 "define user statistic (4)", NAN);601 psMetadataAddF64(addnormalizedimfileArgs, PS_LIST_TAIL, "-user_5", 0,602 "define user statistic (5)", NAN);603 psMetadataAddStr(addnormalizedimfileArgs, PS_LIST_TAIL, "-path_base", 0,604 "define base output location", NULL);605 psMetadataAddS16(addnormalizedimfileArgs, PS_LIST_TAIL, "-code", 0,606 "set fault code", 0);607 608 // -normalizedimfile609 psMetadata *normalizedimfileArgs = psMetadataAlloc();610 psMetadataAddStr(normalizedimfileArgs, PS_LIST_TAIL, "-det_id", 0,611 "search for detrend ID", NULL);612 psMetadataAddS32(normalizedimfileArgs, PS_LIST_TAIL, "-iteration", 0,613 "search for iteration number", 0);614 psMetadataAddStr(normalizedimfileArgs, PS_LIST_TAIL, "-class_id", 0,615 "search for class ID", NULL);616 psMetadataAddStr(normalizedimfileArgs, PS_LIST_TAIL, "-recip", 0,617 "search for recipe", NULL);618 psMetadataAddU64(normalizedimfileArgs, PS_LIST_TAIL, "-limit", 0,619 "limit result set to N items", 0);620 psMetadataAddBool(normalizedimfileArgs, PS_LIST_TAIL, "-faulted", 0,621 "only return imfiles with a fault status set", false);622 psMetadataAddBool(normalizedimfileArgs, PS_LIST_TAIL, "-simple", 0,623 "use the simple output format", false);624 625 // -revertnormalizedimfile626 psMetadata *revertnormalizedimfileArgs = psMetadataAlloc();627 psMetadataAddStr(revertnormalizedimfileArgs, PS_LIST_TAIL, "-det_id", 0,628 "search by detrend ID (required)", NULL);629 psMetadataAddS32(revertnormalizedimfileArgs, PS_LIST_TAIL, "-iteration", 0,630 "search by iteration number", 0);631 psMetadataAddStr(revertnormalizedimfileArgs, PS_LIST_TAIL, "-class_id", 0,632 "search by class ID", NULL);633 psMetadataAddS16(revertnormalizedimfileArgs, PS_LIST_TAIL, "-code", 0,634 "search by fault code", 0);635 636 // -tonormalizedexp637 psMetadata *tonormalizedexpArgs = psMetadataAlloc();638 psMetadataAddU64(tonormalizedexpArgs, PS_LIST_TAIL, "-limit", 0,639 "limit result set to N items", 0);640 psMetadataAddBool(tonormalizedexpArgs, PS_LIST_TAIL, "-simple", 0,641 "use the simple output format", false);642 643 // -addnormalizedexp644 psMetadata *addnormalizedexpArgs = psMetadataAlloc();645 psMetadataAddStr(addnormalizedexpArgs, PS_LIST_TAIL, "-det_id", 0,646 "define detrend ID (required)", NULL);647 psMetadataAddS32(addnormalizedexpArgs, PS_LIST_TAIL, "-iteration", 0,648 "define iteration number", 0);649 psMetadataAddStr(addnormalizedexpArgs, PS_LIST_TAIL, "-recip", 0,650 "search for recipe (required)", NULL);651 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-bg", 0,652 "define exposure background (required)", NAN);653 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-bg_stdev", 0,654 "define exposure background stdev (required)", NAN);655 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,656 "define exposure background mean stdev", NAN);657 658 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-user_1", 0,659 "define user statistic (1)", NAN);660 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-user_2", 0,661 "define user statistic (2)", NAN);662 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-user_3", 0,663 "define user statistic (3)", NAN);664 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-user_4", 0,665 "define user statistic (4)", NAN);666 psMetadataAddF64(addnormalizedexpArgs, PS_LIST_TAIL, "-user_5", 0,667 "define user statistic (5)", NAN);668 669 psMetadataAddStr(addnormalizedexpArgs, PS_LIST_TAIL, "-path_base", 0,670 "define base output location", NULL);671 psMetadataAddS16(addnormalizedexpArgs, PS_LIST_TAIL, "-code", 0,672 "set fault code", 0);673 674 // -normalizedexp675 psMetadata *normalizedexpArgs = psMetadataAlloc();676 psMetadataAddStr(normalizedexpArgs, PS_LIST_TAIL, "-det_id", 0,677 "define detrend ID", NULL);678 psMetadataAddS32(normalizedexpArgs, PS_LIST_TAIL, "-iteration", 0,679 "define iteration number", 0);680 psMetadataAddStr(normalizedexpArgs, PS_LIST_TAIL, "-recip", 0,681 "search for recipe", NULL);682 psMetadataAddF64(normalizedexpArgs, PS_LIST_TAIL, "-bg", 0,683 "define exposure background", NAN);684 psMetadataAddF64(normalizedexpArgs, PS_LIST_TAIL, "-bg_stdev", 0,685 "define exposure background stdev", NAN);686 psMetadataAddF64(normalizedexpArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,687 "define exposure background mean stdev", NAN);688 psMetadataAddStr(normalizedexpArgs, PS_LIST_TAIL, "-path_base", 0,689 "define base output location", NULL);690 psMetadataAddU64(normalizedexpArgs, PS_LIST_TAIL, "-limit", 0,691 "limit result set to N items", 0);692 psMetadataAddBool(normalizedexpArgs, PS_LIST_TAIL, "-faulted", 0,693 "only return imfiles with a fault status set", false);694 psMetadataAddBool(normalizedexpArgs, PS_LIST_TAIL, "-simple", 0,695 "use the simple output format", false);696 697 // -revertnormalizedexp698 psMetadata *revertnormalizedexpArgs = psMetadataAlloc();699 psMetadataAddStr(revertnormalizedexpArgs, PS_LIST_TAIL, "-det_id", 0,700 "search by detrend ID (required)", NULL);701 psMetadataAddS32(revertnormalizedexpArgs, PS_LIST_TAIL, "-iteration", 0,702 "search by iteration number", 0);703 psMetadataAddS16(revertnormalizedexpArgs, PS_LIST_TAIL, "-code", 0,704 "search by fault code", 0);705 706 // -toresidimfile707 psMetadata *toresidimfileArgs = psMetadataAlloc();708 psMetadataAddU64(toresidimfileArgs, PS_LIST_TAIL, "-limit", 0,709 "limit result set to N items", 0);710 psMetadataAddBool(toresidimfileArgs, PS_LIST_TAIL, "-simple", 0,711 "use the simple output format", false);712 713 // -toresidexp714 psMetadata *toresidexpArgs = psMetadataAlloc();715 psMetadataAddU64(toresidexpArgs, PS_LIST_TAIL, "-limit", 0,716 "limit result set to N items", 0);717 psMetadataAddBool(toresidexpArgs, PS_LIST_TAIL, "-simple", 0,718 "use the simple output format", false);719 720 // -addresidimfile721 psMetadata *addresidimfileArgs = psMetadataAlloc();722 psMetadataAddStr(addresidimfileArgs, PS_LIST_TAIL, "-det_id", 0,723 "define detrend ID (required)", NULL);724 psMetadataAddS32(addresidimfileArgs, PS_LIST_TAIL, "-iteration", 0,725 "define iteration number", 0);726 psMetadataAddStr(addresidimfileArgs, PS_LIST_TAIL, "-exp_id", 0,727 "define detrend ID (required)", NULL);728 psMetadataAddStr(addresidimfileArgs, PS_LIST_TAIL, "-class_id", 0,729 "define class ID (required)", NULL);730 psMetadataAddStr(addresidimfileArgs, PS_LIST_TAIL, "-uri", 0,731 "define resid file URI (required)", NULL);732 psMetadataAddStr(addresidimfileArgs, PS_LIST_TAIL, "-recip", 0,733 "define recipe (required)", NULL);734 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-bg", 0,735 "define exposure background (required)", NAN);736 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-bg_stdev", 0,737 "define exposure background stdev (required)", NAN);738 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,739 "define exposure background mean stdev", NAN);740 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-bg_skewness", 0,741 "define exposure background skewness", NAN);742 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-bg_kurtosis", 0,743 "define exposure background kurtosis", NAN);744 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-bin_stdev", 0,745 "define exposure background binned stdev", NAN);746 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-fringe_0", 0,747 "define fringe slope (0th term)", NAN);748 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-fringe_1", 0,749 "define fringe slope (1st term)", NAN);750 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-fringe_2", 0,751 "define fringe slope (2nd term)", NAN);752 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-fringe_resid_0", 0,753 "define fringe residual (0th term)", NAN);754 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-fringe_resid_1", 0,755 "define fringe residual (1st term)", NAN);756 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-fringe_resid_2", 0,757 "define fringe residual (2nd term)", NAN);758 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-user_1", 0,759 "define user statistic (1)", NAN);760 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-user_2", 0,761 "define user statistic (2)", NAN);762 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-user_3", 0,763 "define user statistic (3)", NAN);764 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-user_4", 0,765 "define user statistic (4)", NAN);766 psMetadataAddF64(addresidimfileArgs, PS_LIST_TAIL, "-user_5", 0,767 "define user statistic (5)", NAN);768 psMetadataAddStr(addresidimfileArgs, PS_LIST_TAIL, "-path_base", 0,769 "define base output location", NULL);770 psMetadataAddS16(addresidimfileArgs, PS_LIST_TAIL, "-code", 0,771 "set fault code", 0);772 773 // -residimfile774 psMetadata *residimfileArgs = psMetadataAlloc();775 psMetadataAddStr(residimfileArgs, PS_LIST_TAIL, "-det_id", 0,776 "search for detrend ID", NULL);777 psMetadataAddS32(residimfileArgs, PS_LIST_TAIL, "-iteration", 0,778 "search for iteration number", 0);779 psMetadataAddStr(residimfileArgs, PS_LIST_TAIL, "-exp_id", 0,780 "define detrend ID", NULL);781 psMetadataAddStr(residimfileArgs, PS_LIST_TAIL, "-class_id", 0,782 "search for class ID", NULL);783 psMetadataAddStr(residimfileArgs, PS_LIST_TAIL, "-recip", 0,784 "search for recipe", NULL);785 psMetadataAddU64(residimfileArgs, PS_LIST_TAIL, "-limit", 0,786 "limit result set to N items", 0);787 psMetadataAddBool(residimfileArgs, PS_LIST_TAIL, "-faulted", 0,788 "only return imfiles with a fault status set", false);789 psMetadataAddBool(residimfileArgs, PS_LIST_TAIL, "-simple", 0,790 "use the simple output format", false);791 psMetadataAddStr(residimfileArgs, PS_LIST_TAIL, "-select_state", 0,792 "search for state", NULL);793 794 // -revertresidimfile795 psMetadata *revertresidimfileArgs = psMetadataAlloc();796 psMetadataAddStr(revertresidimfileArgs, PS_LIST_TAIL, "-det_id", 0,797 "search by detrend ID (required)", NULL);798 psMetadataAddS32(revertresidimfileArgs, PS_LIST_TAIL, "-iteration", 0,799 "search by iteration number", 0);800 psMetadataAddStr(revertresidimfileArgs, PS_LIST_TAIL, "-exp_id", 0,801 "search by detrend ID", NULL);802 psMetadataAddStr(revertresidimfileArgs, PS_LIST_TAIL, "-class_id", 0,803 "search for class ID", NULL);804 psMetadataAddS16(revertresidimfileArgs, PS_LIST_TAIL, "-code", 0,805 "search by fault code", 0);806 807 // -addresidexp808 psMetadata *addresidexpArgs = psMetadataAlloc();809 psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-det_id", 0,810 "define detrend ID (required)", NULL);811 psMetadataAddS32(addresidexpArgs, PS_LIST_TAIL, "-iteration", 0,812 "define iteration number", 0);813 psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-exp_id", 0,814 "define detrend ID (required)", NULL);815 psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-recip", 0,816 "define recipe (required)", NULL);817 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-bg", 0,818 "define exposure background (required)", NAN);819 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-bg_stdev", 0,820 "define exposure background stdev (required)", NAN);821 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,822 "define exposure background mean stdev", NAN);823 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-bg_skewness", 0,824 "define exposure background skewness", NAN);825 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-bg_kurtosis", 0,826 "define exposure background kurtosis", NAN);827 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-bin_stdev", 0,828 "define exposure background binned stdev", NAN);829 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-fringe_0", 0,830 "define fringe slope (0th term)", NAN);831 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-fringe_1", 0,832 "define fringe slope (1st term)", NAN);833 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-fringe_2", 0,834 "define fringe slope (2nd term)", NAN);835 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-fringe_resid_0", 0,836 "define fringe residual (0th term)", NAN);837 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-fringe_resid_1", 0,838 "define fringe residual (1st term)", NAN);839 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-fringe_resid_2", 0,840 "define fringe residual (2nd term)", NAN);841 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-user_1", 0,842 "define user statistic (1)", NAN);843 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-user_2", 0,844 "define user statistic (2)", NAN);845 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-user_3", 0,846 "define user statistic (3)", NAN);847 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-user_4", 0,848 "define user statistic (4)", NAN);849 psMetadataAddF64(addresidexpArgs, PS_LIST_TAIL, "-user_5", 0,850 "define user statistic (5)", NAN);851 psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-path_base", 0,852 "define base output location", NULL);853 psMetadataAddS16(addresidexpArgs, PS_LIST_TAIL, "-code", 0,854 "set fault code", 0);855 psMetadataAddBool(addresidexpArgs, PS_LIST_TAIL, "-reject", 0,856 "exposure is not to be stacked in the next iteration", false);857 858 // -residexp859 psMetadata *residexpArgs = psMetadataAlloc();860 psMetadataAddStr(residexpArgs, PS_LIST_TAIL, "-det_id", 0,861 "search for detrend ID", NULL);862 psMetadataAddS32(residexpArgs, PS_LIST_TAIL, "-iteration", 0,863 "search for iteration number", 0);864 psMetadataAddStr(residexpArgs, PS_LIST_TAIL, "-exp_id", 0,865 "search for exp ID", NULL);866 psMetadataAddStr(residexpArgs, PS_LIST_TAIL, "-recip", 0,867 "search for recipe", NULL);868 psMetadataAddU64(residexpArgs, PS_LIST_TAIL, "-limit", 0,869 "limit result set to N items", 0);870 psMetadataAddBool(residexpArgs, PS_LIST_TAIL, "-faulted", 0,871 "only return imfiles with a fault status set", false);872 psMetadataAddBool(residexpArgs, PS_LIST_TAIL, "-reject", 0,873 "search for acceptable residuals", false);874 psMetadataAddBool(residexpArgs, PS_LIST_TAIL, "-simple", 0,875 "use the simple output format", false);876 877 // -revertresidexp878 psMetadata *revertresidexpArgs = psMetadataAlloc();879 psMetadataAddStr(revertresidexpArgs, PS_LIST_TAIL, "-det_id", 0,880 "search by detrend ID (required)", NULL);881 psMetadataAddS32(revertresidexpArgs, PS_LIST_TAIL, "-iteration", 0,882 "search by iteration number", 0);883 psMetadataAddStr(revertresidexpArgs, PS_LIST_TAIL, "-exp_id", 0,884 "search by detrend ID", NULL);885 psMetadataAddS16(revertresidexpArgs, PS_LIST_TAIL, "-code", 0,886 "search by fault code", 0);887 888 // -todetrunsummary889 psMetadata *todetrunsummaryArgs = psMetadataAlloc();890 psMetadataAddBool(todetrunsummaryArgs, PS_LIST_TAIL, "-simple", 0,891 "use the simple output format", false);892 psMetadataAddU64(todetrunsummaryArgs, PS_LIST_TAIL, "-limit", 0,893 "limit result set to N items", 0);894 895 // -updateresidexp896 psMetadata *updateresidexpArgs = psMetadataAlloc();897 psMetadataAddStr(updateresidexpArgs, PS_LIST_TAIL, "-det_id", 0,898 "define detrend ID", NULL);899 psMetadataAddS32(updateresidexpArgs, PS_LIST_TAIL, "-iteration", 0,900 "define iteration number", 0);901 psMetadataAddStr(updateresidexpArgs, PS_LIST_TAIL, "-exp_id", 0,902 "define exp ID", NULL);903 psMetadataAddStr(updateresidexpArgs, PS_LIST_TAIL, "-recip", 0,904 "define recipe", NULL);905 psMetadataAddF64(updateresidexpArgs, PS_LIST_TAIL, "-bg", 0,906 "define exposure background", NAN);907 psMetadataAddF64(updateresidexpArgs, PS_LIST_TAIL, "-bg_stdev", 0,908 "define exposure background stdev", NAN);909 psMetadataAddF64(updateresidexpArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,910 "define exposure background mean stdev", NAN);911 psMetadataAddStr(updateresidexpArgs, PS_LIST_TAIL, "-path_base", 0,912 "define base output location", NULL);913 psMetadataAddBool(updateresidexpArgs, PS_LIST_TAIL, "-reject", 0,914 "exposure is not to be stacked in the next iteration", false);915 916 // -adddetrunsummary917 psMetadata *adddetrunsummaryArgs = psMetadataAlloc();918 psMetadataAddStr(adddetrunsummaryArgs, PS_LIST_TAIL, "-det_id", 0,919 "define detrend ID (required)", NULL);920 psMetadataAddS32(adddetrunsummaryArgs, PS_LIST_TAIL, "-iteration", 0,921 "define iteration number", 0);922 psMetadataAddF64(adddetrunsummaryArgs, PS_LIST_TAIL, "-bg", 0,923 "define exposure background (required)", NAN);924 psMetadataAddF64(adddetrunsummaryArgs, PS_LIST_TAIL, "-bg_stdev", 0,925 "define exposure background stdev (required)", NAN);926 psMetadataAddF64(adddetrunsummaryArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,927 "define exposure background mean stdev", NAN);928 psMetadataAddS16(adddetrunsummaryArgs, PS_LIST_TAIL, "-code", 0,929 "set fault code", 0);930 psMetadataAddBool(adddetrunsummaryArgs, PS_LIST_TAIL, "-accept", 0,931 "declare that this detrun iteration is accepted as a master", false);932 psMetadataAddBool(adddetrunsummaryArgs, PS_LIST_TAIL, "-again", 0,933 "start a new iteration of this detrend run", false);934 935 // -detrunsummary936 psMetadata *detrunsummaryArgs = psMetadataAlloc();937 psMetadataAddStr(detrunsummaryArgs, PS_LIST_TAIL, "-det_id", 0,938 "search for detrend ID", NULL);939 psMetadataAddU64(detrunsummaryArgs, PS_LIST_TAIL, "-limit", 0,940 "limit result set to N items", 0);941 psMetadataAddS32(detrunsummaryArgs, PS_LIST_TAIL, "-iteration", 0,942 "search for iteration number", 0);943 psMetadataAddBool(detrunsummaryArgs, PS_LIST_TAIL, "-faulted", 0,944 "only return imfiles with a fault status set", false);945 psMetadataAddBool(detrunsummaryArgs, PS_LIST_TAIL, "-reject", 0,946 "search for acceptable residuals", false);947 psMetadataAddBool(detrunsummaryArgs, PS_LIST_TAIL, "-simple", 0,948 "use the simple output format", false);949 950 // -revertdetrunsummary951 psMetadata *revertdetrunsummaryArgs = psMetadataAlloc();952 psMetadataAddStr(revertdetrunsummaryArgs, PS_LIST_TAIL, "-det_id", 0,953 "search by detrend ID (required)", NULL);954 psMetadataAddS32(revertdetrunsummaryArgs, PS_LIST_TAIL, "-iteration", 0,955 "search by iteration number", 0);956 psMetadataAddS16(revertdetrunsummaryArgs, PS_LIST_TAIL, "-code", 0,957 "search by fault code", 0);958 959 // -updatedetrun960 psMetadata *updatedetrunArgs = psMetadataAlloc();961 psMetadataAddStr(updatedetrunArgs, PS_LIST_TAIL, "-det_id", 0,962 "search for detrend master for detrend ID (required)", NULL);963 psMetadataAddBool(updatedetrunArgs, PS_LIST_TAIL, "-again", 0,964 "start a new iteration of this detrend run", false);965 psMetadataAddStr(updatedetrunArgs, PS_LIST_TAIL, "-state", 0,966 "set the state of this detrend run", false);967 968 // -rerun969 psMetadata *rerunArgs = psMetadataAlloc();970 psMetadataAddStr(rerunArgs, PS_LIST_TAIL, "-det_id", 0,971 "search for detrend master for detrend ID (required)", NULL);972 psMetadataAddStr(rerunArgs, PS_LIST_TAIL, "-exp_id", PS_META_DUPLICATE_OK,973 "include this exposure (multiple OK, required)", NULL);974 975 // -register_detrend976 psMetadata *register_detrendArgs = psMetadataAlloc();977 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-det_type", 0,978 "define the type of detrend run (required)", NULL);979 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-mode", 0,980 "define the mode of this detrend run", "master");981 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-filelevel", 0,982 "define filelevel (required)", NULL);983 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-workdir", 0,984 "define workdir", NULL);985 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-inst", 0,986 "define camera", NULL);987 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-telescope", 0,988 "define telescope", NULL);989 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-exp_type", 0,990 "define exposure type", NULL);991 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-filter", 0,992 "define filter ", NULL);993 psMetadataAddF32(register_detrendArgs, PS_LIST_TAIL, "-airmass_min", 0,994 "define min airmass", NAN);995 psMetadataAddF32(register_detrendArgs, PS_LIST_TAIL, "-airmass_max", 0,996 "define max airmass", NAN);997 psMetadataAddF32(register_detrendArgs, PS_LIST_TAIL, "-exp_time_min", 0,998 "define min exposure time", NAN);999 psMetadataAddF32(register_detrendArgs, PS_LIST_TAIL, "-exp_time_max", 0,1000 "define max exposure time", NAN);1001 psMetadataAddF64(register_detrendArgs, PS_LIST_TAIL, "-ccd_temp_min", 0,1002 "define min ccd tempature", NAN);1003 psMetadataAddF64(register_detrendArgs, PS_LIST_TAIL, "-ccd_temp_max", 0,1004 "define max ccd tempature", NAN);1005 psMetadataAddF64(register_detrendArgs, PS_LIST_TAIL, "-posang_min", 0,1006 "define min rotator position angle", NAN);1007 psMetadataAddF64(register_detrendArgs, PS_LIST_TAIL, "-posang_max", 0,1008 "define max rotator position angle", NAN);1009 psMetadataAddF64(register_detrendArgs, PS_LIST_TAIL, "-solang_min", 0,1010 "define min solar angle", NAN);1011 psMetadataAddF64(register_detrendArgs, PS_LIST_TAIL, "-solang_max", 0,1012 "define max solar angle", NAN);1013 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-registered", 0,1014 "time detrend run was registered", now);1015 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-time_begin", 0,1016 "detrend applyes to exposures taken during this peroid", NULL);1017 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-time_end", 0,1018 "detrend applyes to exposures taken during this peroid", NULL);1019 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-use_begin", 0,1020 "start of detrend run applicable peroid", NULL);1021 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-use_end", 0,1022 "end of detrend run applicable peroid", NULL);1023 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-parent", 0,1024 "define parent det_id", NULL);1025 psMetadataAddStr(register_detrendArgs, PS_LIST_TAIL, "-label", 0,1026 "define detrun label", NULL);1027 psMetadataAddBool(register_detrendArgs, PS_LIST_TAIL, "-simple", 0,1028 "use the simple output format", false);1029 1030 // -register_detrend_imfile1031 psMetadata *register_detrend_imfileArgs = psMetadataAlloc();1032 psMetadataAddStr(register_detrend_imfileArgs, PS_LIST_TAIL, "-det_id", 0,1033 "define detrend ID (required)", NULL);1034 psMetadataAddStr(register_detrend_imfileArgs, PS_LIST_TAIL, "-class_id", 0,1035 "search for class ID (required)", NULL);1036 psMetadataAddStr(register_detrend_imfileArgs, PS_LIST_TAIL, "-uri", 0,1037 "define resid file URI (required)", NULL);1038 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-bg", 0,1039 "define exposure background", NAN);1040 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-bg_stdev", 0,1041 "define exposure background stdev", NAN);1042 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-bg_mean_stdev", 0,1043 "define exposure background mean stdev", NAN);1044 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-user_1", 0,1045 "define user statistic (1)", NAN);1046 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-user_2", 0,1047 "define user statistic (2)", NAN);1048 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-user_3", 0,1049 "define user statistic (3)", NAN);1050 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-user_4", 0,1051 "define user statistic (4)", NAN);1052 psMetadataAddF64(register_detrend_imfileArgs, PS_LIST_TAIL, "-user_5", 0,1053 "define user statistic (5)", NAN);1054 psMetadataAddStr(register_detrend_imfileArgs, PS_LIST_TAIL, "-path_base", 0,1055 "define base output location", NULL);1056 88 1057 89 psFree(now); … … 1060 92 psMetadata *modes = psMetadataAlloc(); 1061 93 1062 PXTOOL_ADD_MODE("-pending", "list active detruns", DETTOOL_MODE_PENDING, pendingArgs); 1063 PXTOOL_ADD_MODE("-definebytag", "", DETTOOL_MODE_DEFINEBYTAG, definebytagArgs); 1064 PXTOOL_ADD_MODE("-definebyquery", "", DETTOOL_MODE_DEFINEBYQUERY, definebyqueryArgs); 1065 PXTOOL_ADD_MODE("-definebydetrun", "", DETTOOL_MODE_DEFINEBYDETRUN, definebydetrunArgs); 1066 PXTOOL_ADD_MODE("-raw", "", DETTOOL_MODE_RAW, rawArgs); 1067 PXTOOL_ADD_MODE("-runs", "", DETTOOL_MODE_RUNS, runsArgs); 1068 PXTOOL_ADD_MODE("-childlessrun", "", DETTOOL_MODE_CHILDLESSRUN, childlessrunArgs); 1069 PXTOOL_ADD_MODE("-input", "", DETTOOL_MODE_INPUT, inputArgs); 1070 PXTOOL_ADD_MODE("-toprocessedimfile", "", DETTOOL_MODE_TOPROCESSEDIMFILE, toprocessedimfileArgs); 1071 PXTOOL_ADD_MODE("-addprocessedimfile", "", DETTOOL_MODE_ADDPROCESSEDIMFILE, addprocessedimfileArgs); 1072 PXTOOL_ADD_MODE("-processedimfile", "", DETTOOL_MODE_PROCESSEDIMFILE, processedimfileArgs); 1073 PXTOOL_ADD_MODE("-revertprocessedimfile", "", DETTOOL_MODE_REVERTPROCESSEDIMFILE, revertprocessedimfileArgs); 1074 PXTOOL_ADD_MODE("-toprocessedexp", "", DETTOOL_MODE_TOPROCESSEDEXP, toprocessedexpArgs); 1075 PXTOOL_ADD_MODE("-addprocessedexp", "", DETTOOL_MODE_ADDPROCESSEDEXP, addprocessedexpArgs); 1076 PXTOOL_ADD_MODE("-revertprocessedexp", "", DETTOOL_MODE_REVERTPROCESSEDEXP, revertprocessedexpArgs); 1077 PXTOOL_ADD_MODE("-processedexp", "", DETTOOL_MODE_PROCESSEDEXP, processedexpArgs); 1078 PXTOOL_ADD_MODE("-tostacked", "", DETTOOL_MODE_TOSTACKED, tostackedArgs); 1079 PXTOOL_ADD_MODE("-addstacked", "", DETTOOL_MODE_ADDSTACKED, addstackedArgs); 1080 PXTOOL_ADD_MODE("-stacked", "", DETTOOL_MODE_STACKED, stackedArgs); 1081 PXTOOL_ADD_MODE("-revertstacked", "", DETTOOL_MODE_REVERTSTACKED, revertstackedArgs); 1082 PXTOOL_ADD_MODE("-tonormalize", "", DETTOOL_MODE_TONORMALIZE, tonormalizeArgs); 1083 PXTOOL_ADD_MODE("-addnormalizedstat", "", DETTOOL_MODE_ADDNORMALIZEDSTAT, addnormstatArgs); 1084 PXTOOL_ADD_MODE("-normalizedstat", "", DETTOOL_MODE_NORMALIZEDSTAT, normalizedstatArgs); 1085 PXTOOL_ADD_MODE("-revertnormalizedstat", "", DETTOOL_MODE_REVERTNORMALIZEDSTAT, revertnormalizedstatArgs); 1086 1087 PXTOOL_ADD_MODE("-tonormalizedstat", "", DETTOOL_MODE_TONORMALIZEDSTAT, tonormstatArgs); 1088 PXTOOL_ADD_MODE("-addnormalizedimfile", "", DETTOOL_MODE_ADDNORMALIZEDIMFILE,addnormalizedimfileArgs); 1089 PXTOOL_ADD_MODE("-normalizedimfile","", DETTOOL_MODE_NORMALIZEDIMFILE, normalizedimfileArgs); 1090 PXTOOL_ADD_MODE("-revertnormalizedimfile","", DETTOOL_MODE_REVERTNORMALIZEDIMFILE, revertnormalizedimfileArgs); 1091 PXTOOL_ADD_MODE("-tonormalizedexp", "", DETTOOL_MODE_TONORMALIZEDEXP, tonormalizedexpArgs); 1092 PXTOOL_ADD_MODE("-addnormalizedexp", "", DETTOOL_MODE_ADDNORMALIZEDEXP, addnormalizedexpArgs); 1093 PXTOOL_ADD_MODE("-normalizedexp", "", DETTOOL_MODE_NORMALIZEDEXP, normalizedexpArgs); 1094 PXTOOL_ADD_MODE("-revertnormalizedexp","", DETTOOL_MODE_REVERTNORMALIZEDEXP, revertnormalizedexpArgs); 1095 PXTOOL_ADD_MODE("-toresidimfile", "", DETTOOL_MODE_TORESIDIMFILE, toresidimfileArgs); 1096 PXTOOL_ADD_MODE("-addresidimfile", "", DETTOOL_MODE_ADDRESIDIMFILE, addresidimfileArgs); 1097 PXTOOL_ADD_MODE("-residimfile", "", DETTOOL_MODE_RESIDIMFILE, residimfileArgs); 1098 PXTOOL_ADD_MODE("-revertresidimfile", "", DETTOOL_MODE_REVERTRESIDIMFILE, revertresidimfileArgs); 1099 PXTOOL_ADD_MODE("-toresidexp", "", DETTOOL_MODE_TORESIDEXP, toresidexpArgs); 1100 PXTOOL_ADD_MODE("-addresidexp", "", DETTOOL_MODE_ADDRESIDEXP, addresidexpArgs); 1101 PXTOOL_ADD_MODE("-residexp", "", DETTOOL_MODE_RESIDEXP, residexpArgs); 1102 PXTOOL_ADD_MODE("-revertresidexp", "", DETTOOL_MODE_REVERTRESIDEXP, revertresidexpArgs); 1103 PXTOOL_ADD_MODE("-todetrunsummary", "", DETTOOL_MODE_TODETRUNSUMMARY, todetrunsummaryArgs); 1104 PXTOOL_ADD_MODE("-updateresidexp", "", DETTOOL_MODE_UPDATERESIDEXP,updateresidexpArgs); 1105 PXTOOL_ADD_MODE("-adddetrunsummary", "", DETTOOL_MODE_ADDDETRUNSUMMARY,adddetrunsummaryArgs); 1106 PXTOOL_ADD_MODE("-detrunsummary", "", DETTOOL_MODE_DETRUNSUMMARY,detrunsummaryArgs); 1107 PXTOOL_ADD_MODE("-revertdetrunsummary", "", DETTOOL_MODE_REVERTDETRUNSUMMARY, revertdetrunsummaryArgs); 1108 PXTOOL_ADD_MODE("-updatedetrun", "", DETTOOL_MODE_UPDATEDETRUN, updatedetrunArgs); 1109 PXTOOL_ADD_MODE("-rerun", "", DETTOOL_MODE_RERUN, rerunArgs); 1110 PXTOOL_ADD_MODE("-register_detrend", "", DETTOOL_MODE_REGISTER_DETREND, register_detrendArgs); 1111 PXTOOL_ADD_MODE("-register_detrend_imfile", "", DETTOOL_MODE_REGISTER_DETREND_IMFILE, register_detrend_imfileArgs); 94 PXTOOL_ADD_MODE("-adddb", "add a DVO calibration DB", 95 CALTOOL_MODE_ADDDB, adddbArgs); 96 PXTOOL_ADD_MODE("-dbs", "list DVO calibration DBs", 97 CALTOOL_MODE_DBS, dbsArgs); 98 PXTOOL_ADD_MODE("-addrun", "add the results of a calibration run", 99 CALTOOL_MODE_ADDRUN, addrunArgs); 100 PXTOOL_ADD_MODE("-runs", "list the results of calibration runs", 101 CALTOOL_MODE_RUNS, runsArgs); 1112 102 1113 103 if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) { … … 1151 141 } 1152 142 } 1153 addWhereStr(det_type);1154 addWhereStr(exp_id);1155 addWhereStr(class_id);1156 // convert '-inst' to 'camera'1157 {1158 psString str = NULL;1159 bool status = false;1160 if ((str = psMetadataLookupStr(&status, config->args, "-inst"))) {1161 if (!psMetadataAddStr(config->where, PS_LIST_TAIL, "camera", 0, "==", str)) {1162 psError(PS_ERR_UNKNOWN, false, "failed to add item camera");1163 psFree(config);1164 return NULL;1165 }1166 }1167 }1168 addWhereStr(telescope);1169 addWhereStr(exp_type);1170 {1171 int n = 0;1172 bool status = false;1173 if ((n = psMetadataLookupS32(&status, config->args, "-imfiles"))) {1174 if (!psMetadataAddS32(config->where, PS_LIST_TAIL, "imfiles", 0, "==", n)) {1175 psError(PS_ERR_UNKNOWN, false, "failed to add item imfiles");1176 psFree(config);1177 return NULL;1178 }1179 }1180 }1181 addWhereStr(filter);1182 addWhereStr(recipe);1183 {1184 int n = 0;1185 bool status = false;1186 if ((n = psMetadataLookupS32(&status, config->args, "-guide_version"))) {1187 if (!psMetadataAddS32(config->where, PS_LIST_TAIL, "guide_version", 0, "==", n)) {1188 psError(PS_ERR_UNKNOWN, false, "failed to add item guide_version");1189 psFree(config);1190 return NULL;1191 }1192 }1193 }1194 {1195 bool boolean = false;1196 bool status = false;1197 143 1198 // map reject -> !accept 1199 if ((boolean = psMetadataLookupBool(&status, config->args, "-reject"))) { 1200 if (!psMetadataAddBool(config->where, PS_LIST_TAIL, "accept", 0, "==", !boolean)) { 1201 psError(PS_ERR_UNKNOWN, false, "failed to add item reject"); 1202 psFree(config); 1203 return NULL; 1204 } 1205 } 1206 } 144 addWhereStr(det_id); 1207 145 1208 146 // convert '-code' to 'fault'
Note:
See TracChangeset
for help on using the changeset viewer.
