Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 6762)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 6763)
@@ -35,4 +35,5 @@
 $(SRC)/find_matches_refstars.$(ARCH).o \
 $(SRC)/find_subset.$(ARCH).o \
+$(SRC)/fakeimage.$(ARCH).o \
 $(SRC)/gcatalog.$(ARCH).o \
 $(SRC)/get2mass.$(ARCH).o \
Index: /trunk/Ohana/src/addstar/doc/notes.txt
===================================================================
--- /trunk/Ohana/src/addstar/doc/notes.txt	(revision 6762)
+++ /trunk/Ohana/src/addstar/doc/notes.txt	(revision 6763)
@@ -1,2 +1,15 @@
+
+2006.04.02
+
+  I am considering an option to insert fake camera images into the
+  database.  The camera would be described with a file specifying the
+  dimensions of each chip (Nx,Ny,pixel scale), the location of each
+  chip in the focal plane, and the optical parameters of the camera
+  (plate scale at center, x,y distortion terms).  Each call to addstar
+  would specify the boresite center:
+
+  addstar -fakeimage ra dec theta
+
+  the camera parameters should be loaded via the config information.
 
 2005.10.24
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 6762)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 6763)
@@ -33,5 +33,5 @@
 typedef struct sockaddr_in SockAddress;
 
-enum {M_IMAGE, M_REFLIST, M_REFCAT};
+enum {M_IMAGE, M_REFLIST, M_REFCAT, M_FAKEIMAGE};
 
 /* global which define database info / data sources (KEEP) */
@@ -53,4 +53,5 @@
 char   SKY_TABLE[256];
 int    SKY_DEPTH;  /** XXX EAM : depth of catalog tables, fix usage */
+char   CameraLayout[256];
 SkyTable *ServerSky;
 
@@ -81,4 +82,7 @@
 double 	Latitude;       // carried into image structure from config
 Coords *MOSAIC;         // carries the mosaic into gstars
+double  FAKE_RA;        // boresite coords for fake images
+double  FAKE_DEC;       // boresite coords for fake images
+double  FAKE_THETA;     // boresite angle for fake images
 
 /* these globals are used separately by both client and server (KEEP) */
@@ -118,4 +122,5 @@
 int        dump_rawstars          PROTO((Stars *stars, int Nstars));
 int        edge_check             PROTO((double *x1, double *y1, double *x2, double *y2));
+Image     *fakeimage              PROTO((char *rootname, int *Nimage, int photcode));
 void       find_matches           PROTO((SkyRegion *region, Stars *stars, int Nstars, Catalog *catalog, Image *image, Image *overlap, int Noverlap, Coords *mosaic, AddstarClientOptions options));
 void       find_matches_closest   PROTO((SkyRegion *region, Stars *stars, int Nstars, Catalog *catalog, Image *image, Image *overlap, int Noverlap, Coords *mosaic, AddstarClientOptions options));
Index: /trunk/Ohana/src/addstar/src/ConfigInit.c
===================================================================
--- /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 6762)
+++ /trunk/Ohana/src/addstar/src/ConfigInit.c	(revision 6763)
@@ -75,4 +75,5 @@
   /* dropped: ScanConfig (config, "IMAGE_CATALOG",          "%s",  0, ImageCat); */
 
+  ScanConfig (config, "CAMERA_LAYOUT",          "%s",  0, CameraLayout);
 
   /* used by client/server setup */
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 6762)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 6763)
@@ -4,7 +4,7 @@
 
   int Nm, Na, Ns, status;
-  int i, Nstars, Noverlap, Nsubset, Naverage, Nmeasure;
+  int i, Nstars, Nimage, Noverlap, Nsubset, Naverage, Nmeasure;
   Stars *stars, **subset;
-  Image image, *overlap;
+  Image image, *imageSet, *overlap;
   Catalog catalog;
   FITS_DB db;
@@ -54,4 +54,28 @@
       skylist = SkyListByPatch (sky, -1, &UserPatch);
       break;
