#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#    Project: Fast Azimuthal integration
#             https://forge.epn-campus.eu/projects/azimuthal
#
#    File: "$Id$"
#
#    Copyright (C) European Synchrotron Radiation Facility, Grenoble, France
#
#    Authors: Jérôme Kieffer <Jerome.Kieffer@ESRF.eu>
#             Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
pyFAI-waxs is the Waxs script of pyFAI that allows data reduction for
Wide Angle Scattering, producing output in 2-theta range output in
radial dimension (and in degrees).
"""

__author__ = "Jerome Kieffer, Picca Frédéric-Emmanuel"
__contact__ = "Jerome.Kieffer@ESRF.eu"
__license__ = "GPLv3+"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "17/02/2012"
__status__ = "production"

import os
import sys
import time
import fabio
import pyFAI, pyFAI.units, pyFAI.utils
hc = pyFAI.units.hc

from optparse import OptionParser


def main():
    usage = "usage: %prog [options] -p ponifile file1.edf file2.edf ..."
    version = "%prog " + pyFAI.version
    description = "Azimuthal integration for WAXS users."
    epilog = """pyFAI-waxs is the script of pyFAI that allows data reduction
    (azimuthal integration) for Wide Angle Scattering to produce X-Ray Powder
    Diffraction Pattern with output axis in 2-theta space.
    """
    parser = OptionParser(usage=usage, version=version)
    parser.add_option("-p", dest="ponifile",
                      type='string', default=None,
                      help="PyFAI parameter file (.poni)")
    parser.add_option("-n", dest="npt",
                      type='int', default=None,
                      help="Number of points in radial dimension")
    parser.add_option("-w", "--wavelength", dest="wavelength", type="float",
                  help="wavelength of the X-Ray beam in Angstrom", default=None)
    parser.add_option("-e", "--energy", dest="energy", type="float",
                  help="energy of the X-Ray beam in keV (hc=%skeV.A)" % hc,
                  default=None)
    parser.add_option("-u", "--dummy", dest="dummy",
                      type="float", default=None,
                      help="dummy value for dead pixels")
    parser.add_option("-U", "--delta_dummy", dest="delta_dummy",
                      type="float", default=None,
                      help="delta dummy value")
    parser.add_option("-m", "--mask", dest="mask",
                      type="string", default=None,
                      help="name of the file containing the mask image")
    parser.add_option("-d", "--dark", dest="dark",
                      type="string", default=None,
                      help="name of the file containing the dark current")
    parser.add_option("-f", "--flat", dest="flat",
                      type="string", default=None,
                      help="name of the file containing the flat field")
    parser.add_option("-P", "--polarization", dest="polarization_factor",
                      type="float", default=None,
                      help="Polarization factor, from -1 (vertical) to +1 (horizontal), \
                      default is None for no correction, synchrotrons are around 0.95")

#    parser.add_option("-b", "--background", dest="background",
#                      type="string", default=None,
#                      help="name of the file containing the background")
    parser.add_option("--error-model", dest="error_model",
                      type="string", default=None,
                      help="Error model to use. Currently on 'poisson' is implemented ")
    parser.add_option("--unit", dest="unit",
                      type="string", default="2th_deg",
                      help="unit for the radial dimension: can be q_nm^-1, q_A^-1, 2th_deg, \
                      2th_rad or r_mm")
    parser.add_option("--ext", dest="ext",
                      type="string", default=".xy",
                      help="extension of the regrouped filename (.xy) ")

    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")

    processFile = pyFAI.utils.expand_args(args)

    if options.ponifile and processFile:
        integrator = pyFAI.load(options.ponifile)
        if options.wavelength:
            integrator.wavelength = options.wavelength*1e-10
        elif options.energy:
            integrator.wavelength = hc / options.energy*1e-10
        if options.mask and os.path.exists(options.mask):  # override with the command line mask
            integrator.maskfile = options.mask
        if options.dark and os.path.exists(options.dark):  # set dark current
            integrator.darkcurrent = fabio.open(options.dark).data
        if options.flat and os.path.exists(options.flat):  # set Flat field
            integrator.flatfield = fabio.open(options.flat).data

        if len(processFile) > 5:
            method = "lut"
        else:
            method = "BBox"
        print(integrator)
        print("Mask: %s\tMethod: %s" % (integrator.maskfile, method))
        for oneFile in processFile:
            sys.stdout.write("Integrating %s --> " % oneFile)
            outFile = os.path.splitext(oneFile)[0] + options.ext
            azimFile = os.path.splitext(oneFile)[0] + ".azim"
            fabioFile = fabio.open(oneFile)
            t0 = time.time()
            integrator.integrate1d(data=fabioFile.data,
                                   nbPt=options.npt or min(fabioFile.data.shape),
                                   filename=outFile,
                                   dummy=options.dummy,
                                   delta_dummy=options.delta_dummy,
                                   method=method,
                                   unit=options.unit,
                                   error_model=options.error_model,
                                   polarization_factor=options.polarization_factor
                                   )

            t1 = time.time()
            integrator.integrate2d(fabioFile.data,
                                   options.npt or min(fabioFile.data.shape),
                                   360,
                                   filename=azimFile,
                                   dummy=options.dummy,
                                   delta_dummy=options.delta_dummy,
                                   method=method,
                                   unit=options.unit,
                                   error_model=options.error_model,
                                   polarization_factor=options.polarization_factor
                                   )
            print("%s\t 1D took  %.3fs, 2D took %.3fs" %
                  (outFile, t1 - t0, time.time() - t1))

if __name__ == "__main__":
    main()
