# Path: tkp/quality/restoringbeam.py
# def beam_invalid(semibmaj, semibmin, theta, oversampled_x=30, elliptical_x=2.0):
#     """ Are the beam shape properties ok?
# 
#     :param semibmaj/semibmin: size of the beam in pixels
# 
#     :returns: True/False
#     """
# 
#     formatted = "bmaj=%s and bmin=%s (pixels)" % (nice_format(semibmaj),
#                                                  nice_format(semibmin))
# 
#     if tkp.quality.restoringbeam.infinite(semibmaj, semibmin, theta):
#         return "Beam infinte. %s" % formatted
#     if tkp.quality.restoringbeam.undersampled(semibmaj, semibmin):
#         return "Beam undersampled. %s" % formatted
#     elif tkp.quality.restoringbeam.oversampled(semibmaj, semibmin,
#         oversampled_x):
#         return "Beam oversampled. %s" % formatted
#     elif tkp.quality.restoringbeam.highly_elliptical(semibmaj, semibmin, elliptical_x):
#         return "Beam too elliptical. %s" % formatted
# 
#     #TODO: this test has been disabled untill antonia solves issue discribed in #3802
#     #elif not tkp.quality.restoringbeam.full_fieldofview(nx, ny, cellsize, fov):
#     #    return "Full field of view not imaged. Imaged FoV=XXdegrees, Observed FoV=XXdegrees"
# 
#     else:
#         return False
# 
# Path: tkp/quality/rms.py
# def rms_invalid(rms, noise, low_bound=1, high_bound=50):
#     """
#     Is the RMS value of an image outside the plausible range?
# 
#     :param rms: RMS value of an image, can be computed with
#                 tkp.quality.statistics.rms
#     :param noise: Theoretical noise level of instrument, can be calculated with
#                   tkp.lofar.noise.noise_level
#     :param low_bound: multiplied with noise to define lower threshold
#     :param high_bound: multiplied with noise to define upper threshold
#     :returns: True/False
#     """
#     if (rms < noise * low_bound) or (rms > noise * high_bound):
#         ratio = rms / noise
#         return "rms value (%s) is %s times theoretical noise (%s)" % \
#                     (nice_format(rms), nice_format(ratio), nice_format(noise))
#     else:
#         return False
# 
# def rms_with_clipped_subregion(data, rms_est_sigma=3, rms_est_fraction=4):
#     """
#     RMS for quality-control.
# 
#     Root mean square value calculated from central region of an image.
#     We sigma-clip the input-data in an attempt to exclude source-pixels
#     and keep only background-pixels.
# 
#     Args:
#         data: A numpy array
#         rms_est_sigma: sigma value used for clipping
#         rms_est_fraction: determines size of subsection, result will be
#             1/fth of the image size where f=rms_est_fraction
#     returns the rms value of a iterative sigma clipped subsection of an image
#     """
#     return rms(clip(subregion(data, rms_est_fraction), rms_est_sigma))


import logging
import tkp.db
import tkp.db.quality as dbquality
from tkp.quality.restoringbeam import beam_invalid
from tkp.quality.rms import rms_invalid, rms_with_clipped_subregion
from tkp.telescope.lofar.noise import noise_level
from tkp.utility import nice_format

logger = logging.getLogger(__name__)


def reject_check_lofar(accessor, job_config):

    lofar_quality_params = job_config['quality_lofar']
    quality_params = job_config['quality']

    low_bound = lofar_quality_params['low_bound']
    high_bound = lofar_quality_params['high_bound']
    oversampled_x = quality_params['oversampled_x']
    elliptical_x = quality_params['elliptical_x']
    min_separation = lofar_quality_params['min_separation']

    if accessor.tau_time == 0:
        logger.info("image %s REJECTED: tau_time is 0, should be > 0" % accessor.url)
        return dbquality.reject_reasons['tau_time'], "tau_time is 0"

    rms_est_sigma = job_config.persistence.rms_est_sigma
    rms_est_fraction = job_config.persistence.rms_est_fraction
    rms_qc = rms_with_clipped_subregion(accessor.data,
                                        rms_est_sigma=rms_est_sigma,
                                        rms_est_fraction=rms_est_fraction)

    noise = noise_level(accessor.freq_eff, accessor.freq_bw, accessor.tau_time,
        accessor.antenna_set, accessor.ncore, accessor.nremote, accessor.nintl
    )

