class Colors:
class msgs:
    def disable(self):
    def __init__(self):
    def alisheader(self, prognm, verbose=2):
    def signal_handler(self, signalnum, handler):
    def error(self, msg, verbose=None):
    def info(self, msg, verbose=None):
    def warn(self, msg, verbose=None):
    def test(self, msg, verbose=None):
    def bug(self, msg, verbose=None):
    def work(self, msg, verbose=None):
    def input(self):
    def newline(self,verbose=None):
    def indent(self,verbose=None): class BrokenPowerLaw(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class Chebyshev(alfunc_polynomial.Polynomial) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def call_GPU(self, x, p, ae='em'): class Constant(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def GPU_kernal(self):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None): class Gaussian(alfunc_base.Base) :
class GaussianConstant(alfunc_base.Base) :
class GaussianConstantHelium(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par, karr):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par, karr):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par, karr):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class Legendre(alfunc_polynomial.Polynomial) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def call_GPU(self, x, p, ae='em'): class Linear(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def GPU_kernal(self):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None): class PhotIon_CrossSection(alfunc_base.Base):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, wave, pin, ae='ab', mkey=None, ncpus=1):
        def calc_xsec(wave, zp1, vars):
        def model(par, karr):
    def load(self, instr, cntr, mp, specid):
        def check_tied_param(ival, cntr, mps, iind, parj):
    def load_xsec(self, ion):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False):
    def parout(self, params, mp, istart, level, errs=None, reletter=False, conv=None):
    def set_pinfo(self, pinfo, level, mp, lnk, mnum): class Polynomial(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def call_GPU(self, x, p, ae='em'):
    def adjust_fix(self, mp, cntr, jval, parj):
    def adjust_lim(self, mp, cntr, jval, jind, parj):
    def load(self, instr, cntr, mp, specid):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par, parb):
    def parout(self, params, mp, istart, level, errs=None, reletter=False, conv=None):
    def set_pinfo(self, pinfo, level, mp, lnk, mnum):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class PowerLaw(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class Random(alfunc_base.Base):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='va', mkey=None, ncpus=1):
    def parin(self, i, par, parb, start=False):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False, start=False): class Spline(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par, karr):
    def call_GPU(self, x, p, ae='em'):
    def adjust_fix(self, mp, cntr, jval, parj):
    def adjust_lim(self, mp, cntr, jval, jind, parj):
    def load(self, instr, cntr, mp, specid):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par, parb):
    def parout(self, params, mp, istart, level, errs=None, reletter=False, conv=None):
    def set_pinfo(self, pinfo, level, mp, lnk, mnum):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class SplineAbs(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, wave, pin, ae='ab', mkey=None, ncpus=1):
        def model(par, karr):
    def load(self, instr, cntr, mp, specid):
        def check_tied_param(ival, cntr, mps, iind, parj):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False):
    def parout(self, params, mp, istart, level, errs=None, reletter=False, conv=None):
    def set_pinfo(self, pinfo, level, mp, lnk, mnum):
    def tick_info(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None): class ThAr(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def parin(self, i, par, parb):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class TopHat(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='em', mkey=None, ncpus=1):
        def model(par):
    def parin(self, i, par, parb):
    def set_pinfo(self, pinfo, level, mp, lnk, mnum):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class Variable(alfunc_base.Base):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ae='va', mkey=None, ncpus=1):
    def parin(self, i, par, parb):
    def set_pinfo(self, pinfo, level, mp, lnk, mnum):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False): class AFWHM(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, y, p, ncpus=1):
    def getminmax(self, par, fitrng, Nsig=5.0):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False, getstdd=None): class APOD(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, y, p, ncpus=1):
    def getfwhm(self):
    def getminmax(self, par, fitrng, Nsig=20.0):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False, getstdd=None): class LSF(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, y, p, ncpus=1):
    def getminmax(self, par, fitrng, Nsig=30.0):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None): class vFWHM(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, y, p, ncpus=1):
    def getminmax(self, par, fitrng, Nsig=10.0):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None): class VoigtConv(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, y, p, ncpus=1):
    def getminmax(self, par, fitrng, Nsig=10.0):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None): class vSigma(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, y, p, ncpus=1):
    def getminmax(self, par, fitrng, Nsig=10.0):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None): class Ashift(alfunc_base.Base) :
class vshift(alfunc_base.Base) :
class vshiftscale(alfunc_base.Base) :
class polyshift(alfunc_base.Base) :
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ncpus=1):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ncpus=1):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ncpus=1):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None):
    def __init__(self, prgname="", getinst=False, atomic=None, verbose=2):
    def call_CPU(self, x, p, ncpus=1):
    def load(self, instr, cntr, mp, specid, forcefix=False):
        def check_tied_param(ival, cntr, mps, iind):
    def parin(self, i, par):
    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, getinfl=False, ddpid=None, getstdd=None):
    def parout(self, params, mp, istart, level, errs=None, reletter=False, conv=None): def load_user_functions():
