[enhancement] improved functionality and flexibility of PDFstatistics class
This commit is contained in:
parent
c500f1b8bb
commit
f428a72e86
@ -12,6 +12,7 @@ from obspy import read_events
|
|||||||
|
|
||||||
from pylot.core.io.phases import picksdict_from_picks
|
from pylot.core.io.phases import picksdict_from_picks
|
||||||
from pylot.core.util.pdf import ProbabilityDensityFunction
|
from pylot.core.util.pdf import ProbabilityDensityFunction
|
||||||
|
from pylot.core.util.utils import find_in_list
|
||||||
from pylot.core.util.version import get_git_version as _getVersionString
|
from pylot.core.util.version import get_git_version as _getVersionString
|
||||||
|
|
||||||
__version__ = _getVersionString()
|
__version__ = _getVersionString()
|
||||||
@ -356,9 +357,9 @@ class PDFstatistics(object):
|
|||||||
|
|
||||||
def __init__(self, directory):
|
def __init__(self, directory):
|
||||||
"""Initiates some values needed when dealing with pdfs later"""
|
"""Initiates some values needed when dealing with pdfs later"""
|
||||||
self.directory = directory
|
self._rootdir = directory
|
||||||
self.evtlist = list()
|
self._evtlist = list()
|
||||||
self.return_phase = None
|
self._rphase = None
|
||||||
self.make_fnlist()
|
self.make_fnlist()
|
||||||
|
|
||||||
def make_fnlist(self, fn_pattern='*.xml'):
|
def make_fnlist(self, fn_pattern='*.xml'):
|
||||||
@ -368,136 +369,97 @@ class PDFstatistics(object):
|
|||||||
:type fn_pattern: string
|
:type fn_pattern: string
|
||||||
:return: creates a list of events saved in the PDFstatistics object.
|
:return: creates a list of events saved in the PDFstatistics object.
|
||||||
"""
|
"""
|
||||||
evtlist = glob.glob1((os.path.join(self.directory)), fn_pattern)
|
evtlist = list()
|
||||||
if not evtlist:
|
for root, _, files in os.walk(self.root):
|
||||||
for root, _, files in os.walk(self.directory):
|
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.endswith(fn_pattern[1:]):
|
if file.endswith(fn_pattern[1:]):
|
||||||
evtlist.append(os.path.join(root, file))
|
evtlist.append(os.path.join(root, file))
|
||||||
self.evtlist = evtlist
|
self._evtlist = evtlist
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Iterating over the PDFstatistics object yields every single pdf from the list of events"""
|
for evt in self._evtlist:
|
||||||
assert isinstance(self.return_phase, str), 'phase has to be set before being able to iterate over items...'
|
yield PDFDictionary.from_quakeml(evt)
|
||||||
for evt in self.evtlist:
|
|
||||||
self.getPDFDict(self.directory, evt)
|
|
||||||
for station, pdfs in self.pdfdict.pdf_data.items():
|
|
||||||
try:
|
|
||||||
yield pdfs[self.return_phase]
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
def set_return_phase(self, type):
|
def __getitem__(self, item):
|
||||||
|
evt = find_in_list(self._evtlist, item)
|
||||||
|
if evt:
|
||||||
|
return PDFDictionary.from_quakeml(evt)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def root(self):
|
||||||
|
return self._rootdir
|
||||||
|
|
||||||
|
@root.setter
|
||||||
|
def root(self, value):
|
||||||
|
if os.path.exists(value):
|
||||||
|
self._rootdir = value
|
||||||
|
else:
|
||||||
|
raise ValueError("path doesn't exist: %s" % value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def curphase(self):
|
||||||
"""
|
"""
|
||||||
Sets the phase typ of event data that is returned on iteration over the object.
|
return the current phase type of interest
|
||||||
:param type: can be either p (p-phase) or s (s-phase).
|
:return: current phase
|
||||||
:type type: string
|
"""
|
||||||
|
return self._rphase
|
||||||
|
|
||||||
|
@curphase.setter
|
||||||
|
def curphase(self, type):
|
||||||
|
"""
|
||||||
|
setter method for property curphase
|
||||||
|
:param type: specify the phase type of interest
|
||||||
|
:type type: string ('p' or 's')
|
||||||
:return: -
|
:return: -
|
||||||
"""
|
"""
|
||||||
if type.upper() not in 'PS':
|
if type.upper() not in 'PS':
|
||||||
raise ValueError("phase type must be either 'P' or 'S'!")
|
raise ValueError("phase type must be either 'P' or 'S'!")
|
||||||
else:
|
else:
|
||||||
self.return_phase = type.upper()
|
self._rphase = type.upper()
|
||||||
|
|
||||||
def quantile_distances(self, value):
|
def get(self, property='std', value=None):
|
||||||
"""
|
"""
|
||||||
takes a probability value and and returns the distance
|
takes a property str and a probability value and returns all
|
||||||
between two complementary quantiles
|
property's values for the current phase of interest
|
||||||
|
:func:`self.curphase`
|
||||||
.. math::
|
|
||||||
|
|
||||||
QA_\alpha = Q(1 - \alpha) - Q(\alpha)
|
|
||||||
|
|
||||||
|
:param property: property name (default: 'std')
|
||||||
|
:type property: str
|
||||||
:param value: probability value :math:\alpha
|
:param value: probability value :math:\alpha
|
||||||
:type value: float
|
:type value: float
|
||||||
:return: list of all quantile distances for all pdfs in
|
:return: list containing all property's values
|
||||||
the list of events.
|
|
||||||
"""
|
"""
|
||||||
|
assert isinstance(self.curphase,
|
||||||
|
str), 'phase has to be set before being ' \
|
||||||
|
'able to iterate over items...'
|
||||||
rlist = []
|
rlist = []
|
||||||
for pdf in self:
|
method_options = dict(STD='standard_deviation',
|
||||||
rval = pdf.quantile_distance(value)
|
Q='quantile',
|
||||||
rlist.append(rval)
|
QD='quantile_distance',
|
||||||
return rlist
|
QDF='quantile_dist_frac')
|
||||||
|
|
||||||
|
# create method caller for easy mapping
|
||||||
def quantile_distance_fractions(self, value):
|
if property.upper() == 'STD':
|
||||||
"""
|
method = operator.methodcaller(method_options[property.upper()])
|
||||||
takes a probability value and returns the fraction of two
|
elif value is not None:
|
||||||
corresponding quantile distances
|
|
||||||
|
|
||||||
.. math::
|
|
||||||
|
|
||||||
Q\Theta_\alpha = \frac{QA(0.5 - \alpha)}{QA(\alpha)}
|
|
||||||
|
|
||||||
:param value: probability value :math:\alpha
|
|
||||||
:return: returns a list of all quantile fractions for all pdfs in
|
|
||||||
the list of events.
|
|
||||||
"""
|
|
||||||
rlist = list()
|
|
||||||
for pdf in self:
|
|
||||||
rval = pdf.quantile_dist_frac(value)
|
|
||||||
rlist.append(rval)
|
|
||||||
return rlist
|
|
||||||
|
|
||||||
|
|
||||||
def getSTD(self):
|
|
||||||
"""
|
|
||||||
Iterates over PDFstatistics object and returns the standard
|
|
||||||
deviation of all pdfs in the list of events.
|
|
||||||
:return: saves an instance of self.p_stdarray or
|
|
||||||
self.s_stdarray, depending on set phase.
|
|
||||||
"""
|
|
||||||
std = []
|
|
||||||
for pdf in self:
|
|
||||||
try:
|
try:
|
||||||
std.append(pdf.standard_deviation())
|
method = operator.methodcaller(method_options[property.upper()],
|
||||||
|
value)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
continue
|
raise KeyError('unknwon property: {0}'.format(property.upper()))
|
||||||
std = np.array(std)
|
|
||||||
self.set_stdarray(std)
|
|
||||||
|
|
||||||
|
|
||||||
def set_stdarray(self, array):
|
|
||||||
"""
|
|
||||||
Helper function for self.getSTD(). This function
|
|
||||||
should not be called directly.
|
|
||||||
"""
|
|
||||||
if self.return_phase == 'P':
|
|
||||||
self.p_stdarray = array
|
|
||||||
elif self.return_phase == 'S':
|
|
||||||
self.s_stdarray = array
|
|
||||||
else:
|
else:
|
||||||
raise ValueError('phase type not set properly...\n'
|
raise ValueError("for call to method {0} value has to be "
|
||||||
'Actual phase type: {0}'.format(self.return_phase))
|
"defined but is 'None' ".format(method_options[
|
||||||
|
property.upper()]))
|
||||||
|
|
||||||
|
for pdf_dict in self:
|
||||||
|
# create worklist
|
||||||
|
wlist = pdf_dict.get_all(self.curphase)
|
||||||
|
# map method calls to object in worklist
|
||||||
|
rlist += map(method, wlist)
|
||||||
|
|
||||||
def getPDFDict(self, month, evt):
|
return rlist
|
||||||
"""
|
|
||||||
Helper function for __iter__(). Should not be called directly.
|
|
||||||
"""
|
|
||||||
self.pdfdict = PDFDictionary.from_quakeml(os.path.join(self.directory,month,evt))
|
|
||||||
|
|
||||||
|
|
||||||
def getStatistics(self):
|
|
||||||
"""
|
|
||||||
On call function will get mean, median and standard deviation values
|
|
||||||
from self.p_stdarray and self.s_stdarray. Both must be
|
|
||||||
instances before calling this function.
|
|
||||||
:return: Creates instances of self.p_mean, self.p_std_std and self.p_median
|
|
||||||
for both phases (simultaneously) for the PDFstatistics object.
|
|
||||||
"""
|
|
||||||
if not self.p_stdarray or not self.s_stdarray:
|
|
||||||
raise NotImplementedError('Arrays are not properly set yet!')
|
|
||||||
elif type(self.p_stdarray) != type(np.zeros(1)) or type(self.s_stdarray) != type(np.zeros(1)):
|
|
||||||
raise TypeError('Array is not a proper numpy array.')
|
|
||||||
|
|
||||||
self.p_mean = self.p_stdarray.mean()
|
|
||||||
self.p_std_std = self.p_stdarray.std()
|
|
||||||
self.p_median = np.median(self.p_stdarray)
|
|
||||||
self.s_mean = self.s_stdarray.mean()
|
|
||||||
self.s_std_std = self.s_stdarray.std()
|
|
||||||
self.s_median = np.median(self.s_stdarray)
|
|
||||||
|
|
||||||
|
|
||||||
def writeThetaToFile(self,array,out_dir):
|
def writeThetaToFile(self,array,out_dir):
|
||||||
"""
|
"""
|
||||||
@ -518,10 +480,8 @@ class PDFstatistics(object):
|
|||||||
def main():
|
def main():
|
||||||
root_dir ='/home/sebastianp/Codetesting/xmls/'
|
root_dir ='/home/sebastianp/Codetesting/xmls/'
|
||||||
Insheim = PDFstatistics(root_dir)
|
Insheim = PDFstatistics(root_dir)
|
||||||
Insheim.make_fnlist()
|
Insheim.curphase = 'p'
|
||||||
Insheim.set_return_phase('p')
|
qdlist = Insheim.get('qdf', 0.2)
|
||||||
Insheim.getSTD()
|
|
||||||
qdlist = Insheim.quantile_distance_fractions(0.2)
|
|
||||||
print qdlist
|
print qdlist
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user