# Path: tkp/quality/restoringbeam.py
# def beam_invalid(semibmaj, semibmin, theta, oversampled_x=30, elliptical_x=2.0):
#     """ Are the beam shape properties ok?
# 
#     :param semibmaj/semibmin: size of the beam in pixels
# 
#     :returns: True/False
#     """
# 
#     formatted = "bmaj=%s and bmin=%s (pixels)" % (nice_format(semibmaj),
#                                                  nice_format(semibmin))
# 
#     if tkp.quality.restoringbeam.infinite(semibmaj, semibmin, theta):
#         return "Beam infinte. %s" % formatted
#     if tkp.quality.restoringbeam.undersampled(semibmaj, semibmin):
#         return "Beam undersampled. %s" % formatted
#     elif tkp.quality.restoringbeam.oversampled(semibmaj, semibmin,
#         oversampled_x):
#         return "Beam oversampled. %s" % formatted
#     elif tkp.quality.restoringbeam.highly_elliptical(semibmaj, semibmin, elliptical_x):
#         return "Beam too elliptical. %s" % formatted
# 
#     #TODO: this test has been disabled untill antonia solves issue discribed in #3802
#     #elif not tkp.quality.restoringbeam.full_fieldofview(nx, ny, cellsize, fov):
#     #    return "Full field of view not imaged. Imaged FoV=XXdegrees, Observed FoV=XXdegrees"
# 
#     else:
#         return False
# 
# Path: tkp/quality/rms.py
# def rms_invalid(rms, noise, low_bound=1, high_bound=50):
#     """
#     Is the RMS value of an image outside the plausible range?
# 
#     :param rms: RMS value of an image, can be computed with
#                 tkp.quality.statistics.rms
#     :param noise: Theoretical noise level of instrument, can be calculated with
#                   tkp.lofar.noise.noise_level
#     :param low_bound: multiplied with noise to define lower threshold
#     :param high_bound: multiplied with noise to define upper threshold
#     :returns: True/False
#     """
#     if (rms < noise * low_bound) or (rms > noise * high_bound):
#         ratio = rms / noise
#         return "rms value (%s) is %s times theoretical noise (%s)" % \
#                     (nice_format(rms), nice_format(ratio), nice_format(noise))
#     else:
#         return False
# 
# def rms_with_clipped_subregion(data, rms_est_sigma=3, rms_est_fraction=4):
#     """
#     RMS for quality-control.
# 
#     Root mean square value calculated from central region of an image.
#     We sigma-clip the input-data in an attempt to exclude source-pixels
#     and keep only background-pixels.
# 
#     Args:
#         data: A numpy array
#         rms_est_sigma: sigma value used for clipping
#         rms_est_fraction: determines size of subsection, result will be
#             1/fth of the image size where f=rms_est_fraction
#     returns the rms value of a iterative sigma clipped subsection of an image
#     """
#     return rms(clip(subregion(data, rms_est_fraction), rms_est_sigma))


# Path: tkp/telescope/lofar/quality.py
import logging
import tkp.db
import tkp.db.quality as dbquality
from tkp.quality.restoringbeam import beam_invalid
from tkp.quality.rms import rms_invalid, rms_with_clipped_subregion
from tkp.telescope.lofar.noise import noise_level
from tkp.utility import nice_format


logger = logging.getLogger(__name__)


def reject_check_lofar(accessor, job_config):

    lofar_quality_params = job_config['quality_lofar']
    quality_params = job_config['quality']

    low_bound = lofar_quality_params['low_bound']
    high_bound = lofar_quality_params['high_bound']
    oversampled_x = quality_params['oversampled_x']
    elliptical_x = quality_params['elliptical_x']
    min_separation = lofar_quality_params['min_separation']

    if accessor.tau_time == 0:
        logger.info("image %s REJECTED: tau_time is 0, should be > 0" % accessor.url)
        return dbquality.reject_reasons['tau_time'], "tau_time is 0"

    rms_est_sigma = job_config.persistence.rms_est_sigma
    rms_est_fraction = job_config.persistence.rms_est_fraction
    rms_qc = rms_with_clipped_subregion(accessor.data,
                                        rms_est_sigma=rms_est_sigma,
                                        rms_est_fraction=rms_est_fraction)

    noise = noise_level(accessor.freq_eff, accessor.freq_bw, accessor.tau_time,
        accessor.antenna_set, accessor.ncore, accessor.nremote, accessor.nintl
    )

    rms_check = rms_invalid(rms_qc, noise, low_bound, high_bound)