#!/usr/bin/env python

import os
import sys
import re
import imgrecom
import gmaptran
import sirrecom
from pyraf import iraf
import numpy as np


def shiftbyhand(band, ifwhm, reject, badfill):

    iraf.digiphot(_doprint = 0)
    iraf.apphot(_doprint = 0)
    iraf.unlearn('phot')
    iraf.unlearn('psfmeasure')
    iraf.unlearn('geomap')

    if ifwhm<5:
        iraf.apphot.centerpars.cbox=5
    else:
        iraf.apphot.centerpars.cbox=ifwhm

    iraf.apphot.fitskypars.dannulu = 2 * ifwhm
    iraf.apphot.datapars.datamin = -1000
    iraf.apphot.datapars.readnoise = 30
    iraf.apphot.datapars.epadu = 5
    iraf.apphot.photpars.aperture = 2 * ifwhm
    iraf.apphot.fitskypars.annulus = 3 * ifwhm
    
    iraf.psfmeasure.display = 'no'
    iraf.psfmeasure.radius = 2 * ifwhm
    iraf.psfmeasure.logfile = 'psfme.txt'
    iraf.psfmeasure.imagecur = 'psfcoo.txt'
    iraf.psfmeasure.graphcur = 'q.txt'
    
    fo=open('q.txt','w')
    print >> fo, 'q'
    fo.close()
  
    idfits, xcoo, ycoo, fid, mag, merr, fwhm, ellip  = fwhmphot(band, badfill)

    fog = open(band+'tran.txt', 'w')
    for i in range(len(idfits)):

        if i == 0:
            print >> fog, "%s 0.0 0.0 1.0 0.0 0.0 0.0 1.0 512 512 512 512 0.0 0.0 1" % idfits[i]
        else:
            fo = open('getgmap.coo', 'w')
            print >> fo, xcoo[0], ycoo[0], xcoo[i], ycoo[i]
            fo.close()
            iraf.geomap('getgmap.coo', 'getgmap.db', xmin=1, xmax=1024, ymin=1, ymax=1024,
                        fitgeometry='shift', verbose='no', interactive='no')

            fdb = open('getgmap.db')
            for ii, gline in enumerate(fdb):
                gvalue = gline[:-1].split()
                if ii == 2:
                    xrefmean = float(gvalue[1])
                if ii == 3:
                    yrefmean = float(gvalue[1])
                if ii == 4:
                    xmean = float(gvalue[1])
                if ii == 5:
                    ymean = float(gvalue[1])
                if ii == 12:
                    rot = float(gvalue[1])
                if ii == 14:
                    xrms = float(gvalue[1])
                if ii == 15:
                    yrms = float(gvalue[1])
                if ii == 25:
                    aa = gvalue[0]
                    dd = gvalue[1]
                if ii == 26:
                    bb = gvalue[0]
                    ee = gvalue[1]
                if ii == 27:
                    cc = gvalue[0]
                    ff = gvalue[1]
                        
            fdb.close()

            os.remove('getgmap.coo')
            os.remove('getgmap.db')
                
            print >> fog, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s 1" % (idfits[i], rot, aa, bb, cc, dd, ee, ff, xrefmean, yrefmean, xmean, ymean, xrms, yrms)
            
    fog.close()

    gmaptran.recominfo(band, 99, 0)

    print 'geotran in progress'
    gmaptran.dotran(band, 99, 0)
    os.remove('gtran.coo')

    print 'combining'
    imgrecom.recomb(band, 99, 0, reject)

    if os.path.exists('../0.ffiles'):
        os.remove('../0.ffiles')

    print 'done'

    photstat(band, fid, mag, merr, fwhm, ellip)

    os.remove('q.txt')


