示例#1
0
def _test():
  """Tests"""
  import ClearMap.Settings as settings 
  import ClearMap.IO.IO as io
  import ClearMap.Visualization.Plot3d as p3d;
  
  import ClearMap.Alignment.Resampling as res
  from importlib import reload
  reload(res)
  
  r = res.resample_shape(source_shape=(100,200,300), sink_shape=(50,50,30));
  print('resampled source_shape=%r, sink_shape=%r, source_resolution=%r, sink_resolution=%r' % r)
 
  r = res.resample_shape(source_shape=(100,200,300), source_resolution=(2,2,2), sink_resolution=(10,2,1))
  print('resampled source_shape=%r, sink_shape=%r, source_resolution=%r, sink_resolution=%r' % r)
  
  
  source = io.join(settings.test_data_path, 'Resampling/test.tif')
  sink   = io.join(settings.test_data_path, "Resampling/resampled.npy")
  
  source = io.join(settings.test_data_path, 'Tif/sequence/sequence<Z,4>.tif')
  sink = io.join(settings.test_data_path, "Resampling/resampled_sequence.tif")  
  
  
  source_shape, sink_shape, source_res, sink_res = res.resample_shape(source_shape=io.shape(source), source_resolution=(1.,1.,1.), sink_resolution=(1.6,1.6,2))
  axes_order = res._axes_order(None, source_shape, sink_shape);
  print(axes_order)
  resampled = res.resample(source, sink, source_resolution=(1.,1.,1.), sink_resolution = (1.6,1.6,2), orientation=None, processes=None);
  p3d.plot(resampled)
  p3d.plot(source)
  
  inverse = res.resample_inverse(resampled, sink=None, resample_source=source, source_resolution=(1,1,1), sink_resolution = (10,10,2), orientation=None, processes='serial')
  p3d.plot([source, inverse])

  
  resampled = res.resample(source, sink, source_resolution=(1,1,1), sink_resolution = (10,10,2), orientation=(2,-1,3), processes=None);
  p3d.plot(resampled)
  
  inverse = res.resample_inverse(resampled, sink=None, resample_source=source, source_resolution=(1,1,1), sink_resolution = (10,10,2), orientation=(2,-1,3), processes=None)
  p3d.plot([source, inverse])
  
  resampled = res.resample(source, sink=None, source_resolution=(1.6,1.6,2), sink_shape=(10,20,30), orientation=None, processes=None)
  p3d.plot(resampled)
  
  
  # ponints
  points = res.np.array([[0,0,0], [1,1,1], [1,2,3]], dtype=float);
  resampled_points = res.resample_points(points, resample_source=source , resample_sink=sink, orientation=None)
  print(resampled_points)

  inverse_points = res.resample_points_inverse(resampled_points, resample_source=source , resample_sink=sink, orientation=None)
  print(inverse_points)
  print(res.np.allclose(points, inverse_points))
示例#2
0
def graph_to_skeleton(graph, sink = None, dtype = bool):
  """Create a binary skeleton from a graph."""
  if not graph.has_edge_geometry():
    coordinates = graph.vertex_coordinates();
  else:
    coordinates = graph.edge_geometry('coordinates');
    coordinates = np.vstack(coordinates);

  if sink is None:
    shape = graph.shape;
    if shape is None:
      shape = tuple(np.max(coordinates, axis = 0));
    sink = np.zeros(shape, dtype=dtype);
  
  shape = io.shape(sink);

  coordinates = list(coordinates.T);
  sink[coordinates] = True;
      
  return sink;