+    case M_FAKEIMAGE:
+      imageSet = fakeimage (argv[1], &Nimage, options.photcode);
+      RegisterMosaic (MOSAIC);
+
+      if (db.dbstate == LCK_EMPTY) {
+	create_image_db (&db);
+      } else {
+	if (!dvo_image_load (&db, VERBOSE, FORCE_READ)) {
+	  Shutdown ("can't read image catalog %s", db.filename);
+	}
+      }	  
+
+      dvo_image_addrows (&db, imageSet, Nimage);
+      SetProtect (TRUE);
+      dvo_image_update (&db, VERBOSE);
+      SetProtect (FALSE);
+
+      ohana_memcheck (FALSE);
+      dvo_image_unlock (&db); /* unlock? */
+
+      gettimeofday (&stop, NULL);
+      dtime = DTIME (stop, start);
+      fprintf (stderr, "SUCCESS: elapsed time %9.4f sec for fake image\n", dtime);
+      exit (0);
   }
   if (options.only_match || options.existing_regions) {
@@ -63,4 +87,6 @@
   if (VERBOSE) fprintf (stderr, "writing to %d regions\n", skylist[0].Nregions);
 
+  /* XXX clean this up a bit : for only_image, I don't need to do this loop
+     unless we are getting the calibration. */
   Naverage = Nmeasure = 0;
   for (i = 0; i < skylist[0].Nregions; i++) {
Index: /trunk/Ohana/src/addstar/src/args.c
===================================================================
--- /trunk/Ohana/src/addstar/src/args.c	(revision 6762)
+++ /trunk/Ohana/src/addstar/src/args.c	(revision 6763)
@@ -23,4 +23,14 @@
   if ((N = get_argument (argc, argv, "-cat"))) {
     options.mode = M_REFCAT;
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-fakeimage"))) {
+    options.mode = M_FAKEIMAGE;
+    remove_argument (N, &argc, argv);
+    FAKE_RA = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    FAKE_DEC = atof (argv[N]);
+    remove_argument (N, &argc, argv);
+    FAKE_THETA = atof (argv[N]);
     remove_argument (N, &argc, argv);
   }
@@ -241,4 +251,5 @@
     fprintf (stderr, "USAGE: addstar -cat (catalog)\n");
     fprintf (stderr, "USAGE: addstar -ref (filename)\n");
+    fprintf (stderr, "USAGE: addstar -fakeimage (ra) (dec) (theta) (name)\n");
     exit (2);
   }
Index: /trunk/Ohana/src/addstar/src/fakeimage.c
===================================================================
--- /trunk/Ohana/src/addstar/src/fakeimage.c	(revision 6763)
+++ /trunk/Ohana/src/addstar/src/fakeimage.c	(revision 6763)
@@ -0,0 +1,196 @@
+# include "addstar.h"
+
+Image *fakeimage (char *rootname, int *Nimage, int photcode) {
+
+  int i, j, Nx, Ny, Nchips;
+  double pltscale, pixscale;
+  double Rmin, Rmax, Dmin, Dmax;
+  // double Xmin, Xmax, Ymin, Ymax;
+  double dX, dY, r, d;
+  char chipname[80], chipdata[256], name[80];
+  char *config;
+  Image *image;
+
+  /* this is a somewhat bogus method to set a time for the exposure */
+  struct timeval now;
+  long int seedval;
+
+  gettimeofday (&now, NULL);
+  seedval = now.tv_sec + now.tv_usec;
+  srand48(seedval);
+
+  e_time MosaicTime = 0xffffffff * drand48();
+  fprintf (stderr, "time: %x\n", MosaicTime);
+
+  /* load in the camera layout file */
+  config = LoadConfigFile (CameraLayout);
+  if (config == (char *) NULL) {
+    fprintf (stderr, "ERROR: can't find camera layout file %s\n", CameraLayout);
+    exit (1);
+  }
+  if (VERBOSE) fprintf (stderr, "loaded camera layout file: %s\n", CameraLayout);
+
+  /* create a mosaic distortion structure */
+  ALLOCATE (MOSAIC, Coords, 1);
+  strcpy (MOSAIC[0].ctype, "RA---DIS");
+  MOSAIC[0].crval1 = FAKE_RA;
+  MOSAIC[0].crval2 = FAKE_DEC;
+  
+  MOSAIC[0].crpix1 = MOSAIC[0].crpix2 = 0.0;
+  
+  /* mosaic 'pixels' are millimeters */
+  ScanConfig (config, "PLATE_SCALE",   "%lf", 0, &pltscale);
+  MOSAIC[0].cdelt1 = MOSAIC[0].cdelt2 = pltscale / 3600.0;
+
+  MOSAIC[0].pc1_1 =  cos(FAKE_THETA*RAD_DEG);
+  MOSAIC[0].pc1_2 = -sin(FAKE_THETA*RAD_DEG);
+  MOSAIC[0].pc2_1 =  sin(FAKE_THETA*RAD_DEG);
+  MOSAIC[0].pc2_2 =  cos(FAKE_THETA*RAD_DEG);
+
+  MOSAIC[0].Npolyterms = 3;
+  for (i = 0; i < 7; i++) {
+    MOSAIC[0].polyterms[i][0] = 0;
+    MOSAIC[0].polyterms[i][1] = 0;
+  }
+  ScanConfig (config, "DPLATE_X",   "%lf", 0, &pltscale);
+  MOSAIC[0].polyterms[3][0] = pltscale;  // L : X^3 Y^0
+  MOSAIC[0].polyterms[5][0] = pltscale;  // L : X^1 Y^2
+  ScanConfig (config, "DPLATE_Y",   "%lf", 0, &pltscale);
+  MOSAIC[0].polyterms[4][1] = pltscale;  // M : X^0 Y^0
+  MOSAIC[0].polyterms[6][1] = pltscale;  // M : X^2 Y^0
+
+  /* some basic data about the chisp */
+  ScanConfig (config, "NCHIPS", "%d", 0, &Nchips);
+  ScanConfig (config, "NAXIS1", "%d", 0, &Nx);
+  ScanConfig (config, "NAXIS2", "%d", 0, &Ny);
+  ScanConfig (config, "PIXEL_SCALE", "%lf", 0, &pixscale);
+
+  ALLOCATE (image, Image, Nchips + 1);
+  
+  Rmin = Rmax = Dmin = Dmax = 0;
+
+  /* define the chip images (1 - Nchips) */
+  for (i = 0; i < Nchips; i++) {
+    /* this is the addstar name for the chip in the camera */
+    sprintf (chipname, "CHIP.%03d", i);
+    ScanConfig (config, chipname, "%s", 0, chipdata);
+
+    sscanf (chipdata, "%s %lf %lf", chipname, &dX, &dY);
+    // if (VERBOSE) fprintf (stderr, "chip %s (%f,%f)\n", chipname, dX, dY);
+
+    /* this is the camera-specific name of a chip */
+    sprintf (name, "%s.%s", rootname, chipname);
+    strcpy (image[i+1].name, name);
+
+    strcpy (image[i+1].coords.ctype, "RA---WRP");
+    
+    image[i+1].coords.crval1 = dX*pixscale;
+    image[i+1].coords.crval2 = dY*pixscale;
+    
+    image[i+1].coords.crpix1 = image[i+1].coords.crpix2 = 0.0;
+    image[i+1].coords.cdelt1 = image[i+1].coords.cdelt2 = pixscale;
+
+    image[i+1].coords.pc1_1 = 1.0;
+    image[i+1].coords.pc1_2 = 0.0;
+    image[i+1].coords.pc2_1 = 0.0;
+    image[i+1].coords.pc2_2 = 1.0;
+
+    image[i+1].coords.Npolyterms = 0;
+    for (j = 0; j < 7; j++) {
+      image[i+1].coords.polyterms[j][0] = 0;
+      image[i+1].coords.polyterms[j][1] = 0;
+    }
+
+    image[i+1].sidtime  = 0.0;
+    image[i+1].latitude = 0.0;
+
+    image[i+1].cerror = 0.0;
+    
+    image[i+1].NX = Nx;
+    image[i+1].NY = Ny;
+
+    image[i+1].source = photcode;
+
+    image[i+1].exptime = 0.0;
+  
+    image[i+1].apmifit_PS = 0.0;
+    image[i+1].dapmifit_PS = 0.0;
+
+    image[i+1].detection_limit = 0.0;
+    image[i+1].saturation_limit = 0.0;
+    image[i+1].fwhm_x = 0.0;
+    image[i+1].fwhm_y = 0.0;
+    image[i+1].tzero = MosaicTime;
+    image[i+1].trate = 0;
+    image[i+1].secz_PS = 1.0;
+    image[i+1].ccdnum = 0xff;
+
+    image[i+1].Mcal_PS = 0.0;
+    image[i+1].Xm   = NO_MAG;
+    image[i+1].code = 0;
+    bzero (image[i+1].dummy, sizeof(image[i+1].dummy));
+
+    image[i+1].nstar = 0;
+    image[i+1].Myyyy = 0;
+
+    /* check if chip hits outer bounds of mosaic */
+    XY_to_RD (&r, &d, 0, 0, &image[i+1].coords);
+    Rmin = MIN (Rmin, r);
+    Rmax = MAX (Rmax, r);
+    Dmin = MIN (Dmin, d);
+    Dmax = MAX (Dmax, d);
+    XY_to_RD (&r, &d, Nx, 0, &image[i+1].coords);
+    Rmin = MIN (Rmin, r);
+    Rmax = MAX (Rmax, r);
+    Dmin = MIN (Dmin, d);
+    Dmax = MAX (Dmax, d);
+    XY_to_RD (&r, &d, 0, Ny, &image[i+1].coords);
+    Rmin = MIN (Rmin, r);
+    Rmax = MAX (Rmax, r);
+    Dmin = MIN (Dmin, d);
+    Dmax = MAX (Dmax, d);
+    XY_to_RD (&r, &d, Nx, Ny, &image[i+1].coords);
+    Rmin = MIN (Rmin, r);
+    Rmax = MAX (Rmax, r);
+    Dmin = MIN (Dmin, d);
+    Dmax = MAX (Dmax, d);
+  }
+
+  /* define the mosaic image */
+  strcpy (image[0].name, rootname);
+
+  image[0].coords = MOSAIC[0];
+  strcpy (image[0].coords.ctype, MOSAIC[0].ctype);
+
+  image[0].sidtime  = 0.0;
+  image[0].latitude = 0.0;
+  image[0].cerror = 0.0;
+    
+  // RD_to_XY (&Xmax, &Ymax, Rmax, Dmax, MOSAIC);
+  // RD_to_XY (&Xmin, &Ymin, Rmin, Dmin, MOSAIC);
+  image[0].NX = Rmax - Rmin;
+  image[0].NY = Dmax - Dmin;
+
+  image[0].source = photcode;
+
+  image[0].exptime = 0.0;
+  image[0].apmifit_PS = 0.0;
+  image[0].dapmifit_PS = 0.0;
+  image[0].detection_limit = 0.0;
+  image[0].saturation_limit = 0.0;
+  image[0].fwhm_x = 0.0;
+  image[0].fwhm_y = 0.0;
+  image[0].tzero = MosaicTime;
+  image[0].trate = 0;
+  image[0].secz_PS = 1.0;
+  image[0].ccdnum = 0xff;
+  image[0].Mcal_PS = 0.0;
+  image[0].Xm   = NO_MAG;
+  image[0].code = 0;
+  bzero (image[0].dummy, sizeof(image[0].dummy));
+  image[0].nstar = 0;
+  image[0].Myyyy = 0;
+
+  *Nimage = Nchips + 1;
+  return (image);
+}
