Source code for lenstools.index

"""

.. module:: index 
	:platform: Unix
	:synopsis: This module implements a set of useful indexing operations useful for analyses with multiple statistical descriptors


.. moduleauthor:: Andrea Petri <[email protected]>


"""

from abc import ABCMeta
from abc import abstractproperty

#######################################################
######Individual descriptor classes####################
#######################################################

class Descriptor(object):
	__metaclass__ = ABCMeta

	def __init__(self):
		self._first = None
		self._last = None
		self._start = 0

	@abstractproperty
	def first(self):
		pass

	@abstractproperty
	def last(self):
		pass

[docs]class PowerSpectrum(Descriptor): """ Power spectrum indexing class :param l_edges: bin edges of multipole moments :type l_edges: array """ name = "power_spectrum" def __init__(self,l_edges): super(PowerSpectrum,self).__init__() self.l_edges = l_edges self.l = 0.5*(l_edges[:-1] + l_edges[1:]) def __repr__(self): return "Power Spectrum descriptor: {0} bins\nEdges: {1}\nMidpoints{2}".format(len(self.l),self.l_edges.__str__(),self.l.__str__()) @property def first(self): self._first = self._start return self._first @property def last(self): self._last = self._start + len(self.l) return self._last
[docs]class Moments(Descriptor): """ Moments indexing class """ name = "moments" def __init__(self,connected=True,dimensionless=False): super(Moments,self).__init__() self.connected = connected self.dimensionless = dimensionless def __repr__(self): repr_str = "Moments descriptor: 2 quadratic moments, 3 cubic, 4 quartic" if self.connected: repr_str += "\nconnected: yes" else: repr_str += "\nconnected: no" if self.dimensionless: repr_str += "\ndimensionless: yes" else: repr_str += "\ndimensionless: no" return repr_str @property def first(self): self._first = self._start return self._first @property def last(self): self._last = self._start + 9 return self._last
[docs]class Peaks(Descriptor): """ Peaks histogram indexing class :param thresholds: peak histogram bin edges :type thresholds: array """ name = "peaks" def __init__(self,thresholds,norm=False): super(Peaks,self).__init__() self.thresholds = thresholds self.midpoints = 0.5*(thresholds[:-1] + thresholds[1:]) self.norm = norm def __repr__(self): if self.norm: answer = "yes" else: answer = "no" return "Peak count descriptor: {0} bins\nEdges: {1}\nMidpoints{2}\nThresholds in sigma units: {3}".format(len(self.midpoints),self.thresholds.__str__(),self.midpoints.__str__(),answer) @property def first(self): self._first = self._start return self._first @property def last(self): self._last = self._start + len(self.midpoints) return self._last
[docs]class MinkowskiSingle(Peaks): """ Single Minkowski functional indexing class, identical to Peaks """ name = "minkowski_single" def __repr__(self): if self.norm: answer = "yes" else: answer = "no" return "Minkowski functionals descriptor (single): {0} bins\nEdges: {1}\nMidpoints{2}\nThresholds in sigma units: {3}".format(len(self.midpoints),self.thresholds.__str__(),self.midpoints.__str__(),answer)
[docs]class PDF(Peaks): """ Probability density function indexing class, identical to Peaks """ name = "pdf"
[docs]class MinkowskiAll(Peaks): """ Minkowski functionals indexing class, inherits from Peaks; the add-ons are some methods that deal with the fact that there are 3 Minkowski functionals """ name = "minkowski_all" def __repr__(self): if self.norm: answer = "yes" else: answer = "no" return "Minkowski functionals descriptor (all): {0} bins\nEdges: {1}\nMidpoints{2}\nThresholds in sigma units: {3}".format(len(self.midpoints),self.thresholds.__str__(),self.midpoints.__str__(),answer) @property def last(self): self._last = self._start + 3*len(self.midpoints) return self._last def separate(self): """ Separates an MinkowskiAll index into 3 separate MinkowsiSingle indices, one for each Minkowski functional :returns: list of three MinkowskiSingle instances """ mink0 = MinkowskiSingle(self.thresholds) mink0._start = self._start mink1 = MinkowskiSingle(self.thresholds) mink1._start = self._start + len(self.midpoints) mink2 = MinkowskiSingle(self.thresholds) mink2._start = self._start + 2*len(self.midpoints) return [mink0,mink1,mink2] ################################### #####Global indexer################ ###################################
[docs]class Indexer(object): """ This class is useful for indexing an array of statistical descriptors that are hstacked together; the Indexer instance keeps track of the memory regions where the different descriptors are stored :param descriptor_list: list of Descriptor subinstances, such as PowerSpectrum; each of these sub instances must be a subclass of Descriptor with a 'first' and 'last' getter methods implemented :type descriptor_list: list. """ def __init__(self,descriptor_list): #Initialize index with descriptor list self.descriptor_list = descriptor_list self.num_descriptors = len(descriptor_list) @classmethod def stack(cls,descriptor_list): _last = 0 #Create an index of all the descriptor bounds by stacking the observables vectors for descriptor in descriptor_list: increment = descriptor.last - descriptor._start descriptor._start = _last _last += increment new_idx = cls(descriptor_list) setattr(new_idx,"_last",_last) return new_idx @property def size(self): if hasattr(self,"_last"): return self._last else: raise AttributeError("This index has not been created by stack() method, cannot determine size!") def __getitem__(self,n): """Allows to access the n-th descriptor by indexing""" return self.descriptor_list[n]