Changeset 20360
- Timestamp:
- Oct 24, 2008, 2:30:41 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/magic/remove/src/streaksremove.c (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/magic/remove/src/streaksremove.c
r20342 r20360 1 1 #include "streaks.h" 2 2 #include "streaksextern.h" 3 #include "libgen.h" 3 4 4 5 extern bool sFileLock(sFile * sfile); 5 6 extern bool sFileUnlock(sFile * sfile); 6 7 extern bool sFileReplace(sFile *dest, sFile *src); 8 9 static nebServer *ourNebServer = NULL; 7 10 8 11 // for clarity in this program we don't propagate errors up the stack … … 13 16 } 14 17 15 static void 16 sFileFree(sFile *sfile) 18 static void sFileFree(sFile *sfile) 17 19 { 18 20 psFree(sfile->resolved_name); … … 21 23 } 22 24 25 // getNebServer() 26 // 27 // it gets created the first time a nebulous file is accessed. 28 // if config is passed in we are to create it and exit if not able. 29 // if config is null we return NULL indicating that there are no nebulous files in use 30 // The purpose of this is to avoid passing extra arguments between all of the functions. 31 // but it is probably a bad idea. 32 // 33 static nebServer *getNebServer(pmConfig *config) 34 { 35 if (ourNebServer) { 36 return ourNebServer; 37 } 38 39 if (!config) { 40 return NULL; 41 } 42 43 psString serverURI = getenv("NEB_SERVER"); 44 45 // XXX: Note: all of the flags to psError should be true, but I don't think nebclient 46 // uses psError 47 if (!serverURI) { 48 bool status; 49 serverURI = psMetadataLookupStr(&status, config->site, "NEB_SERVER"); 50 if (!status) { 51 psError(PM_ERR_CONFIG, true, "failed to lookup config value for NEB_SERVER."); 52 streaksremoveExit("", PS_EXIT_CONFIG_ERROR); 53 } 54 } 55 56 if (!serverURI) { 57 psError(PM_ERR_CONFIG, true, "Could not determine nebulous server URI."); 58 59 streaksremoveExit("", PS_EXIT_CONFIG_ERROR); 60 } 61 62 ourNebServer = nebServerAlloc(serverURI); 63 if (!ourNebServer) { 64 psError(PM_ERR_SYS, true, "failed to create a nebServer object from %s.", serverURI); 65 streaksremoveExit("", PS_EXIT_CONFIG_ERROR); 66 } 67 68 return ourNebServer; 69 } 70 23 71 psString 24 72 resolveFilename(pmConfig *config, sFile *sfile, bool create) 25 73 { 26 74 sfile->inNebulous = IN_NEBULOUS(sfile->name); 75 76 if (sfile->inNebulous) { 77 // make sure we have our neb server connection 78 nebServer *server = getNebServer(config); 79 if (create) { 80 // delete the existing file, since there may be more than one 81 // instance. It will get created below in pmConfigConvertFilename 82 if (nebFind(server, sfile->name)) { 83 nebDelete(server, sfile->name); 84 } 85 } 86 } 27 87 28 88 return pmConfigConvertFilename(sfile->name, config, create, create); … … 37 97 38 98 // We use psFits directly to read the image file unless the stage is warp 39 // or diff. In th at casewe use the pmFPAfile functions to read the image file40 // to make managing the astromet y easy99 // or diff. In those cases we use the pmFPAfile functions to read the image file 100 // to make managing the astrometry easy 41 101 42 102 if (!CHIP_LEVEL_INPUT(stage) && !strcmp(fileSelect, "INPUT")) { … … 67 127 } 68 128 69 sfile->resolved_name = psStringCopy(sfile->pmfile->filename);70 129 pmFPAview *view = pmFPAviewAlloc(0); 71 130 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { … … 74 133 } 75 134 psFree(view); 135 sfile->resolved_name = psStringCopy(sfile->pmfile->filename); 76 136 77 137 // copy header from fpu … … 80 140 return sfile; 81 141 } 142 143 // using psFits for i/o 82 144 83 145 sfile->name = psMetadataLookupStr(&status, config->arguments, fileSelect); … … 211 273 sf->inImage = sFileOpen(config, stage, "INPUT", NULL, true); 212 274 sf->nHDU = sf->inImage->nHDU; 213 sf->outImage = sFileOpen(config, stage, "OUTPUT", ".fits", true); 214 sf->recImage = sFileOpen(config, stage, "RECOVERY", ".fits", true); 275 276 // don't need to free this see basename(3) 277 char *inputBasename = basename(sf->inImage->name); 278 sf->outImage = sFileOpen(config, stage, "OUTPUT", inputBasename, true); 279 sf->recImage = sFileOpen(config, stage, "RECOVERY", inputBasename, true); 215 280 216 281 sf->inMask = sFileOpen(config, stage, "INPUT.MASK", NULL, false); 217 282 if (sf->inMask) { 218 sf->outMask = sFileOpen(config, stage, "OUTPUT", ".mk.fits", true); 219 sf->recMask = sFileOpen(config, stage, "RECOVERY", "wt.fits", true); 283 inputBasename = basename(sf->inMask->name); 284 sf->outMask = sFileOpen(config, stage, "OUTPUT", inputBasename, true); 285 sf->recMask = sFileOpen(config, stage, "RECOVERY", inputBasename, true); 220 286 } 221 287 sf->inWeight = sFileOpen(config, stage, "INPUT.WEIGHT", NULL, false); 222 288 if (sf->inWeight) { 223 sf->outWeight = sFileOpen(config, stage, "OUTPUT", ".wt.fits", true); 224 sf->recWeight = sFileOpen(config, stage, "RECOVERY", ".wt.fits", true); 225 } 226 227 // load astrometry if supplied 289 inputBasename = basename(sf->inWeight->name); 290 sf->outWeight = sFileOpen(config, stage, "OUTPUT", inputBasename, true); 291 sf->recWeight = sFileOpen(config, stage, "RECOVERY", inputBasename, true); 292 } 293 294 // load astrometry file 228 295 if (USE_SUPPLIED_ASTROM(sf->stage)) { 229 296 sf->inAstrom = pmFPAfileDefineFromArgs(&status, config, "PSWARP.ASTROM", "ASTROM"); 230 297 } else { 231 sf->inAstrom = sf->inImage->pmfile;298 // otherwise get astrometry from pmfile 232 299 if (!sf->inImage->pmfile) { 233 300 streaksremoveExit("unexpected null pmFPAfile", PS_EXIT_CONFIG_ERROR); 234 301 } 302 sf->inAstrom = sf->inImage->pmfile; 235 303 } 236 304 setupAstromFromFPA(sf); … … 316 384 } 317 385 386 psString checkdir(char *path) 387 { 388 // insure that path ends in / 389 int len = strlen(path); 390 psString dir = NULL; 391 if (strrchr(path, '/') != (path + len - 1)) { 392 psStringAppend(&dir, "%s/", path); 393 } else { 394 dir = psStringCopy(path); 395 } 396 return dir; 397 } 318 398 319 399 ippStage … … 378 458 } 379 459 460 461 // If input image is in nebulous we require mask, weight, and tmproot to all be 462 // nebulous paths 463 bool nebulousImage = false; 380 464 if ((argnum = psArgumentGet(argc, argv, "-image"))) { 381 465 // for raw and chip level images we use psFits for I/O and ... 466 nebulousImage = IN_NEBULOUS(argv[argnum+1]); 382 467 if (CHIP_LEVEL_INPUT(stage)) { 383 468 psArgumentRemove(argnum, &argc, argv); … … 406 491 if ((argnum = psArgumentGet(argc, argv, "-mask"))) { 407 492 psArgumentRemove(argnum, &argc, argv); 493 bool nebulousMask = IN_NEBULOUS(argv[argnum]); 494 if (nebulousMask != nebulousImage) { 495 psError(PS_ERR_UNKNOWN, true, "mask image must be %snebulous path with %s image path\n", 496 nebulousImage ? "" : "non ", nebulousImage ? "nebulous" : "regular"); 497 return NULL; 498 } 408 499 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "MASK", 0, 409 500 "name of input mask image", argv[argnum]); … … 412 503 if ((argnum = psArgumentGet(argc, argv, "-weight"))) { 413 504 psArgumentRemove(argnum, &argc, argv); 505 bool nebulousWeight = IN_NEBULOUS(argv[argnum]); 506 if (nebulousWeight != nebulousImage) { 507 psError(PS_ERR_UNKNOWN, true, "weight image must have %snebulous path with %s image path\n", 508 nebulousImage ? "" : "non ", nebulousImage ? "nebulous" : "regular"); 509 return NULL; 510 } 414 511 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "WEIGHT", 0, 415 512 "name of input weight image", argv[argnum]); … … 418 515 if ((argnum = psArgumentGet(argc, argv, "-tmproot"))) { 419 516 psArgumentRemove(argnum, &argc, argv); 420 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "root name of temporary files", 421 argv[argnum]); 422 psArgumentRemove(argnum, &argc, argv); 423 } else { 424 psError(PS_ERR_UNKNOWN, true, "-outroot is required\n"); 517 bool nebulousTmp = IN_NEBULOUS(argv[argnum]); 518 if (nebulousTmp != nebulousImage) { 519 psError(PS_ERR_UNKNOWN, true, "tmproot must have %snebulous path with %s image path\n", 520 nebulousImage ? "" : "non ", nebulousImage ? "nebulous" : "regular"); 521 return NULL; 522 } 523 psString dir = checkdir(argv[argnum]); 524 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "directory for temporary files", 525 dir); 526 psArgumentRemove(argnum, &argc, argv); 527 } else { 528 psError(PS_ERR_UNKNOWN, true, "-tmproot is required\n"); 425 529 return NULL; 426 530 } 427 531 if ((argnum = psArgumentGet(argc, argv, "-recovery"))) { 428 532 psArgumentRemove(argnum, &argc, argv); 429 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "Name of recovery root", 430 argv[argnum]); 533 psString dir = checkdir(argv[argnum]); 534 psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "directory for recovery files", 535 dir); 431 536 psArgumentRemove(argnum, &argc, argv); 432 537 } else if (stage == IPP_STAGE_RAW) { … … 434 539 return NULL; 435 540 } 541 bool gotReplace = false; 436 542 if ((argnum = psArgumentGet(argc, argv, "-replace"))) { 543 gotReplace = true; 437 544 psArgumentRemove(argnum, &argc, argv); 438 545 psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REPLACE", 0, "replace input files", … … 440 547 } 441 548 if ((argnum = psArgumentGet(argc, argv, "-remove"))) { 442 psArgumentRemove(argnum, &argc, argv); 443 psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REMOVE", 0, "remove input files", 549 if (!gotReplace) { 550 psError(PS_ERR_UNKNOWN, true, "-replace is required with -remove\n"); 551 return NULL; 552 } 553 psArgumentRemove(argnum, &argc, argv); 554 psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REMOVE", 0, "remove original files", 444 555 true); 556 } 557 558 if (argc != 1) { 559 psString unexpectedArguments = NULL; 560 for (int i=1; i<argc; i++) { 561 psStringAppend(&unexpectedArguments, "%s ", argv[i]); 562 } 563 psError(PS_ERR_UNKNOWN, true, "unexpected arguments: %s", unexpectedArguments); 564 psFree(unexpectedArguments); 565 return NULL; 445 566 } 446 567 … … 709 830 createRecoveryImage(sFile *rec, sFile *in, int extnum) 710 831 { 711 // PFS: may not be necessary but replaced in->numRows with in->image->numRows712 832 rec->image = psImageRecycle(rec->image, in->image->numCols, in->image->numRows, in->image->type.type); 713 833 if (!rec->image) { … … 879 999 880 1000 static bool 881 replicate( nebServer *server,sFile *sfile, void *xattr)1001 replicate(sFile *sfile, void *xattr) 882 1002 { 883 1003 if (!sfile->inNebulous) { 884 1004 return true; 885 1005 } 1006 nebServer *server = getNebServer(NULL); 1007 886 1008 // for now just set "user.copies" to 2 887 1009 if (!nebSetXattr(server, sfile->name, "user.copies", "2", NEB_REPLACE)) { … … 903 1025 { 904 1026 bool status = false; 905 psString neb_server = getenv("NEB_SERVER");906 907 // XXX: Note: all of the flags to psError should be true, but I don't think nebclient908 // uses psError909 if (!neb_server) {910 neb_server = psMetadataLookupStr(&status, sfiles->config->site, "NEB_SERVER");911 if (!status) {912 psError(PM_ERR_CONFIG, true, "failed to lookup config value for NEB_SERVER.");913 return false;914 }915 }916 917 if (!neb_server) {918 psError(PM_ERR_CONFIG, true, "Could not determine nebulous server URI.");919 return false;920 }921 922 sfiles->nebServer = nebServerAlloc(neb_server);923 if (!sfiles->nebServer) {924 psError(PM_ERR_SYS, true, "failed to create a nebServer object.");925 return false;926 }927 1027 928 1028 // XXX: TODO: need a nebGetXatrr function, but there isn't one 1029 // another option would be to take the number of copies to be 1030 // created as an option. That way the system could decide 1031 // whether to replicate anything other than raw Image files 929 1032 void *xattr = NULL; 930 1033 931 if (!replicate(sfiles-> nebServer, sfiles->outImage, xattr)) {1034 if (!replicate(sfiles->outImage, xattr)) { 932 1035 psError(PM_ERR_SYS, false, "failed to replicate outImage."); 933 1036 return false; … … 935 1038 936 1039 #ifdef notyet 937 // don't replicate mask and weight images until we can look up1040 // XXX: don't replicate mask and weight images until we can look up 938 1041 // the input's xattr. There may be a perl program that can getXattr 939 1042 if (sfiles->outMask) { 940 1043 // get xattr from input to see if we need to replicate 941 if (!replicate(sfiles-> nebServer, sfiles->outMask, xattr)) {1044 if (!replicate(sfiles->outMask, xattr)) { 942 1045 psError(PM_ERR_SYS, false, "failed to replicate outImage."); 943 1046 return false; … … 946 1049 if (sfiles->outWeight) { 947 1050 // get xattr from input to see if we need to replicate 948 if (!replicate(sfiles-> nebServer, sfiles->outWeight, xattr)) {1051 if (!replicate(sfiles->outWeight, xattr)) { 949 1052 psError(PM_ERR_SYS, false, "failed to replicate outImage."); 950 1053 return false; … … 959 1062 return true; 960 1063 } 1064 1065 static bool 1066 swapOutputToInput(sFile *in, sFile *out) 1067 { 1068 1069 if (in->inNebulous) { 1070 nebServer *server = getNebServer(NULL); 1071 1072 if (!nebSwap(server, in->name, out->name)) { 1073 psError(PM_ERR_SYS, true, "failed to swap files for: %s.", 1074 in->name, nebErr(server)); 1075 return false; 1076 } 1077 } else { 1078 psString command = NULL; 1079 1080 // regular files. use mv creating a backup 1081 // NOTE: -b is a gnu option and may not always be available 1082 psStringAppend(&command, "mv -b --suffix=.bak %s %s", out->resolved_name, in->resolved_name); 1083 int status = system(command); 1084 if (status != 0) { 1085 psError(PM_ERR_SYS, true, "%s failed with status %d.", 1086 command, status); 1087 psFree(command); 1088 return false; 1089 } 1090 psFree(command); 1091 } 1092 1093 return true; 1094 } 961 1095 static bool 962 1096 swapOutputsToInputs(streakFiles *sfiles) 963 1097 { 964 bool status = false; 965 966 if (!sfiles->nebServer) { 967 // no output files are in nebulous 968 return true; 969 } 970 971 // XXX: we should check for consistency before here 972 // We need to insure that the database is consistent 973 // If input is in nebulous, output must be 974 // if input is not in nebulous output must not be Catch in parseArguments 975 // if not in nebulous create a backup of input before overwriting 976 977 if (sfiles->inImage->inNebulous && sfiles->outImage->inNebulous) { 978 if (!nebSwap(sfiles->nebServer, sfiles->outImage->name, sfiles->inImage->name)) { 979 psError(PM_ERR_SYS, false, "failed to swap instances for Image\n%s.", 980 nebErr(sfiles->nebServer)); 1098 if (sfiles->inMask) { 1099 if (!swapOutputToInput(sfiles->inMask, sfiles->outMask)) { 1100 psError(PM_ERR_SYS, false, "failed to swap instances for Mask."); 981 1101 return false; 982 1102 } 983 1103 } 984 1104 985 // TODO: handle weight and mask images 1105 if (sfiles->inWeight) { 1106 if (!swapOutputToInput(sfiles->inWeight, sfiles->outWeight)) { 1107 psError(PM_ERR_SYS, false, "failed to swap instances for Weight."); 1108 return false; 1109 } 1110 } 1111 1112 if (!swapOutputToInput(sfiles->inImage, sfiles->outImage)) { 1113 psError(PM_ERR_SYS, false, "failed to swap instances for Image."); 1114 return false; 1115 } 986 1116 987 1117 return true; 988 1118 } 1119 989 1120 static bool 990 1121 deleteTemps(streakFiles *sfiles) … … 992 1123 bool status = false; 993 1124 994 if (!sfiles->nebServer) { 995 // no output files are in nebulous 1125 nebServer *server = getNebServer(NULL); 1126 1127 if (!server) { 1128 // TODO: handle this 1129 // 1130 // no files are in nebulous 996 1131 return true; 997 1132 } 998 999 // XXX: we should check for consistency before here1000 // We need to insure that the database is consistent1001 // If input is in nebulous, output must be1002 // if input is not in nebulous output must not be Catch in parseArguments1003 // if not in nebulous create a backup of input before overwriting1004 1005 1133 if (sfiles->outImage->inNebulous) { 1006 if (!nebDelete(s files->nebServer, sfiles->outImage->name)) {1134 if (!nebDelete(server, sfiles->outImage->name)) { 1007 1135 psError(PM_ERR_SYS, false, "failed to delete %s\n%s.", sfiles->outImage->name, 1008 nebErr( sfiles->nebServer));1136 nebErr(getNebServer(NULL))); 1009 1137 return false; 1010 1138 } … … 1031 1159 psString streaksFileName = psMetadataLookupStr(NULL, config->arguments, "STREAKS"); 1032 1160 Streaks *streaks = readStreaksFile(streaksFileName); 1161 1162 if (!streaks) { 1163 psErrorStackPrint(stderr, "failed to read streaks file: %s", streaksFileName); 1164 exit (PS_EXIT_PROG_ERROR); 1165 } 1033 1166 1034 1167 streakFiles *sfiles = openFiles(config); … … 1085 1218 #endif 1086 1219 1220 // XXX: This loop following will SEGV for raw video Cells becuase the image is null 1087 1221 for (i = 0; i < psArrayLength (pixels); ++i) { 1088 1222 pixelPos = psArrayGet (pixels, i); … … 1127 1261 // Note this is a database operation. No file I/O is performed 1128 1262 if (!swapOutputsToInputs(sfiles)) { 1129 psError(PS_ERR_UNKNOWN, false, "failed to replicate output files"); 1263 psError(PS_ERR_UNKNOWN, false, "failed to swap files"); 1264 1130 1265 // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that 1131 1266 // it has done and give a detailed report of what happened 1267 1132 1268 psErrorStackPrint(stderr, ""); 1133 1269 exit(PS_EXIT_UNKNOWN_ERROR); 1134 1270 } 1135 } 1136 1137 if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) { 1138 // delete the temporary storage objects (which now points to the original image(s) 1139 if (!deleteTemps(sfiles)) { 1140 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files"); 1141 // XXX: Now what? At this point the output files have been swapped, so we can't 1142 // repeat the operation. 1143 // Returning error status is problematic. Maybe just print an error message and 1144 // let other system tools clean up 1145 psErrorStackPrint(stderr, ""); 1146 exit(PS_EXIT_UNKNOWN_ERROR); 1271 1272 if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) { 1273 // delete the temporary storage objects (which now points to the original image(s) 1274 if (!deleteTemps(sfiles)) { 1275 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files"); 1276 // XXX: Now what? At this point the output files have been swapped, so we can't 1277 // repeat the operation. 1278 1279 // Returning error status here is problematic. The inputs have been streak removed 1280 // but they're still lying around 1281 // Maybe just print an error message and 1282 // let other system tools clean up 1283 psErrorStackPrint(stderr, ""); 1284 exit(PS_EXIT_UNKNOWN_ERROR); 1285 } 1147 1286 } 1148 1287 }
Note:
See TracChangeset
for help on using the changeset viewer.