示例#3
0
def detect_cells(
        source,
        sink=None,
        cell_detection_parameter=default_cell_detection_parameter,
        processing_parameter=default_cell_detection_processing_parameter):
    """Cell detection pipeline.
  
  Arguments
  ---------
  source : source specification
    The source of the stitched raw data.
  sink : sink specification or None
    The sink to write the result to. If None, an array is returned.
  cell_detection_parameter : dict
    Parameter for the binarization. See below for details.
  processing_parameter : dict
    Parameter for the parallel processing. 
    See :func:`ClearMap.ParallelProcessing.BlockProcesing.process` for 
    description of all the parameter.
  verbose : bool
    If True, print progress output.
  
  Returns
  -------
  sink : Source
    The result of the cell detection.
  
  Notes
  -----
  Effectively this function performs the following steps:
    * illumination correction via :func:`~ClearMap.ImageProcessing.IlluminationCorrection.correct_illumination`
    * background removal
    * difference of Gaussians (DoG) filter
    * maxima detection via :func:`~ClearMap.Analysis.Measurements.MaximaDetection.find_extended_maxima`
    * cell shape detection via :func:`~ClearMap.Analysis.Measurements.ShapeDetection.detect_shape`
    * cell intensity and size measurements via: :func:`~ClearMap.ImageProcessing.Measurements.ShapeDetection.find_intensity`,
      :func:`~ClearMap.ImageProcessing.Measurements.ShapeDetection.find_size`. 

  
  The parameters for each step are passed as sub-dictionaries to the 
    cell_detection_parameter dictionary.
  
  * If None is passed for one of the steps this step is skipped.
  
  * Each step also has an additional parameter 'save' that enables saving of 
    the result of that step to a file to inspect the pipeline.
  
  
  Illumination correction
  -----------------------
  illumination_correction : dict or None
    Illumination correction step parameter.

    flatfield : array or str 
      The flat field estimate for the image planes.
    
    background : array or None
      A background level to assume for the flatfield correction.
    
    scaling : float, 'max', 'mean' or None
      Optional scaling after the flat field correction.
    
    save : str or None
      Save the result of this step to the specified file if not None.
          
  See also :func:`ClearMap.ImageProcessing.IlluminationCorrection.correct_illumination`
  
  
  Background removal
  ------------------
  background_correction : dict or None
    Background removal step parameter.

    shape : tuple
      The shape of the structure lement to estimate the background.
      This should be larger than the typical cell size.
    
    form : str
      The form of the structur element (e.g. 'Disk')
        
    save : str or None
      Save the result of this step to the specified file if not None.
  
  Equalization
  ------------
  equalization : dict or None
    Equalization step parameter.
    See also :func:`ClearMap.ImageProcessing.LocalStatistics.local_percentile`
    
    precentile : tuple
      The lower and upper percentiles used to estimate the equalization.
      The lower percentile is used for normalization, the upper to limit the
      maximal boost to a maximal intensity above this percentile.
    
    max_value : float
      The maximal intensity value in the equalized image.
    
    selem : tuple
      The structural element size to estimate the percentiles. 
      Should be larger than the larger vessels.
    
    spacing : tuple
      The spacing used to move the structural elements.
      Larger spacings speed up processing but become locally less precise.
        
    interpolate : int
      The order of the interpoltation used in constructing the full 
      background estimate in case a non-trivial spacing is used.
      
    save : str or None
      Save the result of this step to the specified file if not None.
  
  
  DoG Filter
  ----------
  dog_filter : dict or None
    Difference of Gaussian filter step parameter.

    shape : tuple
      The shape of the filter.
      This should be near the typical cell size.
      
    sigma : tuple or None
       The std of the inner Gaussian.
       If None, detemined automatically from shape.
    
    sigma2 : tuple or None
       The std of the outer Gaussian.
       If None, detemined automatically from shape.
    
    save : str or None
      Save the result of this step to the specified file if not None.
  
  
  Maxima detection
  ----------------
  maxima_detection : dict or None
    Extended maxima detection step parameter.

    h_max : float or None
      The 'height'for the extended maxima.
      If None, simple local maxima detection isused.

    shape : tuple
      The shape of the structural element for extended maxima detection.
      This should be near the typical cell size.
    
    threshold : float or None
      Only maxima above this threshold are detected. If None, all maxima
      are detected.
      
    valid : bool
      If True, only detect cell centers in the valid range of the blocks with
      overlap.
    
    save : str or None
      Save the result of this step to the specified file if not None.
  
  
  Shape detection
  ---------------
  shape_detection : dict or None
    Shape detection step parameter.

    threshold : float
      Cell shape is expanded from maxima if pixles are above this threshold
      and not closer to another maxima.
    
    save : str or None
      Save the result of this step to the specified file if not None.
  
  
  Intensity detection
  -------------------
  intensity_detection : dict or None
    Intensity detection step parameter.

    method : {'max'|'min','mean'|'sum'}
      The method to use to measure the intensity of a cell.
      
    shape : tuple or None
      If no cell shapes are detected a disk of this shape is used to measure
      the cell intensity.
    
    save : str or None
      Save the result of this step to the specified file if not None.
  
  References
  ----------
  [1] Renier, Adams, Kirst, Wu et al., "Mapping of Brain Activity by Automated Volume Analysis of Immediate Early Genes.", Cell 165, 1789 (2016)
  [1] Kirst et al., "Mapping the Fine-Scale Organization and Plasticity of the Brain Vasculature", Cell 180, 780 (2020)
  """

    #initialize sink
    shape = io.shape(source)
    order = io.order(source)

    for key in cell_detection_parameter.keys():
        par = cell_detection_parameter[key]
        if isinstance(par, dict):
            filename = par.get('save', None)
            if filename:
                ap.initialize_sink(filename,
                                   shape=shape,
                                   order=order,
                                   dtype='float')

    cell_detection_parameter.update(
        verbose=processing_parameter.get('verbose', False))

    results, blocks = bp.process(detect_cells_block,
                                 source,
                                 sink=None,
                                 function_type='block',
                                 return_result=True,
                                 return_blocks=True,
                                 parameter=cell_detection_parameter,
                                 **processing_parameter)

    #merge results
    results = np.vstack([np.hstack(r) for r in results])

    #create column headers
    header = ['x', 'y', 'z']
    dtypes = [int, int, int]
    if cell_detection_parameter['shape_detection'] is not None:
        header += ['size']
        dtypes += [int]
    measures = cell_detection_parameter['intensity_detection']['measure']
    header += measures
    dtypes += [float] * len(measures)

    dt = {
        'names': header,
        'formats': dtypes
    }
    cells = np.zeros(len(results), dtype=dt)
    for i, h in enumerate(header):
        cells[h] = results[:, i]

    #save results
    return io.write(sink, cells)