def fwhmphot(band, badfill):


    SCRIPTDIR = os.path.realpath(os.path.dirname(sys.argv[0]))

    idfits = []
    xcoo = []
    ycoo = []
    fid = []
    mag = []
    merr = []
    fwhm = []
    ellip = []
    fin = open(band+'imgrecom.list')
    for line in fin:
        fdir = (line[:-1].split())[0]
        fnum = (line[:-1].split())[1]
        yymmdd = (fdir.split('ffiles'))[0]

        fname = '../'+fdir+'/'+band+'f'+fnum+'.fits'

        pflag = 0
        errormsg = ''
        if not os.access(fname, os.F_OK):
            print '%s was not found' % fname
        else:
            v = phot2v(fname)

            if v[2] == '108' or v[4] == '305':
                if badfill == 1:
                    cprog = 'badfill'
                    os.system("%s/%s %s recomtmp.fits" % (SCRIPTDIR, cprog, fname))
                    print '!! measure it again !!'
                    v = phot2v('recomtmp.fits')

                else:
                    pass
            else:
                pass

            if v[0] == 'INDEF':
                print '%s was not measured' % fname
                pflag = 1
            else:
                if not v[2] == '0' and not v[2] == '107':
                    pflag = 1
                    errormsg = 'cier = '+v[2]+' '
                if not v[3] == '0' and not v[3] == '202':
                    pflag = 1
                    errormsg = errormsg + 'sier = '+v[3]+' '
                if not v[4] == '0':
                    pflag = 1
                    errormsg = errormsg + 'pier = '+v[4]+' '

            if pflag == 0:

                idfits.append(yymmdd+band+'f'+fnum)

                fp = open('psfcoo.txt', 'w')
                print >> fp, v[0], v[1]
                fp.close()

                if not os.access('recomtmp.fits', os.R_OK):
                    cprog = 'badfill'
                    os.system("%s/%s %s recomtmp.fits" % (SCRIPTDIR, cprog, fname))

                iraf.psfmeasure('recomtmp.fits', Stdout=1, StdoutG='/dev/null')
                psf1, psf2 = sirrecom.getpsf()
                os.remove('psfme.txt')
                
                nfwhm = float(psf1)

                if nfwhm < 5:
                    iraf.apphot.centerpars.cbox = 5
                else:
                    iraf.apphot.centerpars.cbox = nfwhm
                    
                iraf.apphot.fitskypars.dannulu = 2 * nfwhm
                iraf.apphot.photpars.aperture = 2 * nfwhm
                iraf.apphot.fitskypars.annulus = 3 * nfwhm
                iraf.psfmeasure.radius = 2 * nfwhm

                iraf.phot('recomtmp.fits', coords='psfcoo.txt', output='byhand.mag', interactive='no', verify='no')
                txout = iraf.txdump('byhand.mag', fields='xc, yc, cier, sier, pier, mag, merr', expr='yes', Stdout=1)
                v = txout[0].split()
    
                fid.append(fname)
                xcoo.append(v[0])
                ycoo.append(v[1])
                mag.append(v[5])
                merr.append(v[6])
                fwhm.append(psf1)
                ellip.append(psf2)

                os.remove('recomtmp.fits')
                os.remove('psfcoo.txt')
                os.remove('byhand.mag')

            else:
                fid.append(fname)
                mag.append('INDEF')
                merr.append('INDEF')
                fwhm.append('INDEF')
                ellip.append('INDEF')
                print '%s was excluded' % fname
                print 'because of %s' % errormsg

    fin.close()

    return idfits, xcoo, ycoo, fid, mag, merr, fwhm, ellip
    

def phot2v(fname):

    iraf.display(fname, '1', fill='yes')
    iraf.phot(fname, output='byhand.mag', interactive='yes', verify='no')
    if os.access('byhand.mag', os.R_OK):
        txout = iraf.txdump('byhand.mag', fields='xc, yc, cier, sier, pier, mag, merr', expr='yes', Stdout=1)
        os.remove('byhand.mag')
        v = txout[0].split()
    else:
        v = ['INDEF', 'INDEF', 'INDEF', 'INDEF', 'INDEF', 'INDEF', 'INDEF']

    return v


def photstat(band, arr0, arr1, arr2, arr3, arr4):

    fout = open(band+'magpsf.txt', 'w')
    mag = np.array([])
    merr = np.array([])
    fwhm = np.array([])
    ellip = np.array([])
    for i in range(len(arr1)):
        print >> fout, '%s %s %s %s %s' % (arr0[i], arr1[i], arr2[i], arr3[i], arr4[i])
        if arr1[i] != 'INDEF' and arr2[i] != 'INDEF':
            mag = np.append(mag, float(arr1[i]))
            merr = np.append(merr, float(arr2[i]))
    fout.close()

    print ''
    print 'stats of instrumental magnitudes and errors of the star'
    print 'mean : %.2f %.2f' % (np.mean(mag), np.mean(merr))
    print 'median : %.2f %.2f' % (np.median(mag), np.median(merr))
    print 'max : %.2f %.2f' % (np.max(mag), np.max(merr))
    print 'min : %.2f %.2f' % (np.min(mag), np.min(merr))
    print 'std : %.2f %.2f' % (np.std(mag), np.std(merr))
    print ''


if __name__ == "__main__":
    
    argvs = sys.argv
    argc = len(argvs)

    if argc < 2 or argvs[1] == '--help':
        print 'usage: recombyhand.py [init|run] band[j|h|k]'
        print 'options: '
        print '-fwhm=[float] (default : 3)'
        print '-reject=minmax (default : sigclip)'
        print '-badfill=[0|1] (default : 0 no-badfill)'
        print 'exmaples '
        print 'recombyhand init j '
        print 'recombyhand run j -fwhm=5'
        print 'recombyhand run k -reject=minmax'
        print ''
        print 'usage: recombyhand.py --help'
        print 'to show this messege'
        print ''
        sys.exit()

    ifwhm = 3
    reject = 'sigclip'
    badfill = 0

    if argc > 3:
        for i in range(3, argc, 1):
            print argvs[i]
            if re.match('-fwhm', argvs[i]):
                ifwhm=float(argvs[i][6:])
            elif re.match('-reject', argvs[i]):
                reject=argvs[i][8:]
            elif re.match('-badfill', argvs[i]):
                badfill=int(argvs[i][9:])
            else:
                print 'typo? -fwhm=[float] -reject=[minmax] -badfill=[0|1]'
                sys.exit()

    if argvs[1] == 'init':
        imgrecom.initrecom(argvs[2])
    elif argvs[1] == 'run':
        if os.access(argvs[2]+'imgrecom.list', os.F_OK):
            shiftbyhand(argvs[2], ifwhm, reject, badfill)
        else:
            print argvs[2]+'imgrecom.list not found'
            print 'execute recombyhand.py init '+argvs[2]
    else:
        print 'typo? '
        print 'usage: recombyhand.py [init|run] band[j|h|k]'
    


    
