"""Expanded and refined local position profile on a fixed sparse GPI measurement."""
import numpy as np
from gpi_reduction import sky_measurements,real_comparison,real_response
from imaging_reduction import fit_spectrum

def position_profile(data,dataset,images,separation,pa,algorithm):
    observed=sky_measurements(images,separation,pa,spatial=True)
    mean,covariance,angles=real_comparison(images,separation,pa,spatial=True)
    points={}
    def evaluate(trial_separation,trial_pa,stage):
        coordinates=(float(trial_separation),float(trial_pa))
        if coordinates in points:return points[coordinates]
        response=real_response(data,dataset,*coordinates,separation,pa,algorithm,spatial=True)
        result=fit_spectrum(observed-mean,response,covariance)
        point={'separation_mas':coordinates[0],'pa_degrees':coordinates[1],
            'chi_square':result['chi_square'],'negative2loglikelihood':result['negative2loglikelihood'],
            'contrast':result['contrast'],'stage':stage}
        points[coordinates]=point
        return point
    separations=np.arange(400.,461.,10.)
    position_angles=np.arange(205.6,217.7,2.)
    for trial_separation in separations:
        for trial_pa in position_angles:evaluate(trial_separation,trial_pa,'expanded')
    expanded_best=min(points.values(),key=lambda point:point['negative2loglikelihood'])
    expanded_boundary=expanded_best['separation_mas']in(separations[0],separations[-1])or expanded_best['pa_degrees']in(position_angles[0],position_angles[-1])
    for delta_separation in (-5.,-2.5,0.,2.5,5.):
        for delta_pa in (-1.,-.5,0.,.5,1.):
            evaluate(expanded_best['separation_mas']+delta_separation,expanded_best['pa_degrees']+delta_pa,'refined')
    best=min(points.values(),key=lambda point:point['negative2loglikelihood'])
    refined_boundary=abs(best['separation_mas']-expanded_best['separation_mas'])==5.0 or abs(best['pa_degrees']-expanded_best['pa_degrees'])==1.0
    return {'status':'available','patch_count':len(angles),'dimension':30,
        'rank':int(np.linalg.matrix_rank(covariance)),'condition':float(np.linalg.cond(covariance)),
        'measurement_roi':{'separation_mas':separation,'pa_degrees':pa,'origin':'Disclosed historical ROI; held fixed for all measurements/covariance.'},
        'expanded_grid':{'separation_mas':separations.tolist(),'pa_degrees':position_angles.tolist()},
        'expanded_minimum':expanded_best,'expanded_minimum_on_boundary':bool(expanded_boundary),
        'refined_minimum_on_boundary':bool(refined_boundary),'minimum':best,'points':list(points.values()),
        'interpretation':'Working Gaussian profile with one fixed empirical covariance and its log determinant. Expanded/refined grid minima are diagnostics, not calibrated astrometric intervals or a posterior.'}
