IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 27, 2015, 4:49:06 PM (11 years ago)
Author:
eugene
Message:

extensive work on relphot, relastro, uniphot, dvomerge aiming to the construction and calibration of PV3

Location:
trunk/Ohana
Files:
34 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/Ohana

  • trunk/Ohana/src/relastro/Makefile

    r38062 r38986  
    2020relastro_client: $(BIN)/relastro_client.$(ARCH)
    2121
    22 install: $(DESTBIN)/relastro $(DESTBIN)/relastro_client $(DESTBIN)/testparallax
     22install: $(DESTBIN)/relastro $(DESTBIN)/relastro_client
     23
     24# $(DESTBIN)/testparallax
    2325
    2426RELASTRO = \
     
    2628$(SRC)/FitChip.$(ARCH).o             \
    2729$(SRC)/FitMosaic.$(ARCH).o           \
     30$(SRC)/FitSimple.$(ARCH).o           \
     31$(SRC)/FitAstromOps.$(ARCH).o           \
    2832$(SRC)/FitPM.$(ARCH).o               \
    29 $(SRC)/FitPar.$(ARCH).o              \
    3033$(SRC)/FitPMandPar.$(ARCH).o         \
    31 $(SRC)/FitSimple.$(ARCH).o           \
     34$(SRC)/FitPosPMfixed.$(ARCH).o       \
    3235$(SRC)/ImageOps.$(ARCH).o            \
    3336$(SRC)/MosaicOps.$(ARCH).o           \
     
    99102RELASTRO_CLIENT = \
    100103$(SRC)/ConfigInit.$(ARCH).o          \
     104$(SRC)/FitSimple.$(ARCH).o           \
     105$(SRC)/FitAstromOps.$(ARCH).o           \
    101106$(SRC)/FitPM.$(ARCH).o               \
    102 $(SRC)/FitPar.$(ARCH).o              \
    103107$(SRC)/FitPMandPar.$(ARCH).o         \
    104 $(SRC)/FitSimple.$(ARCH).o           \
     108$(SRC)/FitPosPMfixed.$(ARCH).o       \
    105109$(SRC)/ImageOps.$(ARCH).o            \
    106110$(SRC)/MosaicOps.$(ARCH).o           \
  • trunk/Ohana/src/relastro/include/relastro.h

    r38441 r38986  
    2828
    2929typedef enum {TARGET_NONE, TARGET_SIMPLE, TARGET_CHIPS, TARGET_MOSAICS} FitTarget;
     30
     31typedef enum {
     32  FIT_RESULT_RA,
     33  FIT_RESULT_DEC,
     34  FIT_RESULT_uR,
     35  FIT_RESULT_uD,
     36  FIT_RESULT_PLX,
     37} FitAstromResultMode;
    3038
    3139typedef enum {
     
    115123  double Ro, dRo;
    116124  double Do, dDo;
    117 
    118125  double uR, duR;
    119126  double uD, duD;
    120 
    121   double p, dp;
     127  double  p, dp;
    122128
    123129  double chisq;
    124130  int Nfit;
    125 } PMFit;
     131} FitAstromResult;
     132
     133typedef struct {
     134  double **A;
     135  double **B;
     136  int Nterms;
     137} FitAstromData;
     138
     139typedef struct {
     140  double X, dX;
     141  double Y, dY;
     142  double R, dR;
     143  double D, dD;
     144  double T, dT;
     145  double pR;
     146  double pD;
     147  double C_blue;
     148  double C_red;
     149  int measure;
     150} FitAstromPoint;
     151
     152typedef struct {
     153  off_t Nave;
     154  off_t Npm;
     155  off_t Npar;
     156  off_t Nskip;
     157  off_t Noffset;
     158
     159  double *values;
     160  FitAstromResult *fit; // use bootstrap resampling to generate Nfit fits to measure the stats
     161  int Nfit;
     162  int NfitAlloc;
     163
     164  FitAstromPoint *points;
     165  FitAstromPoint *sample;
     166  int Npoints;
     167  int NpointsAlloc;
     168
     169  FitAstromData *fitdataPos;
     170  FitAstromData *fitdataPM;
     171  FitAstromData *fitdataPar;
     172
     173  Coords coords;
     174  time_t T2000;
     175} FitStats;
    126176
    127177typedef struct {
     
    150200
    151201typedef struct {
    152   off_t Nave;
    153   off_t Npm;
    154   off_t Npar;
    155   off_t Nskip;
    156   off_t Noffset;
    157 } FitStats;
    158 
    159 typedef struct {
    160202  double scale;
    161203  double **Roff;
     
    180222  int Nicrfobj;
    181223} ICRFobj;
     224
     225# define ID_MEAS_OBJECT_HAS_2MASS ID_MEAS_POOR_PHOTOM
    182226
    183227/* global variables set in parameter file */
     
    224268int    PARALLEL_OUTPUT;
    225269
     270int    VERBOSE_IMAGE;
     271
    226272int    VERBOSE;
    227273int    VERBOSE2;
     
    234280int    USE_ICRF_SHFIT;
    235281int    USE_ICRF_POLE;
     282
     283int    USE_ALL_IMAGES;
    236284
    237285int    RESET;
     
    252300int    CHIPORDER;
    253301int    CHIPMAP;
     302
     303int    N_BOOTSTRAP_SAMPLES;
    254304
    255305int MaxDensityUse;
     
    369419int           liststats_pos       PROTO((double *value, double *dvalue, int N, StatType *stats, int XVERB));
    370420Catalog      *load_catalogs       PROTO((SkyList *skylist, int *Ncatalog, int subselect, int hostID, char *hostpath, char *syncfile));
    371 int           load_images         PROTO((FITS_DB *db, SkyList *skylist, int UseFullOverlap));
     421int           load_images         PROTO((FITS_DB *db, SkyList *skylist, int UseFullOverlap, int UseAllImages));
    372422Image        *select_images       PROTO((SkyList *skylist, Image *timage, off_t Ntimage, off_t **LineNumber, off_t *Nimage, int UseFullOverlap));
    373423
     
    448498int UpdateObjects (Catalog *catalog, int Ncatalog, int Nloop);
    449499int UpdateSimple (Catalog *catalog, int Ncatalog);
    450 int UpdateChips (Catalog *catalog, int Ncatalog);
     500int UpdateChips (Catalog *catalog, int Ncatalog, int Nloop);
    451501int UpdateMosaic (Catalog *catalog, int Ncatalog);
    452502int UpdateMeasures (Catalog *catalog, int Ncatalog);
     
    457507
    458508int sun_ecliptic (double jd, double *lambda, double *beta, double *epsilon, double *Radius);
    459 int ParFactor (double *pR, double *pD, double RA, double Dec, double Time, double Tmean);
    460 int FitPM (PMFit *fit, double *X, double *dX, double *Y, double *dY, double *T, int Npts, int XVERB);
    461 int FitPar (PMFit *fit, double *X, double *dX, double *Y, double *dY, double *pR, double *pD, int Npts);
    462 int FitPMandPar (PMFit *fit, double *X, double *dX, double *Y, double *dY, double *T, double *pR, double *pD, int Npts, int XVERB);
     509int ParFactor (double *pR, double *pD, double RA, double Dec, double Time);
     510int FitPM (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints);
     511int FitPMandPar (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints);
     512int FitPosPMfixed (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints);
    463513
    464514Mosaic *getMosaicForImage (off_t N);
     
    661711int client_logger_init (char *dirname);
    662712int client_logger_message (char *format,...);
     713
     714int FitAstromSetChisq (FitAstromResult *fit, FitAstromPoint *points, int Npoints, FitMode mode);
     715double VectorFractionInterpolate (double *values, float fraction, int Npts);
     716int BootstrapRobustStats (FitAstromResult *result, FitAstromResult *fit, int Nfit, int mode);
     717int BootstrapResample (FitAstromPoint *sample, FitAstromPoint *points, int Npoints);
     718int CatalogMaxNmeasure (Catalog *catalog, int Ncatalog);
     719int FitAstromPoints_Project (FitStats *fitStats, double *Tmean, double *Trange, double *parRange);
     720int UpdateObjects_SelectMeasures (FitStats *fit, Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int isStack);
     721int UpdateObjects_Stack (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats);
     722int UpdateObjects_Chips (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats, int cat, off_t measOff);
     723
     724void FitAstromResultInit (FitAstromResult *fit);
     725void FitAstromPointInit (FitAstromPoint *object);
     726void FitAstromDataFree (FitAstromData *fit);
     727FitAstromData *FitAstromDataInit (int Nterms);
     728void FitStatsFree (FitStats *fitStats);
     729void FitStatsSum (FitStats *src, FitStats *tgt);
     730void FitStatsReset (FitStats *tgt);
     731FitStats *FitStatsInit (int Nmax, int Nboot);
     732int FitAstromResultSetPM (FitAstromResult *fit, int Nfit, Average *average);
     733void AstromErrorSetLoop (int Nloop, int isImageMode);
  • trunk/Ohana/src/relastro/src/FitChip.c

    r37807 r38986  
    8181    }
    8282
    83     if (VERBOSE2) fprintf (stderr, "using %d for %s\n", order_use, image[0].name);
     83    if (VERBOSE2) {
     84      fprintf (stderr, "using %d for %s\n", order_use, image[0].name);
     85    }
    8486
    8587    // when fitting the map, first fit a linear model (below? change Npolyterms to -1)
     
    9294    for (i = 0; i < Nmatch; i++) {
    9395      if (raw[i].mask) continue;
    94       fit_add (fit, raw[i].X, raw[i].Y, ref[i].L, ref[i].M, raw[i].dPos);
     96      fit_add (fit, raw[i].X, raw[i].Y, ref[i].L, ref[i].M, ref[i].dPos);
    9597    }
    9698
     
    310312  int i, N;
    311313
    312   float *x, *y, *dX, *dY;
     314  float *x, *y, *dX, *dY, *dP;
    313315  ALLOCATE (x,  float, Npts);
    314316  ALLOCATE (y,  float, Npts);
    315317  ALLOCATE (dX, float, Npts);
    316318  ALLOCATE (dY, float, Npts);
     319  ALLOCATE (dP, float, Npts);
    317320
    318321  N = 0;
     
    323326    dX[N] = ref[i].X - raw[i].X;
    324327    dY[N] = ref[i].Y - raw[i].Y;
     328    dP[N] = ref[i].dPos;
    325329    N++;
    326330  }
     
    329333  // (L,M) = f(X',Y') : (X',Y') = (X,Y) + (dX,dY)
    330334
    331   AstromOffsetMapFit (map, x, y, dX, N, TRUE);
    332   AstromOffsetMapFit (map, x, y, dY, N, FALSE);
     335  AstromOffsetMapFit (map, x, y, dX, dP, N, TRUE);
     336  AstromOffsetMapFit (map, x, y, dY, dP, N, FALSE);
    333337
    334338  AstromOffsetMapRepair (map, TRUE);
     
    339343  free (dX);
    340344  free (dY);
     345  free (dP);
    341346
    342347  return TRUE;
  • trunk/Ohana/src/relastro/src/FitPM.c

    r32695 r38986  
    11# include "relastro.h"
    22
    3 /* do we want an init function which does the alloc and a clear function to free? */
    4 int FitPM (PMFit *fit, double *X, double *dX, double *Y, double *dY, double *T, int Npts, int XVERB) {
     3// initial values of *fit are ignored
     4int FitPM (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints) {
    55
    66  int i;
    77
    8   double **A, **B;
    98  double wx, wy, Wx, Wy, Tx, Ty, Tx2, Ty2, Xs, Ys, XT, YT;
    10   double chisq, Xf, Yf;
    119
    12   /* do I need to do this as 2 2x2 matrix equations? */
    13   A = array_init (4, 4);
    14   B = array_init (4, 1);
     10  myAssert (data->Nterms == 4, "invalid fit arrays");
    1511
    1612  Wx = Wy = Tx = Ty = Tx2 = Ty2 = Xs = Ys = XT = YT = 0.0;
    17   for (i = 0; i < Npts; i++) {
     13
     14  for (i = 0; i < Npoints; i++) {
    1815    /* handle case where dX or dY = 0.0 */
    19     wx = 1.0 / SQ(dX[i]);
    20     wy = 1.0 / SQ(dY[i]);
     16    wx = 1.0 / SQ(points[i].dX);
     17    wy = 1.0 / SQ(points[i].dY);
    2118
    2219    Wx += wx;
    2320    Wy += wy;
    2421
    25     Tx += T[i]*wx;
    26     Ty += T[i]*wy;
     22    Tx += points[i].T*wx;
     23    Ty += points[i].T*wy;
    2724   
    28     Tx2 += SQ(T[i])*wx;
    29     Ty2 += SQ(T[i])*wy;
     25    Tx2 += SQ(points[i].T)*wx;
     26    Ty2 += SQ(points[i].T)*wy;
    3027   
    31     Xs += X[i]*wx;
    32     Ys += Y[i]*wy;
     28    Xs += points[i].X*wx;
     29    Ys += points[i].Y*wy;
    3330
    34     XT += X[i]*T[i]*wx;
    35     YT += Y[i]*T[i]*wy;
     31    XT += points[i].X*points[i].T*wx;
     32    YT += points[i].Y*points[i].T*wy;
    3633  }
    3734
    38   A[0][0] = Wx;
    39   A[0][1] = Tx;
     35  data->A[0][0] = Wx;
     36  data->A[0][1] = Tx;
    4037
    41   A[1][0] = Tx;
    42   A[1][1] = Tx2;
     38  data->A[1][0] = Tx;
     39  data->A[1][1] = Tx2;
    4340
    44   A[2][2] = Wy;
    45   A[2][3] = Ty;
     41  data->A[2][2] = Wy;
     42  data->A[2][3] = Ty;
    4643
    47   A[3][2] = Ty;
    48   A[3][3] = Ty2;
     44  data->A[3][2] = Ty;
     45  data->A[3][3] = Ty2;
    4946
    50   B[0][0] = Xs;
    51   B[1][0] = XT;
    52   B[2][0] = Ys;
    53   B[3][0] = YT;
     47  data->B[0][0] = Xs;
     48  data->B[1][0] = XT;
     49  data->B[2][0] = Ys;
     50  data->B[3][0] = YT;
    5451
    55   dgaussjordan (A, B, 4, 1);
     52  dgaussjordan (data->A, data->B, 4, 1);
    5653
    57   fit[0].Ro = B[0][0];
    58   fit[0].uR = B[1][0];
    59   fit[0].Do = B[2][0];
    60   fit[0].uD = B[3][0];
    61   fit[0].p  = 0.0;
     54  fit->Ro = data->B[0][0];
     55  fit->uR = data->B[1][0];
     56  fit->Do = data->B[2][0];
     57  fit->uD = data->B[3][0];
     58  fit->p  = 0.0;
    6259 
    63   fit[0].dRo = sqrt(A[0][0]);
    64   fit[0].duR = sqrt(A[1][1]);
    65   fit[0].dDo = sqrt(A[2][2]);
    66   fit[0].duD = sqrt(A[3][3]);
    67   fit[0].dp  = 0.0;
     60  fit->dRo = sqrt(data->A[0][0]);
     61  fit->duR = sqrt(data->A[1][1]);
     62  fit->dDo = sqrt(data->A[2][2]);
     63  fit->duD = sqrt(data->A[3][3]);
     64  fit->dp  = 0.0;
    6865 
    69   array_free (A, 4);
    70   array_free (B, 4);
     66  fit->Nfit = Npoints;
    7167
    72   // add up the chi square for the fit
    73   chisq = 0.0;
    74   for (i = 0; i < Npts; i++) {
    75     Xf = fit[0].Ro + fit[0].uR*T[i];
    76     Yf = fit[0].Do + fit[0].uD*T[i];
    77     chisq += SQ(X[i] - Xf) / SQ(dX[i]);
    78     chisq += SQ(Y[i] - Yf) / SQ(dY[i]);
    79     if (XVERB) fprintf (stderr, "chisq contrib : %f %f : %f %f : %f %f : %f %f : %f\n", Xf, Yf, X[i] - Xf, Y[i] - Yf, dX[i], dY[i], (X[i] - Xf) / dX[i], (Y[i] - Yf) / dY[i], chisq);
    80   }
    81   fit[0].Nfit = Npts;
    82 
    83   // the reduced chisq is divided by (Ndof = 2*Npts - 4)
    84   fit[0].chisq = chisq / (2.0*Npts - 4.0);
    8568  return (TRUE);
    8669}
    87 
    88 // XXX this function should (optionally?) iterate and clip outlier detections
  • trunk/Ohana/src/relastro/src/FitPMandPar.c

    r32695 r38986  
    11# include "relastro.h"
    22
    3 /* do we want an init function which does the alloc and a clear function to free? */
    4 int FitPMandPar (PMFit *fit, double *X, double *dX, double *Y, double *dY, double *T, double *pR, double *pD, int Npts, int XVERB) {
     3// initial values of *fit are ignored
     4int FitPMandPar (FitAstromResult *fit, FitAstromData *data, FitAstromPoint *points, int Npoints) {
    55
    66  int i;
    77
    8   double **A, **B;
    98  double wx, wy, Wx, Wy, Tx, Ty, Tx2, Ty2, Xs, Ys, XT, YT;
    109  double PR, PD, PRT, PDT, PRX, PDY, PR2, PD2;
    11   double chisq, Xf, Yf;
    1210
    13   A = array_init (5, 5);
    14   B = array_init (5, 1);
     11  myAssert (data->Nterms == 5, "invalid fit arrays");
    1512
    1613  PR = PD = PRT = PDT = PRX = PDY = PR2 = PD2 = 0.0;
    1714  Wx = Wy = Tx = Ty = Tx2 = Ty2 = Xs = Ys = XT = YT = 0.0;
    18   for (i = 0; i < Npts; i++) {
     15
     16  for (i = 0; i < Npoints; i++) {
    1917    /* handle case where dX or dY = 0.0 */
    20     wx = 1.0 / SQ(dX[i]);
    21     wy = 1.0 / SQ(dY[i]);
     18    wx = 1.0 / SQ(points[i].dX);
     19    wy = 1.0 / SQ(points[i].dY);
    2220
    2321    Wx += wx;
    2422    Wy += wy;
    2523
    26     Tx += T[i]*wx;
    27     Ty += T[i]*wy;
     24    Tx += points[i].T*wx;
     25    Ty += points[i].T*wy;
    2826   
    29     Tx2 += SQ(T[i])*wx;
    30     Ty2 += SQ(T[i])*wy;
     27    Tx2 += SQ(points[i].T)*wx;
     28    Ty2 += SQ(points[i].T)*wy;
    3129   
    32     PR += pR[i]*wx;
    33     PD += pD[i]*wy;
     30    PR += points[i].pR*wx;
     31    PD += points[i].pD*wy;
    3432   
    35     PRT += pR[i]*T[i]*wx;
    36     PDT += pD[i]*T[i]*wy;
     33    PRT += points[i].pR*points[i].T*wx;
     34    PDT += points[i].pD*points[i].T*wy;
    3735   
    38     PRX += pR[i]*X[i]*wx;
    39     PDY += pD[i]*Y[i]*wy;
     36    PRX += points[i].pR*points[i].X*wx;
     37    PDY += points[i].pD*points[i].Y*wy;
    4038   
    41     PR2 += SQ(pR[i])*wx;
    42     PD2 += SQ(pD[i])*wy;
     39    PR2 += SQ(points[i].pR)*wx;
     40    PD2 += SQ(points[i].pD)*wy;
    4341
    44     Xs += X[i]*wx;
    45     Ys += Y[i]*wy;
     42    Xs += points[i].X*wx;
     43    Ys += points[i].Y*wy;
    4644
    47     XT += X[i]*T[i]*wx;
    48     YT += Y[i]*T[i]*wy;
     45    XT += points[i].X*points[i].T*wx;
     46    YT += points[i].Y*points[i].T*wy;
    4947  }
    5048
    51   A[0][0] = Wx;
    52   A[0][1] = Tx;
    53   A[0][4] = PR;
     49  data->A[0][0] = Wx;
     50  data->A[0][1] = Tx;
     51  data->A[0][4] = PR;
    5452
    55   A[1][0] = Tx;
    56   A[1][1] = Tx2;
    57   A[1][4] = PRT;
     53  data->A[1][0] = Tx;
     54  data->A[1][1] = Tx2;
     55  data->A[1][4] = PRT;
    5856
    59   A[2][2] = Wy;
    60   A[2][3] = Ty;
    61   A[2][4] = PD;
     57  data->A[2][2] = Wy;
     58  data->A[2][3] = Ty;
     59  data->A[2][4] = PD;
    6260
    63   A[3][2] = Ty;
    64   A[3][3] = Ty2;
    65   A[3][4] = PDT;
     61  data->A[3][2] = Ty;
     62  data->A[3][3] = Ty2;
     63  data->A[3][4] = PDT;
    6664
    67   A[4][0] = PR;
    68   A[4][1] = PRT;
    69   A[4][2] = PD;
    70   A[4][3] = PDT;
    71   A[4][4] = PR2 + PD2;
     65  data->A[4][0] = PR;
     66  data->A[4][1] = PRT;
     67  data->A[4][2] = PD;
     68  data->A[4][3] = PDT;
     69  data->A[4][4] = PR2 + PD2;
    7270
    73   B[0][0] = Xs;
    74   B[1][0] = XT;
    75   B[2][0] = Ys;
    76   B[3][0] = YT;
    77   B[4][0] = PRX + PDY;
     71  data->B[0][0] = Xs;
     72  data->B[1][0] = XT;
     73  data->B[2][0] = Ys;
     74  data->B[3][0] = YT;
     75  data->B[4][0] = PRX + PDY;
    7876
    79   dgaussjordan (A, B, 5, 1);
     77  dgaussjordan (data->A, data->B, 5, 1);
    8078
    81   fit[0].Ro = B[0][0];
    82   fit[0].uR = B[1][0];
    83   fit[0].Do = B[2][0];
    84   fit[0].uD = B[3][0];
    85   fit[0].p  = B[4][0];
     79  fit->Ro = data->B[0][0];
     80  fit->uR = data->B[1][0];
     81  fit->Do = data->B[2][0];
     82  fit->uD = data->B[3][0];
     83  fit->p  = data->B[4][0];
    8684 
    87   fit[0].dRo = sqrt(A[0][0]);
    88   fit[0].duR = sqrt(A[1][1]);
    89   fit[0].dDo = sqrt(A[2][2]);
    90   fit[0].duD = sqrt(A[3][3]);
    91   fit[0].dp  = sqrt(A[4][4]);
     85  fit->dRo = sqrt(data->A[0][0]);
     86  fit->duR = sqrt(data->A[1][1]);
     87  fit->dDo = sqrt(data->A[2][2]);
     88  fit->duD = sqrt(data->A[3][3]);
     89  fit->dp  = sqrt(data->A[4][4]);
    9290 
    93   array_free (A, 5);
    94   array_free (B, 5);
     91  fit->Nfit = Npoints;
    9592
    96   /* get the chisq from the matrix values */
    97 
    98   // add up the chi square for the fit
    99   chisq = 0.0;
    100   for (i = 0; i < Npts; i++) {
    101     Xf = fit[0].Ro + fit[0].uR*T[i] + fit[0].p*pR[i];
    102     Yf = fit[0].Do + fit[0].uD*T[i] + fit[0].p*pD[i];
    103     chisq += SQ(X[i] - Xf) / SQ(dX[i]);
    104     chisq += SQ(Y[i] - Yf) / SQ(dY[i]);
    105     if (XVERB) fprintf (stderr, "chisq contrib : %f %f : %f %f : %f %f : %f %f : %f\n", Xf, Yf, X[i] - Xf, Y[i] - Yf, dX[i], dY[i], (X[i] - Xf) / dX[i], (Y[i] - Yf) / dY[i], chisq);
    106 
    107   }
    108   fit[0].Nfit = Npts;
    109 
    110   // the reduced chisq is divided by (Ndof = 2*Npts - 5)
    111   fit[0].chisq = chisq / (2.0*Npts - 5.0);
    11293  return (TRUE);
    11394}
  • trunk/Ohana/src/relastro/src/FrameCorrection.c

    r38062 r38986  
    479479    }
    480480
    481     AstromOffsetMapFit (map, Xfit, Yfit, dXfit, Nkeep, TRUE);
    482     AstromOffsetMapFit (map, Xfit, Yfit, dYfit, Nkeep, FALSE);
     481    AstromOffsetMapFit (map, Xfit, Yfit, dXfit, NULL, Nkeep, TRUE);
     482    AstromOffsetMapFit (map, Xfit, Yfit, dYfit, NULL, Nkeep, FALSE);
    483483
    484484    for (i = 0; i < Npts; i++) {
  • trunk/Ohana/src/relastro/src/FrameCorrectionUtils.c

    r38553 r38986  
    240240  float *buffer = (float *)matrix->buffer;
    241241
    242   float **value = (raDirection) ? map->dXv : map->dYv;
     242  float *value = (raDirection) ? map->dXv : map->dYv;
    243243
    244244  int ix, iy;
    245245  for (ix = 0; ix < map->Nx; ix++) {
    246246    for (iy = 0; iy < map->Ny; iy++) {
    247       buffer[ix + map->Nx*iy] = value[ix][iy];
     247      buffer[ix + map->Nx*iy] = value[ix + map->Nx*iy];
    248248    }
    249249  }
     
    265265  float *buffer = (float *) matrix->buffer;
    266266
    267   float **value = (raDirection) ? map->dXv : map->dYv;
     267  float *value = (raDirection) ? map->dXv : map->dYv;
    268268
    269269  int ix, iy;
    270270  for (ix = 0; ix < map->Nx; ix++) {
    271271    for (iy = 0; iy < map->Ny; iy++) {
    272       value[ix][iy] = buffer[ix + map->Nx*iy];
     272      value[ix + map->Nx*iy] = buffer[ix + map->Nx*iy];
    273273    }
    274274  }
  • trunk/Ohana/src/relastro/src/GetAstromError.c

    r36833 r38986  
    11# include "relastro.h"
    22# define WEIGHTED_ERRORS 1
     3
     4// XXX hard-wire the trends identified by CZW
     5static float BrightMo[] = {-15.6, -16.8, -17.0, -16.7, -16.0};
     6static float BrightMs[] = {1.3, 1.3, 1.3, 1.8, 2.0};
     7
     8static int Nloop = -1;
     9static int isImage = FALSE;
     10
     11// Nloop is used to modify the per detection errors
     12void AstromErrorSetLoop (int N, int isImageMode) {
     13  Nloop = N;
     14  isImage = isImageMode;
     15}
    316
    417float GetAstromErrorTiny (MeasureTiny *measure, int mode) {
     
    4154  dPtotal = sqrt(SQ(dPsys) + SQ(AS*dPobs) + SQ(MS*dM));
    4255
     56  // for GPC1 data, we have a bright end model:
     57  if ((measure[0].photcode > 10000) && (measure[0].photcode < 10480)) {
     58    int Np = ((int) (measure[0].photcode / 100)) % 100;
     59    myAssert (Np >= 0, "oops");
     60    myAssert (Np <= 4, "oops");
     61
     62    float Minst = measure[0].M - measure[0].dt - 25.0;
     63    float dPbright = 0.335 / (1.0 + exp(BrightMs[Np]*(Minst - BrightMo[Np])));
     64    dPtotal = hypot(dPtotal, dPbright);
     65  }
    4366  dPtotal = MAX (dPtotal, MIN_ERROR);
     67
     68  // early on, we want 2MASS and Tycho to have a very high weight.  This will force images
     69  // to match the 2MASS / Tycho / ICRS reference frame.  As Nloop gets higher, the weight
     70  // needs to drop to allow the ps1 measurements to drive the solution
     71  int is2MASS  = USE_GALAXY_MODEL && !isImage && (measure[0].photcode >= 2011) && (measure[0].photcode <= 2013);
     72  int isTycho  = USE_GALAXY_MODEL && !isImage && (measure[0].photcode >= 2020) && (measure[0].photcode <= 2021);
     73  int has2MASS = USE_GALAXY_MODEL &&  isImage && (measure[0].dbFlags & ID_MEAS_OBJECT_HAS_2MASS);
     74
     75  // serious hack: if the object has 2MASS, we set this internal bit and adjust the
     76  // weight to ensure the image is tied down to the 2mass frame
     77
     78  if (has2MASS) {
     79    switch (Nloop) {
     80      case 0:
     81        dPtotal = dPtotal / 1000.0;
     82        break;
     83      case 1:
     84        dPtotal = dPtotal / 300.0;
     85        break;
     86      case 2:
     87        dPtotal = dPtotal / 100.0;
     88        break;
     89      case 3:
     90        dPtotal = dPtotal / 30.0;
     91        break;
     92      case 4:
     93        dPtotal = dPtotal / 10.0;
     94        break;
     95      case 5:
     96        dPtotal = dPtotal / 10.0;
     97        break;
     98      default:
     99        break;
     100    }
     101  }
     102  if (is2MASS) {
     103    switch (Nloop) {
     104      case 0:
     105        dPtotal = dPtotal / 1000.0;
     106        break;
     107      case 1:
     108        dPtotal = dPtotal / 300.0;
     109        break;
     110      case 2:
     111        dPtotal = dPtotal / 100.0;
     112        break;
     113      case 3:
     114        dPtotal = dPtotal / 30.0;
     115        break;
     116      case 4:
     117        dPtotal = dPtotal / 10.0;
     118        break;
     119      case 5:
     120        dPtotal = dPtotal / 10.0;
     121        break;
     122      default:
     123        break;
     124    }
     125  }
     126  if (isTycho) {
     127    switch (Nloop) {
     128      case 0:
     129      case 1:
     130        dPtotal = dPtotal / 200.0;
     131        break;
     132      case 2:
     133      case 3:
     134        dPtotal = dPtotal / 100.0;
     135        break;
     136      case 4:
     137      case 5:
     138        dPtotal = dPtotal / 50.0;
     139        break;
     140      default:
     141        break;
     142    }
     143  }
     144
    44145  return (dPtotal);
    45146}
     
    84185  dPtotal = sqrt(SQ(dPsys) + SQ(AS*dPobs) + SQ(MS*dM));
    85186
     187  // for GPC1 data, we have a bright end model:
     188  if ((measure[0].photcode > 10000) && (measure[0].photcode < 10480)) {
     189    int Np = ((int) (measure[0].photcode / 100)) % 100;
     190    myAssert (Np >= 0, "oops");
     191    myAssert (Np <= 4, "oops");
     192
     193    float Minst = measure[0].M - measure[0].dt - 25.0;
     194    float dPbright = 0.335 / (1.0 + exp(BrightMs[Np]*(Minst - BrightMo[Np])));
     195    dPtotal = hypot(dPtotal, dPbright);
     196  }
     197
    86198  dPtotal = MAX (dPtotal, MIN_ERROR);
    87199  return (dPtotal);
  • trunk/Ohana/src/relastro/src/ImageOps.c

    r38062 r38986  
    11# include "relastro.h"
     2int isGPC1chip (int photcode);
    23
    34# define USE_IMAGE_ID 1
     
    690691      raw[i].mask |= MARK_NAN_POS_ERROR;
    691692    }
     693
     694    // XXX A TEST: can we use only 2MASS measurements to fit the images?
     695    // XXX Do NOT apply this for the real calibration
     696    if (FALSE && !(measure[0].dbFlags & ID_MEAS_OBJECT_HAS_2MASS)) {
     697      fprintf (stderr, "@");
     698      raw[i].mask |= MARK_BIG_OFFSET;
     699    }
     700
    692701    raw[i].Nmeas = catalog[c].average[n].Nmeasure; // record so we can check how well connected an image is
    693702
     
    751760    ref[i].R = catalog[c].average[n].R;
    752761    ref[i].D = catalog[c].average[n].D;
     762   
     763    // if we are applying the galaxy model, move the reference position...
     764    if (USE_GALAXY_MODEL) {
     765      // apply proper-motion from average position to measure epoch:
     766      float dTime = (measure[0].t - catalog[c].average[n].Tmean) / (86400*365.25) ; // time relative to Tmean in years
     767
     768      // XXX do this in a better way?
     769      ref[i].R += dTime * catalog[c].average[n].uR / 3600.0 / cos(ref[i].D*RAD_DEG);
     770      ref[i].D += dTime * catalog[c].average[n].uD / 3600.0;
     771    }
    753772
    754773    // if we are correcting for the Galaxy Motion Model, we assume the mean R,D is at the J2000 epoch position
    755     if (USE_GALAXY_MODEL) {
     774    if (0) {
    756775      myAssert (!isnan(measure[0].RoffGAL), "oops");
    757776      myAssert (!isnan(measure[0].DoffGAL), "oops");
     
    9811000  if (VERBOSE) fprintf (stderr, "%d measures marked poor, %d total\n", Ndel, Nave);
    9821001  free (R);
    983   free(dR);
    984   free(D);
    985   free(dD);
     1002  free (dR);
     1003  free (D);
     1004  free (dD);
    9861005}
    9871006
     
    11101129  if (VERBOSE) fprintf (stderr, "%d measures marked poor, %d total\n", Ndel, Nave);
    11111130  free (R);
    1112   free(dR);
    1113   free(D);
    1114   free(dD);
    1115   free(d2);
    1116   free(index);
     1131  free (dR);
     1132  free (D);
     1133  free (dD);
     1134  free (d2);
     1135  free (index);
    11171136}
    11181137
     
    12151234  } 
    12161235 
    1217   if (MinBadQF > 0.0) {
     1236  if ((MinBadQF > 0.0) && isGPC1chip(measure[0].photcode)) {
     1237    if (!isfinite(measure[0].psfQF)) return FALSE;
    12181238    if (measure[0].psfQF < MinBadQF) return FALSE;
    12191239  }
  • trunk/Ohana/src/relastro/src/ParFactor.c

    r37261 r38986  
    22# define J2000 2451545.       /* Julian date at standard epoch */
    33
    4 # if (0)
    5 /* Low precision formulae for the sun, from Almanac p. C24 (1990) */
    6 /* ra and dec are returned as decimal hours and decimal degrees. */
    7 void lpsun (double jd, double *ra, double *dec) {
     4/* Low precision formulae for the sun, from Astro. Almanac p. C5 (2012) */
     5// jdoff is days since J2000
     6int sun_ecliptic (double jdoff, double *lambda, double *beta, double *epsilon, double *Radius) {
    87
    9   double n, L, g, lambda,epsilon,alpha,delta,x,y,z;
    10 
    11   n = jd - J2000;
    12   L = 280.460 + 0.9856474 * n;
    13   g = (357.528 + 0.9856003 * n)/DEG_IN_RADIAN;
    14   lambda = (L + 1.915 * sin(g) + 0.020 * sin(2. * g))/DEG_IN_RADIAN;
    15   epsilon = (23.439 - 0.0000004 * n)/DEG_IN_RADIAN;
    16 
    17   // this is the conversion from ecliptic to celestial coords
    18   x = cos(lambda);
    19   y = cos(epsilon)*sin(lambda);
    20   z = sin(epsilon)*sin(lambda);
    21 
    22   *ra = (atan_circ(x,y))*HRS_IN_RADIAN;
    23   *dec = (asin(z))*DEG_IN_RADIAN;
    24 }
    25 # endif
    26 
    27 # if (0)
    28 /* code borrowed from Skycalc : fix this stuff XXX */
    29 /* Low precision formulae for the sun, from Almanac p. C24 (1990) */
    30 int sun_ecliptic (double jd, double *lambda, double *beta, double *epsilon) {
    31 
    32   double n, L, g;
    33 
    34 
    35   n = jd - J2000;
    36   L = 280.460 + 0.9856474 * n;
    37   g = (357.528 + 0.9856003 * n)*RAD_DEG;
    38   *lambda = L + 1.915 * sin(g) + 0.020 * sin(2. * g); // longitude in degrees
    39   *beta = 0.0;                                    // approx latitude
    40   *epsilon = (23.439 - 0.0000004 * n);            // obliquity of ecliptic in degrees
    41   return TRUE;
    42 }
    43 # endif
    44 
    45 /* Low precision formulae for the sun, from Astro. Almanac p. C5 (2012) */
    46 int sun_ecliptic (double jd, double *lambda, double *beta, double *epsilon, double *Radius) {
    47 
    48   double n = jd - J2000;              // day number
     8  double n = jdoff;           // day number
    499  double L = 280.460 + 0.9856474 * n; // mean solar longitute (corr. for aberration)
    5010  double g = (357.528 + 0.9856003 * n)*RAD_DEG; // Mean anomaly
     
    5818
    5919/* given RA, DEC, Time, calculate the parallax factor */
    60 // Time is relative to Tmean, Tmean is years relative to J2000
    61 int ParFactor (double *pR, double *pD, double RA, double DEC, double Time, double Tmean) {
     20// Time is years since J2000
     21int ParFactor (double *pR, double *pD, double RA, double DEC, double Time) {
    6222
    63   double jd, lambda, beta, epsilon, Radius;
     23  double lambda, beta, epsilon, Radius;
    6424
    65   /* given a Time relative to Tmean, Tmean in years since J2000, determine the solar
    66     longitude S */
     25  /* given a Time in years since J2000, determine the solar longitude S */
    6726
    68   // jd = ohana_sec_to_jd (365.25*86400.0*(Time + Tmean));
    69   jd = 365.25*(Time + Tmean) + J2000;
    70   // fprintf (stderr, "Time: %f, jd: %f\n", Time, jd);
     27  double jdoff = 365.25*Time;
    7128
    72   sun_ecliptic (jd, &lambda, &beta, &epsilon, &Radius);
     29  sun_ecliptic (jdoff, &lambda, &beta, &epsilon, &Radius);
    7330
    7431  double lambda_rad = lambda*RAD_DEG;
     
    9956  return TRUE;
    10057}
     58
     59# if (0)
     60/* Low precision formulae for the sun, from Almanac p. C24 (1990) */
     61/* ra and dec are returned as decimal hours and decimal degrees. */
     62void lpsun (double jd, double *ra, double *dec) {
     63
     64  double n, L, g, lambda,epsilon,alpha,delta,x,y,z;
     65
     66  n = jd - J2000;
     67  L = 280.460 + 0.9856474 * n;
     68  g = (357.528 + 0.9856003 * n)/DEG_IN_RADIAN;
     69  lambda = (L + 1.915 * sin(g) + 0.020 * sin(2. * g))/DEG_IN_RADIAN;
     70  epsilon = (23.439 - 0.0000004 * n)/DEG_IN_RADIAN;
     71
     72  // this is the conversion from ecliptic to celestial coords
     73  x = cos(lambda);
     74  y = cos(epsilon)*sin(lambda);
     75  z = sin(epsilon)*sin(lambda);
     76
     77  *ra = (atan_circ(x,y))*HRS_IN_RADIAN;
     78  *dec = (asin(z))*DEG_IN_RADIAN;
     79}
     80
     81/* code borrowed from Skycalc : fix this stuff XXX */
     82/* Low precision formulae for the sun, from Almanac p. C24 (1990) */
     83int sun_ecliptic (double jd, double *lambda, double *beta, double *epsilon) {
     84
     85  double n, L, g;
     86
     87
     88  n = jd - J2000;
     89  L = 280.460 + 0.9856474 * n;
     90  g = (357.528 + 0.9856003 * n)*RAD_DEG;
     91  *lambda = L + 1.915 * sin(g) + 0.020 * sin(2. * g); // longitude in degrees
     92  *beta = 0.0;                                    // approx latitude
     93  *epsilon = (23.439 - 0.0000004 * n);            // obliquity of ecliptic in degrees
     94  return TRUE;
     95}
     96# endif
     97
  • trunk/Ohana/src/relastro/src/Shutdown.c

    r37038 r38986  
    2121  va_end (argp);
    2222
    23   SetProtect (TRUE);
    24   gfits_db_close (db);
    2523  fprintf (stderr, "ERROR: relastro halted\n");
    2624  exit (1);
  • trunk/Ohana/src/relastro/src/StarMaps.c

    r37807 r38986  
    163163  }
    164164
    165   if (VERBOSE2) fprintf (stderr, "max deviations for %s using %d pts : %f, %f\n", images[N].name, starmap[N].Npoints, dLmax, dMmax);
     165  if (VERBOSE2) fprintf (stderr, "max deviations for %s using %d pts (%d fitted) : %f, %f\n", images[N].name, starmap[N].Npoints, images[N].nFitAstrom, dLmax, dMmax);
    166166
    167167  if (dLmax > DPOS_MAX) {
    168       if (VERBOSE) fprintf (stderr, "max deviations for %s using %d pts : %f, %f\n", images[N].name, starmap[N].Npoints, dLmax, dMmax);
     168    if (VERBOSE) fprintf (stderr, "max deviations for %s using %d pts (%d fitted) : %f, %f\n", images[N].name, starmap[N].Npoints, images[N].nFitAstrom, dLmax, dMmax);
    169169      return (FALSE);
    170170  }
    171171  if (dMmax > DPOS_MAX) {
    172       if (VERBOSE) fprintf (stderr, "max deviations for %s using %d pts : %f, %f\n", images[N].name, starmap[N].Npoints, dLmax, dMmax);
     172      if (VERBOSE) fprintf (stderr, "max deviations for %s using %d pts (%d fitted) : %f, %f\n", images[N].name, starmap[N].Npoints, images[N].nFitAstrom, dLmax, dMmax);
    173173      return (FALSE);
    174174  }
  • trunk/Ohana/src/relastro/src/UpdateChips.c

    r38062 r38986  
    2929// update astrometry of all chips relative to the average positions
    3030// if NTHREADS is non-zero, call the threaded version of this function
    31 int UpdateChips (Catalog *catalog, int Ncatalog) {
     31int UpdateChips (Catalog *catalog, int Ncatalog, int Nloop) {
    3232
    3333  off_t Nskip, Nmosaic, NnewFit, NoldFit;
     
    4040  char *mode;
    4141
     42  AstromErrorSetLoop (Nloop, TRUE);
     43
    4244  if (NTHREADS) {
    4345    UpdateChips_threaded (catalog, Ncatalog);
     
    5759  // each chip is fitted independently, so we could do N at once in parallel
    5860  for (i = 0; i < Nimage; i++) {
     61
     62    VERBOSE_IMAGE = !strcmp(image[i].name, "o5745g0516o.356887.cm.982631.smf[XY54]");
    5963
    6064    // XXX looks like everything below is thread safe : we can unroll this into a set of
     
    9195    }
    9296
     97    if (VERBOSE_IMAGE) {
     98      dump_stardata_pts (raw, Nraw, "testimage.raw.dat");
     99      dump_stardata_pts (ref, Nref, "testimage.ref.dat");
     100      fprintf (stderr, "dumped test image\n");
     101    }
     102
    93103    // note that Nraw & Nref must be equal: if not, we made a programming error in one of these two functions.
    94104    assert (Nraw == Nref);
     
    105115    // fprintf (stderr, "image "OFF_T_FMT" : Nstars: "OFF_T_FMT"\n",  i,  Nraw);
    106116    if (!FitChip (raw, ref, Nraw, &image[i])) {
    107       if (VERBOSE) fprintf (stderr, "reject fit for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT" of %d\n", image[i].name,  i,  Nraw, image[i].nstar);
     117      if (VERBOSE) fprintf (stderr, "reject fit for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT", Nused %d of %d\n", image[i].name,  i,  Nraw, image[i].nFitAstrom, image[i].nstar);
    108118
    109119      if (1) {
     
    124134
    125135    if (!checkStarMap (i)) {
    126       if (VERBOSE) fprintf (stderr, "fit diverges too much for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT"\n", image[i].name,  i,  Nraw);
     136      if (VERBOSE) fprintf (stderr, "fit diverges too much for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT", Nused: %d\n", image[i].name,  i,  Nraw, image[i].nFitAstrom);
    127137
    128138      if (1) {
     
    148158    setImageRaw (catalog, Ncatalog, i, raw, Nraw, MODE_MOSAIC);
    149159    if (USE_GALAXY_MODEL) {
     160      // XXX DEPRECATE?
    150161      image[i].flags |= ID_IMAGE_ASTROM_GMM;
    151162    }
     
    311322    // fprintf (stderr, "image "OFF_T_FMT" : Nstars: "OFF_T_FMT"\n",  i,  Nraw);
    312323    if (!FitChip (raw, ref, Nraw, &image[i])) {
    313       if (VERBOSE) fprintf (stderr, "reject fit for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT" of %d\n", image[i].name,  i,  Nraw, image[i].nstar);
     324      if (VERBOSE) fprintf (stderr, "reject fit for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT", Nused %d of %d\n", image[i].name,  i,  Nraw, image[i].nFitAstrom, image[i].nstar);
    314325
    315326      // restore status quo ante (replace truMap with tmpMap)
     
    328339
    329340    if (!checkStarMap (i)) {
    330       if (VERBOSE) fprintf (stderr, "fit diverges too much for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT"\n", image[i].name,  i,  Nraw);
     341      if (VERBOSE) fprintf (stderr, "fit diverges too much for image %s ("OFF_T_FMT") : Nstars: "OFF_T_FMT", Nused: %d\n", image[i].name,  i,  Nraw, image[i].nFitAstrom);
    331342
    332343      // restore status quo ante (replace truMap with tmpMap)
  • trunk/Ohana/src/relastro/src/UpdateObjectOffsets.c

    r38471 r38986  
    9797  }   
    9898
    99 # if (0)
     99# if (1)
    100100 
    101101  UpdateObjectOffsets_parallel_table (table, sky);
     
    155155
    156156    char *command = NULL;
    157     strextend (&command, "relastro_client -update-offsets -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f -statmode %s -minerror %f",
    158               group->hosts[i][0].hostID, CATDIR, group->hosts[i][0].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, STATMODE, MIN_ERROR);
     157    strextend (&command, "relastro_client -update-offsets");
     158    strextend (&command, "-hostID %d", group->hosts[i][0].hostID);
     159    strextend (&command, "-D CATDIR %s", CATDIR);
     160    strextend (&command, "-hostdir %s", group->hosts[i][0].pathname);
     161    strextend (&command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     162    strextend (&command, "-statmode %s", STATMODE);
     163    strextend (&command, "-minerror %f", MIN_ERROR);
    159164
    160165    if (FIT_MODE == FIT_PM_ONLY)         strextend (&command, "-pm");
     
    176181    if (ExcludeBogus)    strextend (&command, "-exclude-bogus %f", ExcludeBogusRadius);
    177182   
     183    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
    178184    if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1");
    179185
     
    184190    if (PhotFlagPoor)       strextend (&command, "+photflagpoor %d", PhotFlagPoor);
    185191    // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
     192
     193    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES);
    186194
    187195    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
     
    303311    // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
    304312
     313    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES);
     314
    305315    if (DCR_BLUE_COLOR_POS && DCR_BLUE_COLOR_NEG) {
    306316      strextend (&command, "-dcr-blue-color %s %s", DCR_BLUE_COLOR_POS, DCR_BLUE_COLOR_NEG);
  • trunk/Ohana/src/relastro/src/UpdateObjects.c

    r37807 r38986  
    22# define PAR_TOOFEW 5
    33
    4 int UpdateObjects_Chips (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats, int i, off_t m, int applyGalaxyOffset);
    5 int UpdateObjects_Stack (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats);
    6 
    7 static off_t Nmax;
    8 static double *X, *dX;
    9 static double *Y, *dY;
    10 static double *R, *dR;
    11 static double *D, *dD;
    12 static double *pX;
    13 static double *pY;
    14 static double *T;
    15 static double *dT;
    16 static double *C_blue;
    17 static double *C_red;
    18 
    19 static Coords coords;
    20 
    21 static time_t T2000;
    22 
    23 void initFitStats (FitStats *fitStats) {
    24   fitStats->Nave = 0; 
    25   fitStats->Npm = 0;   
    26   fitStats->Npar = 0; 
    27   fitStats->Nskip = 0;
    28   fitStats->Noffset = 0;
    29   return;
    30 }
    31 
    32 void sumFitStats (FitStats *srcFitStats, FitStats *tgtFitStats) {
    33   tgtFitStats->Nave    += srcFitStats->Nave    ; 
    34   tgtFitStats->Npm     += srcFitStats->Npm     ;   
    35   tgtFitStats->Npar    += srcFitStats->Npar    ; 
    36   tgtFitStats->Nskip   += srcFitStats->Nskip   ;
    37   tgtFitStats->Noffset += srcFitStats->Noffset ;
    38   return;
    39 }
    40 
    41 void initObjectData (Catalog *catalog, int Ncatalog) {
    42 
    43   off_t i, j;
    44  
    45   Nmax = 0;
    46   for (i = 0; i < Ncatalog; i++) {
    47     for (j = 0; j < catalog[i].Naverage; j++) {
    48       Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure);
    49     }
    50   }
    51 
    52   ALLOCATE (R, double, MAX (1, Nmax));
    53   ALLOCATE (D, double, MAX (1, Nmax));
    54   ALLOCATE (T, double, MAX (1, Nmax));
    55   ALLOCATE (X, double, MAX (1, Nmax));
    56   ALLOCATE (Y, double, MAX (1, Nmax));
    57 
    58   ALLOCATE (dR, double, MAX (1, Nmax));
    59   ALLOCATE (dD, double, MAX (1, Nmax));
    60   ALLOCATE (dT, double, MAX (1, Nmax));
    61   ALLOCATE (dX, double, MAX (1, Nmax));
    62   ALLOCATE (dY, double, MAX (1, Nmax));
    63 
    64   ALLOCATE (pX, double, MAX (1, Nmax));
    65   ALLOCATE (pY, double, MAX (1, Nmax));
    66 
    67   ALLOCATE (C_blue, double, MAX (1, Nmax));
    68   ALLOCATE (C_red,  double, MAX (1, Nmax));
    69 
    70   /* project coordinates to a plane centered on the object with units of arcsec */
    71   InitCoords (&coords, "DEC--SIN");
    72   coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0;
    73 
    74   // use J2000 as a reference time
    75   T2000 = ohana_date_to_sec ("2000/01/01,12:00:00");
    76 
    77 
    78 void freeObjectData () {
    79 
    80   free (R);
    81   free (D);
    82   free (T);
    83   free (X);
    84   free (Y);
    85 
    86   free (dR);
    87   free (dD);
    88   free (dT);
    89   free (dX);
    90   free (dY);
    91 
    92   free (pX);
    93   free (pY);
    94 
    95   free (C_blue);
    96   free (C_red);
    97 
     4int DumpObjectsWith2MASS (Catalog *catalog, int Ncatalog);
    985
    996// This function operates on both Measure and MeasureTiny.  In the big stages, this should
    1007// be called with just MeasureTiny set and Measure == NULL
    1018int UpdateObjects (Catalog *catalog, int Ncatalog, int Nloop) {
    102 
    103   initObjectData (catalog, Ncatalog);
    1049
    10510  // XXX in the future, use catalog[0].Nsecfilt only?  allow catalogs to have variable Nsecfilt?
     
    10914  }
    11015
    111   FitStats sumStatsChips; initFitStats (&sumStatsChips);
    112   FitStats sumStatsStack; initFitStats (&sumStatsStack);
     16  int NmeasureMax = CatalogMaxNmeasure (catalog, Ncatalog);
     17
     18  // allocate summary stats with Nmax = 0, Nboot = 0
     19  FitStats *sumStatsChips = FitStatsInit (0, 0);
     20  FitStats *sumStatsStack = FitStatsInit (0, 0);
     21
     22  FitStats *fitStatsChips = FitStatsInit (NmeasureMax, N_BOOTSTRAP_SAMPLES);
     23  FitStats *fitStatsStack = FitStatsInit (NmeasureMax, N_BOOTSTRAP_SAMPLES);
     24
     25  AstromErrorSetLoop (Nloop, FALSE);
    11326
    11427  int i;
     
    11730    if (VERBOSE2) fprintf (stderr, "astrometrize catalog %d : "OFF_T_FMT" ave, "OFF_T_FMT" meas\n", i,  catalog[i].Naverage,  catalog[i].Nmeasure);
    11831
    119     FitStats fitStatsChips; initFitStats (&fitStatsChips);
    120     FitStats fitStatsStack; initFitStats (&fitStatsStack);
     32    FitStatsReset (fitStatsChips);
     33    FitStatsReset (fitStatsStack);
    12134
    12235    off_t j;
     
    12942      SecFilt *secfilt = &catalog[i].secfilt[j*Nsecfilt];
    13043
    131       UpdateObjects_Stack(average, secfilt, measure, measureBig, Nsecfilt, &fitStatsStack);
    132       UpdateObjects_Chips(average, secfilt, measure, measureBig, Nsecfilt, &fitStatsChips, i, m, Nloop);
    133     }
    134     if (VERBOSE2) fprintf (stderr, "catalog %d : chips "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  fitStatsChips.Nave,  fitStatsChips.Npm,  fitStatsChips.Npar,  fitStatsChips.Nskip, fitStatsChips.Noffset);
    135     if (VERBOSE2) fprintf (stderr, "catalog %d : stack "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  fitStatsStack.Nave,  fitStatsStack.Npm,  fitStatsStack.Npar,  fitStatsStack.Nskip, fitStatsStack.Noffset);
    136     sumFitStats (&fitStatsChips, &sumStatsChips);
    137     sumFitStats (&fitStatsStack, &sumStatsStack);
    138   }
    139   freeObjectData ();
    140 
    141   if (VERBOSE && (Ncatalog > 1)) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (sumStatsChips.Nave + sumStatsChips.Npm + sumStatsChips.Npar),  sumStatsChips.Nave,  sumStatsChips.Npm,  sumStatsChips.Npar,  sumStatsChips.Nskip, sumStatsChips.Noffset);
    142   if (VERBOSE && (Ncatalog > 1)) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (sumStatsStack.Nave + sumStatsStack.Npm + sumStatsStack.Npar),  sumStatsStack.Nave,  sumStatsStack.Npm,  sumStatsStack.Npar,  sumStatsStack.Nskip, sumStatsStack.Noffset);
     44      UpdateObjects_Stack(average, secfilt, measure, measureBig, Nsecfilt, fitStatsStack);
     45      UpdateObjects_Chips(average, secfilt, measure, measureBig, Nsecfilt, fitStatsChips, i, m);
     46    }
     47    if (VERBOSE2) fprintf (stderr, "catalog %d : chips "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  fitStatsChips->Nave,  fitStatsChips->Npm,  fitStatsChips->Npar,  fitStatsChips->Nskip, fitStatsChips->Noffset);
     48    if (VERBOSE2) fprintf (stderr, "catalog %d : stack "OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par : Nskip "OFF_T_FMT", Noffset "OFF_T_FMT"\n",  i,  fitStatsStack->Nave,  fitStatsStack->Npm,  fitStatsStack->Npar,  fitStatsStack->Nskip, fitStatsStack->Noffset);
     49    FitStatsSum (fitStatsChips, sumStatsChips);
     50    FitStatsSum (fitStatsStack, sumStatsStack);
     51  }
     52
     53  // DumpObjectsWith2MASS (catalog, Ncatalog);
     54
     55  FitStatsFree (fitStatsChips);
     56  FitStatsFree (fitStatsStack);
     57
     58  if (VERBOSE && (Ncatalog > 1)) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (sumStatsChips->Nave + sumStatsChips->Npm + sumStatsChips->Npar),  sumStatsChips->Nave,  sumStatsChips->Npm,  sumStatsChips->Npar,  sumStatsChips->Nskip, sumStatsChips->Noffset);
     59  if (VERBOSE && (Ncatalog > 1)) fprintf (stderr, "fitted "OFF_T_FMT" objects ("OFF_T_FMT" ave, "OFF_T_FMT" pm, "OFF_T_FMT" par), skipped "OFF_T_FMT", "OFF_T_FMT" have too large an offset\n",  (sumStatsStack->Nave + sumStatsStack->Npm + sumStatsStack->Npar),  sumStatsStack->Nave,  sumStatsStack->Npm,  sumStatsStack->Npar,  sumStatsStack->Nskip, sumStatsStack->Noffset);
     60
     61  FitStatsFree (sumStatsChips);
     62  FitStatsFree (sumStatsStack);
     63
    14364  return (TRUE);
    14465}
     
    14667// This function operates on both Measure and MeasureTiny.  In the big stages, this should
    14768// be called with just MeasureTiny set and Measure == NULL
    148 int UpdateObjects_Chips (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats, int i, off_t m, int applyGalaxyOffset) {
    149 
    150   int setRefColor = areImagesMatched();
     69int DumpObjectsWith2MASS (Catalog *catalog, int Ncatalog) {
     70
     71  int i;
     72  for (i = 0; i < Ncatalog; i++) {
     73    off_t j;
     74    for (j = 0; j < catalog[i].Naverage; j++) {
     75      /* calculate the average value of R,D for a single star */
     76      off_t m = catalog[i].average[j].measureOffset;
     77
     78      off_t k;
     79      for (k = 0; k < catalog[i].average[j].Nmeasure; k++) {
     80        MeasureTiny *measure = &catalog[i].measureT[m+k];
     81        if (measure->dbFlags & ID_MEAS_OBJECT_HAS_2MASS) {
     82          fprintf (stderr, "0x%08x 0x%08x : %12.8f %12.8f %5d\n", catalog[i].average[j].objID, catalog[i].average[j].catID, measure->R, measure->D, measure->photcode);
     83        }
     84      }
     85    }
     86  }
     87  return (TRUE);
     88}
     89
     90// This function operates on both Measure and MeasureTiny.  In the big stages, this should
     91// be called with just MeasureTiny set and Measure == NULL
     92int UpdateObjects_Chips (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats, int cat, off_t measOff) {
     93
     94  int k;
    15195
    15296  /* calculate the average value of R,D for a single star */
    15397
    154   PMFit fit;    memset (&fit,    0, sizeof(fit));
    155   PMFit fitAve; memset (&fitAve, 0, sizeof(fitAve)); fitAve.chisq = NAN;
    156   PMFit fitPM;  memset (&fitPM,  0, sizeof(fitPM));  fitPM.chisq = NAN;
    157   PMFit fitPAR; memset (&fitPAR, 0, sizeof(fitPAR)); fitPAR.chisq = NAN;
     98  FitAstromResult fitPos, fitPM, fitPar;
     99  FitAstromResultInit (&fitPos);
     100  FitAstromResultInit (&fitPM);
     101  FitAstromResultInit (&fitPar);
    158102
    159103  // if we fail to fit the astrometry for some reason, we need to set/reset these
     
    167111  if (average[0].Nmeasure == 0) return TRUE;
    168112
    169   int NcBlue = 0;
    170   int NcRed = 0;
    171   int N = 0;
    172 
    173113  int mode = FIT_MODE; // start with the globally-defined fit mode
    174114
     
    177117  XVERB |= (average[0].objID == OBJ_ID_DST) && (average[0].catID == CAT_ID_DST);
    178118
    179   // find the basic properties of the detections for this object (Tmin, Tmax, Tmean)
    180   off_t k;
    181   for (k = 0; k < average[0].Nmeasure; k++) {
    182 
    183     if (XVERB) {
    184       char *date = ohana_sec_to_date (measure[k].t);
    185       int dbFlagsBig = measureBig ? measureBig[k].dbFlags : 0;
    186       fprintf (stderr, OFF_T_FMT" %f %f %s : 0x%08x : 0x%08x\n",  k, measure[k].R, measure[k].D, date, measure[k].dbFlags, dbFlagsBig);
    187       free (date);
    188     }
    189 
    190     // SKIP gpc1 stack data
    191     if (isGPC1stack(measure[k].photcode)) continue;
    192 
    193     // SKIP gpc1 forced-warp data
    194     if (isGPC1warp(measure[k].photcode)) continue;
    195 
    196     // reset the bit to note that a detection was used (or not)
    197     measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
    198     if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
    199 
    200     // does the measurement pass the supplied filtering constraints?
    201     // MeasFilterTestTiny does not test psfQF
    202     // exclude bad detections based on: photcodes, psfQF, time range, photflags & astromBadMask, mag_inst
    203     int keepMeasure = measureBig ? MeasFilterTest(&measureBig[k], FALSE) : MeasFilterTestTiny(&measure[k], FALSE);
    204     if (!keepMeasure) {
    205       continue;
    206     }
    207 
    208     double Ri = getMeanR (&measure[k], average, secfilt);
    209     double Di = getMeanD (&measure[k], average, secfilt);
    210 
    211     // if we are correcting for the Galaxy Motion Model, only should apply it here
    212     // (a) when we are working to correct the images (mean R,D assumed to be at J2000) and
    213     // (b) if we think the measure R,D is already at the image epoch position
    214     if (USE_GALAXY_MODEL && applyGalaxyOffset) {
    215       Ri -= measure[k].RoffGAL / 3600.0;
    216       Di -= measure[k].DoffGAL / 3600.0;
    217     }
    218 
    219     // XXX add in dR,dD GAL here
    220 
    221     // mark (as POOR) any measurements which are deviant from the mean by > ExcludeBogusRadius
    222     if (ExcludeBogus) {
    223       coords.crval1 = average[0].R;
    224       coords.crval2 = average[0].D;
    225       double Xi, Yi;
    226       RD_to_XY (&Xi, &Yi, Ri, Di, &coords);
    227       double radius = hypot(Xi, Yi);
    228       if (radius > ExcludeBogusRadius) {
    229         measure[k].dbFlags |= ID_MEAS_POOR_ASTROM;
    230         if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_POOR_ASTROM; }
    231         continue;
    232       }
    233       measure[k].dbFlags &= ~ID_MEAS_POOR_ASTROM;
    234       if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_POOR_ASTROM; }
    235     }
    236 
    237     // outlier rejection
    238     if (FALSE && FlagOutlier && (measure[k].dbFlags & ID_MEAS_POOR_ASTROM)) {
    239       continue;
    240     }
    241 
    242     R[N] = Ri;
    243     D[N] = Di;
    244 
    245     // measure[k].t is UNIX seconds, T2000 is UNIX seconds for J2000.
    246     // T[] is time in years since J2000 (jd = 2451545)
    247     T[N] = (measure[k].t - T2000) / (86400*365.25) ; // time relative to J2000 in years
    248 
    249     // dX, dY : error in arcsec --
    250     dX[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_RA);
    251     dY[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_DEC);
    252 
    253     // allow a given photcode or measurement to be
    254     // ignored if the error is NAN (for photcode, set astromErrSys to NaN)
    255     if (isnan(dX[N])) continue;
    256     if (isnan(dY[N])) continue;
    257 
    258     // add systematic error in quadrature, if desired
    259     // only do this after the fit has converged (or you will never improve the poor images)
    260     // if (INCLUDE_SYS_ERR) {
    261     // float dRsys = FromShortPixels(measure[k].dRsys);
    262     // dX[N] = hypot(dX[N], dRsys);
    263     // dY[N] = hypot(dY[N], dRsys);
    264     // }
    265 
    266     // dX[N] = 0.1;
    267     // dY[N] = 0.1;
    268 
    269     dT[N] = measure[k].dt;
    270 
    271     // XXX this is (slightly) inconsistent: dX,dY are the X and Y direction errors in
    272     // arcseconds.  dR, dD are the errors in those directions in degrees.  IF we have
    273     // non-circular errors (different values for X and Y), then dR and dD will be
    274     // incorrect: they would need to be rotated to take out the position angle
    275     dR[N] = dX[N] / 3600.0;
    276     dD[N] = dY[N] / 3600.0;
    277 
    278     if (setRefColor) {
    279       float colorBlue = getColorBlue (m+k, i);
    280       if (!isnan(colorBlue)) {
    281         C_blue[NcBlue] = colorBlue;
    282         NcBlue++;
    283       }
    284       float colorRed = getColorRed (m+k, i);
    285       if (!isnan(colorRed)) {
    286         C_red[NcRed] = colorRed;
    287         NcRed++;
    288       }
    289     }
    290 
    291     measure[k].dbFlags |= ID_MEAS_USED_OBJ;
    292     if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_USED_OBJ; }
    293 
    294     N++;
    295   } // loop over measurements : average[0].Nmeasure
    296 
    297   if (N < 1) {
     119  // select the measurements to be used in this analysis
     120  UpdateObjects_SelectMeasures (fitStats, average, secfilt, measure, measureBig, FALSE);
     121
     122  // if there are no exposure detections, use the stack position
     123  if (fitStats->Npoints < 1) {
    298124    if (isfinite(average[0].Rstk) && isfinite(average[0].Dstk)) {
    299125      average[0].R  = average[0].Rstk;
     
    301127      average[0].dR = average[0].dRstk;
    302128      average[0].dD = average[0].dDstk;
     129      average[0].flags |= ID_STACK_ASTROM;
    303130    }
    304131    return FALSE;
    305132  }
    306133
    307   // if we have too few good detections for the desired fit, or too limited a
    308   // baseline, use a fit with fewer parameters.  XXX if we have too few measurements
    309   // for even the average position, consider including the lower-quality detections?
    310 
    311   // find Tmin & Tmax from the list of accepted measurements
    312   double Tmean = 0.0;
    313   double Tmin = T[0];
    314   double Tmax = T[0];
    315   for (k = 0; k < N; k++) {
    316     Tmin = MIN(Tmin, T[k]);
    317     Tmax = MAX(Tmax, T[k]);
    318     Tmean += T[k];
    319   }
    320   double Trange = Tmax - Tmin;
    321 
    322   if (RELASTRO_OP == OP_HIGH_SPEED) {
    323     Tmean = 0.5*(Tmax - Tmin);
    324   } else {
    325     Tmean /= (float) N;
    326   }
    327 
    328   /* we need to do the fit in a locally linear space; choose a ref coordinate */
    329   coords.crval1 = R[0];
    330   coords.crval2 = D[0];
     134  double Tmean, Trange, parRange;
     135  FitAstromPoints_Project (fitStats, &Tmean, &Trange, &parRange);
    331136
    332137  // to judge the quality of the PM and PAR fits, we need to fit all three models and compare Chisq
    333138
    334   // project all of the R,D coordinates to a plane centered on this coordinate. set
    335   // the times to be relative to Tmean (this is required for parallax as well)
    336   for (k = 0; k < N; k++) {
    337     RD_to_XY (&X[k], &Y[k], R[k], D[k], &coords);
    338     T[k] -= Tmean;
    339     if (XVERB) {
    340       fprintf (stderr, OFF_T_FMT" %f %f %f  %f %f +/- %f %f\n",  k, T[k], R[k], D[k], X[k], Y[k], dX[k], dY[k]);
    341     }
    342   }       
     139  // if we have too few good detections for the desired fit, or too limited a baseline,
     140  // use a fit with fewer parameters.
    343141
    344142  // *** first fit for the proper motion (skip fit if Trange or Npts is too small) ***
     
    346144    if (Trange < PM_DT_MIN) {
    347145      mode = FIT_AVERAGE;
    348       goto skipPM;
    349     }
    350     if (N <= PM_TOOFEW) {
     146      goto justPosition;
     147    }
     148    if (fitStats->Npoints <= PM_TOOFEW) {
    351149      mode = FIT_AVERAGE;
    352       goto skipPM;
    353     }
    354 
    355     FitPM (&fitPM, X, dX, Y, dY, T, N, XVERB);
    356 
    357     if (XVERB) fprintf (stderr, "fitted PM:  %f - %f : %f %f : %f %f : %f vs %f\n", Tmin, Tmax, fitPM.Ro, fitPM.Do, fitPM.uR, fitPM.uD, fitPM.chisq, fitAve.chisq);
     150      goto justPosition;
     151    }
     152
     153    if (fitStats->NfitAlloc == 1) {
     154      // if N_BOOTSTRAP_SAMPLES = 1, no bootstrap resampling:
     155      FitPM (&fitPM, fitStats->fitdataPM, fitStats->points, fitStats->Npoints);
     156    } else {
     157      fitStats->Nfit = 0;
     158      for (k = 0; k < fitStats->NfitAlloc; k++) {
     159        BootstrapResample (fitStats->sample, fitStats->points, fitStats->Npoints);
     160        if (!FitPM (&fitStats->fit[k], fitStats->fitdataPM, fitStats->sample, fitStats->Npoints)) continue;
     161        fitStats->Nfit ++;
     162      }
     163      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
     164      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
     165      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_uR);
     166      BootstrapRobustStats (&fitPM, fitStats->fit, fitStats->Nfit, FIT_RESULT_uD);
     167    }
     168    FitAstromSetChisq (&fitPM, fitStats->points, fitStats->Npoints, FIT_PM_ONLY);
    358169
    359170    // project Ro, Do back to RA,DEC
    360     XY_to_RD (&fitPM.Ro, &fitPM.Do, fitPM.Ro, fitPM.Do, &coords);
    361     if (XVERB) fprintf (stderr, "project: %f %f : %f %f : %f\n", fitPM.Ro, fitPM.Do, fitPM.uR, fitPM.uD, fitPM.p);
     171    XY_to_RD (&fitPM.Ro, &fitPM.Do, fitPM.Ro, fitPM.Do, &fitStats->coords);
    362172    if (fabs(fitPM.Ro) < 0.01) fprintf (stderr, "watch out for 0,360 boundary\n");
    363     // XXX : does this make sense at 0,360 boundary?
    364173
    365174    fitPM.p  = fitPM.dp  = 0.0;
     
    374183  }
    375184 
    376 skipPM:
    377185  // fit the parallax + proper-motion model
    378186  // NOTE : we only fit PAR if we have already fitted for proper motion. if we do not fit PM or we fail
    379187  // to fit PM, we do not attempt PAR.  thus failure to fit PAR falls back to PM-only
    380188  if (mode == FIT_PM_AND_PAR) {
    381     if (Trange < PM_DT_MIN) {
    382       mode = FIT_PM_ONLY;
    383       goto skipPAR;
    384     }
    385     if (N <= PAR_TOOFEW) {
    386       mode = FIT_PM_ONLY;
    387       goto skipPAR;
    388     }
    389     float pXmin = +2.0;
    390     float pXmax = -2.0;
    391     float pYmin = +2.0;
    392     float pYmax = -2.0;
    393     for (k = 0; k < N; k++) {
    394       ParFactor (&pX[k], &pY[k], R[k], D[k], T[k], Tmean);
    395       pXmin = MIN (pXmin, pX[k]);
    396       pXmax = MAX (pXmax, pX[k]);
    397       pYmin = MIN (pYmin, pY[k]);
    398       pYmax = MAX (pYmax, pY[k]);
    399     }
    400     float dXRange = pXmax - pXmin;
    401     float dYRange = pYmax - pYmin;
    402     float parRange = hypot (dXRange, dYRange);
    403        
    404189    if (parRange < PAR_FACTOR_MIN) {
    405190      mode = FIT_PM_ONLY;
    406       goto skipPAR;
    407     }
    408 
    409     FitPMandPar (&fitPAR, X, dX, Y, dY, T, pX, pY, N, XVERB);
    410     if (XVERB) fprintf (stderr, "fitted PM+PAR:  %f - %f : %f %f : %f %f : %f %f : %f vs %f vs %f\n", Tmin, Tmax, fitPAR.Ro, fitPAR.Do, fitPAR.uR, fitPAR.uD, fitPAR.p, fitPAR.dp, fitPAR.chisq, fitPM.chisq, fitAve.chisq);
    411 
    412     XY_to_RD (&fitPAR.Ro, &fitPAR.Do, fitPAR.Ro, fitPAR.Do, &coords);
     191      goto justPosition;
     192    }
     193    if (fitStats->Npoints <= PAR_TOOFEW) {
     194      mode = FIT_PM_ONLY;
     195      goto justPosition;
     196    }
     197
     198    if (fitStats->NfitAlloc == 1) {
     199      // if N_BOOTSTRAP_SAMPLES = 1, no bootstrap resampling:
     200      FitPMandPar (&fitPar, fitStats->fitdataPar, fitStats->points, fitStats->Npoints);
     201    } else {
     202      fitStats->Nfit = 0;
     203      for (k = 0; k < fitStats->NfitAlloc; k++) {
     204        BootstrapResample (fitStats->sample, fitStats->points, fitStats->Npoints);
     205        FitPMandPar (&fitStats->fit[k], fitStats->fitdataPar, fitStats->sample, fitStats->Npoints);
     206        fitStats->Nfit ++;
     207      }
     208      BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
     209      BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
     210      BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_uR);
     211      BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_uD);
     212      BootstrapRobustStats (&fitPar, fitStats->fit, fitStats->Nfit, FIT_RESULT_PLX);
     213    }
     214    FitAstromSetChisq (&fitPar, fitStats->points, fitStats->Npoints, FIT_PM_AND_PAR);
     215
     216    // project Ro, Do back to RA,DEC
     217    XY_to_RD (&fitPar.Ro, &fitPar.Do, fitPar.Ro, fitPar.Do, &fitStats->coords);
     218    if (fabs(fitPar.Ro) < 0.01) fprintf (stderr, "watch out for 0,360 boundary\n");
     219
    413220    average[0].flags |= ID_STAR_FIT_PAR;
    414221    fitStats->Npar ++;
    415222
    416     if (fabs(fitPM.Ro) < 0.01) fprintf (stderr, "watch out for 0,360 boundary\n");
    417 
    418223    // XXX a hard-wired hack...
    419     if ((fabs(fitPAR.uR) > 2.0) || (fabs(fitPAR.uD) > 2.0)) {
     224    if ((fabs(fitPar.uR) > 2.0) || (fabs(fitPar.uD) > 2.0)) {
    420225      mode = FIT_PM_ONLY;
    421226    }
    422227  }       
    423228
    424 skipPAR:
     229justPosition:
    425230  {
    426     // ALWAYS fit the average model
    427     StatType statsR, statsD;
    428     liststats_pos (X, dX, N, &statsR, XVERB); // WARNING: this function modifies R (do not use after here)
    429     liststats_pos (Y, dY, N, &statsD, XVERB); // WARNING: this function modifies D (do not use after here)
     231    // use bootstrap resampling to check the error distribution
     232    // if we only have one point, this is silly...
     233   
     234    if (fitStats->NfitAlloc == 1) {
     235      FitAstromResultSetPM (&fitPos, 1, average);
     236      FitPosPMfixed (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints);
     237    } else {
     238      fitStats->Nfit = 0;
     239      FitAstromResultSetPM (fitStats->fit, fitStats->NfitAlloc, average);
     240      for (k = 0; k < fitStats->NfitAlloc; k++) {
     241        BootstrapResample (fitStats->sample, fitStats->points, fitStats->Npoints);
     242        FitPosPMfixed (&fitStats->fit[k], fitStats->fitdataPos, fitStats->sample, fitStats->Npoints);
     243        fitStats->Nfit ++;
     244      }
     245      BootstrapRobustStats (&fitPos, fitStats->fit, fitStats->Nfit, FIT_RESULT_RA);
     246      BootstrapRobustStats (&fitPos, fitStats->fit, fitStats->Nfit, FIT_RESULT_DEC);
     247    }
     248    FitAstromSetChisq (&fitPos, fitStats->points, fitStats->Npoints, FIT_AVERAGE);
    430249
    431250    // project Ro, Do back to RA,DEC
    432     XY_to_RD (&fitAve.Ro, &fitAve.Do, statsR.mean, statsD.mean, &coords);
    433     if (XVERB) fprintf (stderr, "average: %f %f\n", fitAve.Ro, fitAve.Do);
    434 
    435     fitAve.dRo = statsR.sigma;
    436     fitAve.dDo = statsD.sigma;
    437 
    438     fitAve.chisq = (N > 1) ? 0.5 * (statsR.chisq + statsD.chisq) : NAN;
    439     fitAve.Nfit = N;
    440 
    441     fitAve.uR = fitAve.duR = 0.0;
    442     fitAve.uD = fitAve.duD = 0.0;
    443     fitAve.p  = fitAve.dp  = 0.0;
     251    XY_to_RD (&fitPos.Ro, &fitPos.Do, fitPos.Ro, fitPos.Do, &fitStats->coords);
    444252    average[0].flags |= ID_STAR_FIT_AVE;
    445253    fitStats->Nave ++;
    446254  }
    447255
     256  // update the bit flags of which points were used
     257  for (k = 0; k < fitStats->Npoints; k++) {
     258    int Nm = fitStats->points[k].measure;
     259    myAssert (Nm >= 0, "oops");
     260    measure[Nm].dbFlags |= ID_MEAS_USED_OBJ;
     261    if (measureBig) { measureBig[Nm].dbFlags |= ID_MEAS_USED_OBJ; }
     262  }
     263
     264  // we can set the star reference-image color only if we have loaded the image data
     265  int setRefColor = areImagesMatched();
    448266  if (setRefColor) {
     267    float *C_blue = NULL;
     268    float *C_red = NULL;
     269    ALLOCATE (C_blue, float, fitStats->Npoints);
     270    ALLOCATE (C_red, float, fitStats->Npoints);
     271
     272    int NcBlue = 0;
     273    int NcRed = 0;
     274
     275    for (k = 0; k < fitStats->Npoints; k++) {
     276      int Nm = fitStats->points[k].measure;
     277      float colorBlue = getColorBlue (measOff + Nm, cat);
     278      if (!isnan(colorBlue)) {
     279        C_blue[NcBlue] = colorBlue;
     280        NcBlue++;
     281      }
     282      float colorRed = getColorRed (measOff + Nm, cat);
     283      if (!isnan(colorRed)) {
     284        C_red[NcRed] = colorRed;
     285        NcRed++;
     286      }
     287    }
     288
     289    // need to reassign here if isfinite()
    449290    float colorMedian;
    450     dsort (C_blue, NcBlue);
     291    fsort (C_blue, NcBlue);
    451292    colorMedian = (NcBlue > 0) ? C_blue[(int)(0.5*NcBlue)] : NAN;
    452293    average[0].refColorBlue = colorMedian;
    453     dsort (C_red, NcRed);
     294    fsort (C_red, NcRed);
    454295    colorMedian = (NcRed > 0) ? C_red[(int)(0.5*NcRed)] : NAN;
    455296    average[0].refColorRed = colorMedian;
     297
     298    free (C_blue);
     299    free (C_red);
    456300  }
    457301
     
    459303  // XXXX for now, just use the mode as the result:
    460304  int result = mode;
     305  FitAstromResult fit;
     306  FitAstromResultInit (&fit);
    461307
    462308  switch (result) {
    463309    case FIT_AVERAGE:
    464310      average[0].flags |= ID_STAR_USE_AVE;
    465       fit = fitAve;
     311      fit = fitPos;
    466312      break;
    467313    case FIT_PM_ONLY:
     
    471317    case FIT_PM_AND_PAR:
    472318      average[0].flags |= ID_STAR_USE_PAR;
    473       fit = fitPAR;
     319      fit = fitPar;
    474320      break;
    475321  }
     
    503349
    504350  // what is the offset relative to the mean fit position?
    505   coords.crval1 = average[0].R;
    506   coords.crval2 = average[0].D;
    507   if (isnan(coords.crval1)) {
     351  fitStats->coords.crval1 = average[0].R;
     352  fitStats->coords.crval2 = average[0].D;
     353  if (isnan(fitStats->coords.crval1)) {
    508354    return (FALSE);
    509355  }
    510   if (isnan(coords.crval2)) {
     356  if (isnan(fitStats->coords.crval2)) {
    511357    return (FALSE);
    512358  }
    513359
    514360  double dXoff, dYoff;
    515   RD_to_XY (&dXoff, &dYoff, fit.Ro, fit.Do, &coords);
     361  RD_to_XY (&dXoff, &dYoff, fit.Ro, fit.Do, &fitStats->coords);
    516362  float dPos = hypot (dXoff, dYoff);
    517363  if (dPos > MaxMeanOffset) {
    518364    if (fitStats->Noffset < 100) {
    519       fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", coords.crval1, coords.crval2, fit.Ro, fit.Do, dXoff, dYoff);
     365      fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", fitStats->coords.crval1, fitStats->coords.crval2, fit.Ro, fit.Do, dXoff, dYoff);
    520366    }
    521367    fitStats->Noffset ++;
     
    531377                      average[0].uR,
    532378                      average[0].uD,
    533                       fitAve.chisq, fitPM.chisq, fitPAR.chisq);
     379                      fitPos.chisq, fitPM.chisq, fitPar.chisq);
    534380
    535381  average[0].R          = fit.Ro; // RA in degrees
     
    546392  average[0].dP         = fit.dp; // parallax error in arcsec
    547393
    548   average[0].ChiSqAve   = fitAve.chisq;
     394  average[0].ChiSqAve   = fitPos.chisq;
    549395  average[0].ChiSqPM    = fitPM.chisq;
    550   average[0].ChiSqPar   = fitPAR.chisq;
    551 
    552   average[0].Tmean      = (Tmean * 86400 * 365.25) + T2000;
     396  average[0].ChiSqPar   = fitPar.chisq;
     397
     398  average[0].Tmean      = (Tmean * 86400 * 365.25) + fitStats->T2000;
    553399  average[0].Trange     = (Trange * 86400 * 365.25);
    554400  average[0].Npos       = fit.Nfit;
     
    563409// be called with just MeasureTiny set and Measure == NULL
    564410int UpdateObjects_Stack (Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int Nsecfilt, FitStats *fitStats) {
    565 
    566   off_t k;
    567411
    568412  // set the default values
     
    573417
    574418  /* calculate the average value of R,D for a single star */
    575   PMFit fitAve;
    576   memset (&fitAve, 0, sizeof(fitAve));
    577   fitAve.chisq = NAN;
     419  FitAstromResult fitPos;
     420  FitAstromResultInit (&fitPos);
    578421
    579422  if (average[0].Nmeasure == 0) return TRUE;
    580 
    581   int N = 0;
    582423
    583424  int XVERB = FALSE;
     
    585426  XVERB |= (average[0].objID == OBJ_ID_DST) && (average[0].catID == CAT_ID_DST);
    586427
     428  // select the measurements to be used in this analysis
     429  UpdateObjects_SelectMeasures (fitStats, average, secfilt, measure, measureBig, TRUE);
     430
     431  // too few measurements for average position (require 2 values)
     432  if (fitStats->Npoints < 1) return FALSE; // XXX ??
     433 
     434  double Tmean, Trange, parRange;
     435  FitAstromPoints_Project (fitStats, &Tmean, &Trange, &parRange);
     436
     437  FitPosPMfixed (&fitPos, fitStats->fitdataPos, fitStats->points, fitStats->Npoints);
     438  FitAstromSetChisq (&fitPos, fitStats->points, fitStats->Npoints, FIT_AVERAGE);
     439
     440  // project Ro, Do back to RA,DEC
     441  XY_to_RD (&fitPos.Ro, &fitPos.Do, fitPos.Ro, fitPos.Do, &fitStats->coords);
     442
     443  // XXX choose stack flag? average[0].flags |= ID_STAR_FIT_AVE;
     444  fitStats->Nave ++;
     445
     446  if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f)\n",
     447                      average[0].R,
     448                      average[0].D,
     449                      fitPos.Ro, fitPos.Do,
     450                      3600*(average[0].R - fitPos.Ro),
     451                      3600*(average[0].D - fitPos.Do));
     452
     453  // make sure that the fit succeeded
     454  int status = TRUE;
     455  status &= finite(fitPos.Ro);
     456  status &= finite(fitPos.Do);
     457  status &= finite(fitPos.dRo);
     458  status &= finite(fitPos.dDo);
     459  if (!status) {
     460    fitStats->Nskip ++;
     461    return FALSE;
     462  }
     463
     464  // what is the offset relative to the mean fit position?
     465  fitStats->coords.crval1 = average[0].R;
     466  fitStats->coords.crval2 = average[0].D;
     467
     468  double dXoff, dYoff;
     469  RD_to_XY (&dXoff, &dYoff, fitPos.Ro, fitPos.Do, &fitStats->coords);
     470  float dPos = hypot (dXoff, dYoff);
     471  if (dPos > MaxMeanOffset) {
     472    if (fitStats->Noffset < 100) {
     473      fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", fitStats->coords.crval1, fitStats->coords.crval2, fitPos.Ro, fitPos.Do, dXoff, dYoff);
     474    }
     475    fitStats->Noffset ++;
     476    return FALSE;
     477  }
     478
     479  // set the stack position values
     480  average[0].Rstk  = fitPos.Ro; // RA in degrees
     481  average[0].Dstk  = fitPos.Do; // DEC in degrees
     482  average[0].dRstk = fitPos.dRo; // RA scatter in arcsec
     483  average[0].dDstk = fitPos.dDo; // DEC scatter in arcsec
     484
     485  return (TRUE);
     486}
     487
     488int UpdateObjects_SelectMeasures (FitStats *fit, Average *average, SecFilt *secfilt, MeasureTiny *measure, Measure *measureBig, int isStack) {
     489
     490  // I've already allocated fit->points (and fit->sample) with space for fit->NpointsAlloc entries
     491
     492  int has2MASS = FALSE;
     493
     494  int Npoints = fit->Npoints = 0;
     495  FitAstromPoint *points = fit->points;
     496
     497  int TESTPT2 = FALSE;
     498  TESTPT2 |= CAT_ID_SRC && OBJ_ID_SRC && (average[0].catID == CAT_ID_SRC) && (average[0].objID == OBJ_ID_SRC);
     499  TESTPT2 |= CAT_ID_DST && OBJ_ID_DST && (average[0].catID == CAT_ID_DST) && (average[0].objID == OBJ_ID_DST);
     500  if (TESTPT2) {
     501    fprintf (stderr, "got test det\n");
     502  }
     503
    587504  // find the basic properties of the detections for this object (Tmin, Tmax, Tmean)
     505  off_t k;
    588506  for (k = 0; k < average[0].Nmeasure; k++) {
    589507
    590     if (XVERB) {
     508    if (0) {
    591509      char *date = ohana_sec_to_date (measure[k].t);
    592510      int dbFlagsBig = measureBig ? measureBig[k].dbFlags : 0;
    593       fprintf (stderr, "stack: "OFF_T_FMT" %f %f %s : 0x%08x : 0x%08x\n",  k, measure[k].R, measure[k].D, date, measure[k].dbFlags, dbFlagsBig);
     511      fprintf (stderr, OFF_T_FMT" %f %f %s : 0x%08x : 0x%08x\n",  k, measure[k].R, measure[k].D, date, measure[k].dbFlags, dbFlagsBig);
    594512      free (date);
    595513    }
    596514
    597     // SKIP everything except gpc1 stack data
    598     if (!isGPC1stack(measure[k].photcode)) continue;
    599 
     515    // SKIP gpc1 forced-warp data
     516    if (isGPC1warp(measure[k].photcode)) continue;
     517
     518    // SKIP gpc1 stack data
     519    if (isStack) {
     520      if (!isGPC1stack(measure[k].photcode)) continue;
     521    } else {
     522      if ( isGPC1stack(measure[k].photcode)) continue;
     523    }
     524
     525    // reset the bit to note that a detection was used (or not)
     526    measure[k].dbFlags &= ~ID_MEAS_USED_OBJ;
     527    if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_USED_OBJ; }
     528
     529    // does the measurement pass the supplied filtering constraints?
     530    // MeasFilterTestTiny does not test psfQF
    600531    // exclude bad detections based on: photcodes, psfQF, time range, photflags & astromBadMask, mag_inst
    601532    int keepMeasure = measureBig ? MeasFilterTest(&measureBig[k], FALSE) : MeasFilterTestTiny(&measure[k], FALSE);
     
    604535    }
    605536
    606     R[N] = getMeanR (&measure[k], average, secfilt);
    607     D[N] = getMeanD (&measure[k], average, secfilt);
    608 
    609     // dX, dY : error in arcsec --
    610     dX[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_RA);
    611     dY[N] = GetAstromErrorTiny (&measure[k], ERROR_MODE_DEC);
     537    double Ri = measure[k].R;
     538    double Di = measure[k].D;
     539
     540    // mark (as POOR) any measurements which are deviant from the mean by > ExcludeBogusRadius
     541    if (ExcludeBogus) {
     542      fit->coords.crval1 = average[0].R;
     543      fit->coords.crval2 = average[0].D;
     544      double Xi, Yi;
     545      RD_to_XY (&Xi, &Yi, Ri, Di, &fit->coords);
     546      double radius = hypot(Xi, Yi);
     547      if (radius > ExcludeBogusRadius) {
     548        measure[k].dbFlags |= ID_MEAS_POOR_ASTROM;
     549        if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_POOR_ASTROM; }
     550        continue;
     551      }
     552      measure[k].dbFlags &= ~ID_MEAS_POOR_ASTROM;
     553      if (measureBig) { measureBig[k].dbFlags &= ~ID_MEAS_POOR_ASTROM; }
     554    }
     555
     556    // outlier rejection
     557    if (FALSE && FlagOutlier && (measure[k].dbFlags & ID_MEAS_POOR_ASTROM)) {
     558      continue;
     559    }
     560
     561    FitAstromPointInit (&points[Npoints]);
     562
     563    points[Npoints].R = Ri;
     564    points[Npoints].D = Di;
     565
     566    // measure[k].t is UNIX seconds, T2000 is UNIX seconds for J2000.
     567    // T[] is time in years since J2000 (jd = 2451545)
     568    points[Npoints].T = (measure[k].t - fit->T2000) / (86400*365.25) ; // time relative to J2000 in years
     569
     570    // add measured systematic error in quadrature?  only do this after the fit has
     571    // converged (or you will never improve the poor images)
     572
     573    // dX,dY are the X and Y direction errors in arcseconds.  dR, dD are the errors in
     574    // those directions in degrees.  IF we have non-circular errors (different values for
     575    // X and Y), then dR and dD will be incorrect: they would need to be rotated to take
     576    // out the position angle
     577
     578    // dX, dY : error in arcsec:
     579    points[Npoints].dX = GetAstromErrorTiny (&measure[k], ERROR_MODE_RA);
     580    points[Npoints].dY = GetAstromErrorTiny (&measure[k], ERROR_MODE_DEC);
    612581
    613582    // allow a given photcode or measurement to be
    614583    // ignored if the error is NAN (for photcode, set astromErrSys to NaN)
    615     if (isnan(dX[N])) continue;
    616     if (isnan(dY[N])) continue;
    617 
    618     // XXX this is (slightly) inconsistent: dX,dY are the X and Y direction errors in
    619     // arcseconds.  dR, dD are the errors in those directions in degrees.  IF we have
    620     // non-circular errors (different values for X and Y), then dR and dD will be
    621     // incorrect: they would need to be rotated to take out the position angle
    622     dR[N] = dX[N] / 3600.0;
    623     dD[N] = dY[N] / 3600.0;
    624 
    625     // XXX use a different flag for stack measurements?
    626     // measure[k].dbFlags |= ID_MEAS_USED_OBJ;
    627     // if (measureBig) { measureBig[k].dbFlags |= ID_MEAS_USED_OBJ; }
    628 
    629     N++;
     584    if (isnan(points[Npoints].dX)) continue;
     585    if (isnan(points[Npoints].dY)) continue;
     586
     587    points[Npoints].dT = measure[k].dt;
     588
     589    points[Npoints].measure = k;
     590    Npoints++;
     591
     592    if ((measure[k].photcode >= 2011) && (measure[k].photcode <= 2013)) {
     593      has2MASS = TRUE;
     594    }
     595
     596    myAssert (Npoints <= fit->NpointsAlloc, "oops");
    630597  } // loop over measurements : average[0].Nmeasure
    631598
    632   // if we have too few good detections for the desired fit, or too limited a
    633   // baseline, use a fit with fewer parameters.  XXX if we have too few measurements
    634   // for even the average position, consider including the lower-quality detections?
    635 
    636   // too few measurements for average position (require 2 values)
    637   if (N < 1) return FALSE; // XXX ??
    638 
    639   // find the mean position
    640   StatType statsR, statsD;
    641   liststats_pos (R, dR, N, &statsR, XVERB); // WARNING: this function modifies R (do not use after here)
    642   liststats_pos (D, dD, N, &statsD, XVERB); // WARNING: this function modifies D (do not use after here)
    643 
    644   fitAve.Ro = statsR.mean;
    645   fitAve.dRo = 3600.0*statsR.sigma;
    646 
    647   fitAve.Do = statsD.mean;
    648   fitAve.dDo = 3600.0*statsD.sigma;
    649 
    650   fitAve.chisq = 0.5 * (statsR.chisq + statsD.chisq);
    651   fitAve.Nfit = N;
    652 
    653   // XXX choose stack flag? average[0].flags |= ID_STAR_FIT_AVE;
    654   fitStats->Nave ++;
    655 
    656   if (XVERB) fprintf (stderr, "%f %f -> %f %f (%f,%f)\n",
    657                       average[0].R,
    658                       average[0].D,
    659                       fitAve.Ro, fitAve.Do,
    660                       3600*(average[0].R - fitAve.Ro),
    661                       3600*(average[0].D - fitAve.Do));
    662 
    663   // make sure that the fit succeeded
    664   int status = TRUE;
    665   status &= finite(fitAve.Ro);
    666   status &= finite(fitAve.Do);
    667   status &= finite(fitAve.dRo);
    668   status &= finite(fitAve.dDo);
    669   if (!status) {
    670     fitStats->Nskip ++;
    671     return FALSE;
    672   }
    673 
    674   // what is the offset relative to the mean fit position?
    675   coords.crval1 = average[0].R;
    676   coords.crval2 = average[0].D;
    677 
    678   double dXoff, dYoff;
    679   RD_to_XY (&dXoff, &dYoff, fitAve.Ro, fitAve.Do, &coords);
    680   float dPos = hypot (dXoff, dYoff);
    681   if (dPos > MaxMeanOffset) {
    682     if (fitStats->Noffset < 100) {
    683       fprintf (stderr, "(%f,%f) -> (%f,%f) (%f,%f)\n", coords.crval1, coords.crval2, fitAve.Ro, fitAve.Do, dXoff, dYoff);
    684     }
    685     fitStats->Noffset ++;
    686     return FALSE;
    687   }
    688 
    689   // set the stack position values
    690   average[0].Rstk  = fitAve.Ro; // RA in degrees
    691   average[0].Dstk  = fitAve.Do; // DEC in degrees
    692   average[0].dRstk = fitAve.dRo; // RA scatter in arcsec
    693   average[0].dDstk = fitAve.dDo; // DEC scatter in arcsec
    694 
     599  int TESTPT = FALSE;
     600  TESTPT |= CAT_ID_SRC && OBJ_ID_SRC && (average[0].catID == CAT_ID_SRC) && (average[0].objID == OBJ_ID_SRC);
     601  TESTPT |= CAT_ID_DST && OBJ_ID_DST && (average[0].catID == CAT_ID_DST) && (average[0].objID == OBJ_ID_DST);
     602  if (TESTPT) {
     603    fprintf (stderr, "got test det\n");
     604  }
     605 
     606  // XXX flag measurements from stars with 2MASS
     607  for (k = 0; k < average[0].Nmeasure; k++) {
     608    // reset the bit to note that a detection was used (or not)
     609    if (has2MASS) {
     610      measure[k].dbFlags |=  ID_MEAS_OBJECT_HAS_2MASS;
     611    } else {
     612      measure[k].dbFlags &= ~ID_MEAS_OBJECT_HAS_2MASS;
     613    }
     614  }
     615
     616  fit->Npoints = Npoints;
     617  return TRUE;
     618}
     619
     620int FitAstromPoints_Project (FitStats *fitStats, double *Tmean, double *Trange, double *parRange) {
     621
     622  int k;
     623
     624  int Npoints = fitStats->Npoints;
     625  FitAstromPoint *points = fitStats->points;
     626
     627  // find Tmin & Tmax from the list of accepted measurements
     628  double Tmin  = points[0].T;
     629  double Tmax  = points[0].T;
     630  double pRmin = +2.0;
     631  double pRmax = -2.0;
     632  double pDmin = +2.0;
     633  double pDmax = -2.0;
     634
     635  *Tmean = 0.0;
     636
     637  double Tsum = 0.0;
     638  double Wsum = 0.0;
     639  for (k = 0; k < Npoints; k++) {
     640    Tmin = MIN(Tmin, points[k].T);
     641    Tmax = MAX(Tmax, points[k].T);
     642
     643    float wx = 1.0 / SQ(points[k].dX);
     644
     645    Tsum += points[k].T * wx;
     646    Wsum += wx;
     647
     648    // at this point, T is in years since J2000
     649    ParFactor (&points[k].pR, &points[k].pD, points[k].R, points[k].D, points[k].T);
     650    pRmin = MIN (pRmin, points[k].pR);
     651    pRmax = MAX (pRmax, points[k].pR);
     652    pDmin = MIN (pDmin, points[k].pD);
     653    pDmax = MAX (pDmax, points[k].pD);
     654  }
     655  *Trange = Tmax - Tmin;
     656
     657  // mean epoch
     658  *Tmean = Tsum / Wsum;
     659
     660  // for HIGH_SPEED, just use the center of the range
     661  if (RELASTRO_OP == OP_HIGH_SPEED) {
     662    *Tmean = 0.5*(Tmax - Tmin);
     663  }
     664
     665  *parRange = hypot (pRmax - pRmin, pDmax - pDmin);
     666
     667  /* we need to do the fit in a locally linear space; choose a ref coordinate */
     668  fitStats->coords.crval1 = points[0].R;
     669  fitStats->coords.crval2 = points[0].D;
     670
     671  // project all of the R,D coordinates to a plane centered on this coordinate. set
     672  // the times to be relative to Tmean
     673  for (k = 0; k < Npoints; k++) {
     674    RD_to_XY (&points[k].X, &points[k].Y, points[k].R, points[k].D, &fitStats->coords);
     675    points[k].T -= *Tmean;
     676  }       
     677  return TRUE;
     678}
     679
     680int CatalogMaxNmeasure (Catalog *catalog, int Ncatalog) {
     681
     682  int i, j;
     683
     684  int Nmax = 0;
     685  for (i = 0; i < Ncatalog; i++) {
     686    for (j = 0; j < catalog[i].Naverage; j++) {
     687      Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure);
     688    }
     689  }
     690  return Nmax;
     691}
     692
     693int BootstrapResample (FitAstromPoint *sample, FitAstromPoint *points, int Npoints) {
     694  int i;
     695
     696  // I need to draw Npoints random entries from 'points' with replacement:
     697  for (i = 0; i < Npoints; i++) {
     698    int N = Npoints * drand48();
     699    sample[i] = points[N];
     700  }
     701  return TRUE;
     702}
     703
     704// calculate mean and sigma points for the 5 fit parameter
     705int BootstrapRobustStats (FitAstromResult *result, FitAstromResult *fit, int Nfit, int mode) {
     706
     707  // generate a histogram for the selected element
     708  double *values = NULL;
     709  ALLOCATE (values, double, Nfit);
     710 
     711  int i;
     712
     713  for (i = 0; i < Nfit; i++) {
     714    switch (mode) {
     715      case FIT_RESULT_RA:
     716        values[i] = fit[i].Ro;
     717        break;
     718      case FIT_RESULT_DEC:
     719        values[i] = fit[i].Do;
     720        break;
     721      case FIT_RESULT_uR:
     722        values[i] = fit[i].uR;
     723        break;
     724      case FIT_RESULT_uD:
     725        values[i] = fit[i].uD;
     726        break;
     727      case FIT_RESULT_PLX:
     728        values[i] = fit[i].p;
     729        break;
     730      default:
     731        myAbort ("invalid option");
     732    }
     733  }
     734
     735  dsort (values, Nfit);
     736
     737  double median;
     738  if (Nfit % 2) {
     739    int Ncenter = Nfit / 2;
     740    median = values[Ncenter];
     741  } else {
     742    int Ncenter = Nfit / 2 - 1;
     743    median = 0.5*(values[Ncenter] + values[Ncenter + 1]);
     744  }
     745
     746  double Slo = VectorFractionInterpolate (values, 0.158655, Nfit);
     747  double Shi = VectorFractionInterpolate (values, 0.841345, Nfit);
     748  double sigma = (Shi - Slo) / 2.0;
     749
     750  switch (mode) {
     751    case FIT_RESULT_RA:
     752      result->Ro = median;
     753      result->dRo = sigma;
     754      break;
     755    case FIT_RESULT_DEC:
     756      result->Do = median;
     757      result->dDo = sigma;
     758      break;
     759    case FIT_RESULT_uR:
     760      result->uR = median;
     761      result->duR = sigma;
     762      break;
     763    case FIT_RESULT_uD:
     764      result->uD = median;
     765      result->duD = sigma;
     766      break;
     767    case FIT_RESULT_PLX:
     768      result->p = median;
     769      result->dp = sigma;
     770      break;
     771    default:
     772      myAbort ("invalid option");
     773  }
     774
     775  return TRUE;
     776}
     777
     778double VectorFractionInterpolate (double *values, float fraction, int Npts) {
     779
     780  float F = fraction * Npts;
     781  int   N = fraction * Npts;
     782
     783  if (N < 0        ) return NAN;
     784  if (N >= Npts - 2) return NAN;
     785
     786  // interpolate between N,N+1
     787   
     788  double S = (F - N) * (values[N+1] - values[N]) + values[N];
     789  return S;
     790}
     791
     792int FitAstromSetChisq (FitAstromResult *fit, FitAstromPoint *points, int Npoints, FitMode mode) {
     793
     794  int i;
     795
     796  // add up the chi square for the fit
     797  double chisq = 0.0;
     798  for (i = 0; i < Npoints; i++) {
     799    double Xf = fit->Ro + fit->uR*points[i].T + fit->p*points[i].pR;
     800    double Yf = fit->Do + fit->uD*points[i].T + fit->p*points[i].pD;
     801    chisq += SQ(points[i].X - Xf) / SQ(points[i].dX);
     802    chisq += SQ(points[i].Y - Yf) / SQ(points[i].dY);
     803  }
     804  switch (mode) {
     805    case FIT_AVERAGE:
     806      fit->chisq = chisq / (2.0*Npoints - 2.0);
     807      break;
     808    case FIT_PM_ONLY:
     809      fit->chisq = chisq / (2.0*Npoints - 4.0);
     810      break;
     811    case FIT_PM_AND_PAR:
     812      fit->chisq = chisq / (2.0*Npoints - 5.0);
     813      break;
     814    default:
     815      myAbort ("invalid mode");
     816  }
     817  fit->Nfit = Npoints;
    695818  return (TRUE);
    696819}
    697820
    698 
    699 
    700 /* fitting proper-motion and parallax:
    701 
    702    given a source at position r,d, at a time t, we need to calculate a vector (pr,pd)
    703 
    704    let x,y be the coordinate in the linearized frame with y parallel to DEC lines
    705 
    706    L,B are the ecliptic longitude and latitude of the object,
    707    dL and dB are the offsets in the L and B directions
    708 
    709    dL = sin(t - topp)
    710    dB = cos(t - topp)*sin(B)
    711 
    712    these need to be rotated to the R,D frame to yield pR,pD.  Then, the equation of motion
    713    for the source in the x,y frame is:
    714 
    715    x = Ro + uR * (t - to) + p * pR
    716    y = Do + uD * (t - to) + p * pD
    717 
    718    the unknowns in these equations are Ro, uR, Do, uD, and p
    719 
    720    XXX think through the concepts for the pole a bit better.  all objects near the pole
    721    move the same way with the same phase.  choose a projection center and define dL,dB relative
    722    to that center point coordinate system?
    723 
    724 */
     821int FitAstromResultSetPM (FitAstromResult *fit, int Nfit, Average *average) {
     822
     823  int i;
     824
     825  if (USE_GALAXY_MODEL) {
     826    for (i = 0; i < Nfit; i++) {
     827      fit->uR = average->uRgal;
     828      fit->uD = average->uDgal;
     829    }
     830  } else {
     831    for (i = 0; i < Nfit; i++) {
     832      fit->uR = 0.0;
     833      fit->uD = 0.0;
     834    }
     835  }
     836
     837  return TRUE;
     838}
  • trunk/Ohana/src/relastro/src/args.c

    r38441 r38986  
    253253  }
    254254
     255  // If we are looking at the whole sky (or whole relevant sky), use the full image table
     256  // -- this save substantial memory.  this could be automatic if the skyregion covers
     257  // more than 2pi.
     258  USE_ALL_IMAGES = FALSE;
     259  if ((N = get_argument (argc, argv, "-use-all-images"))) {
     260    remove_argument (N, &argc, argv);
     261    USE_ALL_IMAGES = TRUE;
     262  }
     263
    255264  USE_BASIC_CHECK = FALSE;
    256265  if ((N = get_argument (argc, argv, "-basic-image-search"))) {
     
    271280    remove_argument (N, &argc, argv);
    272281    APPLY_OFFSETS = TRUE;
     282  }
     283
     284  N_BOOTSTRAP_SAMPLES = 1;
     285  if ((N = get_argument (argc, argv, "-bootstrap-samples"))) {
     286    remove_argument (N, &argc, argv);
     287    N_BOOTSTRAP_SAMPLES = atoi (argv[N]);
     288    remove_argument (N, &argc, argv);
     289    if ((N_BOOTSTRAP_SAMPLES < 1) || ((N_BOOTSTRAP_SAMPLES > 1) && (N_BOOTSTRAP_SAMPLES < 20))) {
     290      fprintf (stderr, "-bootstrap-samples must be either 1 (no sampling) or >= 20\n");
     291      exit (2);
     292    }
    273293  }
    274294
     
    685705  }
    686706
     707  // If we are looking at the whole sky (or whole relevant sky), use the full image table
     708  // -- this save substantial memory.  this could be automatic if the skyregion covers
     709  // more than 2pi.
     710  USE_ALL_IMAGES = FALSE;
     711  if ((N = get_argument (argc, argv, "-use-all-images"))) {
     712    remove_argument (N, &argc, argv);
     713    USE_ALL_IMAGES = TRUE;
     714  }
     715
    687716  USE_BASIC_CHECK = FALSE;
    688717  if ((N = get_argument (argc, argv, "-basic-image-search"))) {
     
    697726    remove_argument (N, &argc, argv);
    698727    MaxDensityUse = TRUE;
     728  }
     729
     730  N_BOOTSTRAP_SAMPLES = 1;
     731  if ((N = get_argument (argc, argv, "-bootstrap-samples"))) {
     732    remove_argument (N, &argc, argv);
     733    N_BOOTSTRAP_SAMPLES = atoi (argv[N]);
     734    remove_argument (N, &argc, argv);
     735    if ((N_BOOTSTRAP_SAMPLES < 1) || ((N_BOOTSTRAP_SAMPLES > 1) && (N_BOOTSTRAP_SAMPLES < 20))) {
     736      fprintf (stderr, "-bootstrap-samples must be either 1 (no sampling) or >= 20\n");
     737      exit (2);
     738    }
    699739  }
    700740
  • trunk/Ohana/src/relastro/src/assign_images.c

    r38441 r38986  
    2626  char mapfile[DVO_MAX_PATH];
    2727  snprintf (mapfile, DVO_MAX_PATH, "%s/AstroMap.fits", CATDIR);
    28   AstromOffsetTable *table = AstromOffsetMapLoad (mapfile, VERBOSE);
     28  AstromOffsetTable *table = AstromOffsetMapLoad (mapfile, 100000, VERBOSE);
    2929
    3030  // assign images.coords.offsetMap -> table->map[i]
  • trunk/Ohana/src/relastro/src/bcatalog.c

    r38441 r38986  
    112112
    113113    // if we want to correct to the galay model, we need to use objects with distances determined by Green & Schlafly
    114     if (USE_GALAXY_MODEL && !catalog[0].average[i].Nstarpar) {
    115       // we may want to add some starpar quality filters...
    116       continue;
     114    if (USE_GALAXY_MODEL) {
     115      // if we use the galaxy model, we need to require the model pm to exist
     116      if (!catalog[0].average[i].Nstarpar) continue;
     117      if (!isfinite(catalog[0].average[i].uRgal)) continue;
     118      if (!isfinite(catalog[0].average[i].uDgal)) continue;
     119    }
     120
     121    int TESTPT = FALSE;
     122    TESTPT |= CAT_ID_SRC && OBJ_ID_SRC && (catalog[0].average[i].catID == CAT_ID_SRC) && (catalog[0].average[i].objID == OBJ_ID_SRC);
     123    TESTPT |= CAT_ID_DST && OBJ_ID_DST && (catalog[0].average[i].catID == CAT_ID_DST) && (catalog[0].average[i].objID == OBJ_ID_DST);
     124    if (TESTPT) {
     125      fprintf (stderr, "got test det\n");
    117126    }
    118127
  • trunk/Ohana/src/relastro/src/high_speed_catalogs.c

    r38471 r38986  
    153153              PHOTCODE_A_LIST, PHOTCODE_B_LIST, RADIUS, outputDir, table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
    154154
     155    strextend (&command, "relastro_client -high-speed %s %s %f %s", PHOTCODE_A_LIST, PHOTCODE_B_LIST, RADIUS, outputDir);
     156    strextend (&command, "-hostID %d", table->hosts[i].hostID);
     157    strextend (&command, "-D CATDIR %s", CATDIR);
     158    strextend (&command, "-hostdir %s", table->hosts[i].pathname);
     159    strextend (&command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     160
    155161    free (outputDir);
    156162
     
    166172    if (MaxDensityUse) { strextend (&command, "-max-density %f", MaxDensityValue); }
    167173   
     174    if (USE_ALL_IMAGES)      { strextend (&command, "-use-all-images"); }
    168175    if (USE_BASIC_CHECK)     { strextend (&command, "-basic-image-search"); }
    169176    if (FlagOutlier)         { strextend (&command, "-clip %d", CLIP_THRESH); }
     
    176183    // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
    177184
    178     if (MinBadQF > 0.0)        { strextend (&command, "-min-bad-psfqf %f", MinBadQF); }
    179     if (MaxMeanOffset != 10.0) { strextend (&command, "-max-mean-offset  %f", MaxMeanOffset); }
     185    if (MinBadQF > 0.0)          strextend (&command, "-min-bad-psfqf %f", MinBadQF);
     186    if (MaxMeanOffset != 10.0)   strextend (&command, "-max-mean-offset  %f", MaxMeanOffset);
     187    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES);
    180188
    181189    if (WHERE_A[0]) { strextend (&command, "-D WHERE_A \"%s\"", WHERE_A); }
  • trunk/Ohana/src/relastro/src/high_speed_objects.c

    r38441 r38986  
    270270
    271271  fprintf (stderr, "found %d matches\n", Nmatch);
    272   dvo_catalog_save (&catalogOut, VERBOSE2);
    273   dvo_catalog_unlock (&catalogOut);
     272
     273  SetProtect (TRUE);
     274  if (!dvo_catalog_save (&catalogOut, VERBOSE2)) { fprintf (stderr, "ERROR: failed to save %s\n", catalogOut.filename); exit (1); }
     275  if (!dvo_catalog_unlock (&catalogOut)) { fprintf (stderr, "ERROR: failed to unlock %s\n", catalogOut.filename); exit (1); }
     276  SetProtect (FALSE);
     277
    274278  dvo_catalog_free (&catalogOut);
    275279  free (slowMoving);
  • trunk/Ohana/src/relastro/src/hpm_catalogs.c

    r38471 r38986  
    148148
    149149    char *command = NULL;
    150     strextend (&command, "relastro_client -hpm %f %s -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f",
    151               RADIUS, outputDir, table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     150    strextend (&command, "relastro_client -hpm %f %s", RADIUS, outputDir);
     151    strextend (&command, " -hostID %d", table->hosts[i].hostID);
     152    strextend (&command, " -D CATDIR %s", CATDIR);
     153    strextend (&command, " -hostdir %s", table->hosts[i].pathname);
     154    strextend (&command, " -region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
    152155
    153156    free (outputDir);
     
    164167    if (MaxDensityUse) { strextend (&command, "-max-density %f", MaxDensityValue); }
    165168   
     169    if (USE_ALL_IMAGES)      { strextend (&command, "-use-all-images"); }
    166170    if (USE_BASIC_CHECK)     { strextend (&command, "-basic-image-search"); }
    167171    if (FlagOutlier)         { strextend (&command, "-clip %d", CLIP_THRESH); }
     
    174178    // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
    175179
    176     if (MinBadQF > 0.0)        { strextend (&command, "-min-bad-psfqf %f", MinBadQF); }
    177     if (MaxMeanOffset != 10.0) { strextend (&command, "-max-mean-offset  %f", MaxMeanOffset); }
     180    if (MinBadQF > 0.0)          strextend (&command, "-min-bad-psfqf %f", MinBadQF);
     181    if (MaxMeanOffset != 10.0)   strextend (&command, "-max-mean-offset  %f", MaxMeanOffset);
     182    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES);
    178183
    179184    if (TimeSelect) {
  • trunk/Ohana/src/relastro/src/hpm_objects.c

    r38441 r38986  
    110110  if (catalog[0].Naverage == Nslow) {
    111111    fprintf (stderr, "no possible fast objects, skipping this catalog\n");
    112     dvo_catalog_save (&catalogOut, VERBOSE2);
    113     dvo_catalog_unlock (&catalogOut);
     112
     113    SetProtect (TRUE);
     114    if (!dvo_catalog_save (&catalogOut, VERBOSE2)) { fprintf (stderr, "ERROR: failed to save %s\n", catalogOut.filename); exit (1); }
     115    if (!dvo_catalog_unlock (&catalogOut)) { fprintf (stderr, "ERROR: failed to unlock %s\n", catalogOut.filename); exit (1); }
     116    SetProtect (FALSE);
     117
    114118    dvo_catalog_free (&catalogOut);
    115119    free (slowMoving);
  • trunk/Ohana/src/relastro/src/launch_region_hosts.c

    r38441 r38986  
    66  int i;
    77
    8   // do not remote the sync and fits files if we do a manual run -- user must clear if needed
     8  // do not remove the sync and fits files if we do a manual run -- user must clear if needed
    99  if (!PARALLEL_REGIONS_MANUAL) {
    1010    // clear the I/O files
  • trunk/Ohana/src/relastro/src/load_catalogs.c

    r38471 r38986  
    163163
    164164    char *command = NULL;
    165     strextend (&command, "relastro_client -load-objects %s -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f -statmode %s -minerror %f -D RELASTRO_SIGMA_LIM %f",
    166               table->hosts[i].results, table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, STATMODE, MIN_ERROR, SIGMA_LIM);
     165    strextend (&command, "relastro_client -load-objects %s", table->hosts[i].results);
     166    strextend (&command, " -hostID %d", table->hosts[i].hostID);
     167    strextend (&command, " -D CATDIR %s", CATDIR);
     168    strextend (&command, " -hostdir %s", table->hosts[i].pathname);
     169    strextend (&command, " -region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     170    strextend (&command, " -statmode %s", STATMODE);
     171    strextend (&command, " -minerror %f", MIN_ERROR);
     172    strextend (&command, " -D RELASTRO_SIGMA_LIM %f", SIGMA_LIM);
    167173
    168174    if (FIT_MODE == FIT_PM_ONLY)         strextend (&command, "-pm");
     
    188194    }
    189195
     196    if (USE_ALL_IMAGES)      strextend (&command, "-use-all-images");
    190197    if (USE_FIXED_PIXCOORDS) strextend (&command, "-D USE_FIXED_PIXCOORDS 1");
    191198    if (PHOTCODE_KEEP_LIST)  strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST);
  • trunk/Ohana/src/relastro/src/load_images.c

    r38441 r38986  
    77 */
    88
    9 int load_images (FITS_DB *db, SkyList *skylist, int UseFullOverlap) {
     9int load_images (FITS_DB *db, SkyList *skylist, int UseFullOverlap, int UseAllImages) {
    1010
    1111  Image     *image, *subset;
    1212  off_t      Nimage, Nsubset;
    13   off_t     *LineNumber;
     13  off_t     *LineNumber, i;
    1414
    1515  INITTIME;
     
    2929  char mapfile[DVO_MAX_PATH];
    3030  snprintf (mapfile, DVO_MAX_PATH, "%s/AstroMap.fits", CATDIR);
    31   table = AstromOffsetMapLoad (mapfile, VERBOSE);
     31  table = AstromOffsetMapLoad (mapfile, 100000, VERBOSE);
    3232
    3333  // assign images.coords.offsetMap -> table->map[i]
     
    3939
    4040  // select the images which overlap the selected sky regions
    41   subset = select_images (skylist, image, Nimage, &LineNumber, &Nsubset, UseFullOverlap);
    42   MARKTIME("  select images: %f sec\n", dtime);
     41  if (UseAllImages) {
     42    ALLOCATE (LineNumber, off_t, Nimage);
     43    for (i = 0; i < Nimage; i++) LineNumber[i] = i;
     44    subset  = image;
     45    Nsubset = Nimage;
     46  } else {
     47    subset = select_images (skylist, image, Nimage, &LineNumber, &Nsubset, UseFullOverlap);
     48    MARKTIME("  select images: %f sec\n", dtime);
    4349
    44   if (Nsubset == Nimage) {
    45     free (subset);
    46     subset = image;
     50    if (Nsubset == Nimage) {
     51      free (subset);
     52      subset = image;
     53    }
    4754  }
    48 
     55   
    4956  initImages (subset, LineNumber, Nsubset);
    5057  MARKTIME("  init images: %f sec\n", dtime);
    51 
     58 
    5259  initMosaics (subset, Nsubset);
    5360  MARKTIME("  init mosaics: %f sec\n", dtime);
  • trunk/Ohana/src/relastro/src/relastro.c

    r36630 r38986  
    44
    55  /* get configuration info, args */
     6  SetSignals ();
    67  initialize (argc, argv);
    78
  • trunk/Ohana/src/relastro/src/relastro_client.c

    r38441 r38986  
    2222
    2323  // get configuration info, args, lockfile (set CATDIR, HOST_ID, HOSTDIR, etc)
     24  SetSignals ();
    2425  initialize_client (argc, argv);
    2526
     
    7879
    7980      /* load regions and images based on specified sky patch (default depth) */
    80       load_images (&db, skylist, FALSE);
     81      load_images (&db, skylist, FALSE, USE_ALL_IMAGES);
    8182     
    8283      // I can free the database after I have loaded the images...
  • trunk/Ohana/src/relastro/src/relastro_images.c

    r38441 r38986  
    2121
    2222  /* load regions and images based on specified sky patch (default depth) (require full overlap) */
    23   load_images (&db, skylist, TRUE);
     23  load_images (&db, skylist, TRUE, USE_ALL_IMAGES);
    2424  MARKTIME("load images: %f sec\n", dtime);
    2525
     
    7373      if (RESET_IMAGES) UpdateMeasures (catalog, Ncatalog);
    7474      for (i = 0; i < NLOOP; i++) {
    75         UpdateObjects (catalog, Ncatalog, (i > 0)); // calculate <R>,<D>; if (i > 0), apply Galaxy Motion Model (if desired)
    76         if ((i > 1) || !USE_GALAXY_MODEL) {
    77           // if GALAXY_MODEL is selected, we want to delay the frame correction until we have
    78           // applied the galaxy model a couple of times.
    79           FrameCorrectionSerial (catalog, Ncatalog);
    80         }
    81         UpdateChips (catalog, Ncatalog);   // measure.X,Y -> R,D, fit image.coords
     75        UpdateObjects (catalog, Ncatalog, i); // calculate <R>,<D>; if (i > 0), apply Galaxy Motion Model (if desired)
     76        UpdateChips (catalog, Ncatalog, i);   // measure.X,Y -> R,D, fit image.coords
    8277        MARKTIME("update chips: %f sec\n", dtime);
    8378      }
     
    10398  freeImageBins (1);
    10499
    105   // XXX why do I do this exactly?
    106   reload_images (&db);
     100  // If we did NOT use all images, then we applied the measured corrections to a subset of
     101  // images.  we now need to set the images associated with db to have those values so
     102  // they will be written out by the dvo_image_update() operations.  If we USE_ALL_IMAGES,
     103  // then we do not need to do this, and we should call dvo_image_save (not dvo_image_update)
     104  if (!USE_ALL_IMAGES) {
     105    reload_images (&db);
     106  }
    107107   
    108108  if (PARALLEL) {
     
    110110    // need to also save the image map table...
    111111    save_astrom_table ();
    112     dvo_image_update (&db, VERBOSE);
     112    if (USE_ALL_IMAGES) {
     113      dvo_image_save (&db, VERBOSE);
     114    } else {
     115      dvo_image_update (&db, VERBOSE);
     116    }
    113117    dvo_image_unlock (&db);
    114118  }
    115119
     120  // NOTE: if we have parallel partitions, then we need to save the Images.dat and
     121  // AstroMap.fits tables BEFORE the remote relastro_clients are launched (they load
     122  // Images.dat and AstroMap.fits)
     123
     124  // if we do NOT have parallel partitions, we must NOT write them out yet: the act of
     125  // writing out the files byte-swaps the data and makes the values invalide for the
     126  // following calls to UpdateObjectOffsets (which attempt to apply the image values from
     127  // the structure in memory)
     128
    116129  // iterate over catalogs to make detection coordinates consistant
    117   UpdateObjectOffsets (skylist, 0, NULL);
     130  if (APPLY_OFFSETS) {
     131    UpdateObjectOffsets (skylist, 0, NULL);
     132  }
    118133
    119134  if (!PARALLEL) {
    120135    // save the updated image parameters
    121136    save_astrom_table ();
    122     dvo_image_update (&db, VERBOSE);
     137    if (USE_ALL_IMAGES) {
     138      dvo_image_save (&db, VERBOSE);
     139    } else {
     140      dvo_image_update (&db, VERBOSE);
     141    }
    123142    dvo_image_unlock (&db);
    124143  }
  • trunk/Ohana/src/relastro/src/relastro_merge_source.c

    r38441 r38986  
    122122    resort_catalog (&catalog_src);
    123123
    124     dvo_catalog_save (&catalog_src, VERBOSE2);
    125     dvo_catalog_unlock (&catalog_src);
     124    SetProtect (TRUE);
     125    if (!dvo_catalog_save (&catalog_src, VERBOSE2)) { fprintf (stderr, "ERROR: failed to save %s\n", catalog_src.filename); exit (1); }
     126    if (!dvo_catalog_unlock (&catalog_src)) { fprintf (stderr, "ERROR: failed to unlock %s\n", catalog_src.filename); exit (1); }
     127    SetProtect (FALSE);
    126128    dvo_catalog_free (&catalog_src);
    127129
  • trunk/Ohana/src/relastro/src/relastro_objects.c

    r38471 r38986  
    150150
    151151    char *command = NULL;
    152     strextend (&command, "relastro_client -update-objects -hostID %d -D CATDIR %s -hostdir %s -region %f %f %f %f -statmode %s",
    153               table->hosts[i].hostID, CATDIR, table->hosts[i].pathname, UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax, STATMODE);
     152    strextend (&command, "relastro_client -update-objects");
     153    strextend (&command, "-hostID %d", table->hosts[i].hostID);
     154    strextend (&command, "-D CATDIR %s", CATDIR);
     155    strextend (&command, "-hostdir %s", table->hosts[i].pathname);
     156    strextend (&command, "-region %f %f %f %f", UserPatch.Rmin, UserPatch.Rmax, UserPatch.Dmin, UserPatch.Dmax);
     157    strextend (&command, "-statmode %s", STATMODE);
    154158
    155159    if (FIT_MODE == FIT_PM_ONLY)         { strextend (&command, "-pm"); }
     
    164168    if (MaxDensityUse) { strextend (&command, "-max-density %f", MaxDensityValue); }
    165169    if (FlagOutlier)   { strextend (&command, "-clip %d", CLIP_THRESH); }
     170
     171    if (USE_ALL_IMAGES)      { strextend (&command, "-use-all-images"); }
    166172    if (USE_FIXED_PIXCOORDS) { strextend (&command, "-D USE_FIXED_PIXCOORDS 1"); }
    167173    if (PHOTCODE_KEEP_LIST)  { strextend (&command, "+photcode %s", PHOTCODE_KEEP_LIST); }
     
    172178    // XXX note that the above pass in the flag as decimal -- also note that args.c cannot handle 0xHEX values
    173179
    174     if (MinBadQF > 0.0)        { strextend (&command, "-min-bad-psfqf %f", MinBadQF); }
    175     if (MaxMeanOffset != 10.0) { strextend (&command, "-max-mean-offset  %f", MaxMeanOffset); }
     180    if (MinBadQF > 0.0)          strextend (&command, "-min-bad-psfqf %f", MinBadQF);
     181    if (MaxMeanOffset != 10.0)   strextend (&command, "-max-mean-offset  %f", MaxMeanOffset);
     182    if (N_BOOTSTRAP_SAMPLES > 1) strextend (&command, "-bootstrap-samples %d", N_BOOTSTRAP_SAMPLES);
    176183
    177184    if (TimeSelect) {
  • trunk/Ohana/src/relastro/src/relastro_parallel_images.c

    r38062 r38986  
    4040  char mapfile[DVO_MAX_PATH];
    4141  snprintf (mapfile, DVO_MAX_PATH, "%s/AstroMap.%d.fits", CATDIR, REGION_HOST_ID);
    42   AstromOffsetTable *table = AstromOffsetMapLoad (mapfile, VERBOSE);
     42  AstromOffsetTable *table = AstromOffsetMapLoad (mapfile, 100000, VERBOSE);
    4343
    4444  // assign images.coords.offsetMap -> table->map[i]
     
    120120      }
    121121      for (i = 0; i < NLOOP; i++) {
    122         UpdateObjects (catalog, Ncatalog, (i > 0));
     122        UpdateObjects (catalog, Ncatalog, i);
    123123        LOGRTIME("UpdateObjects loop %d on %s, host %d: %f sec\n", i, myHostName, REGION_HOST_ID, dtime);
    124         if ((i > 1) || !USE_GALAXY_MODEL) {
    125           // if GALAXY_MODEL is selected, we want to delay the frame correction until we have
    126           // applied the galaxy model a couple of times.
    127           FrameCorrectionParallelSlave (catalog, Ncatalog, regionHosts, i);
    128           LOGRTIME("FrameCorrection loop %d on %s, host %d: %f sec\n", i, myHostName, REGION_HOST_ID, dtime);
    129         }
     124
    130125        share_mean_pos (catalog, Ncatalog, regionHosts, i);
    131126        LOGRTIME("share_mean_pos loop %d on %s, host %d: %f sec\n", i, myHostName, REGION_HOST_ID, dtime);
     
    133128        LOGRTIME("slurp_mean_pos loop %d on %s, host %d: %f sec\n", i, myHostName, REGION_HOST_ID, dtime);
    134129
    135         UpdateChips (catalog, Ncatalog);
     130        UpdateChips (catalog, Ncatalog, i);
    136131        LOGRTIME("UpdateChips loop %d on %s, host %d: %f sec\n", i, myHostName, REGION_HOST_ID, dtime);
    137132
  • trunk/Ohana/src/relastro/src/save_catalogs.c

    r33652 r38986  
    99
    1010    if (VERBOSE2) fprintf (stderr, "saving catalog %s\n", catalog[i].filename);
    11     dvo_catalog_save (&catalog[i], VERBOSE2);
    12     dvo_catalog_unlock (&catalog[i]);
     11    SetProtect (TRUE);
     12    if (!dvo_catalog_save (&catalog[i], VERBOSE2)) { fprintf (stderr, "ERROR: failed to save %s\n", catalog[i].filename); exit (1); }
     13    if (!dvo_catalog_unlock (&catalog[i])) { fprintf (stderr, "ERROR: failed to unlock %s\n", catalog[i].filename); exit (1); }
     14    SetProtect (FALSE);
    1315    dvo_catalog_free (&catalog[i]);
    1416  }
  • trunk/Ohana/src/relastro/src/share_images_pos.c

    r38062 r38986  
    115115    snprintf (mapname, 1024, "%s/AstroMapUpdate.%d.fits", CATDIR, regionHosts->hosts[i].hostID);
    116116   
    117     AstromOffsetTable *table = AstromOffsetMapLoad (mapname, VERBOSE);
     117    AstromOffsetTable *table = AstromOffsetMapLoad (mapname, 100000, VERBOSE);
    118118    LOGRTIME("image_maps_load host %d loop %d on %s, host %d: %f sec\n", i, nloop, myHostName, REGION_HOST_ID, dtime);
    119119 
Note: See TracChangeset for help on using the changeset viewer.