示例#4
0
def average(source,
            sink=None,
            shape=None,
            dtype=None,
            weights=None,
            indices=None,
            kernel=None,
            return_counts=False,
            processes=None,
            verbose=False):
    """Averages a list of points into an volumetric image array.
  
  Arguments
  ---------
  source : str, array or Source
    Source of point of nxd coordinates.
  sink : str, array or None
    The sink for the devolved image, if None return array.
  shape : tuple, str or None
    Shape of the final devolved data. If None, determine from points.
    If str, determine shape from the source at the specified location.
  dtype : dtype or None
    Optional data type of the sink.
  weights : array or None
    Weight array of length n for each point. If None, use uniform weights.  
  method : str
    Method for voxelization: 'sphere', 'rectangle' or 'pixel'.
  indices : array 
    The relative indices to the center to devolve over as nxd array.
  kernel : array
    Optional kernel weights for each index in indices.
  processes : int or None
    Number of processes to use.
  verbose : bool
    If True, print progress info.                        
 
  Returns
  -------
  sink : str, array
    Volumetric data of devolved point data.
  """
    processes, timer = ap.initialize_processing(processes=processes,
                                                verbose=verbose,
                                                function='devolve')

    #points, points_buffer = ap.initialize_source(points);
    points_buffer = io.read(source)
    if points_buffer.ndim == 1:
        points_buffer = points_buffer[:, None]

    if sink is None and shape is None:
        if points_buffer.ndim > 1:
            shape = tuple(
                int(math.ceil(points_buffer[:, d].max()))
                for d in range(points_buffer.shape[1]))
        else:
            shape = (int(math.ceil(points_buffer[:].max())), )
    elif isinstance(shape, str):
        shape = io.shape(shape)

    if sink is None and dtype is None:
        if weights is not None:
            dtype = io.dtype(weights)
        elif kernel is not None:
            kernel = np.asarray(kernel)
            dtype = kernel.dtype
        else:
            dtype = int

    sink, sink_buffer, sink_shape, sink_strides = ap.initialize_sink(
        sink=sink,
        shape=shape,
        dtype=dtype,
        return_shape=True,
        return_strides=True,
        as_1d=True)

    #TODO: initialize properly
    counts = np.zeros(sink_shape, dtype=int, order=sink.order)
    counts_buffer = counts.reshape(-1, order='A')
    #print(counts.shape, counts_buffer.shape)

    if indices is None:
        return sink
    indices = np.asarray(indices, dtype=int)
    if indices.ndim == 1:
        indices = indices[:, None]

    if kernel is not None:
        kernel = np.asarray(kernel, dtype=float)

    #print(kernel);
    #print(weights)
    #return;

    code.average(points_buffer, weights, indices, sink_buffer, sink_shape,
                 sink_strides, counts_buffer, processes)
    #  if weights is None:
    #    if kernel is None:
    #      code.devolve_uniform(points_buffer, indices, sink_buffer, sink_shape, sink_strides, processes);
    #    else:
    #      code.devolve_uniform_kernel(points_buffer, indices, kernel, sink_buffer, sink_shape, sink_strides, processes);
    #  else:
    #    if kernel is None:
    #      code.devolve_weights(points_buffer, weights, indices, sink_buffer, sink_shape, sink_strides, processes);
    #    else:
    #      code.devolve_weights_kernel(points_buffer, weights, indices, kernel, sink_buffer, sink_shape, sink_strides, processes);
    #TODO: move to code
    good = counts_buffer > 0
    sink_buffer[good] /= counts_buffer[good]

    ap.finalize_processing(verbose=verbose, function='devolve', timer=timer)

    if return_counts:
        return sink, counts
    else:
        return sink
