#!python
""" Code to extract sources from a fits frame

Context : SRP
Module  : SRPSourceFinder
Author  : Stefano Covino
Date    : 22/05/2023
E-mail  : stefano.covino@inaf.it
URL:    : http://www.merate.mi.astro.it/utenti/covino
Purpose :

Usage   : SRPSourceFinder -e/-n/-s -f arg1 [-h] [-m arg2] [-S] [-t arg3] [-v]
            -e Eclipse algorithm
            -f FITS file
            -m Minimum number of connected pixel (for native only)
            -n Native algorithm
            -s Sextractor algorithm (default)
            -S Skycat output
            -t Threshold for selection


History : (25/06/2010) First version.
        : (24/08/2010) Output list sorted and minimum number of connected pixel selectable.
        : (04/09/2010) Minor correction.
        : (27/09/2010) Eclipse sources added.
        : (18/10/2010) Import correction.
        : (07/08/2011) Better cosmetics.
        : (18/04/2013) More complete output.
        : (14/03/2016) Python3 porting.
        : (18/05/2017) Minor update.
        : (22/05/2023) Minor bug correction.
"""


from SRPFITS.Fits.FitsImageClass import FitsImage
from SRPFITS.Fits import FitsConstants
from SRPFITS.Fits.IsFits import IsFits
from optparse import OptionParser
import os


parser = OptionParser(usage="usage: %prog -d/-n/-s -f arg1 [-h] [-m arg2] [-S] [-t arg3] [-v]", version="%prog 1.3.0")
parser.add_option("-d", "--daophot", action="store_true", dest="daophot", help="Daophot algorithm")
parser.add_option("-f", "--fits", action="store", nargs=1, type="string", dest="fits", help="FITS file")
parser.add_option("-m", "--minpix", action="store", dest="minpix", type="int", help="Minimum number of connected pixel (for native only)")
parser.add_option("-n", "--native", action="store_true", dest="native", help="Native algorithm")
parser.add_option("-s", "--sextractor", action="store_true", dest="sex", help="Sextractor algorithm (default)")
parser.add_option("-S", "--skycat", action="store_true", dest="skycat", help="Skycat output")
parser.add_option("-t", "--threshold", action="store", type="float", dest="thre", help="Threshold for pixel selection")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Fully describe operations")
(options, args) = parser.parse_args()



if options.fits:
    if not IsFits(options.fits):
        parser.error("Fits file %s not found." % options.fits)
    # No more than one algorithm
    if (options.native and options.daophot) or (options.native and options.sex) or (options.daophot and options.sex):
        parser.error("You can select one only algorithm.")
    # If non chosen daophot is the default
    elif not (options.native or options.sex):
        options.daophot = True
    # Threshold meaning depend on the algorithm
    if not options.thre:
        if options.native:
            options.thre = 5.0
        elif options.daophot:
            options.thre = 5.0
        elif options.sex:
            options.thre = 3.0
    # Safety check on threshold
    if options.thre < 0.0:
        parser.error("Threshold must be positive.")
    if options.verbose:
        print("Threshold: %.2f" % options.thre)
    # Minpix meaningful only for native mode
    if (not options.native) and options.minpix != None:
        parser.error("--minpix parameter meaningful only for native algorithm.")
    # Deafult for minpix if meaningful
    if options.native and not options.minpix:
        options.minpix = 3
    # Safey check on minpix
    if options.native and options.minpix < 1:
        parser.error("Minimum number of pixel must be greater than 1.")
    if options.native and options.verbose:
        print("Minimum number of pixel: %d" % options.minpix)
    # Open file
    if options.verbose:
        print("Opening FITS file %s" % options.fits)
    d = FitsImage(options.fits)
    if d == None:
        parser.error("Problem in reading FITS file %s" % options.fits)

    # Sources
    if options.verbose:
        print("Source extraction...")
    if options.daophot:
        d.DAOSources(options.thre)
    elif options.native:
        d.Sources(options.thre,options.minpix)
    elif options.sex:
        d.SexSources(options.thre)
    if options.verbose:
        print("FWHM computation...")
    d.GetFWHM()
    if options.verbose:
        print("Source list sorting...")
    d.SortSourceList()

    # Save results
    froot,fext = os.path.splitext(options.fits)
    if options.skycat:
        fname = froot+FitsConstants.SkyData
    else:
        fname = froot+FitsConstants.RegData
    if options.verbose:
        print("Output %s creation with %d entries." % (fname, len(d.List)))
    else:
        print("%d %s" % (len(d.List), fname))
    f = open(fname,'w')
    if options.skycat:
        f.write(d.Skycat())
    else:
        f.write(str(d))
    f.close()
else:
    parser.print_help()
