""" Code to perform photometry on FITS frames

Context : SRP
Module  : SRPPhotometry.py
Version : 2.0.2
Author  : Stefano Covino
Date    : 20/08/2011
E-mail  : stefano.covino@brera.inaf.it
URL:    : http://www.merate.mi.astro.it/utenti/covino
Purpose : Manage the photometry of FITS files.

Usage   : SRPPhotometry [-e arg1] [-g arg2] [-h] [-H arg3 arg4] -i arg5 [-r arg6] [-s arg7] [-S] [-v] [-z arg8 arg9]
            -i Input FITS file list or single FITS file
            -g Gain (e-/ADU) for error estimate in photometry
            -s Saturation level (ADU) for frame(s)
            -e Exposure time (sec) for frame(s)
            -S ESO-Skycat output
            -r Radius (pixel) for aperture photometry
            -z Zero point and error for photometry
            -H FITS file header for exposure time, duration, airmass
                and filter [default: MJD-OBS EXPTIME AIRMASS FILTER]

History : (30/05/2003) First version.
        : (04/06/2003) Management of non-numeric exposure times.
        : (15/06/2003) Selection of stars for photometry.
        : (29/06/2003) Better search for exposure times.
        : (20/09/2003) Create SExtractor paramter files only if there are not anymore.
        : (10/10/2003) Aperture photometry in output file.
        : (23/12/2003) Minor correction and zero-point management.
        : (03/02/2005) Optparse.
        : (01/12/2005) CygWin porting.
        : (09/06/2006) Different out filename extension for skycat format.
        : (13/06/2006) Minor correction.
        : (20/10/2008) Minor correction.
        : (11/09/2009) Better pipes.
        : (21/05/2010) Better management of FITS header.
        : (26/08/2010) Minor improvements.
        : (28/09/2010) Better coding.
        : (30/09/2010) More input data.
        : (01/10/2010) Code cosmesis.
        : (13/10/2010) shutil not imported.
        : (15/10/2010) Better management of saturation level.
        : (26/10/2010) No more RA,DEC from sextractor.
        : (07/08/2011) Better cosmetics.
        : (20/08/2011) Exptime in output file.
"""



import os, os.path, shutil, string
from optparse import OptionParser
import SRP.SRPConstants as SRPConstants
import SRP.SRPFiles as SRPFiles
import SRP.SRPUtil as SRPUtil
from SRP.SRPFits.GetHeaderValue import GetHeaderValue
from SRP.SRPFits.IsFits import IsFits
from SRP.SRPFrames import SExtractorConstants
from SRP.SRPSystem.Which import Which
from SRP.SRPFits.GetHeader import GetHeader
from SRP.SRPFrames.Pixel2WCS import Pixel2WCS


parser = OptionParser(usage="usage: %prog [-e arg1] [-g arg2] [-h] [-H arg3 arg4] -i arg5 [-r arg6] [-s arg7] [-S] [-v] [-z arg8 arg9]", version="%prog 2.0.2")
parser.add_option("-i", "--inputlist", action="store", nargs=1, type="string", dest="fitsfilelist", help="Input FITS file list or single FITS file")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Fully describe operations")
parser.add_option("-g", "--gain", action="store", type="float", dest="gainvalue", help="Gain (e-/ADU) for error estimate in photometry")
parser.add_option("-s", "--saturation", action="store", type="float", dest="satvalue", help="Saturation level (ADU) for frame(s)")
parser.add_option("-e", "--exptime", action="store", type="float", dest="exptime", help="Exposure time (sec) for frame(s)")
parser.add_option("-S", "--skycat", action="store_true", dest="skycat", help="ESO-Skycat output")
parser.add_option("-r", "--radius", action="store", type="float", dest="radius", help="Radius (pixel) for aperture photometry")
parser.add_option("-z", "--zerpoints", action="store", nargs=2, type="float", dest="zpoints", help="Zero point and error for photometry")
parser.add_option("-H", "--headerinfo", action="store", nargs=4, type="string", dest="headinf", default=('MJD-OBS','EXPTIME','AIRMASS','FILTER'),help="FITS file header for exposure time, duration, airmass and filter [default: MJD-OBS EXPTIME AIRMASS FILTER]")
(options, args) = parser.parse_args()


