Source code for merlin.rods

from functools import partial
from cytoolz import excepts
from cytoolz import thread_last
from merlin import chips
import numpy as np

[docs]def from_chips(chips): """Accepts sequences of chips and returns time series pixel rods organized by x, y, t for all chips. Chips should be sorted as desired before calling rods() as outputs preserve input order. Args: chips: sequence of chips with data as numpy arrays Returns: 3d numpy array organized by x, y, and t. Output shape matches input chip shape with the chip value replaced by another numpy array of chip time series values 1. For each chip add data to master numpy array. 2. Transpose the master array 3. Horizontally stack the transposed master array elements 4. Reshape the master array to match incoming chip dimensions 5. Pixel rods are now organized for timeseries access by x, y, t >>> chip_one = np.int_([[11, 12, 13], [14, 15, 16], [17, 18, 19]]) >>> chip_two = np.int_([[21, 22, 23], [24, 25, 26], [27, 28, 29]]) >>> chip_three = np.int_([[31, 32, 33], [34, 35, 36], [37, 38, 39]]) >>> master = np.conj([chip_one, chip_two, chip_three]) >>> np.hstack(master.T).reshape(3, 3, -1) array([[[ 11, 21, 31], [ 12, 22, 32], [ 13, 23, 33]], [[ 14, 24, 34], [ 15, 25, 35], [ 16, 26, 36]], [[ 17, 27, 37], [ 18, 28, 38], [ 19, 29, 39]]]) """ master = np.conj([c['data'] for c in chips]) return np.hstack(master.T).reshape(*master[0].shape, -1)
[docs]def locate(rods, locations): """Combines location information with pixel rods. Args: rods: Chip shaped numpy array of rods locations: Chip shaped numpy array of locations Returns: dict: (location):rod for each location and rod in the arrays. Incoming locations as 3d array: >>> array([[[0,0], [0,1], [0,2]], [[1,0], [1,1], [1,2]], [[2,0], [2,1], [2,2]]]) Incoming rods also as 3d array: >>> array([[[110,110,234,664], [23,887,110,111], [110,464,223,112]], [[111,887,1,110], [33,111,12,111], [0,111,66,112]], [[12,99,112,110], [112,87,231,111], [112,45,47,112]]]) locrods converts locations to: >>> locations.reshape(locations.shape[0] * locations.shape[1], -1) array([[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]) And rods to: >>> rods.reshape(rods.shape[0] * rods.shape[1], -1) array([[110, 110, 234, 664], [23, 887, 110, 111], [110, 464, 223, 112], [111, 887, 1, 110], [33, 111, 12, 111], [0, 111, 66, 112], [12, 99, 112, 110], [112, 87, 231, 111], [112, 45, 47, 112]]) Then the locations and rods are zipped together via a dictionary comprehension and returned. >>> { (0,0): [110, 110, 234, 664], (0,1): [23, 887, 110, 111], (0,2): [110, 464, 223, 112], (1,0): [111, 887, 1, 110], (1,1): [33, 111, 12, 111], (1,2): [0, 111, 66, 112], (2,0): [12, 99, 112, 110], (2,1): [112, 87, 231, 111], (2,2): [112, 45, 47, 112] } """ flat_locs = locations.reshape(locations.shape[0] * locations.shape[1], -1) flat_rods = rods.reshape(rods.shape[0] * rods.shape[1], -1) return {tuple(k): v for k, v in zip(flat_locs, flat_rods)}
[docs]def identify(rod, x, y): """Adds chip ids (chip_x, chip_y) to the key for a rod Args: rod: dict of (x, y): [values] x: x coordinate that identifies the source chip y: y coordinate that identifies the source chip Returns: dict: {(chip_x, chip_y, x, y): [values]} """ return {(x, y, k[0], k[1]): v for k, v in rod.items()}
[docs]def create(x, y, chipseq, dateseq, locations, spec_index): """Transforms a sequence of chips into a sequence of rods filtered by date, deduplicated, sorted, located and identified. Args: x (int): x projection coordinate of chip y (int): y projection coordinate of chip chipseq (seq): sequence of chips dates (seq): sequence of dates that should be included in the rods locations (numpy.Array): 2d numpy array of pixel coordinates spec_index (dict): specs indexed by ubid Returns: dict: {(chip_x, chip_y, x, y): {'k1': [], 'k2': [], 'k3': [], ...}} """ return thread_last(chipseq, partial(chips.trim, dates=dateseq), chips.deduplicate, chips.rsort, partial(chips.to_numpy, spec_index=spec_index), excepts(ValueError, from_chips, lambda _: []), excepts(AttributeError, partial(locate, locations=locations), lambda _: {}), partial(identify, x=x, y=y))