#!/usr/bin/env python3
# encoding: utf-8
# Author: Akke Viitanen
# Email: akke.viitanen@helsinki.fi
# Date: 2023-07-18 16:35:28

"""
LSST-specific settings and constants.

https://www.lsst.org/scientists/keynumbers
"""


import argparse
import glob
import math
import os
import random
import re
import subprocess
import sys
import time

import astropy as ap
import astropy.coordinates as c
import astropy.units as u
import fitsio
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import scipy as sp


# zeropoint
# NOTE: the values reported in the key numbers or smtn-002 appear too faint...
# The numbers listed below
#zeropoint = {
#    "u":   27.03,
#    "g":   28.38,
#    "r":   28.16,
#    "i":   27.85,
#    "z":   27.46,
#    "y":   26.68,
#}
zeropoint = {
    "u": 26.7899838658703,
    "g": 28.6422348533437,
    "r": 28.4762158877359,
    "i": 28.150403321047,
    "z": 27.7604119423889,
    "y": 26.9342790022924,
}

# Filter
filter_lam_fwhm = {
    "u": (0.368483, 0.0516),
    "g": (0.480199, 0.146),
    "r": (0.623119, 0.1354),
    "i": (0.754169, 0.1246),
    "z": (0.869047, 0.1024),
    "y": (0.973638, 0.0892),
}

# Seeing
seeing = {
    "u": 0.92,
    "g": 0.87,
    "r": 0.83,
    "i": 0.80,
    "z": 0.78,
    "y": 0.76,
}

# Sky brightness
sky = {
    "u": 22.96,
    "g": 22.26,
    "r": 21.20,
    "i": 20.48,
    "z": 19.60,
    "y": 18.61,
}

# Example LSST psf files
psf = {
    "u": "data/lsst/660230_144_u_psf.fits",
    "g": "data/lsst/781365_170_g_psf.fits",
    "r": "data/lsst/755161_141_r_psf.fits",
    "i": "data/lsst/654496_187_i_psf.fits",
    "z": "data/lsst/707614_42_z_psf.fits",
    "y": "data/lsst/647542_93_y_psf.fits",
}

# Limiting magnitudes
limiting_magnitude_30s = {
    "u": 23.80,
    "g": 24.50,
    "r": 24.03,
    "i": 23.41,
    "z": 22.74,
    "y": 22.96,
}

limiting_magnitude_10yr = {
    "u": 25.6,
    "g": 26.9,
    "r": 26.9,
    "i": 26.4,
    "z": 25.6,
    "y": 24.8,
}

# Number of visits
visit = {k: v for k, v in zip("ugrizy", [56, 80, 184, 184, 160, 160])}

# Filter transmission curves
from util import ROOT
_f = [fitsio.read(f"{ROOT}/opt/egg/share/filter-db/inaf/LSST_LSST.{b}.fits") for b in "ugrizy"]
lam_fil = {k: (v["LAM"][0], v["RES"][0]) for k, v in zip("ugrizy", _f)}


# Reference: baseline v3.4 http://astro-lsst-01.astro.washington.edu:8080/allMetricResults?runId=4#QSO_Number
# (2024-04-11)
qso_number_counts_cosmos = {
    "u": 8894,
    "g": 11763,
    "r": 13406,
    "i": 14569,
    "z": 14431,
    "y": 15500,
}

limiting_magnitude_cosmos = {
    "u":  26.92,
    "g":  28.55,
    "r":  28.55,
    "i":  28.17,
    "z":  27.67,
    "y":  26.24,
}

def get_conf(zeropoint, lam, seeing, sky, psf):
    return f"""\
IMAGE_TYPE         SKY
GAIN               1.0
WELL_CAPACITY      0
SATUR_LEVEL        1e9
READOUT_NOISE      12.7
#READOUT_NOISE      0.0
EXPOSURE_TIME      30.0
MAG_ZEROPOINT      {zeropoint}
PIXEL_SIZE         0.20
PSF_TYPE           FILE
PSF_NAME           {psf}
SEEING_FWHM        {seeing}
AUREOLE_RADIUS     0
PSF_OVERSAMP       1
M1_DIAMETER        8.40
M2_DIAMETER        3.42
WAVELENGTH         {lam}
#BACK_MAG           {sky}
BACK_MAG           99.00
STARCOUNT_ZP       0
VERBOSE_TYPE       FULL
NTHREADS           4"""


def get_psf(band):
    """Return the mock DP0.2 PSF for the given band"""
    return fitsio.read(psf[band])


def main():
    """Write the skymaker configuration files for LSST"""
    for band in 'ugrizy':
        conf = get_conf(
            zeropoint[band],
            filter_lam_fwhm[band][0],
            seeing[band],
            sky[band],
            psf[band],
        )
        filename = f"{band}.conf"
        print("Writing", filename)
        print(conf, file=open(filename, 'w'))


def get_detector(detector):

    R = (
        list(range( 1,  4)) +
        list(range(10, 15)) +
        list(range(20, 25)) +
        list(range(30, 35)) +
        list(range(41, 44))
    )[detector // 9]

    # NOTE: S is in base 3
    S = detector % 9
    S = 10 * (S // 3) + (S % 3)
    return "R%02d_S%02d" % (R, S)

if __name__ == "__main__":
    main()
