""" Code to extract objects from a local catalogue

Context : SRP
Module  : SRPQuery.py
Version : 2.9.0
Author  : Stefano Covino
Date    : 19/08/2013
E-mail  : stefano.covino@brera.inaf.astro.it
URL:    : http://www.merate.mi.astro.it/utenti/covino
Purpose : Manage the extraction of objects from a local catalogue

Usage   : SRPQuery -c arg1 arg2 / -f arg3 -C arg4 [-h] [-m arg5] [-o arg6] -r arg7 [-S] [-v]
            -c is to input J200 RA and DEC coordinates
            -C is the acronym of the catalogue to browse
            -f FITS file to be used for coordinate center
            -m 
            -o optional output file
            -r is the search radius in arcmin. The search is carried out in a cone
            -S to have an ouput compatible to be shown with the ESO-skycat package
            -v generates a verbose output
            For several catalogues you need a working internet connection. Other catalogues
            are local.

History : (07/10/2003) First version.
        : (03/02/2005) Optparse.
        : (02/08/2009) Minor improvement.
        : (11/08/2010) 2MASS catalogue available.
        : (21/09/2010) Better import management.
        : (29/09/2010) New catalogues and code structure.
        : (01/10/2010) Minor correction.
        : (05/10/2010) AstroWise catalogue added.
        : (16/10/2010) Minor output correction.
        : (24/10/2010) USNO-A2 catalogue.
        : (14/12/2010) NIR catalogue collection.
        : (28/03/2011) AGN optical standard stars.
        : (11/06/2011) USNOB1 catalogue.
        : (26/08/2011) Reference FITS file.
        : (26/07/2013) APASS catalogue.
        : (19/08/2013) Max number of entries in output.
"""



import sys, os, os.path
from optparse import OptionParser
from SRP.SRPMath.AstroCoordInput import AstroCoordInput
from SRP.SRPFits.GetWCS import GetWCS
from SRP.SRPFits.IsFits import IsFits
from SRP.SRPCatalogue.BrightStarsClass import BrightStars
from SRP.SRPCatalogue.StetsonJohnsonStandardStarsClass import StetsonOpticalStandardStars
from SRP.SRPCatalogue.AstroWiseStandardStarsClass import AstroWiseStandardStars
from SRP.SRPCatalogue.TWOMASSClass import TWOMASS
from SRP.SRPCatalogue.USNOClass import USNO
from SRP.SRPCatalogue.USNOB1Class import USNOB1
from SRP.SRPCatalogue.SDSSClass import SDSS
from SRP.SRPCatalogue.NIRStandardStarsClass import NIRStandardStars
from SRP.SRPCatalogue.AGNOptRefStarsClass import AGNOptRefStars
from SRP.SRPCatalogue.APASSClass import APASS
from SRP.SRPCatalogue import CatalogueConstants





parser = OptionParser(usage="usage: %prog -c arg1 arg2 / -f arg3 -C arg4 [-h] [-o arg5] -r arg6 [-S] [-v]", version="%prog 2.9.0")
parser.add_option("-c", "--coord", action="store", nargs=2, type="string", dest="coord", help="Coordinates RA DEC (J2000)")
parser.add_option("-C", "--catalog", action="store", nargs=1, type="string", dest="catalog", help="Catalog to browse")
parser.add_option("-f", "--fitsfile", action="store", nargs=1, type="string", dest="fitsfile", help="Reference FITS file")
parser.add_option("-m", "--max", action="store", nargs=1, type="int", dest="max", default=1000, help="Maximum number of entries in output")
parser.add_option("-o", "--out", action="store", nargs=1, type="string", dest="outf", help="Output file")
parser.add_option("-r", "--radius", action="store", nargs=1, type="float", dest="radius", help="Search radius (arcmin)")
parser.add_option("-S", "--skycat", action="store_true", dest="skycat", help="Skycat output")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Fully describe operations")
(options, args) = parser.parse_args()




