Source code for common.num.array_square_cell

'''
Created on 2 nov. 2017

@author: Colley JM
'''

import numpy as np
import matplotlib.pyplot as plt
from common.instru.array_convention import yzegp_to_ijdet_array


        
        
[docs]class ArraySquareCell(object): ''' unit : cm, cm^2 ''' def __init__(self, ncel_x=1, ncel_y=1, size_cm=1.0): ''' ''' self.max_ix = ncel_x - 1 self.max_iy = ncel_y - 1 self.size_cm = size_cm*1.0 self.surf_cell = self.size_cm**2 self.ar_val = np.zeros((ncel_x, ncel_y), dtype=np.float32) self.to_origin_cm = np.array([0.0, 0.0], dtype=np.float32 ) self.l_verb = 0
[docs] def empty_like(self, p_asc): """ Initiation of current with parameter of ArraySquareCell p_asc :param p_asc: array model :type p_asc: ArraySquareCell """ assert isinstance(p_asc, ArraySquareCell) self.max_ix = p_asc.max_ix self.max_iy = p_asc.max_iy self.size_cm = p_asc.size_cm self.surf_cell = self.size_cm**2 self.ar_val = np.zeros((self.max_ix + 1, self.max_iy + 1), dtype=np.float32) self.to_origin_cm = p_asc.to_origin_cm
# setter
[docs] def set_array(self, p_ar): if (self.get_nb_cell_y() != p_ar.shape[1]): return None if (self.get_nb_cell_x() != p_ar.shape[0]): return None self.ar_val = np.copy(p_ar)
[docs] def add_hit(self, apos): """ Add one on pixel associated to position :param apos: array plan position of photon :type apos: numpy array (n,2) """ if apos.size == 0: return idx_pix = self.pos2idx_inf(apos) it = np.nditer([idx_pix[:,0], idx_pix[:,1]], [], [['readonly'], ['readonly']]) for il, ic in it: self.ar_val[il, ic] += 1
[docs] def set_origin_center(self): self.to_origin_cm = self.get_sizecm()/2.0
[docs] def set_pos_corner_lb(self, p_pos_ori : np.array): """ vector OP where P=pos_array_lb and O: origin """ self.to_origin_cm = -p_pos_ori.copy()
[docs] def set_origin(self, p_pos_ori : np.array): """ vector PO where P=pos_array_lb and O: origin """ self.to_origin_cm = p_pos_ori.copy()
# getter
[docs] def get_nb_cell_x(self): return self.ar_val.shape[0]
[docs] def get_nb_cell_y(self): return self.ar_val.shape[1]
[docs] def get_nb_cell(self): return self.ar_val.size
[docs] def get_sizecm(self): array_size = np.array([0,0], dtype=np.float32 ) array_size[0] = self.ar_val.shape[0] * self.size_cm array_size[1] = self.ar_val.shape[1] * self.size_cm return array_size
[docs] def get_surface(self): """ return : [cm]^2 """ array_size = self.get_sizecm() return array_size[0]*array_size[1]
[docs] def pos_rect_array(self): rect = np.empty((2,2), dtype=np.float32) rect[0,:] = self.pos_corner_lb() rect[1,:] = rect[0,:] + self.get_sizecm() return rect
[docs] def pos_rect_cell(self, idx): """ for one cell """ rect = np.empty((2, 2), dtype=np.float32) a_idx = np.array([idx]) rect[0,:] = self.idx2pos_inf(a_idx) rect[1,:] = rect[0,:] + self.size_cm return rect
[docs] def pos_rect_cells(self, aidx): """ for array index cells """ n_rect = aidx.shape[0] arect = np.empty((n_rect,2,2), dtype=np.float32) arect[:,0,:] = self.idx2pos_inf(aidx) arect[:,1,:] = self.idx2pos_sup(aidx) return arect
[docs] def pos_corner_lb(self): """ return : [cm] position corner 'l'eft 'b'ottom """ return -self.to_origin_cm
[docs] def pos_corner_ru(self): """ return : [cm] position corner 'r'ight 'u'pper """ return self.get_sizecm() - self.to_origin_cm
[docs] def pos_center_cells(self): """Return 2 array x and y with center cells :return: 2 array x and y with center cells :rtype: numpy array """ # AFINIR bonne convention de repere x_center = np.arange(self.get_nb_cell_x()) * self.size_cm + self.size_cm / 2 x_center -= self.to_origin_cm[0] y_center = np.arange(self.get_nb_cell_y()) * self.size_cm + self.size_cm / 2 y_center -= self.to_origin_cm[1] return (x_center, y_center)
[docs] def value_at_pos_check(self, pos): idx = self.pos2idx_inf(pos) idx0 = idx[0] if self.l_verb > 0: print("Max: ",self.get_nb_cell_x(), self.get_nb_cell_y()) if idx0 < 0 or idx0 >= self.get_nb_cell_x(): print("ERROR value_at_pos_check(): out of index") return None idx1 = idx[1] if idx1 < 0 or idx1 >= self.get_nb_cell_y(): print("ERROR value_at_pos_check(): out of index") return None return self.value(idx)
[docs] def value_at_pos(self, pos): idx = self.pos2idx_inf(pos) return self.value(idx)
[docs] def value(self, idx): return self.ar_val[idx[0], idx[1]]
[docs] def value_array(self, aidx : np.array): """ aidx (n, 2) """ return self.ar_val[aidx[:,0], aidx[:,1]]
[docs] def get_shape(self): return self.ar_val.shape
[docs] def set_val(self, p_val): self.ar_val[:,:] = p_val
[docs] def get_ij_cell_surrounded_no_0(self): a_ij = np.empty((0,2), dtype=np.int16) p_ar = self.ar_val for p_i in range(1, p_ar.shape[0]-1): for p_j in range(1, p_ar.shape[1]-1): #print(p_i,p_j) if (p_ar[p_i+1, p_j-1]*p_ar[p_i+1, p_j]*p_ar[p_i+1, p_j+1] == 0.0): continue if (p_ar[p_i, p_j-1]*p_ar[p_i, p_j+1] == 0.0): continue if (p_ar[p_i-1, p_j-1]*p_ar[p_i-1, p_j]*p_ar[p_i-1, p_j+1] == 0.0): continue a_ij = np.vstack((a_ij, np.array([p_i, p_j], dtype=np.int16))) return a_ij
# methods convert
[docs] def pos2idx_rect(self, p_rect, p_boundary=False): """ p_rect is one rectangle """ r_idx = np.empty((2,2), dtype=np.int8) r_idx[0] = self.pos2idx_inf(p_rect[0]) r_idx[1] = self.pos2idx_inf(p_rect[1]) if p_boundary: r_idx = np.where(r_idx < 0, 0, r_idx) r_idx[:,0] = np.where(r_idx[:,0] > self.max_ix, self.max_ix, r_idx[:,0]) r_idx[:,1] = np.where(r_idx[:,1] > self.max_iy, self.max_iy, r_idx[:,1]) return r_idx
[docs] def idx2pos(self, array_idx, pos="CTR"): """return array position :param array_idx: array index :type array_idx: int :param pos: pos = {Center: CTR, left bottom :LB, right up :RU} :type pos: string """ array_idx_c = array_idx.copy().astype(np.float32) if pos == "CTR": array_idx_c += np.array([0.5, 0.5], dtype=np.float32) elif pos == "RU": array_idx_c += np.array([1, 1]) pos = array_idx_c*self.size_cm - self.to_origin_cm return pos
[docs] def idx2pos_inf(self, array_idx): return self.idx2pos(array_idx, "LB")
[docs] def idx2pos_sup(self, array_idx): return self.idx2pos(array_idx, "RU")
[docs] def pos2idx(self, pos_cm, round_func = None): array_idx = (pos_cm + self.to_origin_cm)/self.size_cm if not round_func : return (pos_cm + self.to_origin_cm)/self.size_cm idx = round_func(array_idx).astype(int) return idx
[docs] def pos2idx_inf(self, pos_cm): return self.pos2idx(pos_cm, np.floor)
[docs] def pos2idx_sup(self, pos_cm): return self.pos2idx(pos_cm, np.ceil)
# methods on all array in place
[docs] def random_value(self, pmin, pmax): aa = np.random.randint(pmin, pmax + 1, self.ar_val.size).reshape((self.get_nb_cell_x(), -1)) self.set_array(aa)
[docs] def random_pos(self, nb_pos): """ random position in all array :param nb_pos: number position to random :type nb_pos: int """ msize = self.get_sizecm() apos = np.empty((nb_pos,2), dtype=np.float32) apos[:,0] = np.random.uniform(0, msize[0]-1e-5, nb_pos) apos[:,1] = np.random.uniform(0, msize[1]-1e-5, nb_pos) #print (self.to_origin_cm, apos.size) retpos = apos - self.to_origin_cm #print (retpos) return retpos
[docs] def random_pos_rect(self, nb_pos, rec): """ random position in rectangle given by parameter return : nb_pos random position in rec """ epsilon = 1e-5 apos = np.empty((nb_pos,2), dtype=np.float32) apos[:,0] = np.random.uniform(rec[0,0]+epsilon, rec[1,0]-epsilon , nb_pos) apos[:,1] = np.random.uniform(rec[0,1]+epsilon, rec[1,1]-epsilon, nb_pos) return apos
[docs] def surf_intersection_rect(self, p_r1, p_r2): inter_rec = self.intersection_rect(p_r1, p_r2) surface = (inter_rec[1,0] - inter_rec[0,0])*(inter_rec[1,1] - inter_rec[0,1]) return surface
[docs] def intersection_rect(self, p_r1, p_r2): rec_inter_0 = np.zeros((2,2), dtype=np.float32) rec_inter = np.empty_like(rec_inter_0) corner_lb_p = p_r1[0,:] corner_ru_p = p_r1[1,:] corner_lb_pp = p_r2[0,:] corner_ru_pp = p_r2[1,:] # corner lb intersection if corner_lb_pp[0] < corner_lb_p[0]: rec_inter[0,0] = corner_lb_p[0] elif corner_lb_pp[0] < corner_ru_p[0]: rec_inter[0,0] = corner_lb_pp[0] else: return rec_inter_0 if corner_lb_pp[1] < corner_lb_p[1]: rec_inter[0,1] = corner_lb_p[1] elif corner_lb_pp[1] < corner_ru_p[1]: rec_inter[0,1] = corner_lb_pp[1] else: return rec_inter_0 if corner_ru_pp[0] < corner_lb_p[0]: return rec_inter_0 elif corner_ru_pp[0] < corner_ru_p[0]: rec_inter[1,0] = corner_ru_pp[0] else: rec_inter[1,0] = corner_ru_p[0] if corner_ru_pp[1] < corner_lb_p[1]: return rec_inter_0 elif corner_ru_pp[1] < corner_ru_p[1]: rec_inter[1,1] = corner_ru_pp[1] else: rec_inter[1,1] = corner_ru_p[1] return rec_inter
[docs] def intersection(self, o_asc , vec_trans): """ Intersection entre le tableau en attribut et un tableau passé en paramètre à translater return [[x_lb, y_lb], [x_ru, y_ru]] rectangle intersection, lb: left bottom, ru: right uppper """ rec_inter_0 = np.zeros((2,2), dtype=np.float32) rec_inter = np.empty_like(rec_inter_0) corner_lb_p = self.pos_corner_lb() corner_ru_p = self.pos_corner_ru() corner_lb_pp = o_asc.pos_corner_lb() + vec_trans corner_ru_pp = o_asc.pos_corner_ru() + vec_trans # corner lb intersection if corner_lb_pp[0] < corner_lb_p[0]: rec_inter[0,0] = corner_lb_p[0] elif corner_lb_pp[0] < corner_ru_p[0]: rec_inter[0,0] = corner_lb_pp[0] else: return rec_inter_0 if corner_lb_pp[1] < corner_lb_p[1]: rec_inter[0,1] = corner_lb_p[1] elif corner_lb_pp[1] < corner_ru_p[1]: rec_inter[0,1] = corner_lb_pp[1] else: return rec_inter_0 if corner_ru_pp[0] < corner_lb_p[0]: return rec_inter_0 elif corner_ru_pp[0] < corner_ru_p[0]: rec_inter[1,0] = corner_ru_pp[0] else: rec_inter[1,0] = corner_ru_p[0] if corner_ru_pp[1] < corner_lb_p[1]: return rec_inter_0 elif corner_ru_pp[1] < corner_ru_p[1]: rec_inter[1,1] = corner_ru_pp[1] else: rec_inter[1,1] = corner_ru_p[1] return rec_inter
[docs] def sample_up(self, pfact): """ pfact is int result: repeat pfactxpfact each element """ o_asc = ArraySquareCell(self.get_nb_cell_x() * pfact, self.get_nb_cell_y() * pfact, self.size_cm / pfact) su_ar = self.ar_val.repeat(pfact).reshape ((self.get_nb_cell_x(), self.get_nb_cell_y() * pfact)).T su_ar = su_ar.repeat(pfact).reshape((self.get_nb_cell_x() * pfact, self.get_nb_cell_y() * pfact)).T # plt.figure() # plt.imshow(su_ar.T) o_asc.set_array(su_ar) return o_asc
# plot
[docs] def plot_ijdet(self, p_mes=""): plt.figure() plt.title(p_mes) plt.imshow(yzegp_to_ijdet_array(self.ar_val)) plt.colorbar()
[docs] def plot(self, p_mes=""): plt.figure() plt.title(p_mes) plt.imshow(np.transpose(self.ar_val) , origin='lower') plt.colorbar()