""" Code to extract sources from a fits frame

Context : SRP
Module  : SRPAstrometry
Version : 1.1.2
Author  : Stefano Covino
Date    : 26/08/2011
E-mail  : stefano.covino@brera.inaf.it
URL:    : http://www.merate.mi.astro.it/utenti/covino
Purpose : 

Usage   : SRPAstrometry -i arg1 [-c arg2 arg3] [-h] [-N] -o arg4 [-O] [-p arg5 arg6] [-P arg7 arg8] [-r arg9] [-v] [-x arg10 arg11]
            -i Input FITS file.
            -o Output FITS file.
            -c Reference for equatorial coordinates.
            -p Reference for pixel coordinates.
            -P Pointing coordinates.
            -x Increment per pixel [e.g. -1.0 1.0] (arcsec/pix).
            -r Rotation angle (deg).
            -f Frame size (arcmin).
            -O Use USNO-A2 catalogue.
            -N Use 2MASS catalogue.
 

History : (27/09/2010) First version.
        : (03/10/2010) Number of stars for astrometry saved.
        :               RA and DEC shift reported.
        : (13/10/2010) More stars for astrometry.
        : (24/10/2010) USNO-A2 catalogue can also be used.
        : (07/08/2011) Better cosmetics.
        : (26/08/2011) More verbose output.
"""

from SRP.SRPMath.AstroAngleInput import AstroAngleInput
from SRP.SRPMath.AstroCoordInput import AstroCoordInput
from SRP.SRPFrames.AstrometryClass import Astrometry
from SRP.SRPFits.IsFits import IsFits

from optparse import OptionParser
import os


parser = OptionParser(usage="usage: %prog [-d] -i arg1 [-c arg2 arg3] [-h] [-N] -o arg4 [-O] [-p arg5 arg6] [-P arg7 arg8] [-r arg9] [-v] [-x arg10 arg11]", version="%prog 1.1.2")
parser.add_option("-d", "--debug", action="store_true", dest="debug", help="Show starting parameter values.")
parser.add_option("-i", "--inpfits", action="store", nargs=1, type="string", dest="ifits", help="Input FITS file.")
parser.add_option("-o", "--outfits", action="store", nargs=1, type="string", dest="ofits", help="Output FITS file.")
parser.add_option("-c", "--center", action="store", type="float", nargs=2, dest="center", help="Reference for equatorial coordinates.")
parser.add_option("-p", "--pixcenter", action="store", type="float", nargs=2, dest="pixcenter", help="Reference for pixel coordinates.")
parser.add_option("-P", "--point", action="store", type="float", nargs=2, dest="point", help="Pointing coordinates.")
parser.add_option("-x", "--pixincr", action="store", type="float", nargs=2, dest="pixincr", help="Increment per pixel [e.g. -1.0 1.0] (arcsec/pix).")
parser.add_option("-r", "--rot", action="store", type="float", nargs=1, dest="rot", help="Rotation angle (deg).")
parser.add_option("-f", "--framesize", action="store", type="float", nargs=1, dest="framesize", help="Frame size (arcmin).")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Fully describe operations.")
parser.add_option("-O", "--Optical", action="store_true", dest="Optical", help="Use USNO-A2 catalogue.")
parser.add_option("-N", "--NearInfrared", action="store_true", dest="NearInfrared", help="Use 2MASS catalogue.")
(options, args) = parser.parse_args()


if options.ifits and options.ofits:
    # input file
    ifits = options.ifits
    ofits = options.ofits
    if not IsFits(ifits):
        parser.error("Input FITS file %s does not exist." % ifits)
    if options.verbose:
        print "Input FITS file: %s" % options.ifits
    # equatorial center
    if options.center:
        icenter = AstroCoordInput(options.center[0],options.center[1])
        center = (icenter.RA,icenter.DEC)
        if options.verbose:
            print "Reference for equatorial system: "+str(icenter) 
    else:
        center = None
    # pixel center
    if options.pixcenter:
        pixcenter = options.pixcenter
        if options.verbose:
            print "Pixel reference position: %.2g, %.2g" % pixcenter
    else:
        pixcenter = None
    # pointing
    if options.point:
        ipoint = AstroCoordInput(options.point[0],options.point[1])
        point = (ipoint.RA,ipoint.DEC)
        if options.verbose:
            print "Pointing direction: "+str(ipoint)
    else:
        point = None
    # pixel increment
    if options.pixincr:
        pixincr = [i/3600.0 for i in options.pixincr]
        if options.verbose:
            print "Increment per pixel %.2g %.2g arcsec/pix" % options.pixincr
    else:
        pixincr = None
    # rotation
    if options.rot:
        rotangle = options.rot
        if otpions.verbose:
            print "Field rotation: %.2g" % rotangle
    else:
        rotangle = None
    # framesize
    if options.framesize:
        framesize = options.framesize/60.0
        if framesize <= 0:
            parser.error("Frame size must be positive.")
        if options.verbose:
            print "Frame size %.2g arcmin" % options.framesize
    else:
        framesize = None
    # catalogue
    if options.Optical:
        catquery = 'O'
    elif options.NearInfrared:
        catquery = 'N'
    else:
        catquery = 'N'
        if options.verbose:
            print "No catalogue selected or both optical/near-infrared selected. NearInfrared catalogue used."
    #    
    astr = Astrometry(ifits,center,pixcenter,point,pixincr,rotangle,framesize)
    if options.debug:
        print 
        print "Input WCS parameters"
        print "RA, DEC      : ", astr.RA,astr.DEC
        print "CRPIX1,2     : ", astr.CRPIX1, astr.CRPIX2
        print "CDELT1,2     : ", astr.CDELT1, astr.CDELT2
        print "PC11,12,21,22: ", astr.PC11, astr.PC12, astr.PC21, astr.PC22
        print "CRVAL1,2     : ", astr.CRVAL1, astr.CRVAL2
        print "CTYPE1,2     : ", astr.CTYPE1, astr.CTYPE2
    #
    if options.verbose:
        print "Frame source finding..."
    astr.GetEclipseSources(maxobjs=20)
    if options.verbose:
        print "%d sources selected." % len(astr.List)
    #
    if catquery == 'O':
        if options.verbose:
            print "USNO-A2 catalogue source finding..."
    else:
        if options.verbose:
            print "2MASS catalogue source finding..."
    astr.GetCatSources(maxentr=20,catq=catquery)
    if options.verbose:
        print "%d sources selected." % len(astr.CatList)
    #
    if options.verbose:
        print "Finding solution..."
    astr.FindSolution()
    #
    if astr.Astrometrized:
        if options.verbose:
            print "Astrometic solution found!"
            print "Average residual: %.2g arcsec for %d stars." % (astr.Residuals, astr.NStarRes) 
            print "RA and DEC shift wrt the pointing coordinates: %.1f %.1f arcsec" % (astr.RAshift, astr.DECshift)
        else:
            print "%d %.2g %d %.1f %.1f" % (1,astr.Residuals,astr.NStarRes,astr.RAshift,astr.DECshift)
    else:            
        if options.verbose:
            print "Astrometric solution not found."
            print "Average residual: %.2g arcsec for %d stars." % (astr.Residuals, astr.NStarRes) 
        else:
            print "%d %.2g %d" % (0, astr.Residuals, astr.NStarRes)
    #
    if options.verbose:
        print "Saving FITS file %s" % ofits
    astr.SaveFile(ofits)
    #
else:
    parser.print_help()