示例#5
0
def resample_points_inverse(source, sink = None, resample_source = None, resample_sink = None,
                            orientation = None, source_shape = None, sink_shape = None, 
                            source_resolution = None, sink_resolution = None, **args):
  """Resample points from original coordiantes to resampled ones.
  
  Arguments
  ---------
  source : str or array
    Points to be resampled inversely.
  sink : str or None
    Sink for the inversly resmapled points.
  resample_source : str, array or None
    Optional source as in :func:`resample`.
  resample_sink: str, array or None
    Optional sink used in :func:`resample`.
  orientation : tuple
    Orientation as specified in :func:`resample`.
  source_shape : tuple or None
    Optional value of source_shape as in :func:`resample`.
  source_resolution : tuple or None
    Optional value of source_resolution as in :func:`resample`.
  sink_resolution : tuple or None
    Optional value of sink_resolution as in :func:`resample`.
      
  Returns
  -------
  resmapled : array or str
    Sink for the inversly resampled point coordinates.

  Notes
  -----
  * The resampling of points here corresponds to the inverse resampling of 
    an image in :func:`resample`, i.e. to func:`resample_inverse`
  * The arguments should be passed exactly as in :func:`resample` except source
    and sink that point to the point sources. 
    Use resample_source and resmaple_sink to pass the source and sink values
    used in :func:`resample`.
  """
  #orientation
  orientation = format_orientation(orientation);
  
  #original source info
  if source_shape is None:
    if source_resolution is None and resample_source is None:
      raise ValueError('Either source_shape, source_resolution or resample_source must to be given!')
    if resample_source is not None:
      source_shape = io.shape(resample_source);

  #original sink info
  if sink_shape is None and sink_resolution is None: 
    if resample_sink is None:
      sink_shape = io.shape(source);
    else:
      sink_shape = io.shape(resample_sink);
  
  source_shape, sink_shape, source_resolution, sink_resolution = \
      resample_shape(source_shape=source_shape, sink_shape=sink_shape, 
                     source_resolution=source_resolution, sink_resolution=sink_resolution, 
                     orientation=orientation);
  
  sink_shape_in_source_orientation = orient_shape(sink_shape, orientation, inverse=True);
  
  resample_factor = [float(t)/float(s) for s,t in zip(source_shape, sink_shape_in_source_orientation)];
  
  points = io.read(source);
 
  # reorient points
  if orientation is not None:
    #reverse axes
    reslice = False;
    slicing = [slice(None)] * len(source_shape);
    for d,o in enumerate(orientation):
      if o < 0:
        slicing[d] = slice(None, None, -1);
        reslice = True;
    if reslice:
      points = points[slicing];

    #permute
    per = orientation_to_permuation(orientation);
    points = points.transpose(per);
  
  points = points[:] / resample_factor;
  
  return io.write(sink, points);     
