Source code for avni.models.radial_basis

#!/usr/bin/env python
"""This script/module contains routines that are used to analyze/visualize the data sets in the standard AVNI format."""
#####################  IMPORT STANDARD MODULES   ######################################
# python 3 compatibility
from __future__ import absolute_import, division, print_function

import numpy as np #for numerical analysis

####################### IMPORT AVNI LIBRARIES  #######################################

from .. import tools
from .. import constants

#######################################################################################

# Vertical basis parameter class that defines an unique combination of functions, their radial parameterization

[docs]class Radial_basis(object): """A class for radial bases that defines a unique combination of parameters, their radial parameterization and any scaling that is used. Parameters ---------- object : _type_ object.data - Contains the following fields that describe the radial basis. depths_in_km: depth array in km vercof: value of the bases evaluated at those depths dvercof: gradient of the bases evaluated at those depths object.metadata: Contains metadata for various calculations. name: to store a name for the radial_basis type: type of radial basis e.g. vbspl attributes: a dictionary containing variables used to define this particular type e.g. knots for vbspl. Checked that these are defined using self.check. """ ######################### magic ########################## def __init__(self,name,types,metadata=None): self.data = {} self.data['depths_in_km'] = None self.data['vercof'] = None self.data['dvercof'] = None self._name = name self._type = types if metadata is None: self.metadata = {} else: self.metadata = metadata # Check if all required atributes are available self.check() def __eq__(self, other): if not isinstance(other,Radial_basis): return False # convert to array to allow multiple lateral bases to be compared result = np.ones_like(other, dtype=bool) # check if the instances have all required metadata self.check() try: other.check() except AttributeError: # if either is not this class instance return False # check type if self._type != other._type: return False # check all keys for key in self.keys: if not np.array_equal(self.metadata[key],other.metadata[key]): return False # assume equal otherwise return True def __repr__(self): return '{self.__class__.__name__}({self._name})'.format(self=self) def __getitem__(self,key): """returns metadata from key""" return self.metadata[key] def __setitem__(self,key,data): """sets data to key""" self.metadata[key] = data ######################### decorators ########################## @property def type(self): return self._type @property def name(self): return self._name @property def keys(self): return self.metadata.keys() ######################### methods #############################
[docs] def add_attribute(self,key,value): """ Add attributes needed by the radial basis Input parameters: ---------------- key: string key name value: values corresponding to the key """ self.metadata[key] = value
[docs] def check(self): """ Checks that object contains all attributes required for evaluating a particular basis set. """ if self._type in ['vbspl','variable splines']: for key in ['knots']: try: knots = self.metadata[key] except KeyError: print('Current attributes : ',self.keys) raise KeyError('Attribute '+key+' missing for radial basis type '+self._type) elif self._type in ['delta','dirac delta']: for key in ['info']: try: knots = self.metadata[key] except KeyError: print('Current attributes : ',self.keys) raise KeyError('Attribute '+key+' missing for radial basis type '+self._type) elif self._type in ['boxcar']: for key in ['depthtop','depthbottom']: try: knots = self.metadata[key] except KeyError: print('Current attributes : ',self.keys) raise KeyError('Attribute '+key+' missing for radial basis type '+self._type) else: raise TypeError('metadata type note defined in eval_radial %s' % self._type) return knots
[docs] def eval_radial(self,depths_in_km,store=False): """ Evaluates the radial bases at various depths. Input parameters: ---------------- depths_in_km: depths where the radial parameteriation needs to be evaluated. store: store them in data """ # convert to numpy arrays depths = tools.convert2nparray(depths_in_km) # compute the radial parameteriation in specific depths if self._type in ['vbspl','variable splines']: knots = self.metadata['knots'] vercof, dvercof = tools.eval_vbspl(depths,knots) elif self._type in ['delta','dirac delta']: vercof = np.ones((len(depths),1)) dvercof = np.zeros((len(depths),1)) elif self._type in ['boxcar','constant']: # convert to numpy arrays depthtop = tools.convert2nparray(self.metadata['depthtop']) depthbottom = tools.convert2nparray(self.metadata['depthbottom']) rtop = constants.R.to('km').magnitude - depthtop rbottom = constants.R.to('km').magnitude - depthbottom rquery = constants.R.to('km').magnitude - depths rrange = np.vstack((rbottom,rtop)).T vercof, dvercof = tools.eval_polynomial(rquery,rrange,constants.R.to('km').magnitude,types = ['CONSTANT']) else: raise TypeError('metadata type not defined in eval_radial %s' % self._type) # Store if needed if store: self.data['vercof'] = vercof self.data['dvercof'] = dvercof self.data['depths_in_km'] = depths else: return vercof,dvercof