# pynot-instrument-module
"""
Instrument definitions for IFAS student
"""
import numpy as np
import os
import datetime
from os.path import dirname, abspath
from astropy.io import fits
from astropy.table import Table

name = 'ifas'

# absolute path from code directory [DO NOT CHANGE]
path = dirname(abspath(__file__))

# path to classification rules:
rulefile = os.path.join(path, 'data/alfosc.rules')

# path to extinction table:
extinction_fname = os.path.join(path, 'calib/lapalma.ext')

# path to filter names:
filter_table_fname = os.path.join(path, 'calib/alfosc_filters.dat')

# Automatically assign arc-line list:
def auto_linelist(hdr):
    return ''

grism_translate = {'Grism_1' : 'india-gr1'}

slits = ['slit_1.0']

filter_table = Table.read(filter_table_fname, format='ascii.fixed_width')
filter_translate = {long: short for long, short in filter_table['name', 'short_name']}


# Helper functions
def get_header(fname):
    with fits.open(fname) as hdu:
        primhdr = hdu[0].header
        if len(hdu) > 1:
            imghdr = hdu[1].header
            primhdr.update(imghdr)
    return primhdr


def create_pixel_array(hdr, axis):
    """Load reference array from header using CRVAL, CDELT, CRPIX along dispersion axis"""
    if axis not in [1, 2]:
        raise ValueError("Axis must be 1 (X-axis) or 2 (Y-axis)!")
    N = hdr['NAXIS%i' % axis]
    pix_array = np.arange(N)
    return pix_array


def overscan():
    prescan_x = 1
    overscan_x = 1
    prescan_y = 0
    overscan_y = 1
    return (prescan_x, overscan_x, prescan_y, overscan_y)

def get_ccd_extent():
    return (2048, 2048)

def get_detector_arrays(hdr):
    nx = hdr['NAXIS1']
    ny = hdr['NAXIS2']
    xbin = get_binx(hdr)
    ybin = get_biny(hdr)
    X = np.arange(1*xbin, nx*xbin+1, xbin)
    Y = np.arange(1*ybin, ny*ybin+1, ybin)
    return X, Y


def get_binning(fname):
    ccd_setup = "1x1_normal"
    return ccd_setup

def get_binning_from_hdr(hdr):
    ccd_setup = "1x1_normal"
    return ccd_setup

def get_saturation_level():
    # Get Saturation Level in Electrons
    return 113500

def get_binx(hdr):
    return hdr.get('XBINNING', 1)

def get_biny(hdr):
    return hdr.get('YBINNING', 1)

def set_binx(hdr, val):
    hdr['XBINNING'] = val
    return hdr

def set_biny(hdr, val):
    hdr['YBINNING'] = val
    return hdr

def get_filter_raw(hdr):
    return 'Open'

def get_filter(hdr):
    return 'Open'

def get_grism(hdr):
    return 'Grism_1'

def get_slit(hdr):
    return 'slit_1.0'

def get_airmass(hdr):
    """Return the average airmass at mid-exposure"""
    return 1.0

def get_exptime(hdr):
    # if EXPTIME is in the header, this should always be used!
    return hdr.get('EXPTIME')

def get_object(hdr):
    return hdr.get('OBJECT')

def get_target_name(hdr):
    return hdr.get('TARGET')

def get_rotpos(hdr):
    return hdr.get('ROTPOS', 0)

def get_date(hdr):
    return hdr['DATE-OBS']

def get_mjd(hdr):
    """Input Date String in ISO format as in ALFOSC header: '2016-08-01T16:03:57.796'"""
    date_str = get_date(hdr)
    date = datetime.datetime.fromisoformat(date_str)
    mjd_0 = datetime.datetime(1858, 11, 17)
    dt = date - mjd_0
    mjd = dt.days + dt.seconds/(24*3600.)
    return mjd

def get_observing_mode(hdr):
    """Determine the observing mode (either spectroscopy or imaging)"""
    return 'SPECTROSCOPY'

def get_ob_name(hdr):
    date = hdr['DATE-OBS']
    date = date.split('.')[0]
    ob_id = date.replace(':', '_')
    return ob_id

def get_dispaxis(hdr):
    return 1

def get_gain(hdr):
    GAIN = 1.
    return GAIN

def get_readnoise(hdr):
    return 1.