示例#6
0
def resample_inverse(source, sink = None, 
                     resample_source = None, resample_sink = None,
                     orientation = None, 
                     source_shape = None, source_resolution = None, 
                     sink_shape = None, sink_resolution = None, 
                     axes_order = None, method = 'memmap',
                     interpolation = 'linear', 
                     processes = None, verbose = True, **args):
  """Resample data inversely to :func:`resample` routine.
  
  Arguments
  ---------
  source : str, array
    Source to be inversly resampled (e.g. sink in :func:`resample`).
  sink : str or None
    Sink to write the inversly resampled image to.
  resample_source : str, array or None
    Optional source in :func:`resample`.
  resmaple_sink: str, array or None
    Optional sink used in :func:`resample`.
  orientation : tuple
    Orientation as specified as in :func:`resample`.
  source_shape : tuple or None
    Optional value of source_shape as in :func:`resample`.
  source_resolution : tuple or None
    Optional value of source_resolution as in :func:`resample`.
  sink_resolution : tuple or None
    Optional value of sink_resolution as in :func:`resample`.
  processing_directory : str or None
    Optional directory in which to perform resmapling in parallel.
    If None, a temporary directry will be created.
  axis_order : list of tuples of int or None
    The axes pairs along which to resample the data as in :func:`resample`.
  method : 'shared' or 'memmap'
    Method to handle intermediate resampling results. If 'shared' use shared 
    memory, otherwise use a memory map on disk.
  interpolation : str
    Method to use for interpolating to the resmapled image. 
  processes int or None
    Number of processes to use for parallel resampling.
  verbose : bool
    If True, print progress information.
   
  Returns
  -------
  resampled : array or str
     Data or file name of inversly resampled image.

  Notes
  -----
  * All arguments, except source and sink should be passed as :func:`resample`
    to invert the resmapling.
  """   
  source = io.as_source(source);
  ndim = source.ndim;
  dtype = source.dtype;
  
  #orientation
  orientation = format_orientation(orientation);
  orientation_inverse = inverse_orientation(orientation);
  
  #original source info
  if source_shape is None:
    if source_resolution is None and resample_source is None:
      raise ValueError('Either source_shape, source_resolution or resample_source must to be given!')
    if resample_source is not None:
      source_shape = io.shape(resample_source);
  
  #original sink info
  if sink_shape is None and sink_resolution is None: 
    if resample_sink is None:
      sink_shape = io.shape(source);
    else:
      sink_shape = io.shape(resample_sink);
  
  source_shape, sink_shape, source_resolution, sink_resolution = \
      resample_shape(source_shape=source_shape, sink_shape=sink_shape, 
                     source_resolution=source_resolution, sink_resolution=sink_resolution, 
                     orientation=orientation);
  
  sink_shape_in_source_orientation = orient_shape(sink_shape, orientation, inverse=True);
  
  axes_order, shape_order = _axes_order(axes_order, source, source_shape, sink_shape_in_source_orientation);
 
  interpolation = _interpolation_to_cv2(interpolation);                                   

  if processes is None or not processes == 'serial':
      processes = io.mp.cpu_count();
  
  #reversed orientation
  if not orientation is None:
    #reverse axes
    slicing = [slice(None)] * ndim;
    reslice = False;
    for d,o in enumerate(orientation):
      if o < 0:
        slicing[d] = slice(None, None, -1);
        reslice = True;
    if reslice:
      source = source[slicing];   
    
    #re-orient
    per = orientation_to_permuation(orientation_inverse);
    source = io.read(source);
    source = source.transpose(per);
    source = io.sma.as_shared(source);
 
  #reverse resampling steps
  axes_order = axes_order[::-1];
  
  shape_order = shape_order[:-1];
  shape_order = shape_order[::-1];
  shape_order = shape_order + [source_shape]
  #print(axes_order, shape_order)
  
  #reverse resampling
  n_steps = len(axes_order);
  last_source = source;
  delete_files = [];
  #print(last_source)
  for step, axes, shape in zip(range(n_steps), axes_order, shape_order):
    if step == n_steps-1:
      resampled = io.initialize(source=sink, shape=shape, dtype=dtype, memory='shared', as_source=True); 
    else:
      if method == 'shared':
        resampled = io.sma.create(shape, dtype=dtype, order='C', as_source=True);
      else:
        location = tempfile.mktemp() + '.npy';
        resampled = io.mmp.create(location, shape=shape, dtype=dtype, order='C', as_source=True);
        delete_files.append(location);

    #indices for non-resampled axes
    indices = tuple([range(s) for d,s in enumerate(shape) if d not in axes]);
    indices = [i for i in itertools.product(*indices)];
    n_indices = len(indices);
    
    #resample step
    last_source_virtual = last_source.as_virtual();
    resampled_virtual = resampled.as_virtual();
    _resample = ft.partial(_resample_2d, source=last_source_virtual, sink=resampled_virtual, axes=axes, shape=shape, 
                                         interpolation=interpolation, n_indices=n_indices, verbose=verbose)                       
    
    if processes == 'serial': 
      for index in indices:
        _resample(index=index);
    else:
      with concurrent.futures.ProcessPoolExecutor(processes) as executor:
        executor.map(_resample, indices);
        
    last_source = resampled;
  
  for f in delete_files:
      io.delete_file(f);  
  
  sink = resampled.as_real();
      
  return sink;
示例#7
0
def resample_shape(source_shape, sink_shape = None, source_resolution = None, sink_resolution = None, orientation = None):
  """Calculate scaling factors and data shapes for resampling.
  
  Arguments
  ---------
  source_shape : tuple
    The shape the source.
  sink_shape : tuple or None
    The shape of the resmapled sink.
  source_resolution : tuple or None
    The resolution of the source.
  sink_resolution : tuple or None
    The resolution of the sink.
  orientation : tuple or str
    The re-orientation specification.
      
  Returns
  -------
  source_shape : tuple
    The shape of the source.
  sink_shape : tuple
    The shape of the sink.
  source_resolution : tuple or None
    The resolution of the source.
  sink_resolution : tuple or None
    The resolution of the sink.
  
  See Also
  --------
  `Orientation`_
  """
  orientation = format_orientation(orientation);    
  
  #determine shapes if not specified
  if sink_shape is None and source_shape is None:
    raise RuntimeError('Source or sink shape must be defined!');
    
  if sink_shape is None and sink_resolution is None:
    raise RuntimeError('Sink shape or resolution must be defined!');
    
  if sink_resolution is None and not isinstance(sink_shape, tuple):
    sink_shape = io.shape(sink_shape);
  
  if source_shape is not None:
    ndim = len(source_shape);
  else:
    ndim = len(sink_shape);
  
  if sink_shape is None:
    if source_resolution is None:
      source_resolution = (1.0,) * ndim;
    if sink_resolution is None:
      sink_resolution = (1.0,) * ndim;
      
    #orient resolution of source to resolution of sink to get sink shape
    source_resolutionO = orient_resolution(source_resolution, orientation);
    source_shapeO      = orient_shape(source_shape, orientation);
    sink_shape = tuple([int(np.ceil(source_shapeO[i] *  float(source_resolutionO[i])/float(sink_resolution[i]))) for i in range(ndim)]);        
  
  if source_shape is None:
    if source_resolution is None:
      source_resolution = (1,) * ndim;
    if sink_resolution is None:
      sink_resolution = (1,) * ndim;
    
    #orient resolution of source to resolution of sink to get sink shape
    source_resolutionO = orient_resolution(source_resolution, orientation);
    source_shape = tuple([int(np.ceil(sink_shape[i] *  float(sink_resolution[i])/float(source_resolutionO[i]))) for i in range(ndim)]);  
    source_shape = orient_shape(source_shape, orientation, inverse=True);
     
  #calculate effecive resolutions
  if source_resolution is None:
    if sink_resolution is None:
      source_resolution = (1,1,1);
    else:
      source_shapeO = orient_shape(source_shape, orientation);
      source_resolution = tuple(float(sink_shape[i]) / float(source_shapeO[i]) * sink_resolution[i] for i in range(ndim));
      source_resolution = orient_resolution(source_resolution, orientation, inverse=True);
  
  source_shapeO = orient_shape(source_shape, orientation);
  source_resolutionO = orient_resolution(source_resolution, orientation);
  sink_resolution = tuple(float(source_shapeO[i]) / float(sink_shape[i]) * source_resolutionO[i] for i in range(ndim));
  
  return source_shape, sink_shape, source_resolution, sink_resolution  
