[docs]classBlock(slc.Slice):"""Block source A Block is a Slice with a sub-slice indicating the valid region to use when combining the results after block processing. Each block has a index tuple that specifies its position in the grid of blocks in which the source was split into. Each block also can carry a reference to its neighbouring blocks. See also -------- :mod:`ClearMap.ParallelProcessing.BlockProcessing` """def__init__(self,source=None,slicing=None,valid=None,valid_slicing=None,offsets=None,index=None,iteration=None,blocks_shape=None,neighbours=None,name=None):"""Constructor"""super(Block,self).__init__(source=source,slicing=slicing,name=name);ifvalidisNone:ifvalid_slicingisNone:ifoffsetsisNone:valid_slicing=slice(None);else:valid_slicing=_offsets_to_slicing(offsets)valid=slc.Slice(source=self,slicing=valid_slicing);ifnotisinstance(valid,slc.Slice):raiseValueError('The valid slice of the block is not specified correctly!');self._valid=valid;self._index=index;self._iteration=iteration;self._blocks_shape=blocks_shape;self._neighbours=neighbours;@propertydefname(self):"""The name of this source. Returns ------- name : str Name of this source. """return'Block-'+self.source.name;@propertydefvalid(self):"""Return the slice of the valid region of this block. Returns ------- valid : Slice The valid slice of this block. """returnself._valid;@propertydefindex(self):"""Return the grid index of the block. Returns ------- index : tuple of ints The multi index of this block in a grid of blocks. """returnself._index;@propertydefblocks_shape(self):"""Return the shape of the block grid this block belongs too. Returns ------- shape : tuple of ints The shape of the grid of blocks this block is part of. """returnself._blocks_shape;@propertydefiteration(self):"""Return the index of this block in the list of all blocks to process. Returns ------- index : tuple of ints The multi index of this block in a grid of blocks. """ifself._iterationisNone:ifself.indexisnotNoneandself.blocks_shapeisnotNone:returnnp.ravel_multi_index(self.index,self.blocks_shape);returnself._iteration;@iteration.setterdefiteration(self,iteration):self._iteration=iteration;@propertydefn_iterations(self):"""Returns the number of blocks in the grid to which this block belongs. Returns ------- n_iterations : int or None The number of blocks in the block grid. """ifself.blocks_shapeisnotNone:returnnp.prod(self.blocks_shape);@propertydefneighbours(self):"""Returns the neighbours of this block. Returns ------- neighbours : dict or None The neighbours of this block in the form {index : block,...} or None """returnself._neighbours;@neighbours.setterdefneighbours(self,neighbours):self._neighbours=neighbours;
[docs]defiteration_info(self):"""Return info string about the iteration of this block in the gird of blocks. Returns ------- info : str Info string. """info='';iteration=self.iteration;ifiterationisnotNone:info+='%d/%d'%(self.iteration,self.n_iterations);index=self.index;ifindexisnotNone:ifinfo!='':info+='<';info+='%r'%(index,);blocks_shape=self.blocks_shape;ifblocks_shapeisnotNone:info+='/%r'%(blocks_shape,);ifinfo!='':info+='>'returninfo;
[docs]definfo(self,short=True):"""Return info string about this block within the grid of blocks. Returns ------- info : str Info string. """info=self.iteration_info();ifinfo!='':info+=' ';ifshort:info+='%r@%r[%s]'%(self.shape,self.source.shape,slc._slicing_to_str(self.slicing,self.ndim));else:info+='%r @ %r[%r]'%(self,self.source,self.slicing);returninfo
################################################################################## Helpers###############################################################################def_offsets_to_slicing(offsets,ndim=None,shape=None):"""Parses offsets into standard form ((low0, high0),(low1, high1),...)."""ifshapeisnotNone:ndim=len(shape);ifnotisinstance(offsets,(list,tuple)):offsets=[offsets]*(ndimor1);ifndimisnotNone:iflen(offsets)!=ndim:raiseValueError('Offset dimension %d does not match data dimensions %d'%(len(offsets),ndim));else:ndim=len(offsets);new_offsets=[];ford,oinenumerate(offsets):ifnotisinstance(o,(list,tuple)):o=[o];o=list(o);iflen(o)==1:o=(o[0],o[0]);iflen(o)!=2:raiseValueError('Offset %r in dimension %d not valid!'%(o,d));ifo[0]==0:o[0]=None;ifo[1]==0:o[1]=None;elifisinstance(o[1],int):o[1]=-o[1];ifshapeisnotNone:ifo[0]isnotNone:ifo[0]>=shape[d]or-o[0]>shape[d]:raiseValueError('Offset %r out of range %d in dimenion %d!'%(o,shape[d],d));ifo[1]isnotNone:ifo[1]>=shape[d]or-o[1]>shape[d]:raiseValueError('Offset %r out of range %d in dimenion %d!'%(o,shape[d],d));new_offsets.append(o);new_offsets=tuple(slice(o[0],o[1])foroinnew_offsets);returnnew_offsets;################################################################################## Tests###############################################################################def_test():importnumpyasnp#analysis:okimportClearMap.ParallelProcessing.BlockasblkimportClearMap.IO.IOasiosource=io.as_source(np.asarray(np.random.rand(50,100,200),order='F'))block=blk.Block(source=source,index=(1,2,3),blocks_shape=(10,20,30))print(block.n_iterations)print(block.iteration)print(block.iteration_info())