if options.fitsfilelist:
    # Input file
    if os.path.isfile(options.fitsfilelist):
        # FITS file
        if IsFits(options.fitsfilelist):
            if options.verbose:
                print "Input FITS file is: %s" % options.fitsfilelist
            FITSfileflag = True
        # FITS file list
        else:
            f = SRPFiles.SRPFile(SRPConstants.SRPLocalDir,options.fitsfilelist,SRPFiles.ReadMode)
            f.SRPOpenFile()
            if options.verbose:
                print "Input FITS file list is: %s" % options.fitsfilelist
            FITSfileflag = False
        #                        
        flist = []
        nentr = 0
        while True:
            if FITSfileflag:
                flist.append(options.fitsfilelist)
                nentr = 1
                break
            else:
                dt = f.SRPReadFile()
                if dt != '':
                    flist.append(string.split(string.strip(dt))[0])
                    nentr = nentr + 1
                    if not os.path.isfile(flist[nentr-1]):
                        parser.error("Input FITS file %s not found" % flist[nentr-1])
                    if options.verbose:
                        print "FITS file selected: %s" % flist[nentr-1]    
                else:
                    break
        if not FITSfileflag:
            f.SRPCloseFile()
        # Fill data
        hflist = []
        mflist = []
        aflist = []
        wflist = []
        for i in range(len(flist)):
            # exptime
            eh = GetHeaderValue(flist[i],options.headinf[1])
            if eh[0] != None:
                try:
                    hflist.append(float(eh[0]))
                except:
                    hflist.append(1.0)
            else:
                hflist.append(1.0)
            # date
            eh = GetHeaderValue(flist[i],options.headinf[0])
            if eh[0] != None:
                try:
                    mflist.append(eh[0])
                except:
                    mflist.append(-99.0)
            else:
                mflist.append(-99.0)
            # airmass
            eh = GetHeaderValue(flist[i],options.headinf[2])
            if eh[0] != None:
                try:
                    aflist.append(float(eh[0]))
                except:
                    aflist.append(1.0)
            else:
                aflist.append(1.0)
            # airmass
            eh = GetHeaderValue(flist[i],options.headinf[3])
            if eh[0] != None:
                try:
                    wflist.append(eh[0])
                except:
                    wflist.append('Unknown')
            else:
                wflist.append('Unknown')
            #
    else:
        parser.error("Input FITS file or file list %s not found" % options.fitsfilelist)
    if options.gainvalue > 0.0:
        Gain = options.gainvalue
    else:
        Gain = 1.0
    if options.verbose:
        print "Gain value is %.2f" % Gain
    if options.satvalue > 0.0:
        Saturation = options.satvalue
    else:
        Saturation = 55000.0
    if options.verbose:
        print "Saturation level is %.1f" % Saturation
    if options.radius > 0.0:
        Radius = options.radius
    else:
        Radius = 5.0
    if options.verbose:
        print "Aperture photometry radius is %.1f" % Radius
    zpl = [25.0,0.0]
    if options.zpoints:
        zpl[0] = options.zpoints[0]
        zpl[1] = options.zpoints[1]
    if options.verbose:
        print "Zero point is %.3f +/- %.3f" % (zpl[0], zpl[1])
    if Which(SExtractorConstants.SRPsex) == None and Which(SExtractorConstants.SRPsex_cyg) == None:
        parser.error("SExtractor package not found.")
    # sextractor parameters
    pflcreated = False
    for i in range(len(SExtractorConstants.SexFName)):
        if not SRPFiles.IsReadable(SExtractorConstants.SexFName[i]):
            shutil.copyfile(os.path.join(SExtractorConstants.BasePath,SExtractorConstants.GenParSet[i]),os.path.join('.',SExtractorConstants.SexFName[i]))
            pflcreated = True
    if options.verbose and pflcreated:
        print "SExctractor parameter files created."
    # Process
    for i in range(len(flist)):
        if options.verbose:
            print "Processing file: %s..." % flist[i]
        if options.exptime:
            Exptime = options.exptime
        else:
            Exptime = hflist[i]
            if Exptime == None:
                Exptime = 1.0
        if options.verbose:
            print "Exposure time is %.1f" % Exptime
        #
        root,ext = os.path.splitext(flist[i])
        parstr1 = SExtractorConstants.SRPsex+' '+flist[i]+' -c SRP.sex '
        parstr2 = " -GAIN %.2f -SATUR_LEVEL %.1f -PHOT_APERTURES %.1f" % (Gain, Saturation, Radius)
        stardata = SRPFiles.SRPPipe(parstr1+parstr2)
        if stardata == None:
            parser.error("%s not a FITS file." % flist[i])
        starlist = SRPUtil.getStarData(string.split(stardata,os.linesep), Exptime, zpl, mflist[i], aflist[i], wflist[i])
        if options.skycat:
            g = SRPFiles.SRPFile(SRPConstants.SRPLocalDir, root+SRPConstants.SRPPhotomFileSky, SRPFiles.WriteMode)
        else:
            g = SRPFiles.SRPFile(SRPConstants.SRPLocalDir, root+SRPConstants.SRPPhotomFile, SRPFiles.WriteMode)
        g.SRPOpenFile()
        if options.skycat:
            g.SRPWriteFile("serv_type: catalog"+os.linesep)
            g.SRPWriteFile("long_name: SRP catalog for file %s" % flist[i]+os.linesep)
            g.SRPWriteFile("short_name: %s" % root+SRPConstants.SRPPhotomFileSky+os.linesep)
            g.SRPWriteFile("url: ./%s" % root+SRPConstants.SRPPhotomFileSky+os.linesep)
            g.SRPWriteFile("id_col: 0"+os.linesep)
            g.SRPWriteFile("x_col: 1"+os.linesep)
            g.SRPWriteFile("y_col: 2"+os.linesep)
            g.SRPWriteFile("symbol: {} circle 4"+os.linesep)
            g.SRPWriteFile("Id\tX\tY\tRA\tDEC\tmag_ap\temag_ap\tsky\tfmax\tmag\temag\tFWHM\tMJD\tAirmass\tFilter\tExptime"+os.linesep)
            g.SRPWriteFile("---------"+os.linesep)
        ndetec = 0
        #
        # RA,DEC from sextractor not correct.
        fhed = GetHeader(flist[i])[0]
        pixc = []
        for l in range(len(starlist)):
            pixc.append((starlist[l].X,starlist[l].Y))
        fc = Pixel2WCS(fhed,pixc)
        # file header
        for l in range (len(starlist)):
            if starlist[l].fmax < Saturation:
                starlist[l].RA = fc[l][0]
                starlist[l].DEC = fc[l][1]
                g.SRPWriteFile(starlist[l])
                ndetec = ndetec + 1
        if options.skycat:
            g.SRPWriteFile("EOD"+os.linesep)
        g.SRPCloseFile()
        if options.verbose:
            print "%d objects selected." % ndetec
        else:
            if options.skycat:
                print ndetec, root+SRPConstants.SRPPhotomFileSky
            else:
                print ndetec, root+SRPConstants.SRPPhotomFile 
        if options.verbose:
            if options.skycat:
                print "Photometric results reported in file %s" % root+SRPConstants.SRPPhotomFileSky
            else:
                print "Photometric results reported in file %s" % root+SRPConstants.SRPPhotomFile
else:
    parser.print_help()
