def layer_process(self, func, silent=True, **kwargs): """ Generates a new layer from the return of its method 'func', called with **kwargs (and possible args stored in in the keyword 'args' as tuple). The size of the produced layer must be passed in the 'size' keyword. Returns the name of the new layer(s) """ if 'layer' in kwargs: self.input = kwargs['layer'] else: self.input = pyrat.data.active if any([isinstance(foo, list) for foo in self.input]): layshp = self.input self.input = flattenlist(self.input) nested = True else: nested = False query = pyrat.data.queryLayer(self.input) if isinstance(query, list): dshape = query[0]['shape'] else: dshape = query['shape'] if self.vblock: # init block processing self.initBP(dshape[-1]) else: self.initBP(dshape[-2]) if len(self.blocks) > 1 and self.nthreads > 1: # group chunks of blocks idx = [self.blocks[i:i + self.nthreads] for i in range(0, len(self.blocks), self.nthreads)] else: idx = [[block] for block in self.blocks] metain = pyrat.data.getAnnotation(layer=self.input) nb1 = 0 # input block number nb2 = 0 # output block number if silent is False: P = pyrat.tools.ProgressBar(' ' + self.name, len(self.blocks)) P.update(0) for bidx in idx: # loop over chunks of blocks meta = copy.deepcopy(metain) inputs = [] for ix in bidx: # loop over blocks in chunk data = self.read_block(nb1) if nested is True: data = unflattenlist(data, layshp) kwargs_copy = copy.deepcopy(kwargs) kwargs_copy["args"] = data kwargs_copy["meta"] = meta if self.vblock: kwargs_copy['block'] = (0, dshape[-2]) + tuple(self.blocks[nb1]) else: kwargs_copy['block'] = tuple(self.blocks[nb1]) + (0, dshape[-1]) kwargs_copy['valid'] = tuple(self.valid[nb1]) inputs.append((self, func.__name__, kwargs_copy)) # accumulate inputs nb1 += 1 if self.nthreads > 1: result = multimap(inputs) # do the multiprocessing else: result = map(exec_out, inputs) # or avoid it... for res in result: # loop over output blocks (in chunk) metaout = res[1] # meta data (possibly modified) if nb2 == 0: # first block -> generate new layer(s) if isinstance(res[0], list) or isinstance(res[0], tuple): self.output = [] for n, re in enumerate(res[0]): lshape = re.shape[0:-2] # layer geometry if self.vblock: dshape = (re.shape[-2], dshape[-1]) else: dshape = (dshape[-2], re.shape[-1]) if self.blockprocess is False: # no blockprocessing lshape = () # -> entire image dshape = re.shape self.output.append(pyrat.data.addLayer(dtype=re.dtype, shape=lshape + dshape)) else: lshape = res[0].shape[0:-2] # layer geometry if self.vblock: dshape = (res[0].shape[-2], dshape[-1]) else: dshape = (dshape[-2], res[0].shape[-1]) if self.blockprocess is False: # no blockprocessing lshape = () # -> entire image dshape = res[0].shape self.output = pyrat.data.addLayer(dtype=res[0].dtype, shape=lshape + dshape) self.save_block(res[0], nb2) nb2 += 1 if silent is False: P.update(nb2) if silent is False: del P pyrat.data.setAnnotation(metaout, layer=self.output) # add meta data to output layer return self.output # return output layer
def layer_process(self, func, silent=True, **kwargs): """ Generates a new layer from the return of its method 'func', called with **kwargs (and possible args stored in in the keyword 'args' as tuple). The size of the produced layer must be passed in the 'size' keyword. Returns the name of the new layer(s) """ if 'layer' in kwargs: self.input = kwargs['layer'] else: self.input = pyrat.data.active if any([isinstance(foo, list) for foo in self.input]): layshp = self.input self.input = flattenlist(self.input) nested = True else: nested = False query = pyrat.data.queryLayer(self.input) if isinstance(query, list): dshape = query[0]['shape'] else: dshape = query['shape'] if self.vblock: # init block processing self.initBP(dshape[-1]) else: self.initBP(dshape[-2]) if len(self.blocks ) > 1 and self.nthreads > 1: # group chunks of blocks idx = [ self.blocks[i:i + self.nthreads] for i in range(0, len(self.blocks), self.nthreads) ] else: idx = [[block] for block in self.blocks] metain = pyrat.data.getAnnotation(layer=self.input) nb1 = 0 # input block number nb2 = 0 # output block number if silent is False: P = pyrat.tools.ProgressBar(' ' + self.name, len(self.blocks)) P.update(0) for bidx in idx: # loop over chunks of blocks meta = copy.deepcopy(metain) inputs = [] for ix in bidx: # loop over blocks in chunk data = self.read_block(nb1) if nested is True: data = unflattenlist(data, layshp) kwargs_copy = copy.deepcopy(kwargs) kwargs_copy["args"] = data kwargs_copy["meta"] = meta if self.vblock: kwargs_copy['block'] = (0, dshape[-2]) + tuple( self.blocks[nb1]) else: kwargs_copy['block'] = tuple( self.blocks[nb1]) + (0, dshape[-1]) kwargs_copy['valid'] = tuple(self.valid[nb1]) inputs.append( (self, func.__name__, kwargs_copy)) # accumulate inputs nb1 += 1 if self.nthreads > 1: result = multimap(inputs) # do the multiprocessing else: result = map(exec_out, inputs) # or avoid it... for res in result: # loop over output blocks (in chunk) metaout = res[1] # meta data (possibly modified) if nb2 == 0: # first block -> generate new layer(s) if isinstance(res[0], list) or isinstance(res[0], tuple): self.output = [] for n, re in enumerate(res[0]): lshape = re.shape[0:-2] # layer geometry if self.vblock: dshape = (re.shape[-2], dshape[-1]) else: dshape = (dshape[-2], re.shape[-1]) if self.blockprocess is False: # no blockprocessing lshape = () # -> entire image dshape = re.shape self.output.append( pyrat.data.addLayer(dtype=re.dtype, shape=lshape + dshape)) else: lshape = res[0].shape[0:-2] # layer geometry if self.vblock: dshape = (res[0].shape[-2], dshape[-1]) else: dshape = (dshape[-2], res[0].shape[-1]) if self.blockprocess is False: # no blockprocessing lshape = () # -> entire image dshape = res[0].shape self.output = pyrat.data.addLayer(dtype=res[0].dtype, shape=lshape + dshape) self.save_block(res[0], nb2) nb2 += 1 if silent is False: P.update(nb2) if silent is False: del P if 'path' in metaout: del metaout['path'] pyrat.data.setAnnotation( metaout, layer=self.output) # add meta data to output layer return self.output # return output layer