Index: /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtract.c
===================================================================
--- /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtract.c	(revision 23322)
+++ /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtract.c	(revision 23322)
@@ -0,0 +1,83 @@
+/** @file psastroExtract.c
+ *
+ *  @brief
+ *
+ *  @ingroup psastroExtract
+ *
+ *  @author IfA
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-07 02:03:34 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "psastroStandAlone.h"
+
+int main (int argc, char **argv) {
+
+    pmConfig *config = NULL;
+
+    psTimerStart ("complete");
+
+    psastroErrorRegister();              // register our error codes/messages
+
+    // model inits are needed in pmSourceIO
+    // models defined in psphot/src/models are not available in psastro
+    pmModelClassInit ();
+
+    // load configuration information
+    config = psastroExtractArguments (argc, argv);
+
+    // load identify the data sources
+    if (!psastroExtractParseCamera (config)) {
+	psErrorStackPrint(stderr, "error setting up the camera\n");
+	exit (1);
+    }
+
+    // load the raw pixel data (from PSPHOT.SOURCES)
+    // select subset of stars for astrometry
+    if (!psastroExtractDataLoad (config)) {
+	psErrorStackPrint(stderr, "error loading input data\n");
+	exit (1);
+    }
+
+    // load the reference stars overlapping the data stars
+    psArray *refs = psastroLoadRefstars(config);
+    if (!refs) {
+        psError (PSASTRO_ERR_UNKNOWN, false, "failed to load reference data\n");
+        return false;
+    }
+    if (refs->n == 0) {
+        psError(PSASTRO_ERR_REFSTARS, true, "no reference stars found");
+        psFree(refs);
+        return false;
+    }
+
+    if (!psastroChooseRefstars (config, refs)) {
+        psError (PSASTRO_ERR_UNKNOWN, false, "failed to select reference data for chips\n");
+        psFree(refs);
+        return false;
+    }
+
+    // run the full astrometry analysis (chip and/or mosaic)
+    if (!psastroExtractAnalysis (config)) {
+	psErrorStackPrint(stderr, "failure in psastro model analysis\n");
+	exit (1);
+    }
+    
+    // run the full astrometry analysis (chip and/or mosaic)
+    if (!psastroExtractAdjust (config)) {
+	psErrorStackPrint(stderr, "failure in psastro model adjust\n");
+	exit (1);
+    }
+    
+    // save the model
+    if (!psastroExtractDataSave (config)) {
+	psErrorStackPrint(stderr, "error saving output data\n");
+	exit (1);
+    }
+
+    psLogMsg ("psastro", 3, "complete psastro run: %f sec\n", psTimerMark ("complete"));
+
+    // psastroCleanup (config);
+    exit (EXIT_SUCCESS);
+}
Index: /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractAnalysis.c
===================================================================
--- /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractAnalysis.c	(revision 23322)
+++ /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractAnalysis.c	(revision 23322)
@@ -0,0 +1,158 @@
+/** @file psastroExtractAnalysis.c
+ *
+ *  @brief 
+ *
+ *  @ingroup psastroExtract
+ *
+ *  @author IfA
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-07 02:03:34 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "psastroInternal.h"
+
+# define ESCAPE { \
+  psError(PS_ERR_UNKNOWN, false, "I/O failure in psastroMaskUpdate"); \
+  psFree (view); \
+  return false; \
+}
+
+# define TEST_OUTPUT 1
+static pmFits *outStars = NULL;
+
+/**
+ * create a mask or mask regions based on the collection of reference stars that * are in the vicinity of each chip
+ */
+bool psastroExtractAnalysis (pmConfig *config) {
+
+    bool status;
+    pmChip *chip = NULL;
+    pmCell *cell = NULL;
+    pmReadout *readout = NULL;
+    float zeropt, exptime;
+
+    // select the current recipe
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
+    if (!recipe) {
+        psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe");
+        return false;
+    }
+
+    psLogMsg ("psastro", PS_LOG_INFO, "extracting bright-star subrasters");
+
+    double EXTRACT_MAX_MAG = psMetadataLookupF32 (&status, recipe, "EXTRACT_MAX_MAG");
+
+    // we have two input pmFPAfiles: PSASTRO.EXTRACT.INPUT and PSASTRO.EXTRACT.ASTROM.  both are in chip-mosaic or fpa format
+    // we have already loaded the headers from PSASTRO.EXTRACT.ASTROM and determined the astrometry terms
+
+    // select the input data sources
+    pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSASTRO.EXTRACT.INPUT");
+    if (!input) {
+        psError(PSASTRO_ERR_CONFIG, true, "Can't find input data");
+        return false;
+    }
+    pmFPA *fpa = input->fpa;
+
+    // select the input data sources
+    pmFPAfile *astrom = psMetadataLookupPtr (NULL, config->files, "PSASTRO.EXTRACT.ASTROM");
+    if (!input) {
+        psError(PSASTRO_ERR_CONFIG, true, "Can't find input data");
+        return false;
+    }
+
+    // only load data from INPUT
+    pmFPAfileActivate(config->files, false, NULL);
+    pmFPAfileActivate(config->files, true, "PSASTRO.EXTRACT.INPUT");
+
+    // really error-out here?  or just skip?
+    if (!psastroZeroPointFromRecipe (&zeropt, &exptime, fpa, recipe)) {
+        psLogMsg ("psastro", PS_LOG_INFO, "failed to load zeropt data from recipe");
+        return false;
+    }
+
+    // recipe values are given in instrumental magnitudes
+    // use the zero point and exposure time to convert to apparent mags: M_ap = M_inst + C_0 + 2.5*log(exptime)
+    float MagOffset = zeropt + 2.5*log10(exptime);
+    EXTRACT_MAX_MAG += MagOffset;
+
+    // open the output file handle: we are just saving a series of extensions to this file
+    if (!outStars) {
+      char *filename = psMetadataLookupStr (&stats, config->arguments, "OUTPUT");
+      if (!filename) {
+        psLogMsg ("psastro", PS_LOG_INFO, "output filename not supplieda");
+        return false;
+      }
+      outStars = psFitsOpen (filename, "w");
+      if (!outStars) {
+	psError(PS_ERR_IO, false, "error opening file %s\n", filename);
+	return false;
+      }
+      // call: psFitsWriteImage (fits, NULL, subraster, 0, "extname.NN");
+    }
+
+    // open/load files as needed
+    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE;
+
+    // this loop selects the matched stars for all chips
+    while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
+        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process || !chip->file_exists) { continue; }
+        if (!chip->fromFPA) { continue; }
+
+        if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE;
+
+        // text output file for testing
+        FILE *f = NULL;
+        if (TEST_OUTPUT) {
+          char *filename = NULL;
+          char *chipname = psMetadataLookupStr (&status, chip->concepts, "CHIP.NAME");
+          psStringAppend (&filename, "bright.%s.dat", chipname);
+          FILE *f = fopen (filename, "w");
+          if (!f) {
+            psWarning ("cannot create test output file %s\n", filename);
+            continue;
+          }
+          psFree (filename);
+        }
+
+        while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
+            psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
+            if (!cell->process || !cell->file_exists) { continue; }
+
+            // process each of the readouts
+            while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
+                if (! readout->data_exists) { continue; }
+
+                // select the raw objects for this readout (loaded in psastroExtract.c)
+                psArray *refstars = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.REFSTARS");
+                if (refstars == NULL) { continue; }
+
+                // identify the bright stars of interest
+                for (int i = 0; i < refstars->n; i++) {
+                    pmAstromObj *ref = refstars->data[i];
+                    if (ref->Mag > REFSTAR_MASK_MAX_MAG) continue;
+
+                    if (TEST_OUTPUT) {
+                      fprintf (f, "stars %f %f  %f %f   %f\n", ref->chip->x, ref->chip->y, ref->FP->x, ref->FP->y, ref->Mag);
+                    }
+
+                    // XXX for now, assume cell binning is 1x1 relative to chip
+		    psImage *subraster = psastroExtractStar (input->image, ref->chip->x, ref->chip->y, DX, DY);
+                }
+                if (!pmFPAfileIOChecks (config, viewMask, PM_FPA_AFTER)) ESCAPE;
+            }
+            if (!pmFPAfileIOChecks (config, viewMask, PM_FPA_AFTER)) ESCAPE;
+        }
+        if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE;
+
+    }
+    if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE;
+
+    // need to close the output fits file on some basis..
+    fclose (f);
+
+    psFree (view);
+    return true;
+}
+
Index: /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractArguments.c
===================================================================
--- /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractArguments.c	(revision 23322)
+++ /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractArguments.c	(revision 23322)
@@ -0,0 +1,73 @@
+/** @file psastroExtractArguments.c
+ *
+ *  @brief
+ *
+ *  @ingroup psastroExtract
+ *
+ *  @author IfA
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-07 02:03:34 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "psastroStandAlone.h"
+
+static char *usage = "USAGE: psastroExtract [-outroot root] -astrom (cmffiles)";
+
+pmConfig *psastroExtractArguments (int argc, char **argv) {
+
+    int N;
+
+    if (argc == 1) {
+        psError(PSASTRO_ERR_ARGUMENTS, true, "No arguments supplied");
+        psErrorStackPrint(stderr, "%s", usage);
+	exit (1);
+    }
+
+    // load config data from default locations
+    pmConfig *config = pmConfigRead(&argc, argv, PSASTRO_RECIPE);
+    if (config == NULL) {
+        psError(PSASTRO_ERR_CONFIG, false, "Can't read site configuration");
+        psErrorStackPrint(stderr, "%s", usage);
+	exit (1);
+    }
+
+    // save the following additional recipe values based on command-line options
+    // these options override the PSASTRO recipe values loaded from recipe files
+    // psMetadata *options = pmConfigRecipeOptions (config, PSASTRO_RECIPE);
+
+    if (!pmConfigFileSetsMD (config->arguments, &argc, argv, "INPUT", "-file", "-list")) {
+        psError(PSASTRO_ERR_ARGUMENTS, true, "Missing -file (input) or -list (input)");
+        psErrorStackPrint(stderr, "%s", usage);
+	exit (1);
+    }
+
+    // XXX require this?
+    pmConfigFileSetsMD(config->arguments, &argc, argv, "ASTROM",   "-astrom", "-astromlist");
+
+    // define the output filename
+    N = psArgumentGet (argc, argv, "-output");
+    if (!N) {
+	psError(PSASTRO_ERR_ARGUMENTS, true, "Missing -output (root)");
+        psErrorStackPrint(stderr, "%s", usage);
+	exit (1);
+    }
+    psArgumentRemove (N, &argc, argv);
+    psMetadataAddStr (config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "", argv[N]);
+    psArgumentRemove (N, &argc, argv);
+
+    // chip selection is used to limit chips to be processed
+    if ((N = psArgumentGet (argc, argv, "-chip"))) {
+        psArgumentRemove (N, &argc, argv);
+        psMetadataAddStr (config->arguments, PS_LIST_TAIL, "CHIP_SELECTIONS", PS_META_REPLACE, "", argv[N]);
+        psArgumentRemove (N, &argc, argv);
+    }
+    
+    if (argc < 1) {
+        psError(PSASTRO_ERR_ARGUMENTS, true, "Incorrect arguments supplied");
+        psErrorStackPrint(stderr, "exit");
+	exit (1);
+    }
+
+    return (config);
+}
Index: /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractDataLoad.c
===================================================================
--- /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractDataLoad.c	(revision 23322)
+++ /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractDataLoad.c	(revision 23322)
@@ -0,0 +1,103 @@
+/** @file psastroExtractDataLoad.c
+ *
+ *  @brief
+ *
+ *  @ingroup psastroExtract
+ *
+ *  @author IfA
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-07 02:03:34 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "psastroStandAlone.h"
+
+# define ESCAPE { \
+  psError(PS_ERR_UNKNOWN, false, "Failure in psastroExtractDataLoad"); \
+  psFree (view); \
+  return false; \
+}
+  
+/**
+ * this loop loads the header data from the input files, using the output 
+ * pmFPAfile to guide the chip selection and related issues
+ * all of the different astrometry analysis modes use the same data load loop
+ */
+bool psastroExtractDataLoad (pmConfig *config) {
+
+    bool status;
+    pmChip *chip;
+
+    psTimerStart ("psastro");
+
+    // select the current recipe
+    psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSASTRO_RECIPE);
+    if (!recipe) {
+	psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe!\n");
+	return false;
+    }
+
+    // physical pixel scale in microns per pixel
+    double pixelScale = psMetadataLookupF32 (&status, recipe, "PSASTRO.PIXEL.SCALE");
+    if (!status) {
+	psError(PS_ERR_IO, true, "Failed to lookup pixel scale"); 
+	return false; 
+    } 
+
+    // select the input data sources
+    pmFPAfile *astrom = psMetadataLookupPtr (NULL, config->files, "PSASTRO.EXTRACT.ASTROM");
+    if (!astrom) psAbort ("PSASTRO.EXTRACT.ASTROM not listed in config->files");
+
+    pmFPAfileActivate(config->files, false, NULL);
+    pmFPAfileActivate(config->files, true, "PSASTRO.EXTRACT.ASTROM");
+
+    pmFPAview *view = pmFPAviewAlloc (0);
+
+    // files associated with the science image
+    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE;
+
+    // load the headers from the astrometry files
+    while ((chip = pmFPAviewNextChip (view, astrom->fpa, 1)) != NULL) {
+        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process) { continue; }
+	if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE;
+    }
+    psLogMsg ("psastro", 3, "load headers : %f sec\n", psTimerMark ("psastro"));
+
+    // check PHU header to see if we are using mosaic-level or per-chip astrometry
+    bool bilevelAstrometry = false;
+    pmHDU *phu = pmFPAviewThisPHU (view, astrom->fpa);
+    if (phu) {
+      char *ctype = psMetadataLookupStr (NULL, phu->header, "CTYPE1");
+      if (ctype) bilevelAstrometry = !strcmp (&ctype[4], "-DIS");
+    }
+    if (bilevelAstrometry) {
+      pmAstromReadBilevelMosaic (astrom->fpa, phu->header);
+    } 
+
+    while ((chip = pmFPAviewNextChip (view, astrom->fpa, 1)) != NULL) {
+      psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+      if (!chip->process || !chip->file_exists || !chip->data_exists) { continue; }
+
+      // read WCS data from the corresponding header
+      pmHDU *hdu = pmFPAviewThisHDU (view, astrom->fpa);
+      int nAstro = psMetadataLookupS32 (&status, hdu->header, "NASTRO");
+      if (!nAstro) continue;
+
+      if (bilevelAstrometry) {
+	if (!pmAstromReadBilevelChip (chip, hdu->header)) {
+	  psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 
+	  continue;
+	} 
+      } else {
+	if (!pmAstromReadWCS (astrom->fpa, chip, hdu->header, pixelScale)) {
+	  psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 
+	  continue;
+	} 
+      }
+    }
+    psLogMsg ("psastro", 3, "convert wcs terms to internal format : %f sec\n", psTimerMark ("psastro"));
+
+    psFree (view);
+    return true;
+}
Index: /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractDataSave.c
===================================================================
--- /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractDataSave.c	(revision 23322)
+++ /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractDataSave.c	(revision 23322)
@@ -0,0 +1,52 @@
+/** @file psastroModelDataSave.c
+ *
+ *  @brief
+ *
+ *  @ingroup psastroModel
+ *
+ *  @author IfA
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-02-07 02:03:34 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "psastroStandAlone.h"
+# define NONLIN_TOL 0.001 ///< tolerance in pixels 
+
+# define ESCAPE { \
+  psError(PS_ERR_UNKNOWN, false, "Failure in psastroModelDataSave"); \
+  psFree (view); \
+  return false; \
+}
+  
+bool psastroModelDataSave (pmConfig *config) {
+
+    bool status;
+
+    // select the current recipe
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
+    if (!recipe) {
+	psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe");
+	return false;
+    }
+
+    pmFPAfile *output = psMetadataLookupPtr (&status, config->files, "PSASTRO.OUT.MODEL");
+    if (!status) psAbort ("Can't find output pmFPAfile PSASTRO.OUT.MODEL");
+
+    pmFPAview *view = pmFPAviewAlloc (0);
+    pmChip *chip = NULL;
+
+    while ((chip = pmFPAviewNextChip (view, output->fpa, 1)) != NULL) {
+        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
+        if (!chip->process) { continue; }
+	if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE;
+    }
+    if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE;
+
+    psLogMsg ("psastro", 3, "save headers : %f sec\n", psTimerMark ("psastro"));
+
+    return true;
+}
+
+
+
Index: /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractParseCamera.c
===================================================================
--- /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractParseCamera.c	(revision 23322)
+++ /branches/eam_branches/eam_branch_20090312/psastro/src/psastroExtractParseCamera.c	(revision 23322)
@@ -0,0 +1,69 @@
+/** @file psastroExtractParseCamera.c
+ *
+ *  @brief
+ *
+ *  @ingroup psastroExtract
+ *
+ *  @author IfA
+ *  @version $Revision: 1.3 $ 
+ *  @date $Date: 2009-02-07 02:03:34 $
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+# include "psastroInternal.h"
+
+bool psastroExtractParseCamera (pmConfig *config) {
+
+    bool status = false;
+    pmFPAfile *input = NULL;
+
+    // the input image(s) are required arguments; they define the camera
+    status = false;
+    pmFPAfile *input = pmFPAfileDefineFromArgs(&status, config, "PSASTRO.EXTRACT.INPUT", "INPUT");
+    if (!input || !status) {
+        psError(PSASTRO_ERR_CONFIG, false, "Failed to build FPA from PSASTRO.EXTRACT.INPUT");
+        return false;
+    }
+
+    // the input image(s) are required arguments; they define the camera
+    status = false;
+    pmFPAfile *astrom = pmFPAfileDefineFromArgs(&status, config, "PSASTRO.EXTRACT.ASTROM", "ASTROM");
+    if (!status) {
+        psError (PS_ERR_UNKNOWN, false, "failed to load astrometry definition");
+        return NULL;
+    }
+    if (astrom) {
+        psLogMsg ("psastro", 3, "using supplied astrometry\n");
+    } else {
+        psLogMsg ("psastro", 3, "using header astrometry\n");
+    }
+
+# if (0)    
+    // XXX for now, don't use the pmFPAfile methods
+    // set up an output fpa structure & file based on the last input file
+    pmFPAfile *output = pmFPAfileDefineOutput (config, input->fpa, "PSASTRO.OUT.MODEL");
+    if (!output) {
+	psError(PSASTRO_ERR_CONFIG, false, "Failed to build FPA for PSASTRO.OUT.MODEL from input");
+	return false;
+    }
+    output->save = true;
+# endif
+
+    // Chip selection: turn on only the chips specified (option is not required)
+    char *chipLine = psMetadataLookupStr(&status, config->arguments, "CHIP_SELECTIONS"); 
+    psArray *chips = psStringSplitArray (chipLine, ",", false);
+    if (chips->n > 0) {
+	pmFPASelectChip (output->fpa, -1, true); // deselect all chips
+	for (int i = 0; i < chips->n; i++) {
+	    int chipNum = atoi(chips->data[i]);
+	    if (! pmFPASelectChip(output->fpa, chipNum, false)) {
+		psError(PSASTRO_ERR_CONFIG, true, "Chip number %d doesn't exist in camera.\n", chipNum);
+		return false;
+	    }
+        }
+    }
+    psFree (chips);
+
+    psTrace("psastro", 1, "Done with psastroExtractParseCamera...\n");
+    return true;
+}
