""" Code to convert Stokes parameters to polarization and viceversa
    
Context : SRP
Module  : SRPStokesPol
Author  : Stefano Covino
Date    : 16/07/2014
E-mail  : stefano.covino@brera.inaf.it
URL:    : http://www.merate.mi.astro.it/utenti/covino
Purpose : Convert Stokes parameters to polarization and viceversa

Usage   : SRPStokesPol [-h] [-m] [-n n] [-p P eP Theta eTheta Chi eChi]
                    [-s Q eQ U eU V eV] [-v] [--version]

            -m, --montecarlo      Compute errors by means of a MonteCarlo run
            -n id the number of trials for error computation
            -p P eP Theta eTheta Chi eChi are the normalized polarization parameters
            -s Q eQ U eU V eV  are the normalized Stokes parameters 
    
History : (19/02/2012) First version.
        : (20/03/2013) More digits in output.
        : (21/02/2014) Message syntax correction.
        : (16/07/2014) Polarization bias correction
"""

__version__ = '2.1.0'


import argparse, math, sys
import numpy
from SRP.SRPPolarimetry.Pol2Stokes import Pol2Stokes
from SRP.SRPPolarimetry.Stokes2Pol import Stokes2Pol
from SRP.SRPPolarimetry.PolBias import PolBias
from SRP.SRPStatistics.GenGaussSet import GenGaussSet
from SRP.SRPStatistics.ScoreatPercentile import ScoreatPercentile



parser = argparse.ArgumentParser()
parser.add_argument("-b", "--polbias", action="store_true", help="Correct for polarization bias (Plaszcyinski et al. 2014, MNRAS 439 4048)")
parser.add_argument("-m", "--montecarlo", action="store_true", help="Compute errors by means of a MonteCarlo run")
parser.add_argument("-n", "--ntrial", action="store", type=int, default=1000, help="Number of trials for error computation", metavar='n')
parser.add_argument("-p", "--pol", action="store", type=float, nargs=6, help="Normalized polarization parameters", metavar=('P', 'eP', 'Theta', 'eTheta', 'Chi', 'eChi'))
parser.add_argument("-s", "--stokes", action="store", type=float, nargs=6, help="Normalized Stokes parameters", metavar=('Q', 'eQ', 'U', 'eU', 'V', 'eV'))
parser.add_argument("-v", "--verbose", action="store_true", help="Fully describe operations")
parser.add_argument("--version", action="version", version=__version__)
options = parser.parse_args()


#
if options.montecarlo:
    if options.verbose:
        print "Errors computed by a Monte Carlo run."
else:
    if options.verbose:
        print "Errors computed by error propagation."
#
if options.ntrial <= 0 and options.montecarlo:
    parser.error ("Number of trials must be positive.")
#
if (options.pol or options.stokes) and not (options.pol and options.stokes):
    if options.stokes:
        if (options.stokes[0]**2 + options.stokes[2]**2 + options.stokes[4]**2) > 1:
            parser.error("Polarization cannot be larger than 1.")
    elif options.pol:
        if options.pol[0] > 1.0:
            parser.error("Polarization cannot be larger than 1.")
    if options.verbose:
        if options.stokes:
            print "Q, eQ: %.5g +/- %.5g" % (options.stokes[0],options.stokes[1])
            print "U, eU: %.5g +/- %.5g" % (options.stokes[2],options.stokes[3])
            print "V, eV: %.5g +/- %.5g" % (options.stokes[4],options.stokes[5])
        elif options.pol:
            print "P, eP        : %.5g +/- %.5g" % (options.pol[0],options.pol[1])
            print "Theta, eTheta: %.3g +/- %.3g" % (options.pol[2],options.pol[3])
            print "Chi, eChi    : %.3g +/- %.3g" % (options.pol[4],options.pol[5])
    #
    if options.stokes:
        pol = Stokes2Pol(1.0,options.stokes[0],options.stokes[2],options.stokes[4],options.stokes[1],options.stokes[3],options.stokes[5]) 
        if options.montecarlo:
            pols = Stokes2Pol(1.0,GenGaussSet(options.stokes[0],options.stokes[1],options.ntrial),GenGaussSet(options.stokes[2],options.stokes[3],options.ntrial),GenGaussSet(options.stokes[4],options.stokes[5],options.ntrial))
    elif options.pol:
        stokes = Pol2Stokes(1.0,options.pol[0],math.radians(options.pol[2]),math.radians(options.pol[4]),options.pol[1],math.radians(options.pol[3]),math.radians(options.pol[5]))
        if options.montecarlo:
            stokess = Pol2Stokes(1.0,GenGaussSet(options.pol[0],options.pol[1],options.ntrial),GenGaussSet(math.radians(options.pol[2]),math.radians(options.pol[3]),options.ntrial),GenGaussSet(math.radians(options.pol[4]),math.radians(options.pol[5]),options.ntrial))
    #
    if options.stokes:
        P = pol[1]
        T = pol[2]
        C = pol[3]
        if options.montecarlo:
            eP = ScoreatPercentile(pols[1])[3]
            eT = ScoreatPercentile(pols[2])[3]
            eC = ScoreatPercentile(pols[3])[3]            
        else:
            eP = pol[4]
            eT = pol[5]
            eC = pol[6]
    if options.pol:
        Q = stokes[1]
        U = stokes[2]
        V = stokes[3]
        if options.montecarlo:
            eQ = ScoreatPercentile(stokess[1])[3]
            eU = ScoreatPercentile(stokess[2])[3]
            eV = ScoreatPercentile(stokess[3])[3]
        else:
            eQ = stokes[4]
            eU = stokes[5]
            eV = stokes[6]
    #
    if options.polbias and options.stokes:
        nPol = PolBias (P, eP)
    #
    if options.verbose:
        if options.stokes:
            print "P, eP: %.5g +/- %.5g" % (P,eP)
            print "Theta, eTheta: %.3g +/- %.3g" % (math.degrees(T),math.degrees(eT))
            print "Chi, eChi    : %.3g +/- %.3g" % (math.degrees(C),math.degrees(eC))
            print "Bias corrected P: %.5g" % (nPol)
        elif options.pol:
            print "Q, eQ: %.5g +/- %.5g" % (Q,eQ)
            print "U, eU: %.5g +/- %.5g" % (U,eU)
            print "V, eV: %.5g +/- %.5g" % (V,eV)
    else:
        if options.stokes:
            prstr = "%.5g %.5g %.5g %.5g %.5g %.5g" % (P,eP,math.degrees(T),math.degrees(eT),math.degrees(C),math.degrees(eC))
            if options.polbias:
                print "%s %.5g" % (prstr, nPol)
            else:
                print prstr
        elif options.pol:
            print "%.5g %.5g %.3g %.3g %.3g %.3g" % (Q,eQ,U,eU,V,eV)
else:
    parser.print_help()
#