"""
"""
from __future__ import division, absolute_import, print_function
__author__ = 'andrea tramacere'
import numpy as np
import copy
from ..coordinates.geometry_representation import GeomRepresentation,Representation2D
from ..observables.quantity import Quantity
from ..tools.tools import iter_input
from ..image_manager.image import Image
[docs]class EventTable(object):
def __init__(self,geom_represent,observables=[],IDs=None,ID_offset=None):
"""
EnvenTable class to store geometry representations with observables/features
Args:
geom_represent:
observables:
IDs:
ID_offset:
Returns:
"""
if observables==[]:
raise ValueError("you have to provide at leas one observable instance")
self._geom_represent=[]
self._observables=[]
self._add_geom_representation(geom_represent)
self._add_observable(observables)
self._check_shape_consistency()
self._set_IDs(IDs,ID_offset)
def _check_shape_consistency(self,check=None):
"""
check that shapes each table column is compatible
Args:
check:
Returns:
"""
if check is None:
check=self._observables
if type(check) != list:
check=[check]
for obj_to_check in check:
if len(obj_to_check.shape)==0:
if len(self.geom_represent.shape)==0:
self._Nevts=1
else:
raise RuntimeError("shape of %s and %s do not match"%(obj_to_check.__class__,))
if len(obj_to_check.shape)>0:
for g_repr in self._geom_represent:
if g_repr.shape[0]==obj_to_check.shape[0]:
self._Nevts=g_repr.shape[0]
else:
raise RuntimeError("shape of %s and %s do not match"%(obj_to_check.__class__,g_repr.__class__))
def __repr__(self,hide_values=True):
repr_str=''
for observable in self._observables:
repr_str+='observable= '+observable.__repr__(hide_values=hide_values)
repr_str+='\n'
for geom_repr in self._geom_represent:
repr_str+='geom_repr= '+geom_repr.__repr__(hide_values=hide_values)
repr_str+='\n'
return repr_str
@property
def Nevts(self):
return self._Nevts
@property
def position(self,ID=None,repr_id=0):
if ID==None:
return self._geom_represent[repr_id].coords
else:
return self._geom_represent[repr_id].coords[ID]
@property
def observable(self,ID=None,repr_id=0):
if ID==None:
return self._observables[repr_id].values
else:
return self._observables[repr_id].values[ID]
def _set_IDs(self,IDs,ID_offset):
if ID_offset is None:
self._ID_offset=0
else:
self._ID_offset=ID_offset
if IDs is None:
self._IDs=np.arange(0,)
else:
self._IDs=IDs + self._ID_offset
@iter_input
def _add_observable(self,observables,name=None):
for observable in observables:
obj,name=self._check_add_obj(observable,Quantity,name)
self._observables.append(obj)
setattr(self,name,observable)
@iter_input
def _add_geom_representation(self,geom_represent,name=None):
for g_repr in geom_represent:
obj,name=self._check_add_obj(g_repr,GeomRepresentation,name)
self._geom_represent.append(obj)
setattr(self,name,g_repr)
def _get_ndarray(self):
pass
def _check_add_obj(self,adding_obj,expected_class,name=None):
"""
checks on added object(geom repr/ feature)
Args:
adding_obj:
expected_class:
name:
Returns:
"""
if isinstance(adding_obj,expected_class):
pass
else:
raise TypeError(""" object %s is not an instance of %s"""%(adding_obj.__class__,expected_class))
if name is None or name == {}:
check_name=adding_obj.name
else:
if type(name)==dict:
check_name=name['name']
# print(check_name,name)
if hasattr(self,check_name):
raise ValueError("attribute with name=%s already in object instance, choose another name "%(check_name))
self._check_shape_consistency(check=adding_obj)
return adding_obj,check_name
[docs] def build_new_from_ids(self,ids,keep_original_ids=False):
new_obj=copy.deepcopy(self)
for observable in new_obj._observables:
observable._set_values(observable.values[ids],copy=False)
for geom_repr in new_obj._geom_represent:
geom_repr._set_coords(geom_repr.coords[ids],None,None,copy=False)
if keep_original_ids==False:
new_obj._set_IDs(None,None)
else:
new_obj._set_IDs(ids,None)
#new_obj._check_shape_consistency()
return new_obj
@classmethod
[docs] def from_image_array(cls,image_array,masked=None):
"""
class method to create object from an image array
Args:
image_array:
masked: boolean 2-dim array, True==masked, False==visible
Returns:
"""
if type(image_array)==np.ndarray:
pass
else:
raise TypeError('image_array is of type %s but shoudl be %s'%(type(image_array),np.ndarray))
if masked is None:
masked=np.ones(image_array.shape, dtype=np.bool)
y,x=np.where(~masked)
x_c=image_array.shape[1]*0.5
y_c=image_array.shape[0]*0.5
return EventTable(Representation2D('cartesian',first_coord=x,second_coord=y,rotation_center_x=x_c,rotation_center_y=y_c),Quantity(image_array[~masked].flatten(),units='cts',name='flux'))
@classmethod
[docs] def from_Image_class(cls,image_obj,masked=None):
"""
class method to create object from an image class instance
Args:
image_obj:
mask: boolean 2-dim array, True==masked, False==visible
Returns:
"""
if isinstance(image_obj,Image):
pass
else:
raise TypeError('image_array is of type %s but shoudl be %s'%(type(image_obj),Image))
if masked is None:
masked=np.ones(image_obj.shape, dtype=np.bool)
else:
masked=np.logical_and(masked,image_obj.mask)
x_c=image_obj._rotation_center_x
y_c=image_obj._rotation_center_y
return EventTable(Representation2D('cartesian',first_coord=x,second_coord=y,rotation_center_x=x_c,rotation_center_y=y_c),Quantity(image_obj.valid_flatten(),units='cts',name='flux'))