diff --git a/montage/README.md b/montage/README.md new file mode 100644 index 0000000..b5da874 --- /dev/null +++ b/montage/README.md @@ -0,0 +1,48 @@ + + +Montage Workflow Example +------------------------ + +This workflow gives an example of using Makeflow to parallelize +the Montage astronomical image mosaic tool. + +If you have not done so already, please clone this example repository like so: +``` +git clone https://github.com/cooperative-computing-lab/makeflow-examples.git +cd ./makeflow-examples/montage +``` + +First, build the Montage binary for your architecture: + +``` +git clone https://github.com/Caltech-IPAC/Montage ./montage +cp ./mDAG.c ./montage/grid/Pegasus +cd montage +make +cd .. +``` + +Then, create a working directory and generate a workflow: + +``` +mkdir ./montage_example +./montage/bin/mDAG 2mass j m51 0.5 0.5 0.00277778 ./montage_example http://montage-web.ipac.caltech.edu/workspace/m51 +``` + +Next, run the file_get.pl script to grab all the necessary images of the sky using the URLs generated by mDAG: + +``` +cp ./file_get.pl ./montage_example +cd ./montage_example +perl ./file_get.pl ./url.list +``` + +Finally, execute the workflow using makeflow locally, +or using a batch system like Condor, SGE, or Work Queue: + +``` +makeflow montage.mf +makeflow -T condor montage.mf +makeflow -T sge montage.mf +makeflow -T wq montage.mf +``` diff --git a/montage/file_get.pl b/montage/file_get.pl new file mode 100644 index 0000000..09a38c7 --- /dev/null +++ b/montage/file_get.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl +# +#Copyright (C) 2016- The University of Notre Dame +#This software is distributed under the GNU General Public License. +#See the file COPYING for details. +# + +use strict; +use Scalar::Util qw(looks_like_number); +use Math::Complex; +use POSIX; + +my $num_args = $#ARGV + 1; +if($num_args ne 1) { + print "Must specify input data file.\n"; + exit 1; +} + +my $in = $ARGV[0]; +my $result = 0; +my $i = 1; +open(INPUT, $in); + + while (my $line = ) { + chomp $line; + my @parts = split(" ",$line); + my $final = $parts[0]; + my $intermediate = $parts[0] . ".gz"; + my $url = $parts[1]; + $result = system("curl $url -o $intermediate"); + if($result ne 0) { print "Error in curl #$i\n"; exit 1; } + $result = system("gunzip -c $intermediate > $final; rm $intermediate"); + if($result ne 0) { print "Error in gunzip and rm #$i\n"; exit 1; } + $i++; + sleep(1); + } + +close(INPUT); +exit 0; diff --git a/montage/mDAG.c b/montage/mDAG.c new file mode 100644 index 0000000..74c11cd --- /dev/null +++ b/montage/mDAG.c @@ -0,0 +1,2961 @@ +/* + +Version Developer Date Change +------- --------------- ------- ----------------------- +1.3 Mats Rynge 17Sep10 Updated to Pegasus DAX schema version 2 +1.2 John Good 28Mar06 Add MAGZP processing for 2MASS and fix + location of "idstr" in some file names +1.1 John Good 28Mar06 Added mode based on input template file +1.0 John Good 30Nov05 Baseline code, pretty much just a port + of Joe Jacob's PERL code. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXSTR 1024 + +char *svc_value(); + +int readTemplate(char *template); +int printError (char *msg); +int stradd (char *header, char *card); + +int strcasecmp (const char *s1, const char *s2); + +char *url_encode (char *s); +int tcp_connect (char *hostname, int port); + +int lookup (char *mosaicCenter, double *ra, double *dec); + +static struct WorldCoor *wcs; + +int naxis1, naxis2; +int sys; +double epoch; + +int debug = 1; +FILE *fdebug; + +char fmt [MAXSTR]; +char dfmt [MAXSTR]; + + +/******************************************************************************/ +/* */ +/* mDAG */ +/* */ +/* Creates an XML-based Directed Acyclic Graph (DAG) that specifies "jobs" */ +/* or Montage modules to be run to produce a mosaic, "files" to be */ +/* consumed or generated during processing (input, intermediate, and output */ +/* files), and "dependencies" between jobs and files that imply an order */ +/* in which jobs should be run. In this "abstract graph", logical names are */ +/* assigned to jobs and files. The abstract graph is intended to be an input */ +/* to a job scheduler, such as Pegasus in the Chimera Virtual Data System. */ +/* */ +/* Inputs: */ +/* */ +/* 1) Directory name containing the input data files to be mosaicked. */ +/* 2) Montage template header file specifying the mosaic parameters. */ +/* 3) Directory name for output and temporary files produced by this script. */ +/* */ +/* Outputs: */ +/* */ +/* 1) XML-based DAG */ +/* */ +/* 2) Data files needed for processing the workflow specified in the DAG: */ +/* */ +/* a) Projected image table */ +/* b) Background-corrected image table */ +/* c) Table listing the individual difference image fit plane parameter */ +/* files that will be generated by each run of mFitplane during mosaic */ +/* processing. */ +/* */ +/* NOTE: just filename = 35 characters long */ +/******************************************************************************/ + +int main(int argc, char **argv) +{ + int i, j, k, ncol, nimages; + int haveHdr, itmp, istat, mAddCntr; + int nparents, parent, parent_prev; + int naxis1s, naxis2s; + + //Flag for outputting Makeflow instead of DAX + int dax_mode = 1; + + char line [MAXSTR]; + char mproj [MAXSTR]; + char survey [MAXSTR]; + char band [MAXSTR]; + char hdrFile [MAXSTR]; + char mosaicCenter[MAXSTR]; + char mosaicWidth [MAXSTR]; + char mosaicHeight[MAXSTR]; + char mosaicCdelt [MAXSTR]; + char workdir [MAXSTR]; + char urlbase [MAXSTR]; + char workurlbase [MAXSTR]; + char timestr [MAXSTR]; + char cmd [MAXSTR]; + char status [MAXSTR]; + char msg [MAXSTR]; + char fname [MAXSTR]; + char fitname [MAXSTR]; + char plusname [MAXSTR]; + char minusname [MAXSTR]; + char jobid [MAXSTR]; + char fileList [MAXSTR]; + char parentList [MAXSTR]; + char sortedParent[MAXSTR]; + + char *fileid; + char *parentid; + int haveurlbase = 0; + + clock_t timeval; + + double width; + double height; + double cdelt; + double crval1, crval2; + double crpix1, crpix2; + + int tileSize, tileOverlapX, tileOverlapY; + int numTiles, numTilesX, numTilesY; + + int ifname, iurl, icntr1, icntr2, iplusname, iminusname, iscale; + int cntr, cntr1, cntr2, id, level; + + int shrinkFactor, shrinkFactorX, shrinkFactorY; + + double x, y, z; + double xc, yc, zc; + double xpos, ypos, dtr; + double dist, maxRadius; + double lonc, latc; + + FILE *fp; + FILE *fdag; + FILE *ffit; + FILE *fcache; + FILE *furl; + FILE *ffile; + FILE *fparent; + + char dv_version [MAXSTR]; + + int maxtbl = 1000; + + char key[MAXSTR]; + char val[MAXSTR]; + + struct stat type; + + HT_table_t *depends; + + char *path = getenv("MONTAGE_HOME"); + + + /* Various time value variables */ + + char buffer[256]; + + int yr, mo, day, hr, min, sec, pid; + + time_t curtime; + struct tm *loctime; + + char idstr[256]; + + + dtr = atan(1.0)/45.; + + strcpy(dv_version, "1.0"); + + HT_set_debug(0); + + + /* Generate a unique ID based on data/time/pid */ + + curtime = time (NULL); + loctime = localtime (&curtime); + + strftime(buffer, 256, "%Y", loctime); + yr = atoi(buffer); + + strftime(buffer, 256, "%m", loctime); + mo = atoi(buffer); + + strftime(buffer, 256, "%d", loctime); + day = atoi(buffer); + + strftime(buffer, 256, "%H", loctime); + hr = atoi(buffer); + + strftime(buffer, 256, "%M", loctime); + min = atoi(buffer); + + strftime(buffer, 256, "%S", loctime); + sec = atoi(buffer); + + pid = (int)getpid(); + + sprintf(idstr, "%04d%02d%02d_%02d%02d%02d_%d", + yr, mo, day, hr, min, sec, pid); + + + + /* Set up the dependency hash table */ + + depends = HT_create_table(maxtbl); + + timeval = time(0); + + strcpy(timestr, ctime((const time_t *)(&timeval))); + + for(i=0; i 1) + svc_debug(fdebug); + } + + + + /* Get the location/size information */ + + haveHdr = 0; + + if(argc < 2) + { + printf("[struct stat=\"ERROR\", msg=\"Usage: %s survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -m survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -h survey band hdrfile workdir workurlbase [urlbase] (object/location string must be a single argument)\"]\n", argv[0], argv[0]); + exit(0); + } + + if(strcmp(argv[1], "-h") == 0) + { + if(argc < 7) + { + printf("[struct stat=\"ERROR\", msg=\"Usage: %s survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -m survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -h survey band hdrfile workdir workurlbase [urlbase] (object/location string must be a single argument)\"]\n", argv[0], argv[0]); + exit(0); + } + + haveHdr = 1; + + strcpy(survey, argv[2]); + strcpy(band, argv[3]); + strcpy(hdrFile, argv[4]); + strcpy(workdir, argv[5]); + strcpy(workurlbase, argv[6]); + if(argc == 8) { + strcpy(urlbase, argv[7]); + haveurlbase = 1; + } + } + else if(strcmp(argv[1], "-m") == 0) + { + if(argc < 9) + { + printf("[struct stat=\"ERROR\", msg=\"Usage: %s survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -m survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -h survey band hdrfile workdir workurlbase [urlbase] (object/location string must be a single argument)\"]\n", argv[0], argv[0]); + exit(0); + } + + dax_mode = 0; + + strcpy(survey, argv[1]); + strcpy(band, argv[2]); + strcpy(mosaicCenter, argv[3]); + strcpy(mosaicWidth, argv[4]); + strcpy(mosaicHeight, argv[5]); + strcpy(mosaicCdelt, argv[6]); + strcpy(workdir, argv[7]); + strcpy(workurlbase, argv[8]); + if(argc == 10) { + strcpy(urlbase, argv[9]); + haveurlbase = 1; + } + + width = fabs(atof(mosaicWidth)); + height = fabs(atof(mosaicHeight)); + cdelt = fabs(atof(mosaicCdelt)); + + naxis1 = (int)(width / cdelt) + 0.5; + naxis2 = (int)(height / cdelt) + 0.5; + + crpix1 = (naxis1+1.)/2.; + crpix2 = (naxis2+1.)/2.; + } + else + { + if(argc < 9) + { + printf("[struct stat=\"ERROR\", msg=\"Usage: %s survey band objstr width height cdelt workdir workurlbase [urlbase] | %s -h survey band hdrfile workdir workurlbase [urlbase] (object/location string must be a single argument)\"]\n", argv[0], argv[0]); + exit(0); + } + + strcpy(survey, argv[1]); + strcpy(band, argv[2]); + strcpy(mosaicCenter, argv[3]); + strcpy(mosaicWidth, argv[4]); + strcpy(mosaicHeight, argv[5]); + strcpy(mosaicCdelt, argv[6]); + strcpy(workdir, argv[7]); + strcpy(workurlbase, argv[8]); + if(argc == 10) { + strcpy(urlbase, argv[9]); + haveurlbase = 1; + } + + width = fabs(atof(mosaicWidth)); + height = fabs(atof(mosaicHeight)); + cdelt = fabs(atof(mosaicCdelt)); + + naxis1 = (int)(width / cdelt) + 0.5; + naxis2 = (int)(height / cdelt) + 0.5; + + crpix1 = (naxis1+1.)/2.; + crpix2 = (naxis2+1.)/2.; + } + + istat = stat(workdir, &type); + if(istat < 0) + printError("work directory doesn't exist"); + + strcpy(mproj, "mProjectPP"); + + if(strcasecmp(survey, "dss") == 0 + || strcasecmp(survey, "dposs") == 0) + strcpy(mproj, "mProject"); + + + /**************************************************************/ + /* If we already have the header, we need the size and center */ + /* or if we have the size/center, we need to build the header */ + /**************************************************************/ + + if(haveHdr) + { + maxRadius = 0; + + readTemplate(hdrFile); + + + /* Coordinates of center */ + + pix2wcs(wcs, naxis1/2., naxis2/2., + &xpos, &ypos); + + xc = cos(ypos*dtr) * cos(xpos*dtr); + yc = cos(ypos*dtr) * sin(xpos*dtr); + zc = sin(ypos*dtr); + + convertCoordinates(sys, epoch, xpos, ypos, + EQUJ, 2000., &lonc, &latc, 0.0); + + sprintf(mosaicCenter, "%.6f %.6f eq J2000", lonc, latc); + + + /* Lower left */ + + pix2wcs(wcs, 0.5, 0.5, &xpos, &ypos); + + x = cos(ypos*dtr) * cos(xpos*dtr); + y = cos(ypos*dtr) * sin(xpos*dtr); + z = sin(ypos*dtr); + + dist = acos(x*xc + y*yc + z*zc) / dtr; + + if(dist > maxRadius) + maxRadius = dist; + + + /* Lower right */ + + pix2wcs(wcs, naxis1+0.5, 0.5, &xpos, &ypos); + + x = cos(ypos*dtr) * cos(xpos*dtr); + y = cos(ypos*dtr) * sin(xpos*dtr); + z = sin(ypos*dtr); + + dist = acos(x*xc + y*yc + z*zc) / dtr; + + if(dist > maxRadius) + maxRadius = dist; + + + /* Upper right */ + pix2wcs(wcs, naxis1+0.5, + naxis2+0.5, &xpos, &ypos); + + x = cos(ypos*dtr) * cos(xpos*dtr); + y = cos(ypos*dtr) * sin(xpos*dtr); + z = sin(ypos*dtr); + + dist = acos(x*xc + y*yc + z*zc) / dtr; + + if(dist > maxRadius) + maxRadius = dist; + + + /* Upper left */ + + pix2wcs(wcs, 0.5, naxis2+0.5, &xpos, &ypos); + + x = cos(ypos*dtr) * cos(xpos*dtr); + y = cos(ypos*dtr) * sin(xpos*dtr); + z = sin(ypos*dtr); + + dist = acos(x*xc + y*yc + z*zc) / dtr; + + if(dist > maxRadius) + maxRadius = dist; + + width = 2. * maxRadius; + height = 2. * maxRadius; + + sprintf(mosaicWidth, "%.6f", width); + sprintf(mosaicHeight, "%.6f", height); + } + + else + { + /****************************************************/ + /* Find the coordinates for the center of the image */ + /****************************************************/ + + lookup(mosaicCenter, &crval1, &crval2); + + + /*******************************/ + /* Create header template file */ + /*******************************/ + + sprintf(hdrFile, "%s/region.hdr", workdir); + + fp = fopen(hdrFile, "w+"); + + if(fp == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening header template file\"]\n"); + exit(0); + } + + fprintf(fp, "SIMPLE = T\n" ); + fprintf(fp, "BITPIX = -64\n" ); + fprintf(fp, "NAXIS = 2\n" ); + fprintf(fp, "NAXIS1 = %d\n", naxis1 ); + fprintf(fp, "NAXIS2 = %d\n", naxis2 ); + fprintf(fp, "CTYPE1 = '%s'\n", "RA---TAN" ); + fprintf(fp, "CTYPE2 = '%s'\n", "DEC--TAN" ); + fprintf(fp, "CRVAL1 = %11.6f\n", crval1 ); + fprintf(fp, "CRVAL2 = %11.6f\n", crval2 ); + fprintf(fp, "CRPIX1 = %11.6f\n", crpix1 ); + fprintf(fp, "CRPIX2 = %11.6f\n", crpix2 ); + fprintf(fp, "CDELT1 = %.9f\n", -cdelt ); + fprintf(fp, "CDELT2 = %.9f\n", cdelt ); + fprintf(fp, "CROTA2 = %11.6f\n", 0.0 ); + fprintf(fp, "EQUINOX = %d\n", 2000 ); + + if(strcasecmp(survey, "2MASS") == 0) + { + if(strcasecmp(band, "J") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 20.9044); + + else if(strcasecmp(band, "H") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 20.4871); + + else if(strcasecmp(band, "K") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 19.9757); + } + + fprintf(fp, "END\n" ); + + fclose(fp); + } + + + + /***********************************/ + /* Create big header template file */ + /***********************************/ + + sprintf(hdrFile, "%s/big_region.hdr", workdir); + + fp = fopen(hdrFile, "w+"); + + if(fp == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening big header template file\"]\n"); + exit(0); + } + + fprintf(fp, "SIMPLE = T\n" ); + fprintf(fp, "BITPIX = -64\n" ); + fprintf(fp, "NAXIS = 2\n" ); + fprintf(fp, "NAXIS1 = %d\n", naxis1+3000 ); + fprintf(fp, "NAXIS2 = %d\n", naxis2+3000 ); + fprintf(fp, "CTYPE1 = '%s'\n", "RA---TAN" ); + fprintf(fp, "CTYPE2 = '%s'\n", "DEC--TAN" ); + fprintf(fp, "CRVAL1 = %11.6f\n", crval1 ); + fprintf(fp, "CRVAL2 = %11.6f\n", crval2 ); + fprintf(fp, "CRPIX1 = %11.6f\n", crpix1+1500 ); + fprintf(fp, "CRPIX2 = %11.6f\n", crpix2+1500 ); + fprintf(fp, "CDELT1 = %.9f\n", -cdelt ); + fprintf(fp, "CDELT2 = %.9f\n", cdelt ); + fprintf(fp, "CROTA2 = %11.6f\n", 0.0 ); + fprintf(fp, "EQUINOX = %d\n", 2000 ); + + if(strcasecmp(survey, "2MASS") == 0) + { + if(strcasecmp(band, "J") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 20.9044); + + else if(strcasecmp(band, "H") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 20.4871); + + else if(strcasecmp(band, "K") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 19.9757); + } + + fprintf(fp, "END\n" ); + fclose(fp); + + + /************************************************/ + /* Get list of raw input images for this region */ + /************************************************/ + + /* this is how mExec is implemented */ + double scaleWidth = width * 1.42; + double scaleHeight = height * 1.42; + + if(path) + sprintf(cmd, "%s/bin/mArchiveList %s %s \"%s\" %.2f %.2f %s/images.tbl", + path, survey, band, mosaicCenter, scaleWidth, scaleHeight, workdir); + else + sprintf(cmd, "mArchiveList %s %s \"%s\" %.2f %.2f %s/images.tbl", + survey, band, mosaicCenter, scaleWidth, scaleHeight, workdir); + + if(debug) + { + fprintf(fdebug, "[%s]\n", cmd); + fflush(fdebug); + } + + svc_run(cmd); + + strcpy( status, svc_value( "stat" )); + + if (strcmp( status, "ERROR") == 0) + { + strcpy( msg, svc_value( "msg" )); + + printError(msg); + } + + if (strcmp(status, "ABORT") == 0) + { + strcpy( msg, svc_value( "msg" )); + + printError(msg); + } + + nimages = atof(svc_value("count")); + + if (nimages == 0) + { + sprintf( msg, "%s has no data covering this area", survey); + + printError(msg); + } + + + + /*****************************************/ + /* Get the image lists the DAG will need */ + /*****************************************/ + + if(path) + sprintf(cmd, "%s/bin/mDAGTbls %s/images.tbl %s/big_region.hdr %s/rimages.tbl %s/pimages.tbl %s/cimages.tbl", + path, workdir, workdir, workdir, workdir, workdir); + else + sprintf(cmd, "mDAGTbls %s/images.tbl %s/big_region.hdr %s/rimages.tbl %s/pimages.tbl %s/cimages.tbl", + workdir, workdir, workdir, workdir, workdir); + + + if(debug) + { + fprintf(fdebug, "[%s]\n", cmd); + fflush(fdebug); + } + + svc_run(cmd); + + strcpy( status, svc_value( "stat" )); + + if (strcmp( status, "ERROR") == 0) + { + strcpy( msg, svc_value( "msg" )); + + printError(msg); + } + + + + /******************************************/ + /* Get the overlap list the DAG will need */ + /******************************************/ + + if(path) + sprintf(cmd, "%s/bin/mOverlaps %s/rimages.tbl %s/diffs.tbl", + path, workdir, workdir); + else + sprintf(cmd, " mOverlaps %s/rimages.tbl %s/diffs.tbl", + workdir, workdir); + + if(debug) + { + fprintf(fdebug, "[%s]\n", cmd); + fflush(fdebug); + } + + svc_run(cmd); + + strcpy( status, svc_value( "stat" )); + + if (strcmp( status, "ERROR") == 0) + { + strcpy( msg, svc_value( "msg" )); + + printError(msg); + } + + + + /********************************************/ + /* Determine number of output mosaic tiles. */ + /********************************************/ + + tileSize = 7200; + tileOverlapX = 100; + tileOverlapY = 100; + + numTilesX = naxis1 / tileSize + 1; + numTilesY = naxis2 / tileSize + 1; + + numTiles = numTilesX * numTilesY; + + + + /****************************************************/ + /* Determine shrink factor for presentation image. */ + /****************************************************/ + + shrinkFactorX = (int)(naxis1 / 1024. + 1.); + shrinkFactorY = (int)(naxis2 / 1024. + 1.); + + shrinkFactor = shrinkFactorX; + if(shrinkFactor < shrinkFactorY) + shrinkFactor = shrinkFactorY; + + if(debug) + { + fprintf(fdebug, "\n"); + fprintf(fdebug, "numTilesX = %d\n", numTilesX); + fprintf(fdebug, "numTilesY = %d\n", numTilesY); + fprintf(fdebug, "numTiles = %d\n", numTiles); + fprintf(fdebug, "\n"); + fprintf(fdebug, "shrinkFactorX = %d\n", shrinkFactorX); + fprintf(fdebug, "shrinkFactorY = %d\n", shrinkFactorY); + fprintf(fdebug, "shrinkFactor = %d\n", shrinkFactor); + fprintf(fdebug, "\n"); + fflush(fdebug); + } + + if(numTiles > 1) + { + /*******************************/ + /* Create header template file */ + /*******************************/ + + sprintf(hdrFile, "%s/shrunken.hdr", workdir); + + fp = fopen(hdrFile, "w+"); + + if(fp == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening header template file\"]\n"); + exit(0); + } + + naxis1s = floor((double)naxis1/shrinkFactor); + naxis2s = floor((double)naxis2/shrinkFactor); + + fprintf(fp, "SIMPLE = T\n" ); + fprintf(fp, "BITPIX = -64\n" ); + fprintf(fp, "NAXIS = 2\n" ); + fprintf(fp, "NAXIS1 = %d\n", naxis1s ); + fprintf(fp, "NAXIS2 = %d\n", naxis2s ); + fprintf(fp, "CTYPE1 = '%s'\n", "RA---TAN" ); + fprintf(fp, "CTYPE2 = '%s'\n", "DEC--TAN" ); + fprintf(fp, "CRVAL1 = %11.6f\n", crval1 ); + fprintf(fp, "CRVAL2 = %11.6f\n", crval2 ); + fprintf(fp, "CRPIX1 = %11.6f\n", crpix1/shrinkFactor ); + fprintf(fp, "CRPIX2 = %11.6f\n", crpix2/shrinkFactor ); + fprintf(fp, "CDELT1 = %.9f\n", -cdelt*shrinkFactor ); + fprintf(fp, "CDELT2 = %.9f\n", cdelt*shrinkFactor ); + fprintf(fp, "CROTA2 = %11.6f\n", 0.0 ); + fprintf(fp, "EQUINOX = %d\n", 2000 ); + + if(strcasecmp(survey, "2MASS") == 0) + { + if(strcasecmp(band, "J") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 20.9044); + + else if(strcasecmp(band, "H") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 20.4871); + + else if(strcasecmp(band, "K") == 0) + fprintf(fp, "MAGZP = %11.6f\n", 19.9757); + } + + fprintf(fp, "END\n" ); + + fclose(fp); + } + + + + /**************************************************************************/ + /* If we are tiling the output mosaic: */ + /* */ + /* Create tiled header files, subset image tables, and list of shrunken */ + /* images. */ + /**************************************************************************/ + + if(!dax_mode) + { + sprintf(cmd, "%s/montage.makeflow", workdir); + fdag = fopen(cmd, "w+"); + } + + if(numTiles > 1) + { + sprintf(cmd, "%s/slist.tbl", workdir); + + fp = fopen(cmd, "w+"); + + if(fp == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening image list\"]\n"); + exit(0); + } + + fprintf(fp, "| file |\n"); + fprintf(fp, "| char |\n"); + + for(i=0; i\n"); + fprintf(fdag, "\n", timestr); + fprintf(fdag, "\n\n"); + fprintf(fdag, "\n\n"); + + fflush(fdag); + + fprintf(fdag, " \n", survey); + fprintf(fdag, " \n", band); + fprintf(fdag, " \n", mosaicCenter); + + if(haveHdr) + fprintf(fdag, " \n"); + else + { + fprintf(fdag, " \n", mosaicWidth); + fprintf(fdag, " \n", mosaicHeight); + } + + fprintf(fdag, "\n\n"); + fflush(fdag); + } + + /******************************************/ + /* compose the url lfn cache list */ + /******************************************/ + + sprintf(cmd, "%s/images.tbl", workdir); + + ncol = topen(cmd); + + ifname = tcol("file"); + iurl = tcol("URL"); + + if(ifname < 0) + printError("'Raw' image list does not have column 'file'"); + + if(iurl < 0) + printError("'Raw' image list does not have column 'url'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + fprintf(furl, "%s %s pool=\"ipac_cluster\"\n", tval(ifname), tval(iurl)); + + if(!dax_mode) + { + fprintf(fdag, "%s:\n\twget %s -O %s.gz %s.gz ; gunzip -d %s.gz\n\n", tval(ifname), tval(iurl), tval(ifname), tval(ifname), tval(ifname)); + } + } + + tclose(); + fclose(furl); + + + /******************************************/ + /* DAG: "filename" lines for input images */ + /******************************************/ + + if(dax_mode) + { + if(debug) + { + fprintf(fdebug, "Generating DAG file filename list ...\n"); + fflush(fdebug); + } + + fprintf(fdag, " \n\n"); + + sprintf(cmd, "%s/rimages.tbl", workdir); + + ncol = topen(cmd); + + ifname = tcol("file"); + + if(ifname < 0) + printError("'Raw' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + fprintf(fdag, " \n", tval(ifname)); + } + + fprintf(fdag, "\n"); + fflush(fdag); + tclose(); + } + + + /**********************************************/ + /* DAG: "filename" lines for projected images */ + /* including area files */ + /**********************************************/ + + if(dax_mode) + { + sprintf(cmd, "%s/pimages.tbl", workdir); + + ncol = topen(cmd); + + ifname = tcol("file"); + + if(ifname < 0) + printError("'Projected' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + fprintf(fdag, " \n", tval(ifname)); + + strcpy(fname, tval(ifname)); + + fname[strlen(fname)-5] = '\0'; + + strcat(fname, "_area.fits"); + + fprintf(fdag, " \n", fname); + } + + fprintf(fdag, "\n"); + fflush(fdag); + tclose(); + } + + + /***********************************************/ + /* DAG: "filename" lines for difference images */ + /* and fit output files (plus one more file */ + /* with a list of these fits) */ + /***********************************************/ + + sprintf(cmd, "%s/diffs.tbl", workdir); + + ncol = topen(cmd); + ifname = tcol("diff"); + icntr1 = tcol("cntr1"); + icntr2 = tcol("cntr2"); + + if(ifname < 0) + printError("'Diff' image list does not have column 'diff'"); + + sprintf(cmd, "%s/statfile.tbl", workdir); + + ffit = fopen(cmd, "w+"); + + sprintf(fmt, "|%%7s|%%7s|%%22s|\n"); + sprintf(dfmt, " %%7d %%7d %%22s \n"); + + fprintf(ffit, fmt, "cntr1", "cntr2", "stat"); + fprintf(ffit, fmt, "int", "int", "char"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + cntr1 = atoi(tval(icntr1)); + cntr2 = atoi(tval(icntr2)); + + if(dax_mode) + { + fprintf(fdag, " \n", tval(ifname)); + } + + strcpy(fname, tval(ifname)); + + fname[strlen(fname)-5] = '\0'; + + sprintf(fitname, "fit%s.txt", fname+4); + + if(dax_mode) + { + fprintf(fdag, " \n\n", fitname); + } + + fprintf(ffit, dfmt, cntr1, cntr2, fitname); + } + + fflush(fdag); + tclose(); + + fclose(ffit); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n"); + fprintf(fdag, "\n"); + fflush(fdag); + } + + fprintf(fcache, "statfile_%s.tbl %s/%s/statfile.tbl pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + + + /***********************************************/ + /* DAG: "filename" lines for corrections table */ + /* and the corrected image files (including */ + /* area files) */ + /***********************************************/ + + if(dax_mode) + { + fprintf(fdag, " \n"); + fprintf(fdag, "\n"); + fflush(fdag); + + sprintf(cmd, "%s/cimages.tbl", workdir); + + ncol = topen(cmd); + ifname = tcol("file"); + + if(ifname < 0) + printError("'Corrected' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + fprintf(fdag, " \n", tval(ifname)); + + strcpy(fname, tval(ifname)); + + fname[strlen(fname)-5] = '\0'; + + strcat(fname, "_area.fits"); + + fprintf(fdag, " \n", fname); + } + + fprintf(fdag, "\n"); + fflush(fdag); + tclose(); + } + + + /***********************************************/ + /* DAG: "filename" lines for template files, */ + /* subset image files, output files, and */ + /* shrunken output files. */ + /***********************************************/ + + if(dax_mode) + { + if(numTiles > 1) + { + for(i=0; i\n", i, j, idstr); + fprintf(fdag, " \n", i, j, idstr); + fprintf(fdag, " \n", i, j); + fprintf(fdag, " \n", i, j, idstr); + fprintf(fdag, " \n", i, j, idstr); + fprintf(fdag, " \n", i, j, idstr); + fprintf(fdag, "\n"); + + fprintf(fcache, "region_%d_%d_%s.hdr %s/%s/region_%d_%d.hdr pool=\"ipac_cluster\"\n", i, j, idstr, workurlbase, workdir, i, j); + fprintf(fcache, "cimages_%d_%d_%s.tbl %s/%s/cimages_%d_%d.tbl pool=\"ipac_cluster\"\n", i, j, idstr, workurlbase, workdir, i, j); + + } + } + + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, "\n"); + fflush(fdag); + + fprintf(fcache, "slist_%s.tbl %s/%s/slist.tbl pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + fflush(fdag); + fflush(fcache); + } + else + { + fprintf(fdag, " \n"); + fprintf(fdag, "\n"); + fflush(fdag); + } + + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, "\n"); + + if(numTiles == 1) + { + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, "\n"); + } + else + { + fprintf(fdag, " \n", idstr); + } + + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + fprintf(fdag, "\n\n"); + fflush(fdag); + + fprintf(fcache, "region_%s.hdr %s/%s/region.hdr pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + fprintf(fcache, "big_region_%s.hdr %s/%s/big_region.hdr pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + + if(numTiles > 1) + { + fprintf(fcache, "shrunken_%s.hdr %s/%s/shrunken.hdr pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + } + + fprintf(fcache, "pimages_%s.tbl %s/%s/pimages.tbl pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + fprintf(fcache, "cimages_%s.tbl %s/%s/cimages.tbl pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + fflush(fcache); + + /* to be saved in user's storage space */ + fprintf(fcache, "dag_%s.xml %s/%s/dag.xml pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + fprintf(fcache, "images_%s.tbl %s/%s/images.tbl pool=\"ipac_cluster\"\n", idstr, workurlbase, workdir); + } + + /**************************************************/ + /* DAG: "job" lines for mProject/mProjectPP jobs. */ + /**************************************************/ + + if(debug) + { + fprintf(fdebug, "Generating DAG file job list ...\n"); + fflush(fdebug); + } + + id = 0; + level = 9; + + if(numTiles > 1) + level = 12; + + if(dax_mode) + { + fprintf(fdag, " \n\n"); + } + + cntr = 0; + + sprintf(cmd, "%s/rimages.tbl", workdir); + + ncol = topen(cmd); + + ifname = tcol("file"); + iscale = tcol("scale"); + + if(ifname < 0) + printError("'Raw' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + ++id; + ++cntr; + + strcpy(fname, tval(ifname)); + + fname[strlen(fname) - 5] = '\0'; + + if(dax_mode) + { + fprintf(fdag," \n", id, mproj, level, cntr); + + if(iscale >= 0) + fprintf(fdag," \n -X\n -x %s\n \n \n \n \n\n", tval(iscale), fname, fname, idstr); + else + fprintf(fdag," \n -X\n \n \n \n \n\n", fname, fname, idstr); + + fprintf(fdag," \n", fname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "%s.fits", fname); + HT_add_entry(depends, key, val); + + if(haveurlbase) + { + if(dax_mode) + { + fprintf(fcache,"%s.fits %s/%s.fits pool=\"ipac_cluster\"\n",fname,urlbase,fname); + } + } + + if(dax_mode) + { + fprintf(fdag," \n", fname); + } + + sprintf(key, "p%s.fits", fname); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag," \n", fname); + + fprintf(fdag," \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "big_region.hdr"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag," \n\n\n"); + } + + if(!dax_mode) + { + if(iscale >= 0) + { + fprintf(fdag, "p%s.fits p%s_area.fits: %s.fits big_region.hdr ./%s\n\t./%s -X -x %s %s.fits p%s.fits big_region.hdr\n\n", fname, fname, fname, mproj, mproj, tval(iscale), fname, fname); + } + else + { + fprintf(fdag, "p%s.fits p%s_area.fits: %s.fits big_region.hdr ./%s\n\t./%s -X %s.fits p%s.fits big_region.hdr\n\n", fname, fname, fname, mproj, mproj, fname, fname); + } + } + } + + tclose(); + fflush(fcache); + fclose(fcache); + + + + /***************************************/ + /* DAG: "job" lines for mDiffFit jobs. */ + /***************************************/ + + cntr = 0; + + sprintf(cmd, "%s/diffs.tbl", workdir); + + ncol = topen(cmd); + + icntr1 = tcol("cntr1"); + icntr2 = tcol("cntr2"); + iplusname = tcol("plus"); + iminusname = tcol("minus"); + + --level; + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + ++id; + ++cntr; + + cntr1 = atoi(tval(icntr1)); + cntr2 = atoi(tval(icntr2)); + + strcpy(plusname, tval(iplusname)); + strcpy(minusname, tval(iminusname)); + + plusname [strlen(plusname) - 5] = '\0'; + minusname[strlen(minusname) - 5] = '\0'; + + fname[strlen(fname) - 5] = '\0'; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level, cntr); + + fprintf(fdag, " \n -s \n \n \n \n \n \n\n", + cntr1, cntr2, plusname, minusname, cntr1, cntr2, idstr); + + fprintf(fdag, " \n"); + fprintf(fdag, " \n"); + + fprintf(fdag, " \n", + cntr1, cntr2); + } + + sprintf(key, "fit.%06d.%06d.txt", cntr1, cntr2); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + plusname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "p%s.fits", plusname); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + plusname); + + fprintf(fdag, " \n", + minusname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "p%s.fits", minusname); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + minusname); + + fprintf(fdag, " \n", cntr1, cntr2); + } + + sprintf(key, "diff.%06d.%06d.fits", cntr1, cntr2); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "big_region.hdr"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + + if(!dax_mode) + { + fprintf(fdag, "fit.%06d.%06d.txt diff.%06d.%06d.fits diff.%06d.%06d_area.fits: p%s.fits p%s_area.fits p%s.fits p%s_area.fits big_region.hdr ./mDiffFit\n\t./mDiffFit -s fit.%06d.%06d.txt p%s.fits p%s.fits diff.%06d.%06d.fits big_region.hdr\n\n", cntr1, cntr2, cntr1, cntr2, cntr1, cntr2, plusname, plusname, minusname, minusname, cntr1, cntr2, plusname, minusname, cntr1, cntr2); + } + } + + tclose(); + + + + /****************************************/ + /* DAG: "job" line for mConcatFit jobs. */ + /****************************************/ + + ++id; + + --level; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level); + + fprintf(fdag, " \n \n \n .\n \n\n", idstr); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "statfile.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n"); + } + + sprintf(key, "fits.tbl"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + sprintf(cmd, "%s/diffs.tbl", workdir); + + ncol = topen(cmd); + icntr1 = tcol("cntr1"); + icntr2 = tcol("cntr2"); + + if(!dax_mode) + { + fprintf(fdag, "fits.tbl: "); + } + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + cntr1 = atoi(tval(icntr1)); + cntr2 = atoi(tval(icntr2)); + + if(dax_mode) + { + fprintf(fdag, " \n", + } + else + { + fprintf(fdag, "fit.%06d.%06d.txt ", cntr1, cntr2); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "fit.%06d.%06d.txt", cntr1, cntr2); + HT_add_entry(depends, key, val); + } + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mConcatFit\n\t./mConcatFit statfile.tbl fits.tbl .\n\n", path); + } + tclose(); + + + /*************************************/ + /* DAG: "job" line for mBgModel job. */ + /*************************************/ + + ++id; + + --level; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level); + + fprintf(fdag, " \n -i 100000\n \n \n \n \n\n", idstr); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "pimages.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n"); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "fits.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n"); + } + + sprintf(key, "corrections.tbl"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, "corrections.tbl: pimages.tbl fits.tbl ./mBgModel\n\t./mBgModel -i 100000 pimages.tbl fits.tbl corrections.tbl\n\n", path); + } + + /*****************************************/ + /* DAG: "job" line for mBackground jobs. */ + /*****************************************/ + + --level; + + cntr = 0; + + sprintf(cmd, "%s/rimages.tbl", workdir); + + ncol = topen(cmd); + ifname = tcol("file"); + + if(ifname < 0) + printError("'Raw' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + strcpy(fname, tval(ifname)); + + fname[strlen(fname) - 5] = '\0'; + + ++id; + ++cntr; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level, cntr); + + fprintf(fdag, " \n -t\n \n \n \n \n \n\n", + fname, fname, idstr); + + fprintf(fdag, " \n", + fname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "p%s.fits", fname); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", fname); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "pimages.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n"); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "corrections.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", fname); + } + + sprintf(key, "c%s.fits", fname); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + fname); + + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, "c%s.fits c%s_area.fits: p%s.fits p%s_area.fits pimages.tbl corrections.tbl ./mBackground\n\t./mBackground -t p%s.fits c%s.fits pimages.tbl corrections.tbl\n\n", fname, fname, fname, fname, fname, fname); + } + } + + fflush(fdag); + + + + /**********************************************/ + /* DAG: "job" lines for tile mImgtbl jobs. */ + /* We have to regenerate the cimages table(s) */ + /* because the pixel offsets and sizes need */ + /* to be exactly right and the original is */ + /* only an approximation. */ + /**********************************************/ + + --level; + + cntr = 0; + + if(numTiles > 1) + { + for(i=0; i\n", + id, level, cntr); + + fprintf(fdag, " \n .\n -t \n \n \n\n", + i, j, idstr, i, j); + + fprintf(fdag, " \n", + i, j, idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "cimages_%d_%d.tbl", i, j); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", i, j); + } + + sprintf(key, "newcimages_%d_%d.tbl",i,j); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + sprintf(cmd, "%s/cimages_%d_%d.tbl", workdir, i, j); + + if(!dax_mode) + { + fprintf(fdag, "newcimages_%d_%d.tbl: cimages.tbl ", i, j); + } + + ncol = topen(cmd); + ifname = tcol("file"); + + if(ifname < 0) + printError("'Corrected' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + strcpy(fname, tval(ifname)); + + fname[strlen(fname) - 5] = '\0'; + + if(dax_mode) + { + fprintf(fdag, " \n", + fname); + } + else + { + fprintf(fdag, "%s.fits ", fname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "%s.fits", fname); + HT_add_entry(depends, key, val); + } + + tclose(); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mImgtbl\n\t./mImgtbl . -t cimages.tbl newcimages_%d_%d.tbl\n\n", i, j); + } + + fflush(fdag); + } + } + } + else + { + ++id; + ++cntr; + + if(dax_mode) + { + fprintf(fdag, " \n", + id, level, cntr); + + fprintf(fdag, " \n .\n -t \n \n \n\n", idstr); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "cimages.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n"); + } + + sprintf(key, "newcimages.tbl"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + sprintf(cmd, "%s/cimages.tbl", workdir); + + ncol = topen(cmd); + ifname = tcol("file"); + + if(!dax_mode) + { + fprintf(fdag, "newcimages.tbl: cimages.tbl "); + } + + if(ifname < 0) + printError("'Corrected' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + strcpy(fname, tval(ifname)); + + fname[strlen(fname) - 5] = '\0'; + + if(dax_mode) + { + fprintf(fdag, " \n", + fname); + } + else + { + fprintf(fdag, "%s.fits ", fname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "%s.fits", fname); + HT_add_entry(depends, key, val); + } + + tclose(); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mImgtbl\n\t./mImgtbl . -t cimages.tbl newcimages.tbl\n\n", path); + } + + fflush(fdag); + } + + + + /*******************************************/ + /* DAG: "job" lines for tile mAdd jobs. */ + /*******************************************/ + + --level; + + cntr = 0; + + if(numTiles > 1) + { + for(i=0; i\n", + id, level, cntr); + + fprintf(fdag, " \n -e\n \n \n \n \n\n", + i, j, i, j, idstr, i, j, idstr); + + fprintf(fdag, " \n", + i, j); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "newcimages_%d_%d.tbl", i, j); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + i, j, idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "region_%d_%d.hdr", i, j); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + i, j, idstr); + } + + sprintf(key, "tile_%d_%d.fits", i, j); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + i, j, idstr); + } + + sprintf(cmd, "%s/cimages_%d_%d.tbl", workdir, i, j); + + ncol = topen(cmd); + ifname = tcol("file"); + + if(!dax_mode) + { + fprintf(fdag, "tile_%d_%d_%s.fits tile_%d_%d_%s_area.fits: newcimages_%d_%d.tbl region.hdr ", i, j, idstr, i, j, idstr, i, j); + } + + if(ifname < 0) + printError("'Corrected' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + strcpy(fname, tval(ifname)); + + fname[strlen(fname) - 5] = '\0'; + + if(dax_mode) + { + fprintf(fdag, " \n", + fname); + + fprintf(fdag, " \n", + fname); + } + else + { + fprintf(fdag, "%s.fits %s_area.fits ", fname, fname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "%s.fits", fname); + HT_add_entry(depends, key, val); + } + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mAdd\n\t./mAdd -e newcimages_%d_%d.tbl region.hdr tile_%d_%d_%s.fits\n\n", i, j, i, j, idstr); + } + + fflush(fdag); + } + } + } + else + { + ++id; + ++cntr; + + if(dax_mode) + { + fprintf(fdag, " \n", + id, level, cntr); + + fprintf(fdag, " \n -e\n \n \n \n \n\n", idstr, idstr); + + fprintf(fdag, " \n"); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "newcimages.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "region.hdr"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "mosaic.fits"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(cmd, "%s/cimages.tbl", workdir); + + ncol = topen(cmd); + ifname = tcol("file"); + + if(!dax_mode) + { + fprintf(fdag, "mosaic_%s.fits mosaic_%s_area.fits: newcimages.tbl region.hdr ", idstr, idstr); + } + + if(ifname < 0) + printError("'Corrected' image list does not have column 'file'"); + + while(1) + { + istat = tread(); + + if(istat < 0) + break; + + strcpy(fname, tval(ifname)); + + fname[strlen(fname) - 5] = '\0'; + + if(dax_mode) + { + fprintf(fdag, " \n", + fname); + + fprintf(fdag, " \n", + fname); + } + else + { + fprintf(fdag, "%s.fits %s_area.fits ", fname, fname); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "%s.fits", fname); + HT_add_entry(depends, key, val); + + } + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mAdd\n\t./mAdd -e newcimages.tbl region.hdr mosaic_%s.fits\n\n", idstr); + } + + fflush(fdag); + } + + mAddCntr = cntr; + + + + /*******************************************/ + /* DAG: "job" lines for tile mShrink jobs. */ + /*******************************************/ + + --level; + + cntr = 0; + + if(numTiles > 1) + { + for(i=0; i\n", id, level, cntr); + + fprintf(fdag, " \n \n \n %d\n \n\n", + i, j, idstr, i, j, idstr, shrinkFactor); + + fprintf(fdag, " \n", + i, j, idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "tile_%d_%d.fits", i, j); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", + i, j, idstr); + } + + sprintf(key, "shrunken_%d_%d.fits", i, j); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, "shrunken_%d_%d_%s.fits: tile_%d_%d_%s.fits ./mShrink\n\t./mShrink tile_%d_%d_%s.fits shrunken_%d_%d_%s.fits %d\n\n", + i, j, idstr, i, j, idstr, i, j, idstr, i, j, idstr, shrinkFactor); + } + + } + } + } + else + { + ++id; + ++cntr; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level, cntr); + + fprintf(fdag, " \n \n \n %d\n \n\n", idstr, idstr, shrinkFactor); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "mosaic.fits"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "shrunken.fits"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, "shrunken_%s.fits: mosaic_%s.fits ./mShrink\n\t./mShrink mosaic_%s.fits shrunken_%s.fits %d\n\n", idstr, idstr, idstr, idstr, shrinkFactor); + } + } + + fflush(fdag); + + + + /*******************************************/ + /* DAG: If there are tiles, we need to */ + /* do a final coadd of the shrunken tile */ + /* images to make a full area shrunken */ + /* mosaic. */ + /*******************************************/ + + if(numTiles > 1) + { + /***********/ + /* mImgTbl */ + /***********/ + + ++id; + + --level; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level); + + fprintf(fdag, " \n .\n -t \n \n \n\n", idstr, idstr); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "slist.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "simages.tbl"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(!dax_mode) + { + fprintf(fdag, "simages_%s.tbl: slist_%s.tbl ", idstr, idstr); + } + + for(i=0; i\n", + i, j, idstr); + } + else + { + fprintf(fdag, "shrunken_%d_%d_%s.fits ", i, j, idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "shrunken_%d_%d.fits", i, j); + HT_add_entry(depends, key, val); + } + } + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mImgtbl\n\t./mImgtbl . -t slist_%s.tbl simages_%s.tbl\n\n", idstr, idstr); + } + + fflush(fdag); + + + /********/ + /* mAdd */ + /********/ + + ++id; + + --level; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level, mAddCntr+1); + + fprintf(fdag, " \n -n\n -e\n \n \n \n \n\n", idstr, idstr, idstr); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "simages.tbl"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "shrunken.hdr"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "shrunken.fits"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(!dax_mode) { + fprintf(fdag, "shrunken_%s.fits: simages_%s.tbl shrunken_%s.hdr ", idstr, idstr, idstr); + } + + for(i=0; i\n", + i, j, idstr); + } + else + { + fprintf(fdag, "shrunken_%d_%d_%s.fits ", i, j, idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "shrunken_%d_%d.fits", i, j); + HT_add_entry(depends, key, val); + } + } + + if(dax_mode) + { + fprintf(fdag, " \n\n\n"); + } + else + { + fprintf(fdag, " ./mAdd\n\t./mAdd -n -e simages_%s.tbl shrunken_%s.hdr shrunken_%s.fits\n\n", idstr, idstr, idstr); + } + + } + + fflush(fdag); + + + + /****************************/ + /* DAG: Make the final JPEG */ + /****************************/ + + ++id; + + --level; + + if(dax_mode) + { + fprintf(fdag, " \n", id, level); + + fprintf(fdag, " \n -ct 1\n -gray \n min max gaussianlog\n -out \n \n\n", idstr, idstr); + + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "ID%06d", id); + sprintf(val, "shrunken.fits"); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "shrunken.jpg"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "dag.xml"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n", idstr); + fprintf(fdag, " \n", idstr); + } + + sprintf(key, "images.tbl"); + sprintf(val, "ID%06d", id); + HT_add_entry(depends, key, val); + + if(dax_mode) + { + fprintf(fdag, " \n\n\n\n"); + } + else + { + fprintf(fdag, "shrunken_%s.jpg: shrunken_%s.fits ./mJPEG\n\t./mJPEG -ct 1 -gray shrunken_%s.fits min max gaussianlog -out shrunken_%s.jpg\n\n", + idstr, idstr, idstr, idstr); + } + + fflush(fdag); + + + + /*******************************************/ + /* DAG: Flow control dependencies. */ + /* First, mDiffs depend on mProjects */ + /*******************************************/ + + if(dax_mode) + { + if(debug) + { + fprintf(fdebug, "Generating DAG file parent/child info ...\n"); + fflush(fdebug); + } + + fprintf(fdag, " \n\n"); + + sprintf(fileList, "%s/files.lis", workdir); + sprintf(parentList, "%s/parents.lis", workdir); + sprintf(sortedParent, "%s/sortedParents.lis", workdir); + + for(i=1; i<=id; ++i) + { + sprintf(jobid, "ID%06d", i); + + fileid = HT_lookup_key(depends, jobid); + + ffile = fopen(fileList, "w+"); + + if(ffile == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening working file list for write\"]\n"); + exit(0); + } + + while(fileid != (char *)NULL) + { + fprintf(ffile, "%s\n", fileid); + fflush(ffile); + + fileid = HT_next_entry(depends); + } + + fclose(ffile); + + ffile = fopen(fileList, "r"); + + if(ffile == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening working file list for read\"]\n"); + exit(0); + } + + fparent = fopen(parentList, "w+"); + + if(fparent == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening parent list\"]\n"); + exit(0); + } + + nparents = 0; + + fprintf(fparent, "| parent |\n"); + + while(1) + { + if(fgets(line, MAXSTR, ffile) == (char *)NULL) + break; + + if(line[strlen(line)-1] == '\n') + line[strlen(line)-1] = '\0'; + + parentid = HT_lookup_key(depends, line); + + while(parentid != (char *)NULL) + { + parent = atoi(parentid+2); + + fprintf(fparent, " %12d\n", parent); + fflush(fparent); + + ++nparents; + + parentid = HT_next_entry(depends); + } + } + + fclose(ffile); + fclose(fparent); + + unlink(fileList); + + if(nparents > 0) + { + + if(path) + sprintf(cmd, "%s/bin/mTblSort %s parent %s", path, parentList, sortedParent); + else + sprintf(cmd, "mTblSort %s parent %s", parentList, sortedParent); + + svc_run(cmd); + + strcpy( status, svc_value( "stat" )); + + if (strcmp( status, "ERROR") == 0) + { + strcpy( msg, svc_value( "msg" )); + + printError(msg); + } + + unlink(parentList); + + fparent = fopen(sortedParent, "r"); + + if(fparent == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Error opening sorted parent list\"]\n"); + exit(0); + } + + fgets(line, MAXSTR, fparent); + + fprintf(fdag, " \n", jobid); + + for(j=0; j 0 && parent == parent_prev) + continue; + + fprintf(fdag, " \n", parent); + } + + fprintf(fdag, " \n\n"); + fflush(fdag); + + fclose(fparent); + } + unlink(sortedParent); + } + + fprintf(fdag, "\n"); + fflush(fdag); + fclose(fdag); + + if(debug) + { + fprintf(fdebug, "done.\n"); + fflush(fdebug); + } + } + + printf("[struct stat=\"OK\", id=\"%s\"]\n", idstr); + exit(0); +} + + + + + + +/**************************************************/ +/* */ +/* Read the output header template file. */ +/* Specifically extract the image size info. */ +/* Also, create a single-string version of the */ +/* header data and use it to initialize the */ +/* output WCS transform. */ +/* */ +/**************************************************/ + +int readTemplate(char *template) +{ + int j; + FILE *fp; + char line[MAXSTR]; + char header[80000]; + + fp = fopen(template, "r"); + + if(fp == (FILE *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Bad template: %s\"]\n", + template); + fflush(stdout); + exit(1); + } + + strcpy(header, ""); + + if(debug) + { + fprintf(fdebug, "\nTemplate Header (%s):\n", + template); + fflush(fdebug); + } + + for(j=0; j<1000; ++j) + { + if(fgets(line, MAXSTR, fp) == (char *)NULL) + break; + + if(line[strlen(line)-1] == '\n') + line[strlen(line)-1] = '\0'; + + if(line[strlen(line)-1] == '\r') + line[strlen(line)-1] = '\0'; + + stradd(header, line); + + if(debug) + { + fprintf(fdebug, "%s\n", line); + fflush(fdebug); + } + } + + if(debug) + { + fprintf(fdebug, "\n"); + fflush(fdebug); + } + + + wcs = wcsinit(header); + + if(wcs == (struct WorldCoor *)NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Output wcsinit() failed.\"]\n"); + fflush(stdout); + exit(1); + } + + naxis1 = wcs->nxpix; + naxis2 = wcs->nypix; + + if(wcs->syswcs == WCS_J2000) + { + sys = EQUJ; + epoch = 2000.; + + if(wcs->equinox == 1950.) + epoch = 1950; + } + else if(wcs->syswcs == WCS_B1950) + { + sys = EQUB; + epoch = 1950.; + + if(wcs->equinox == 2000.) + epoch = 2000; + } + else if(wcs->syswcs == WCS_GALACTIC) + { + sys = GAL; + epoch = 2000.; + } + else if(wcs->syswcs == WCS_ECLIPTIC) + { + sys = ECLJ; + epoch = 2000.; + + if(wcs->equinox == 1950.) + { + sys = ECLB; + epoch = 1950.; + } + } + else + { + sys = EQUJ; + epoch = 2000.; + } + + + if(debug) + { + fprintf(fdebug, "DEBUG> Template WCS initialized\n\n"); + fflush(fdebug); + } + + fclose(fp); + + return(0); +} + + + +int stradd(char *header, char *card) +{ + int i, hlen, clen; + + hlen = strlen(header); + clen = strlen(card); + + for(i=0; i ", mosaicCenter); + fflush(fdebug); + } + + send(socket, request, strlen(request), 0); + + + /* Read the data coming back */ + + count = 0; + j = 0; + + while(1) + { + for(i=0; i= endPtr) + { + printf("[struct stat=\"ERROR\", msg=\"Can't find RA in lookup return.\"]\n"); + fflush(stdout); + exit(1); + } + + ++ptr; + + *ra = atof(ptr); + + + /* Find the Dec */ + + ptr = strstr(result, "\"lat\""); + + if(!ptr) + { + printf("[struct stat=\"ERROR\", msg=\"Can't find Dec in lookup return.\"]\n"); + fflush(stdout); + exit(1); + } + + while(*ptr != '>' && ptr < endPtr) + ++ptr; + + if(ptr >= endPtr) + { + printf("[struct stat=\"ERROR\", msg=\"Can't find Dec in lookup return.\"]\n"); + fflush(stdout); + exit(1); + } + + ++ptr; + + *dec = atof(ptr); + + if(debug) + { + fprintf(fdebug, " (%.6f,%.6f)\n\n", *ra, *dec); + fflush(fdebug); + } + + return(0); +} + + + + +/***********************************************/ +/* This is the basic "make a connection" stuff */ +/***********************************************/ + +int tcp_connect(char *hostname, int port) +{ + int sock_fd; + struct hostent *host; + struct sockaddr_in sin; + + + if((host = gethostbyname(hostname)) == NULL) + { + printf("[struct stat=\"ERROR\", msg=\"Couldn't find host %s\"]\n", hostname); + fflush(stdout); + return(0); + } + + if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + printf("[struct stat=\"ERROR\", msg=\"Couldn't create socket()\"]\n"); + fflush(stdout); + return(0); + } + + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + + bcopy(host->h_addr_list[0], &sin.sin_addr, host->h_length); + //bcopy(host->h_addr, &sin.sin_addr, host->h_length); + + if(connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) + { + printf("[struct stat=\"ERROR\", msg=\"%s: connect failed.\"]\n", hostname); + fflush(stdout); + return(0); + } + + return sock_fd; +} + + + +/**************************************/ +/* This routine URL-encodes a string */ +/**************************************/ + +static unsigned char hexchars[] = "0123456789ABCDEF"; + +char *url_encode(char *s) +{ + int len; + register int i, j; + unsigned char *str; + + len = strlen(s); + + str = (unsigned char *) malloc(3 * strlen(s) + 1); + + j = 0; + + for (i=0; i '9') || + (str[j] > 'Z' && str[j] < 'a' && str[j] != '_') || + (str[j] > 'z')) + { + str[j++] = '%'; + + str[j++] = hexchars[(unsigned char) s[i] >> 4]; + + str[j] = hexchars[(unsigned char) s[i] & 15]; + } + + ++j; + } + + str[j] = '\0'; + + return ((char *) str); +} + + +/* vim: set noexpandtab tabstop=3: */ diff --git a/montage/montage.png b/montage/montage.png new file mode 100644 index 0000000..a240c2f Binary files /dev/null and b/montage/montage.png differ