IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 20360


Ignore:
Timestamp:
Oct 24, 2008, 2:30:41 PM (18 years ago)
Author:
bills
Message:

Change tmp file and recovery destinations to be directories rather than
path_bases. Get name of file from input to avoid proliferation of
file rules.

Require -replace fo -remove.

If tmp file already exists in nebulous delete it since there may
be multiple instances

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/magic/remove/src/streaksremove.c

    r20342 r20360  
    11#include "streaks.h"
    22#include "streaksextern.h"
     3#include "libgen.h"
    34
    45extern bool  sFileLock(sFile * sfile);
    56extern bool  sFileUnlock(sFile * sfile);
    67extern bool  sFileReplace(sFile *dest, sFile *src);
     8
     9static nebServer *ourNebServer = NULL;
    710
    811// for clarity in this program we don't propagate errors up the stack
     
    1316}
    1417
    15 static void
    16 sFileFree(sFile *sfile)
     18static void sFileFree(sFile *sfile)
    1719{
    1820    psFree(sfile->resolved_name);
     
    2123}
    2224
     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//
     33static 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
    2371psString
    2472resolveFilename(pmConfig *config, sFile *sfile, bool create)
    2573{
    2674    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    }
    2787
    2888    return pmConfigConvertFilename(sfile->name, config, create, create);
     
    3797
    3898    // We use psFits directly to read the image file unless the stage is warp
    39     // or diff. In that case we use the pmFPAfile functions to read the image file
    40     // to make managing the astromety easy
     99    // or diff. In those cases we use the pmFPAfile functions to read the image file
     100    // to make managing the astrometry easy
    41101
    42102    if (!CHIP_LEVEL_INPUT(stage) && !strcmp(fileSelect, "INPUT")) {
     
    67127        }
    68128
    69         sfile->resolved_name = psStringCopy(sfile->pmfile->filename);
    70129        pmFPAview *view = pmFPAviewAlloc(0);
    71130        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     
    74133        }
    75134        psFree(view);
     135        sfile->resolved_name = psStringCopy(sfile->pmfile->filename);
    76136       
    77137        // copy header from fpu
     
    80140        return sfile;
    81141    }
     142
     143    // using psFits for i/o
    82144
    83145    sfile->name = psMetadataLookupStr(&status, config->arguments, fileSelect);
     
    211273    sf->inImage = sFileOpen(config, stage, "INPUT", NULL, true);
    212274    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);
    215280
    216281    sf->inMask = sFileOpen(config, stage, "INPUT.MASK", NULL, false);
    217282    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);
    220286    }
    221287    sf->inWeight = sFileOpen(config, stage, "INPUT.WEIGHT", NULL, false);
    222288    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
    228295    if (USE_SUPPLIED_ASTROM(sf->stage)) {
    229296        sf->inAstrom = pmFPAfileDefineFromArgs(&status, config, "PSWARP.ASTROM", "ASTROM");
    230297    } else {
    231         sf->inAstrom = sf->inImage->pmfile;
     298        // otherwise get astrometry from pmfile
    232299        if (!sf->inImage->pmfile) {
    233300            streaksremoveExit("unexpected null pmFPAfile", PS_EXIT_CONFIG_ERROR);
    234301        }
     302        sf->inAstrom = sf->inImage->pmfile;
    235303    }
    236304    setupAstromFromFPA(sf);
     
    316384}
    317385
     386psString 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}
    318398
    319399ippStage
     
    378458    }
    379459
     460
     461    // If input image is in nebulous we require mask, weight, and tmproot to all be
     462    // nebulous paths
     463    bool nebulousImage = false;
    380464    if ((argnum = psArgumentGet(argc, argv, "-image"))) {
    381465        // for raw and chip level images we use psFits for I/O and ...
     466        nebulousImage = IN_NEBULOUS(argv[argnum+1]);
    382467        if (CHIP_LEVEL_INPUT(stage)) {
    383468            psArgumentRemove(argnum, &argc, argv);
     
    406491    if ((argnum = psArgumentGet(argc, argv, "-mask"))) {
    407492        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        }
    408499        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "MASK", 0,
    409500                "name of input mask image", argv[argnum]);
     
    412503    if ((argnum = psArgumentGet(argc, argv, "-weight"))) {
    413504        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        }
    414511        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "WEIGHT", 0,
    415512                "name of input weight image", argv[argnum]);
     
    418515    if ((argnum = psArgumentGet(argc, argv, "-tmproot"))) {
    419516        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");
    425529        return NULL;
    426530    }
    427531    if ((argnum = psArgumentGet(argc, argv, "-recovery"))) {
    428532        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);
    431536        psArgumentRemove(argnum, &argc, argv);
    432537    } else if (stage == IPP_STAGE_RAW) {
     
    434539        return NULL;
    435540    }
     541    bool gotReplace = false;
    436542    if ((argnum = psArgumentGet(argc, argv, "-replace"))) {
     543        gotReplace = true;
    437544        psArgumentRemove(argnum, &argc, argv);
    438545        psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REPLACE", 0, "replace input files",
     
    440547    }
    441548    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",
    444555            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;
    445566    }
    446567
     
    709830createRecoveryImage(sFile *rec, sFile *in, int extnum)
    710831{
    711     // PFS: may not be necessary but replaced in->numRows with in->image->numRows
    712832    rec->image = psImageRecycle(rec->image, in->image->numCols, in->image->numRows, in->image->type.type);
    713833    if (!rec->image) {
     
    879999
    8801000static bool
    881 replicate(nebServer *server, sFile *sfile, void *xattr)
     1001replicate(sFile *sfile, void *xattr)
    8821002{
    8831003    if (!sfile->inNebulous) {
    8841004        return true;
    8851005    }
     1006    nebServer *server = getNebServer(NULL);
     1007
    8861008    // for now just set "user.copies" to 2
    8871009    if (!nebSetXattr(server, sfile->name, "user.copies", "2",  NEB_REPLACE)) {
     
    9031025{
    9041026    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 nebclient
    908     // uses psError
    909     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     }
    9271027
    9281028    // 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
    9291032    void *xattr = NULL;
    9301033
    931     if (!replicate(sfiles->nebServer, sfiles->outImage, xattr)) {
     1034    if (!replicate(sfiles->outImage, xattr)) {
    9321035        psError(PM_ERR_SYS, false, "failed to replicate outImage.");
    9331036        return false;
     
    9351038
    9361039#ifdef notyet
    937     // don't replicate mask and weight images until we can look up
     1040    // XXX: don't replicate mask and weight images until we can look up
    9381041    // the input's xattr. There may be a perl program that can getXattr
    9391042    if (sfiles->outMask) {
    9401043        // 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)) {
    9421045            psError(PM_ERR_SYS, false, "failed to replicate outImage.");
    9431046            return false;
     
    9461049    if (sfiles->outWeight) {
    9471050        // 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)) {
    9491052            psError(PM_ERR_SYS, false, "failed to replicate outImage.");
    9501053            return false;
     
    9591062    return true;
    9601063}
     1064
     1065static bool
     1066swapOutputToInput(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}
    9611095static bool
    9621096swapOutputsToInputs(streakFiles *sfiles)
    9631097{
    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.");
    9811101            return false;
    9821102        }
    9831103    }
    9841104
    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    }
    9861116
    9871117    return true;
    9881118}
     1119
    9891120static bool
    9901121deleteTemps(streakFiles *sfiles)
     
    9921123    bool status = false;
    9931124
    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
    9961131        return true;
    9971132    }
    998 
    999     // XXX: we should check for consistency before here
    1000     // We need to insure that the database is consistent
    1001     // If input is in nebulous, output must be
    1002     // if input is not in nebulous output must not be Catch in parseArguments
    1003     // if not in nebulous create a backup of input before overwriting
    1004 
    10051133    if (sfiles->outImage->inNebulous) {
    1006         if (!nebDelete(sfiles->nebServer, sfiles->outImage->name)) {
     1134        if (!nebDelete(server, sfiles->outImage->name)) {
    10071135            psError(PM_ERR_SYS, false, "failed to delete %s\n%s.", sfiles->outImage->name,
    1008                 nebErr(sfiles->nebServer));
     1136                nebErr(getNebServer(NULL)));
    10091137            return false;
    10101138        }
     
    10311159    psString streaksFileName = psMetadataLookupStr(NULL, config->arguments, "STREAKS");
    10321160    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    }
    10331166
    10341167    streakFiles *sfiles = openFiles(config);
     
    10851218#endif
    10861219
     1220        // XXX: This loop following will SEGV for raw video Cells becuase the image is null
    10871221        for (i = 0; i < psArrayLength (pixels); ++i) {
    10881222            pixelPos = psArrayGet (pixels, i);
     
    11271261        //     Note this is a database operation. No file I/O is performed
    11281262        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
    11301265            // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that
    11311266            // it has done and give a detailed report of what happened
     1267
    11321268            psErrorStackPrint(stderr, "");
    11331269            exit(PS_EXIT_UNKNOWN_ERROR);
    11341270        }
    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            }
    11471286        }
    11481287    }
Note: See TracChangeset for help on using the changeset viewer.