# include "relastro.h"
# define WEIGHTED_ERRORS 1

float GetAstromErrorTiny (MeasureTiny *measure, int mode) {

  PhotCode *code;
  float dPobs, dPsys, dPtotal, dM, AS, MS, dX, dY;

  if (!WEIGHTED_ERRORS) {
    // if we don't understand the errors at all, this at least lets us get things roughly
    // right:
    return 0.1;
  }

  switch (mode) {
    case ERROR_MODE_RA:
      dPobs = FromShortPixels(measure[0].dXccd);  // dXccd is a value in pixels
      break;
    case ERROR_MODE_DEC:
      dPobs = FromShortPixels(measure[0].dYccd);  // dYccd is a value in pixels
      break;
    case ERROR_MODE_POS:
      dX = FromShortPixels(measure[0].dXccd);  // dXccd is a value in pixels
      dY = FromShortPixels(measure[0].dYccd);  // dYccd is a value in pixels
      dPobs = hypot (dX, dY);
      break;
    default:
      abort();
  }

  code 	= GetPhotcodebyCode (measure[0].photcode);

  // do not raise an exception, just send back the result
  if (isnan(code[0].astromErrSys)) return NAN;

  AS   	= code[0].astromErrScale;
  MS   	= code[0].astromErrMagScale;
  dPsys = code[0].astromErrSys;
  dM    = measure[0].dM;
  dPtotal = sqrt(SQ(dPsys) + SQ(AS*dPobs) + SQ(MS*dM));

  dPtotal = MAX (dPtotal, MIN_ERROR);
  return (dPtotal);
}

float GetAstromError (Measure *measure, int mode) {

  PhotCode *code;
  float dPobs, dPsys, dPtotal, dM, AS, MS, dX, dY;

  if (!WEIGHTED_ERRORS) {
    // if we don't understand the errors at all, this at least lets us get things roughly
    // right:
    return 0.1;
  }

  switch (mode) {
    case ERROR_MODE_RA:
      dPobs = FromShortPixels(measure[0].dXccd);  // dXccd is a value in pixels
      break;
    case ERROR_MODE_DEC:
      dPobs = FromShortPixels(measure[0].dYccd);  // dYccd is a value in pixels
      break;
    case ERROR_MODE_POS:
      dX = FromShortPixels(measure[0].dXccd);  // dXccd is a value in pixels
      dY = FromShortPixels(measure[0].dYccd);  // dYccd is a value in pixels
      dPobs = hypot (dX, dY);
      break;
    default:
      abort();
  }

  code 	= GetPhotcodebyCode (measure[0].photcode);

  // do not raise an exception, just send back the result
  if (isnan(code[0].astromErrSys)) return NAN;

  AS   	= code[0].astromErrScale;
  MS   	= code[0].astromErrMagScale;
  dPsys = code[0].astromErrSys;
  dM    = measure[0].dM;
  dPtotal = sqrt(SQ(dPsys) + SQ(AS*dPobs) + SQ(MS*dM));

  dPtotal = MAX (dPtotal, MIN_ERROR);
  return (dPtotal);
}

/* for a long time, psphot was either not reported position errors, or was reporting
 * completely wrong astrometry errors.  This function lets us handle, in the
 * configuration, different strategies to generating a position error 
 *
 * astrometry systematic error : this is the minimum expected per-position error.  You
 * should probably measure this from you data.  watch out for the chicken and egg problem!
 *
 * astrometry error scale : this field lets you accept position errors in (say) pixels and
 * convert them with this term to arcsec.  AS : pixel scale in arcsec
 *
 * astrometry mag scale : this field lets you define position errors based on the
 * photometry error.  the scale factor should be something like a typical seeing number
 * (in arcsec) for the given instrument
 *
 */