import numpy as np
import traceback
import sys
from alis import almsgs
from alis import alfunc_brokenpowerlaw
from alis import alfunc_chebyshev
from alis import alfunc_constant
from alis import alfunc_gaussian
from alis import alfunc_legendre
from alis import alfunc_linear
from alis import alfunc_lineemission
from alis import alfunc_phionxs
from alis import alfunc_polynomial
from alis import alfunc_powerlaw
from alis import alfunc_random
from alis import alfunc_spline
from alis import alfunc_splineabs
from alis import alfunc_thar
from alis import alfunc_tophat
from alis import alfunc_variable
from alis import alfunc_voigt
from alis import alfunc_afwhm
from alis import alfunc_apod
from alis import alfunc_lsf
from alis import alfunc_vfwhm
from alis import alfunc_voigtconv
from alis import alfunc_vsigma
from alis import alshift
from alis import alfunc_user
            # First Check if there are any operations/links to perform on this parameter
            if len(lnk['opA']) != 0:
                breakit=False
                for j in range(len(mp['tpar'])):
                    if breakit: break
                    if mp['tpar'][j][1] == level+levadd: # then this is a tied parameter
                        # Check if this tied parameter is to be linked to another parameter
                        for k in range(len(lnk['opA'])):
                            if mp['tpar'][j][0] == lnk['opA'][k]:
                                ttext = lnk['exp'][k]
                                for l in lnk['opB'][k]:
                                    for m in range(len(mp['tpar'])):
                                        if mp['tpar'][m][0] == l:
                                            pn = mp['tpar'][m][1]
                                            break
                                    ttext = ttext.replace(l,'p[{0:d}]'.format(pn))
                                pinfo[level+levadd]['tied'] = ttext
                                breakit = True
                                break
            # Now set limits and fixed values
            if mp['mtie'][mnum][i] >= 0: add -= 1
            elif mp['mtie'][mnum][i] <= -2:
                pinfo[level+levadd]['limited'] = [0 if o is None else 1 for o in mp['mlim'][mnum][i]]
                pinfo[level+levadd]['limits']  = [0.0 if o is None else np.float64(o) for o in mp['mlim'][mnum][i]]
                mp['mfix'][mnum][i] = -1
                levadd += 1
            else:
                pinfo[level+levadd]['limited'] = [0 if o is None else 1 for o in mp['mlim'][mnum][i]]
                pinfo[level+levadd]['limits']  = [0.0 if o is None else np.float64(o) for o in mp['mlim'][mnum][i]]
                pinfo[level+levadd]['fixed']   = mp['mfix'][mnum][i]
                levadd += 1
        return pinfo, add

    def set_vars(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None, nexbin=None, ddpid=None, getinfl=False):
        """
        Return the parameters for a Gaussian function to be used by 'call'
        The only thing that should be changed here is the parb values
        """
        levadd=0
        params=np.zeros(self._pnumr)
        parinf=[]
        for i in range(self._pnumr):
            lnkprm = None
            parb = dict({'ap_1a':self._keywd['wave'], 'ap_2a':params[1]})
            if mp['mtie'][ival][i] >= 0:
                getid = mp['tpar'][mp['mtie'][ival][i]][1]
            elif mp['mtie'][ival][i] <= -2:
                if len(mp['mlnk']) == 0:
                    lnkprm = mp['mpar'][ival][i]
                else:
                    for j in range(len(mp['mlnk'])):
                        if mp['mlnk'][j][0] == mp['mtie'][ival][i]:
                            cmd = 'lnkprm = ' + mp['mlnk'][j][1]
                            namespace = dict({'p': p})
                            exec(cmd, namespace)
                            lnkprm = namespace['lnkprm']
                levadd += 1
            else:
                getid = level+levadd
                levadd+=1
            if lnkprm is None:
                params[i] = self.parin(i, p[getid], parb)
                if mp['mfix'][ival][i] == 0: parinf.append(getid)
            else:
                params[i] = lnkprm
        if ddpid is not None:
            if ddpid not in parinf: return []
        if nexbin is not None:
            if params[2] == 0.0: msgs.error("Cannot calculate "+self._idstr+" subpixellation -- width = 0.0")
            if nexbin[0] == "km/s": return params, 1
            elif nexbin[0] == "A" : return params, 1
            else: msgs.bug("bintype "+nexbin[0]+" should not have been specified in model function: "+self._idstr, verbose=self._verbose)
        elif getinfl: return params, parinf
        else: return params

    def gtoef(self, num, fmt):
        """
        A definition to make the printout much nicer looking
        """
        return fmt.replace("g}","f}")+"    " if np.abs(np.log10(np.abs(num))) < 3. or num==0.0 else fmt.replace("g","E")

    def tick_info(self, p, level, mp, ival, wvrng=[0.0,0.0], spid='None', levid=None):
        """
        For a given model, determine the wavelengths that
        tick marks should be plotted, and the label that
        should be associated with this tick mark.
        By default, return no tick marks and no labels.
        """
        return [], []
#######################################################################################
#######################################################################################
#######################################################################################

# Import all of the functions used in alis
# Convolution+shifting routines

"""
Initialises the functions that are used in this file.
If you want your function to be recognised, you must
include it's idstr value and the function call here.
"""

def call(prgname="",getfuncs=False,getinst=False,atomic=None,verbose=2):
    sendatomic = ['voigt', 'lineemission', 'splineabs', 'phionxs']
    # Add your new function to the following:
    fd = dict({ 'Afwhm'          : alfunc_afwhm.AFWHM,
                'apod'           : alfunc_apod.APOD,
                'Ashift'         : alshift.Ashift,
                'brokenpowerlaw' : alfunc_brokenpowerlaw.BrokenPowerLaw,
                'chebyshev'      : alfunc_chebyshev.Chebyshev,
                'constant'       : alfunc_constant.Constant,
                'gaussian'       : alfunc_gaussian.Gaussian,
                'gaussianconst'  : alfunc_gaussian.GaussianConstant,
                'gaussianconsthelium'  : alfunc_gaussian.GaussianConstantHelium,
                'legendre'       : alfunc_legendre.Legendre,
                'linear'         : alfunc_linear.Linear,
                'lineemission'   : alfunc_lineemission.LineEmission,
                'phionxs'        : alfunc_phionxs.PhotIon_CrossSection,
                'polynomial'     : alfunc_polynomial.Polynomial,
                'polyshift'      : alshift.polyshift,

                'powerlaw'       : alfunc_powerlaw.PowerLaw,