示例#8
0
def binarize(source, sink = None, binarization_parameter = default_binarization_parameter, processing_parameter = default_binarization_processing_parameter):
  """Multi-path binarization of iDISCO+ cleared vasculature data.
  
  Arguments
  ---------
  source : source specification
    The source of the stitched raw data.
  sink : sink specification or None
    The sink to write the result to. If None, an array is returned.
  binarization_parameter : dict
    Parameter for the binarization. See below for details.
  processing_parameter : dict
    Parameter for the parallel processing. 
    See :func:`ClearMap.ParallelProcessing.BlockProcesing.process` for 
    description of all the parameter.
  verbose : bool
    If True, print progress output.
  
  Returns
  -------
  sink : Source
    The result of the binarization.
  
  Notes
  -----
  * The binarization pipeline is composed of several steps. The parameters for
    each step are passed as sub-dictionaries to the binarization_parameter 
    dictionary.
  
  * If None is passed for one of the steps this step is skipped.
  
  * Each step also has an additional parameter 'save' that enables saving of 
    the result of that step to a file to inspect the pipeline.
    
  General parameter
  -----------------
  binary_status : str or None
    File name to save the information about which part of the multi-path 
    binarization contributed to the final result.
    
  max_bin : int
    Number of intensity levels to use for the data after preprocessing.
    Higher values will increase the intensity resolution but slow down
    processing. 
    
    For the vasculature a typical value is 2**12.

  Clipping
  --------
  clip : dict or None
    Clipping and mask generation step parameter.

    clip_range : tuple 
      The range to clip the raw data as (lowest, highest)
      Voxels above lowest define the foregournd mask used 
      in the following steps.
      
      For the vasculature a typical value is (400,60000). 
      
    save : str or None
      Save the result of this step to the specified file if not None.
          
  See also :mod:`ClearMap.ImageProcessing.Clipping.Clipping`
      
  Lightsheet correction
  ---------------------  
  lightsheet : dict or None
    Lightsheet correction step parameter.
   
    percentile : float
      Percentile in [0,1] used to estimate the lightshieet artifact.
      
      For the vasculature a typical value is 0.25.
      
    lightsheet : dict
      Parameter for the ligthsheet artifact percentile estimation. 
      See :func:`ClearMap.ImageProcessing.LightsheetCorrection.correct_lightsheet`
      for list of all parameters. The crucial parameter is
      
      selem : tuple
        The structural element shape used to estimate the stripe artifact.
        It should match the typical lenght, width, and depth of the artifact 
        in the data.
        
        For the vasculature a typical value is (150,1,1).
    
    background : dict
      Parameter for the background estimation in the light sheet correction. 
      See :func:`ClearMap.ImageProcessing.LightsheetCorrection.correct_lightsheet`
      for list of all parameters. The crucial parameters are
      
      selem : tuple
        The structural element shape used to estimate the background.
        It should be bigger than the largest vessels,
        
        For the vasculature a typical value is (200,200,1).

      spacing : tuple
        The spacing to use to estimate the background. Larger spacings speed up
        processing but become less local estimates.
        
        For the vasculature a typical value is (25,25,1)
        
      step : tuple
        This parameter enables to subsample from the entire array defined by
        the structural element using larger than single voxel steps.
        
        For the vasculature a typical value is (2,2,1).
        
      interpolate : int
        The order of the interpoltation used in constructing the full 
        background estimate in case a non-trivial spacing is used.
        
        For the vasculature a typical value is 1.
        
    lightsheet_vs_background : float
      The background is multiplied by this weight before comparing to the
      lightsheet artifact estimate. 
      
      For the vasculature a typical value is 2.
    
    save : str or None
      Save the result of this step to the specified file if not None.

  Median filter
  -------------
  median : dict or None
    Median correction step parameter.
    See :func:`ClearMap.ImageProcessing.Filter.Rank.median` for all parameter.
    The important parameters are

    selem : tuple
      The structural element size for the median filter.
      
      For the vascualture a typical value is (3,3,3).
    
    save : str or None
      Save the result of this step to the specified file if not None.  
  
  Pseudo Deconvolution
  --------------------
  deconvolve : dict
    The deconvolution step parameter.
    
    sigma : float
      The std of a Gaussina filter applied to the high intensity pixel image.
      The number should reflect the scale of the halo effect seen around high
      intensity structures.
      
      For the vasculature a typical value is 10.
    
    save : str or None
      Save the result of this step to the specified file if not None.   
      
    threshold : float 
      Voxels above this threshold will be added to the binarization result
      in the multi-path biniarization.
      
      For the vasculature a typical value is 750.
  
  Adaptive Thresholding
  ---------------------
  adaptive : dict or None
    Adaptive thresholding step parameter.
    A local ISODATA threshold is estimated.
    See also :mod:`ClearMap.ImageProcessing.LocalStatistics`.
    
    selem : tuple
      The structural element size to estimate the percentiles. 
      Should be larger than the larger vessels.
      
      For the vasculature a typical value is (200,200,5).
    
    spacing : tuple
      The spacing used to move the structural elements.
      Larger spacings speed up processing but become locally less precise.
               
      For the vasculature a typical value is (50,50,5)
        
    interpolate : int
      The order of the interpoltation used in constructing the full 
      background estimate in case a non-trivial spacing is used.
      
      For the vasculature a typical value is 1.
      
    save : str or None
      Save the result of this step to the specified file if not None.   


  Equalization
  ------------
  equalize : dict or None
    Equalization step parameter.
    See also :func:`ClearMap.ImageProcessing.LocalStatistics.local_percentile`
    
    precentile : tuple
      The lower and upper percentiles used to estimate the equalization.
      The lower percentile is used for normalization, the upper to limit the
      maximal boost to a maximal intensity above this percentile.
    
      For the vasculature a typical value is (0.4, 0.975).
    
    max_value : float
      The maximal intensity value in the equalized image.
               
      For the vasculature a typical value is 1.5. 
    
    selem : tuple
      The structural element size to estimate the percentiles. 
      Should be larger than the larger vessels.
      
      For the vasculature a typical value is (200,200,5).
    
    spacing : tuple
      The spacing used to move the structural elements.
      Larger spacings speed up processing but become locally less precise.
               
      For the vasculature a typical value is (50,50,5)
        
    interpolate : int
      The order of the interpoltation used in constructing the full 
      background estimate in case a non-trivial spacing is used.
      
      For the vasculature a typical value is 1.
      
    save : str or None
      Save the result of this step to the specified file if not None.   
      
    threshold : float 
      Voxels above this threshold will be added to the binarization result
      in the multi-path biniarization.
      
      For the vasculature a typical value is 1.1.

  Tube filter
  -----------
  vesselize : dict
    The tube filter step parameter.
    
    background : dict or None
      Parameters to correct for local background. See 
      :func:`ClearMap.ImageProcessing.Filter.Rank.percentile`.
      If None, no background correction is done before the tube filter.
      
      selem : tuple
        The structural element specification to estimate the percentiles. 
        Should be larger than the largest vessels intended to be 
        boosted by the tube filter.
        
        For the vasculature a typical value is ('disk', (30,30,1)) .

      percentile : float
        Percentile in [0,1] used to estimate the background.

        For the vasculature a typical value is 0.5.
        
    tubness : dict
      Parameters used for the tube filter. See 
      :func:`ClearMap.ImageProcessing.Differentiation.Hessian.lambda123`.
      
      sigma : float
        The scale of the vessels to boos in the filter.
        
        For the vasculature a typical value is 1.0.
  
    save : str or None
      Save the result of this step to the specified file if not None.   
      
    threshold : float 
      Voxels above this threshold will be added to the binarization result
      in the multi-path biniarization.
      
      For the vasculature a typical value is 120.
  
  Binary filling
  --------------
  fill : dict or None
    If not None, apply a binary filling the binarized result.

  For the vasculature this step is set to None and done globally 
  in the postprocessing step.
  
  Binary smoothing
  ----------------
  smooth : dict or None
    The smoothing parameter passed to 
    :func:`ClearMap.ImageProcessing.Binary.Smoothing.smooth_by_configuration`.
  
  For the vasculature this step is set to None and done globally 
  in the postprocessing step.
  
  References
  ----------
  [1] C. Kirst et al., "Mapping the Fine-Scale Organization and Plasticity of the Brain Vasculature", Cell 180, 780 (2020)
  """
    
  #initialize sink
  shape = io.shape(source);
  order = io.order(source);
  sink, sink_buffer = ap.initialize_sink(sink=sink, shape=shape, order=order, dtype=bool); #, memory='shared');
  
  #initialize addition output sinks  
  binary_status = binarization_parameter.get('binary_status', None);
  if binary_status:
    ap.initialize_sink(binary_status, source=sink, shape=shape, order=order, dtype='uint16');

  for key in binarization_parameter.keys():
    par = binarization_parameter[key];
    if isinstance(par, dict):
      filename = par.get('save', None);
      if filename:
        ap.initialize_sink(filename, shape=shape, order=order, dtype='float');
        
  binarization_parameter.update(verbose=processing_parameter.get('verbose', False));
  
  bp.process(binarize_block, source, sink, function_type='block', parameter=binarization_parameter, **processing_parameter)                   
  
  return sink;                