if (options.coord or options.fitsfile) and options.catalog and options.radius:
    # Catalogue
    if not options.catalog in CatalogueConstants.SRPCatalDict.keys():
        print "Available catalogues:"
        catlist = CatalogueConstants.SRPCatalDict.keys()
        catlist.sort()
        for i in catlist:
            print "Code %s for %s" % (i, CatalogueConstants.SRPCatalDict[i])
        parser.error("Catalogue requested not available.")
    else:
        if options.verbose:
            print "Catalogue requested is: %s" % CatalogueConstants.SRPCatalDict[options.catalog]
    # Search radius
    if options.radius <= 0.0:
        parser.error("Radius %.2f arcmin not acceptable." % options.radius)
    else:
        if options.verbose:
            print "Search radius %.2f arcmin" % options.radius
    # Maximum number of entries
    if options.max <= 0:
        parser.error("Number of entries in output must be positive.")
    if options.verbose:
        print "Up to %d entries retrieved." % options.max
    # FITS or coordinates
    if options.coord and options.fitsfile:
        parser.error("You cannot indicate coordinates and a reference FITS file frame.")
    #
    if options.coord:
        # Center coordinates
        inpcoord = AstroCoordInput(options.coord[0],options.coord[1])
        #
        if inpcoord.Valid == False:
            parser.error("Coordinates not corrected.")
        else:
            if options.verbose:
                print "Center coordinates: "+str(inpcoord)
    elif options.fitsfile:
        # FITS file
        if IsFits(options.fitsfile):
            if options.verbose:
                print "Reference FITS file is: %s" % options.fitsfile
            #
            cwcs = GetWCS(options.fitsfile)[0]
            if cwcs == None:
                parser.error("WCS not readable.")
            #
            crd = cwcs.getCentreWCSCoords()
            inpcoord = AstroCoordInput(crd[0],crd[1])
            #rad = cwcs.getHalfSizeDeg()*60.
            #
            if inpcoord.Valid == False:
                parser.error("FITS file coordinates not corrected.")
            else:
                if options.verbose:
                    print "Center coordinates: "+str(inpcoord)
            #
        else:
            parser.error("FITS file cannot be read.")
    # Output file
        if options.outf:
            if options.verbose:
                print "Output file name is: %s" % options.outf
    #
    # Bright Star Catalogue
    if CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.BSC:
        dt = BrightStars(inpcoord.RA,inpcoord.DEC,options.radius)
    # Stetson Standard Stars
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.SSC:
        dt = StetsonOpticalStandardStars(inpcoord.RA,inpcoord.DEC,options.radius)
    # 2MASS Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.TMC:
        dt = TWOMASS(inpcoord.RA,inpcoord.DEC,options.radius)
    # AstroWiseCatalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.AWC:
        dt = AstroWiseStandardStars(inpcoord.RA,inpcoord.DEC,options.radius)
    # USNO-B1 Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.USB:
        dt = USNOB1(inpcoord.RA,inpcoord.DEC,options.radius)
    # USNO-A2 Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.USC:
        dt = USNO(inpcoord.RA,inpcoord.DEC,options.radius)
    # NIR Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.NCC:
        dt = NIRStandardStars(inpcoord.RA,inpcoord.DEC,options.radius)
    # AGN Opt Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.AGNOPT:
        dt = AGNOptRefStars(inpcoord.RA,inpcoord.DEC,options.radius)
    # SDSS Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.SDSS:
        dt = SDSS(inpcoord.RA,inpcoord.DEC,options.radius)
    # APASS Catalogue
    elif CatalogueConstants.SRPCatalDict[options.catalog] == CatalogueConstants.APS:
        dt = APASS(inpcoord.RA,inpcoord.DEC,options.radius)
    #
    nobj = dt.GetData()
    if nobj == None:
        if options.verbose:
            print "Catalogue not accessible."
        sys.exit(1)
    #
    dt.sort()
    #
    if nobj > options.max:
        nobj = options.max
        dt.ListEntries = dt.ListEntries[0:options.max]
    #
    if options.outf:
        o = file(options.outf,'w')
        if options.skycat:
            o.write(dt.Skycat(options.outf))
        else:
            o.write(str(dt))
        o.close()
    else:
        if options.skycat:
            print dt.Skycat(options.outf)
        else:
            print dt
    #
    if options.verbose:
        if nobj >= 1:
            print "%d objects retrieved." % nobj
        else:
            print "No objects retrieved."
    else:
        if options.outf:
            print nobj, options.outf
        else:
            print nobj
    #
else:
    parser.print_help()
