Source code for jetset.loglog_poly_model



__author__ = "Andrea Tramacere"

from .model_parameters import ModelParameterArray, ModelParameter
from .base_model import Model

from .spectral_shapes import SED

from numpy import log10,power,sqrt,shape,zeros

import numpy as np

from numpy import polyfit,polyval,polyder


__all__=['find_max_cubic','LogCubic','LogLinear','LogLogModel','LogParabolaEp','LogParabolaPL','PolyParameter']

[docs] class PolyParameter(ModelParameter): """ This class is a subclass of the :class:`.ModelParameter` class, extending the base class to loglog polynomial parameters. """ def __init__(self,polymodel,**keywords): self.polymodel=polymodel self.allowed_par_types=['curvature','peak freq','peak flux','third-degree','spectral-slope','flux-const','turn-over freq'] super(PolyParameter,self).__init__( **keywords) if 'val' in keywords.keys(): val=keywords['val'] self.assign_val(self.name,val)
[docs] def set(self,**keywords): super(PolyParameter,self).set(**keywords ) """ sets a parameter value checking for physical boundaries """ if 'val' in keywords.keys(): self.assign_val(self.name,keywords['val'])
[docs] def assign_val(self,name,val): setattr(self.polymodel,name,val)
[docs] class LogLogModel(Model): def __init__(self,nu_size=100, **keywords): super(LogLogModel,self).__init__(**keywords) self.model_type='LogLogModel'
[docs] def lin_func(self,nu): nu_log=np.log10(nu) return np.power(10.0,self.log_func(nu_log))
[docs] class LogLinear(LogLogModel): """ Class to handle log-linear model """ def __init__(self,nu_size=100,**keywords): """ """ super(LogLinear,self).__init__( **keywords) self.name='LogLinear' self.SED = SED(name=self.model_type) self.parameters = ModelParameterArray() self.alpha=-1.0 self.parameters.add_par(PolyParameter(self,name='alpha',par_type='spectral-slope',val=-1.0,val_min=-10.,val_max=10.,units='')) self.K=-10 self.parameters.add_par(PolyParameter(self,name='K',par_type='flux-const',val=-10.0,val_min=None,val_max=None,units='erg cm^-2 s^-1',log=True))
[docs] def log_func(self,log_nu): #x_log=log_nu #print(x_log) #print self.Ep,self.Sp,self.b,self.c,x_log return self.K + self.alpha*(log_nu)
[docs] class LogParabolaEp(LogLogModel): """ Class to handle log-parabolic model """ def __init__(self,nu_size=100, **keywords): """ """ super(LogParabolaEp,self).__init__( **keywords) self.name='LogParabolaEp' self.SED = SED(name=self.model_type) self.parameters = ModelParameterArray() self.b=-1.0 self.parameters.add_par(PolyParameter(self,name='b',par_type='curvature',val=-1.0,val_min=-10.,val_max=10.,units='')) self.Ep=14.0 self.parameters.add_par(PolyParameter(self,name='Ep',par_type='peak freq',val=14.0,val_min=0.,val_max=30.,units='Hz',log=True)) self.Sp=-10 self.parameters.add_par(PolyParameter(self,name='Sp',par_type='peak flux',val=-10.0,val_min=-30.,val_max=0.,units='erg cm^-2 s^-1',log=True))
[docs] def log_func(self,log_nu): x_log=log_nu-self.Ep return self.Sp + self.b*(x_log*x_log)
[docs] class LogParabolaPL(LogLogModel): """ Class to handle a log-par + pl model """ def __init__(self,nu_size=100,**keywords): """ """ super(LogParabolaPL,self).__init__( **keywords) self.name='LogParabolaPL' self.SED = SED(name=self.model_type) self.parameters = ModelParameterArray() self.b=-1.0 self.parameters.add_par(PolyParameter(self,name='b',par_type='curvature',val=-1.0,val_min=-10.,val_max=10.,units='')) self.E0=14.0 self.parameters.add_par(PolyParameter(self,name='E0',par_type='turn-over freq',val=14.0,val_min=0.,val_max=30.,units='Hz',log=True)) self.alpha=0.5 self.parameters.add_par(PolyParameter(self,name='alpha',par_type='spectral-slope',val=0.5,val_min=-10.,val_max=10.,units='')) self.K=-10 self.parameters.add_par(PolyParameter(self,name='K',par_type='flux-const',val=-10.0,val_min=-30.,val_max=0.,units='erg cm^-2 s^-1',log=True))
[docs] def log_func(self,log_nu): #TODO fix this to numpy array function if shape(log_nu)==(): return self.composite_func(log_nu) else: y_log=zeros(log_nu.size) for i in range(log_nu.size): y_log[i]=self.composite_func(log_nu[i]) return y_log
[docs] def composite_func(self,log_nu): x_log=log_nu-self.E0 if log_nu >= self.E0: return self.K + x_log*(self.alpha + self.b*x_log) else: return self.K + x_log*self.alpha
[docs] class LogCubic(LogLogModel): """ Class to handle log-cubic model """ def __init__(self,nu_size=100, **keywords): """ """ super(LogCubic,self).__init__( **keywords) self.name='LogCubic' self.SED = SED(name=self.model_type) self.parameters = ModelParameterArray() self.b=-1.0 self.parameters.add_par(PolyParameter(self,name='b',par_type='curvature',val=-1.0,val_min=-10.,val_max=10.,units='')) self.c=0.0 self.parameters.add_par(PolyParameter(self,name='c',par_type='third-degree',val=-1.0,val_min=-10.,val_max=10.,units='')) self.Ep=14.0 self.parameters.add_par(PolyParameter(self,name='Ep',par_type='peak freq',val=14.0,val_min=0.,val_max=30.,units='Hz',log=True)) self.Sp=-10 self.parameters.add_par(PolyParameter(self,name='Sp',par_type='peak flux',val=-10.0,val_min=-30.,val_max=0.,units='erg cm^-2 s^-1',log=True))
[docs] def log_func(self,log_nu): x_log=log_nu-self.Ep #print self.Ep,self.Sp,self.b,self.c,x_log return self.Sp + self.b*(x_log*x_log)+ self.c*(x_log*x_log*x_log)
[docs] def find_max_cubic(x_log,y_log,x_range=None): if x_range is not None: msk = x_log >x_range[0] msk*= x_log <x_range[1] x_log=x_log[msk] y_log=y_log[msk] p=polyfit(x_log,y_log,3) der=polyder(p,1) delta=der[1]*der[1] -(4*der[0]*der[2]) if delta>=0: #print p,der root1=(-der[1]+sqrt(delta))/(2*der[0]) root2=(-der[1]-sqrt(delta))/(2*der[0]) #print root1,root2 if der[0]>0: xp=min(root1,root2) else: xp=max(root1,root2) return xp else: print("!!! no maxima found for cubic fit") return None