示例#9
0
    size_intensity = np.hstack(
        [raw_source[c][:, None] for c in ['size', 'background']])
    coordinates_raw = np.hstack([raw_source[c][:, None] for c in 'xyz'])

    # Swap axes to go from horizontal to sagittal orientation
    coordinates_raw_swapped_axes = np.zeros_like(coordinates_raw)
    coordinates_raw_swapped_axes[:, 0] = coordinates_raw[:, 2]
    coordinates_raw_swapped_axes[:, 1] = coordinates_raw[:, 1]
    coordinates_raw_swapped_axes[:, 2] = coordinates_raw[:, 0]

    # Transform cell coordinates from raw 642-space to downsampled 642-space
    coordinates_resampled = res.resample_points(
        coordinates_raw_swapped_axes,
        sink=None,
        orientation=None,
        source_shape=io.shape(ws.filename('stitched'))[::-1],
        sink_shape=io.shape(ch642_downsized_file))

    # Transform cell coordinates from 642-space to 488-space
    coordinates_aligned_to_488 = elx.transform_points(
        coordinates_resampled,
        sink=None,
        transform_directory=os.path.join(elastix_inverse_dir, '488_to_642'),
        temp_file='/tmp/elastix_input_pipeline.bin',
        result_directory='/tmp/elastix_output_pipeline')

    # Change permissions back since transformix alters permissions when it is run
    os.chmod(
        os.path.join(elastix_inverse_dir, '488_to_642',
                     'TransformParameters.0.txt'), 0o777)
    os.chmod(
示例#10
0
def test_completed_cumulatives_in_spheres(points1,
                                          intensities1,
                                          points2,
                                          intensities2,
                                          shape=ano.default_annotation_file,
                                          radius=100,
                                          method='AndresonDarling'):
    """Performs completed cumulative distribution tests for each pixel using points in a ball centered at that cooridnates, returns 4 arrays p value, statistic value, number in each group"""

    #TODO: sinple implementation -> slow -> speed up
    if not isinstance(shape, tuple):
        shape = io.shape(shape)
    if len(shape) != 3:
        raise RuntimeError('Shape expected to be 3d, found %r' % (shape, ))

    # distances^2 to origin
    x1 = points1[:, 0]
    y1 = points1[:, 1]
    z1 = points1[:, 2]
    i1 = intensities1
    d1 = x1 * x1 + y1 * y1 + z1 * z1

    x2 = points2[:, 0]
    y2 = points2[:, 1]
    z2 = points2[:, 2]
    i2 = intensities2
    d2 = x2 * x2 + y2 * y2 + z2 * z2

    r2 = radius * radius
    # TODO: inhomogenous in 3d !

    p = np.zeros(dataSize)
    s = np.zeros(dataSize)
    n1 = np.zeros(dataSize, dtype='int')
    n2 = np.zeros(dataSize, dtype='int')

    for x in range(dataSize[0]):
        #print x
        for y in range(dataSize[1]):
            #print y
            for z in range(dataSize[2]):
                #print z
                d11 = d1 - 2 * (x * x1 + y * y1 + z * z1) + (x * x + y * y +
                                                             z * z)
                d22 = d2 - 2 * (x * x2 + y * y2 + z * z2) + (x * x + y * y +
                                                             z * z)

                ii1 = d11 < r2
                ii2 = d22 < r2

                n1[x, y, z] = ii1.sum()
                n2[x, y, z] = ii2.sum()

                if n1[x, y, z] > 0 and n2[x, y, z] > 0:
                    (pp, ss) = self.testCompletedCumulatives(
                        (i1[ii1], i2[ii2]), method=method)
                else:
                    pp = 0
                    ss = 0

                p[x, y, z] = pp
                s[x, y, z] = ss

    return (p, s, n1, n2)