Example #1
0
    def _calculateSingleId(self):
        """
        Calculates statistics (see method calculate) when ids is a single 
        (int) id.

        Does not calculate statistics on the mean.

        """

        # do calculations for all segments
        self.mean = ndimage.mean(input=self.data,
                                 labels=self.labels,
                                 index=self._ids)
        self.std = ndimage.standard_deviation(input=self.data,
                                              labels=self.labels,
                                              index=self._ids)
        # maximum bug fix
        extr = ndimage.extrema(input=self.data,
                               labels=self.labels,
                               index=self._ids)
        extr_bug = ndimage.extrema(input=-self.data,
                                   labels=self.labels,
                                   index=self._ids)

        # put extrema results in data arrays
        (self.min, self.max) = (extr[0], extr[1])
        self.max = -extr_bug[0]
        self.minPos = extr[2][0]
        #self.maxPos = extr[3][0]
        self.maxPos = extr_bug[2][0]
Example #2
0
def fit_gauss(ph):
    for i in range(4):
		# bepaal de counts en de bingrootte in een range van 0 t/m 1000 ADC
        y, bins =  histogram(ph[i], bins=500, range=[0, 1000]) # loop for elke plaat
        x = (bins[:-1] + bins[1:])/2.  #let op neem bins om het midden te vinden van de bin
        
        if y[np.random.random_integers(200, 300)] != 0 : # ter controle of de data van de detector betrouwbaar is, aangezien plaat 4 503 geen goede data bevatte 3-01-2013
            # vanwege bartels (2012) kiezen we waar de ADC waarde tussen 150 en 410 zit voor de gauss fit, schat geeft de elementen waar tussen gefit moet worden.
            schat = np.where((x > 150) & (x < 600)) # geeft een tweeledig array terug    
            x1 = x[schat[0]] # geeft de waarde van de elementen gevonden met de determinatie hierboven in het eerste element
            #bovenstaande kan ook met x1 = fit_xa[np.where(x>150) & (x< 420)]
            y1 = y[schat] # bepaling van de count in de meting 
            max_min = ndimage.extrema(y1)
            max_y = ndimage.extrema(y1)[1] #maximale count y waarde piek van de gauss!)
        
            min_x = max_min[0]  #  de laagste waarde van de count
            max_x = max_min[1]  # hoogste waarde van de count -> a waarde in de gauss fit
            b_temp = max_min[3]
            b_place = b_temp[0] # b waarde
            b = x1[b_place] # de b-waarde van de gauss curve
        
            bound1 = max_x - (max_x - min_x)*0.75 
        
            if (max_x- min_x) <= 50:
                bound2 = max_x + (max_x - min_x)*1.5
            else:
                bound2 = max_x + (max_x - min_x)
        
            x2 = x1.compress((bound1 <= x1) & (x1 < bound2))
            y2 = y1.compress((bound1 <= x1) & (x1 < bound2))
        
              
            #popt, pcov = curve_fit(func1, x1, y1, [200, 250, 50] ) # werkende fit met een handmatige guess kleine verschillen. orde van 0.2 
            popt, pcov = curve_fit(func1, x1, y1, [max_x, b, 20] ) # fit met guess gebruikt werkt ook
        
            pylab.plot(func1(range(0,600), *popt), '--')
            peak = popt[1]
        
            if i == 0:
                MIP1 = peak
                MPV1.append(MIP1)  #bij herhalen  van de loop oor ander station append deze regel op de juiste manier?
            elif i == 1:
                MIP2 = peak
                MPV2.append(MIP2)
            elif i == 2:
                MIP3 = peak
                MPV3.append(MIP3)
            elif i == 3:
                MIP4 = peak
                MPV4.append(MIP4)
        
            print 'The MPV of detector',i + 1, 'lies at', peak, 'ADC'
        
        else:
            
            print 'The data of the detector ',i + 1, 'could not be fitted to a gauss curve'
def bounding_boxes(seg):
    lbl, nlbl = ndimage.label(seg)
    class_label, _, minxy, maxxy = ndimage.extrema(seg,
                                                   lbl,
                                                   index=np.arange(
                                                       1, nlbl + 1))
    return class_label, minxy, maxxy
Example #4
0
def test_extrema(shape, chunks, has_lbls, ind):
    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = None
    d_lbls = None

    if has_lbls:
        lbls = np.zeros(a.shape, dtype=np.int64)
        lbls += ((a < 0.5).astype(lbls.dtype) + (a < 0.25).astype(lbls.dtype) +
                 (a < 0.125).astype(lbls.dtype) +
                 (a < 0.0625).astype(lbls.dtype))
        d_lbls = da.from_array(lbls, chunks=d.chunks)

    a_r = spnd.extrema(a, lbls, ind)
    d_r = dask_image.ndmeasure.extrema(d, d_lbls, ind)

    assert len(a_r) == len(d_r)

    for i in irange(len(a_r)):
        a_r_i = np.array(a_r[i])
        if a_r_i.dtype != d_r[i].dtype:
            wrn.warn(
                "Encountered a type mismatch."
                " Expected type, %s, but got type, %s."
                "" % (str(a_r_i.dtype), str(d_r[i].dtype)), RuntimeWarning)
        assert a_r_i.shape == d_r[i].shape
        assert np.allclose(a_r_i, np.array(d_r[i]), equal_nan=True)
Example #5
0
    def new_image(self, data):
        """
        Update the window with the new image (the window is resize to have the image
        at ratio 1:1)
        data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
        """
        if data.ndim == 3 and 3 in data.shape: # RGB
            rgb = img.ensureYXC(data)
        elif numpy.prod(data.shape) == data.shape[-1]: # 1D image => bar plot
            # TODO: add "(plot)" to the window title
            # Create a simple bar plot of X x 400 px
            lenx = data.shape[-1]
            leny = 400
            maxy = data.max()
            logging.info("Plot data max = %s", maxy)
            rgb = numpy.zeros((leny, lenx, 3), dtype=numpy.uint8)
            for i, v in numpy.ndenumerate(data):
                h = leny - int((v * leny) / maxy)
                rgb[h:-1, i[-1], :] = 255
        else: # Greyscale (hopefully)
            mn, mx, mnp, mxp = ndimage.extrema(data)
            logging.info("Image data from %s to %s", mn, mx)
            rgb = img.DataArray2RGB(data) # auto brightness/contrast

        self.app.img = NDImage2wxImage(rgb)
        wx.CallAfter(self.app.update_view)
Example #6
0
def normalized_per_object(image, labels):
    """Normalize the intensities of each object to the [0, 1] range."""
    nobjects = labels.max()
    objects = np.arange(nobjects + 1)
    lmin, lmax = scind.extrema(image, labels, objects)[:2]
    # Divisor is the object's max - min, or 1 if they are the same.
    divisor = np.ones((nobjects + 1,))
    divisor[lmax > lmin] = (lmax - lmin)[lmax > lmin]
    return (image - lmin[labels]) / divisor[labels]
Example #7
0
def normalized_per_object(image, labels):
    """Normalize the intensities of each object to the [0, 1] range."""
    nobjects = labels.max()
    objects = np.arange(nobjects + 1)
    lmin, lmax = scind.extrema(image, labels, objects)[:2]
    # Divisor is the object's max - min, or 1 if they are the same.
    divisor = np.ones((nobjects + 1,))
    divisor[lmax > lmin] = (lmax - lmin)[lmax > lmin]
    return (image - lmin[labels]) / divisor[labels]
Example #8
0
def test_extrema02():
    labels = np.array([1, 2])
    for type in types:
        input = np.array([[1, 2], [3, 4]], type)
        output1 = ndimage.extrema(input, labels=labels, index=2)
        output2 = ndimage.minimum(input, labels=labels, index=2)
        output3 = ndimage.maximum(input, labels=labels, index=2)
        output4 = ndimage.minimum_position(input, labels=labels, index=2)
        output5 = ndimage.maximum_position(input, labels=labels, index=2)
        assert_equal(output1, (output2, output3, output4, output5))
Example #9
0
def test_extrema01():
    "extrema 1"
    labels = np.array([1, 0], bool)
    for type in types:
        input = np.array([[1, 2], [3, 4]], type)
        output1 = ndimage.extrema(input, labels=labels)
        output2 = ndimage.minimum(input, labels=labels)
        output3 = ndimage.maximum(input, labels=labels)
        output4 = ndimage.minimum_position(input, labels=labels)
        output5 = ndimage.maximum_position(input, labels=labels)
        assert_equal(output1, (output2, output3, output4, output5))
Example #10
0
def lut(im, table, limits=None):
    "Look up each pixel of an image in a table"
    if limits is None: limits = extrema(im)
    lo, hi = limits
    ny, nx, nc = im.shape  #sizes(im)
    bins = len(table)
    for y in range(0, ny):
        for x in range(0, nx):
            for c in range(0, nc):
                v = (im[y, x, c] - lo) / (hi - lo) * (bins - 1)
                im[y, x, c] = table[int(v)]
Example #11
0
 def new_image(self, data):
     """
     Update the window with the new image (the window is resize to have the image
     at ratio 1:1)
     data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
     """
     mn, mx, mnp, mxp = ndimage.extrema(data)
     logging.info("Image data from %s to %s", mn, mx)
     rgb = DataArray2RGB(data) # auto brightness/contrast
     self.app.img = NDImage2wxImage(rgb)
     wx.CallAfter(self.app.update_view)
Example #12
0
 def f(array, il):
     i = il[0]
     # This function returns (mini, maxi), the indexes of the max
     # and min of the array.  They return the *lowest* possible
     # such indexes, thus the max(0, ...) below.
     min_, max_, mini, maxi = extrema(array)
     #print array, (min_, max_, mini, maxi), mini[0]+i-halfwidth, maxi[0]+i-halfwidth
     minima[max(0, mini[0]+i-halfwidth)] += 1
     maxima[       maxi[0]+i-halfwidth ] += 1
     il[0] += 1
     return 0
Example #13
0
 def new_image(self, data):
     """
     Update the window with the new image (the window is resize to have the image
     at ratio 1:1)
     data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
     """
     mn, mx, mnp, mxp = ndimage.extrema(data)
     logging.info("Image data from %s to %s", mn, mx)
     rgb = DataArray2RGB(data)  # auto brightness/contrast
     self.app.img = NDImage2wxImage(rgb)
     wx.CallAfter(self.app.update_view)
Example #14
0
def test_extrema01():
    labels = np.array([1, 0], bool)
    for type in types:
        input = np.array([[1, 2], [3, 4]], type)
        output1 = ndimage.extrema(input, labels=labels)
        output2 = ndimage.minimum(input, labels=labels)
        output3 = ndimage.maximum(input, labels=labels)
        output4 = ndimage.minimum_position(input,
                                                     labels=labels)
        output5 = ndimage.maximum_position(input,
                                                     labels=labels)
        assert_equal(output1, (output2, output3, output4, output5))
def scipy_features(image):
    histo = ndimage.measurements.histogram(image, 0, 255, 10)
    mini, maxi, minpos, maxpos = ndimage.extrema(image)
    return numpy.concatenate((
        histo,
        minpos,
        maxpos,
        ndimage.measurements.center_of_mass(image),
        [
            mini,
            maxi,
        ]
    ))
Example #16
0
def test_extrema04():
    labels = [1, 2, 0, 4]
    for type in types:
        input = np.array([[5, 4, 2, 5], [3, 7, 8, 2], [1, 5, 1, 1]], type)
        output1 = ndimage.extrema(input, labels, [1, 2])
        output2 = ndimage.minimum(input, labels, [1, 2])
        output3 = ndimage.maximum(input, labels, [1, 2])
        output4 = ndimage.minimum_position(input, labels, [1, 2])
        output5 = ndimage.maximum_position(input, labels, [1, 2])
        assert_array_almost_equal(output1[0], output2)
        assert_array_almost_equal(output1[1], output3)
        assert_array_almost_equal(output1[2], output4)
        assert_array_almost_equal(output1[3], output5)
Example #17
0
def grad_graph(img, interactive=True):
    """
    gradient graph: use gradient to define different objects and then segment the image to those objects
    :param img: image to process
    :return: fragmentation
    """

    blur_radius = 2
    imgf = ndimage.gaussian_filter(img, blur_radius)


    scharr2 = np.array([[ -3, 0,  3],
                       [-10, 0, 10],
                       [ -3, 0,  3]])
    grad = [convolve2d(imgf[:, :, i], scharr2, boundary='symm', mode='same') for i in np.arange(3)]
    grad = np.sum(np.abs(grad), 0, dtype=np.uint8)
    imgf[ndimage.gaussian_filter(grad/np.mean(grad), 3) < 1] = 0
    threshold = np.mean(imgf)
    mask = np.any(imgf > threshold, -1)
    labeled, nr_objects = ndimage.label(mask)
    # labeled: a width X height matrix, in which each pixel of object i is given index i

    sizes = ndimage.sum(mask, labeled, range(nr_objects + 1))
    #plt.title('objects are colored')
    #plt.imshow(labeled)
    #plt.show()
    labeled[(sizes < 1000)[labeled]] = 0  # filter noise
    label_im = np.searchsorted(np.unique(labeled), labeled)
    # TODO: can we do better with widths and heights (Eran: I think it is the way to calc width/height)
    widths_heights = np.abs(np.diff((np.array(ndimage.extrema(mask, label_im, range(np.max(label_im) + 1))[2:])), axis=0)[0, :, :])
    label_im[(widths_heights[:, 0] < 5) | (widths_heights[:, 0] > 800) | (widths_heights[:, 1] > 300)] = 0
    label_im = np.searchsorted(np.unique(label_im), label_im)

    #plt.hist(widths_heights[:, 0],100) width histogram
    #plt.show()

    # now given the objects return their positions (frags)
    frags = ndimage.find_objects(label_im, max_label=np.max(label_im))
    if interactive:
        # show example of one of the words
        img2 = np.array(img, copy=True)
        img2[label_im == 0] = 0
        plt.imshow(img2)
        plt.show()

        #
        fragment_to_show = len(frags)//2
        plt.imshow(img[frags[fragment_to_show]])
        plt.show()

    return frags
Example #18
0
    def new_image(self, data):
        """
        Update the window with the new image (the window is resize to have the image
        at ratio 1:1)
        data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
        """
        if data.ndim == 3 and 3 in data.shape: # RGB
            rgb = img.ensureYXC(data)
        else: # Greyscale (hopefully)
            mn, mx, mnp, mxp = ndimage.extrema(data)
            logging.info("Image data from %s to %s", mn, mx)
            rgb = img.DataArray2RGB(data) # auto brightness/contrast

        self.app.img = NDImage2wxImage(rgb)
        wx.CallAfter(self.app.update_view)
Example #19
0
def test_extrema02():
    "extrema 2"
    labels = np.array([1, 2])
    for type in types:
        input = np.array([[1, 2], [3, 4]], type)
        output1 = ndimage.extrema(input, labels=labels,
                                            index=2)
        output2 = ndimage.minimum(input, labels=labels,
                                            index=2)
        output3 = ndimage.maximum(input, labels=labels,
                                            index=2)
        output4 = ndimage.minimum_position(input,
                                            labels=labels, index=2)
        output5 = ndimage.maximum_position(input,
                                            labels=labels, index=2)
        assert_equal(output1, (output2, output3, output4, output5))
Example #20
0
def test_extrema04():
    labels = [1, 2, 0, 4]
    for type in types:
        input = np.array([[5, 4, 2, 5],
                                [3, 7, 8, 2],
                                [1, 5, 1, 1]], type)
        output1 = ndimage.extrema(input, labels, [1, 2])
        output2 = ndimage.minimum(input, labels, [1, 2])
        output3 = ndimage.maximum(input, labels, [1, 2])
        output4 = ndimage.minimum_position(input, labels,
                                                     [1, 2])
        output5 = ndimage.maximum_position(input, labels,
                                                     [1, 2])
        assert_array_almost_equal(output1[0], output2)
        assert_array_almost_equal(output1[1], output3)
        assert_array_almost_equal(output1[2], output4)
        assert_array_almost_equal(output1[3], output5)
Example #21
0
def test_extrema03():
    labels = np.array([[1, 2], [2, 3]])
    for type in types:
        input = np.array([[1, 2], [3, 4]], type)
        output1 = ndimage.extrema(input, labels=labels, index=[2, 3, 8])
        output2 = ndimage.minimum(input, labels=labels, index=[2, 3, 8])
        output3 = ndimage.maximum(input, labels=labels, index=[2, 3, 8])
        output4 = ndimage.minimum_position(input,
                                           labels=labels,
                                           index=[2, 3, 8])
        output5 = ndimage.maximum_position(input,
                                           labels=labels,
                                           index=[2, 3, 8])
        assert_array_almost_equal(output1[0], output2)
        assert_array_almost_equal(output1[1], output3)
        assert_array_almost_equal(output1[2], output4)
        assert_array_almost_equal(output1[3], output5)
Example #22
0
    def mark_peaks_of_trace(self, absolute=None, relative=None):
        '''Absolute means that the peak-finding is based on the raw value.  
           Relative is a fraction of the maximum. '''
        # Calculate the cutoff
        # The logic is inflated for sanity check 
        if (absolute is not None) and (relative is None):
            ekg_cutoff = absolute
        elif (relative is not None) and (absolute is None):
            ekg_cutoff = self.global_ekg_max * relative
        else:
            # Probably not necessary, as ekg_cutoff would be undefined
            raise RuntimeError("Must sepcify ekg cutoff in one way!")
        
        # Stuff to store internally. 
        self.spike_times = []   # The times in EKG ms offset
        self.spike_number = []  # The number of spikes
        self.spike_heights = [] # The amplitudes

        # For each EKG trace
        for n, tr in enumerate(self.traces):
            # Find the area above the cutoff
            screen = (tr > ekg_cutoff)

            # Label each and record the number of labels
            labels, spike_count = ndimage.label(screen)
            
            # Find the extrema; locations and amplitudes
            indexs_of_spikes = range(1, spike_count + 1)

            # This conditional should not be necessary.  
            # TODO: scipy bug-tracker is down . . .  report this one
            if indexs_of_spikes != []:
                ext = ndimage.extrema(tr, labels=labels, index=indexs_of_spikes)
            else:
                ext = ([],[],[],[])
            
            # Break out the results of the extrema, ignore min-related values
            min_vals, max_vals, min_locs, max_locs = ext

            # Store the values on a per-experiment basis
            # The arrays appended _could_ be empty, but will be an object . . . 
            # so the offsets will still be correct.
            self.spike_times.append( array(max_locs).flatten() )
            self.spike_number.append( spike_count )
            self.spike_heights.append( array(max_vals).flatten() ) 
Example #23
0
def test_extrema03():
    labels = np.array([[1, 2], [2, 3]])
    for type in types:
        input = np.array([[1, 2], [3, 4]], type)
        output1 = ndimage.extrema(input, labels=labels,
                                            index=[2, 3, 8])
        output2 = ndimage.minimum(input, labels=labels,
                                            index=[2, 3, 8])
        output3 = ndimage.maximum(input, labels=labels,
                                            index=[2, 3, 8])
        output4 = ndimage.minimum_position(input,
                                    labels=labels, index=[2, 3, 8])
        output5 = ndimage.maximum_position(input,
                                    labels=labels, index=[2, 3, 8])
        assert_array_almost_equal(output1[0], output2)
        assert_array_almost_equal(output1[1], output3)
        assert_array_almost_equal(output1[2], output4)
        assert_array_almost_equal(output1[3], output5)
Example #24
0
 def new_image(self, data):
     """
     Update the window with the new image (the window is resize to have the image
     at ratio 1:1)
     data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
     """
     if data.ndim == 3 and 3 in data.shape:  # RGB
         rgb = img.ensureYXC(data)
     elif numpy.prod(data.shape) == data.shape[-1]:  # 1D image => bar plot
         # TODO: add "(plot)" to the window title
         # Create a simple bar plot of X x 400 px
         lenx = data.shape[-1]
         if lenx > MAX_WIDTH:
             binning = lenx // MAX_WIDTH
             data = data[..., 0::binning]
             logging.debug("Compressed data from %d to %d elements", lenx,
                           data.shape[-1])
             lenx = data.shape[-1]
         leny = 400
         miny = min(0, data.min())
         maxy = data.max()
         diffy = maxy - miny
         if diffy == 0:
             diffy = 1
         logging.info("Plot data from %s to %s", miny, maxy)
         rgb = numpy.zeros((leny, lenx, 3), dtype=numpy.uint8)
         for i, v in numpy.ndenumerate(data):
             # TODO: have the base at 0, instead of miny, so that negative values are columns going down
             h = leny - int(((v - miny) * leny) / diffy)
             rgb[h:-1, i[-1], :] = 255
     else:  # Greyscale (hopefully)
         mn, mx, mnp, mxp = ndimage.extrema(data)
         logging.info("Image data from %s to %s", mn, mx)
         rgb = img.DataArray2RGB(data)  # auto brightness/contrast
     self.app.spots, self.app.translation, self.app.scaling, self.app.rotation = FindGridSpots(
         data, self.gridsize)
     self.app.img = NDImage2wxImage(rgb)
     wx.CallAfter(self.app.update_view)
Example #25
0
 def new_image(self, data):
     """
     Update the window with the new image (the window is resize to have the image
     at ratio 1:1)
     data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
     """
     if data.ndim == 3 and 3 in data.shape:  # RGB
         rgb = img.ensureYXC(data)
     elif numpy.prod(data.shape) == data.shape[-1]:  # 1D image => bar plot
         # TODO: add "(plot)" to the window title
         # Create a simple bar plot of X x 400 px
         lenx = data.shape[-1]
         if lenx > MAX_WIDTH:
             binning = lenx // MAX_WIDTH
             data = data[..., 0::binning]
             logging.debug("Compressed data from %d to %d elements", lenx, data.shape[-1])
             lenx = data.shape[-1]
         leny = 400
         miny = min(0, data.min())
         maxy = data.max()
         diffy = maxy - miny
         if diffy == 0:
             diffy = 1
         logging.info("Plot data from %s to %s", miny, maxy)
         rgb = numpy.zeros((leny, lenx, 3), dtype=numpy.uint8)
         for i, v in numpy.ndenumerate(data):
             # TODO: have the base at 0, instead of miny, so that negative values are columns going down
             h = leny - int(((v - miny) * leny) / diffy)
             rgb[h:-1, i[-1], :] = 255
     else:  # Greyscale (hopefully)
         mn, mx, mnp, mxp = ndimage.extrema(data)
         logging.info("Image data from %s to %s", mn, mx)
         rgb = img.DataArray2RGB(data)  # auto brightness/contrast
     self.app.spots, self.app.translation, self.app.scaling, self.app.rotation = FindGridSpots(data, self.gridsize)
     self.app.img = NDImage2wxImage(rgb)
     wx.CallAfter(self.app.update_view)
    def run(self, workspace):
        objects = workspace.object_set.get_objects(self.object_name.value)
        assert isinstance(objects, cpo.Objects)
        has_pixels = objects.areas > 0
        labels = objects.small_removed_segmented
        kept_labels = objects.segmented
        neighbor_objects = workspace.object_set.get_objects(self.neighbors_name.value)
        assert isinstance(neighbor_objects, cpo.Objects)
        neighbor_labels = neighbor_objects.small_removed_segmented
        #
        # Need to add in labels touching border.
        #
        unedited_segmented = neighbor_objects.unedited_segmented
        touching_border = np.zeros(np.max(unedited_segmented) + 1, bool)
        touching_border[unedited_segmented[0, :]] = True
        touching_border[unedited_segmented[-1, :]] = True
        touching_border[unedited_segmented[:, 0]] = True
        touching_border[unedited_segmented[:, -1]] = True
        touching_border[0] = False
        touching_border_mask = touching_border[unedited_segmented]
        if np.any(touching_border) and \
           np.all(~ touching_border_mask[neighbor_labels]):
            # Add the border labels if any were excluded
            touching_border_object_number = np.cumsum(touching_border) + \
                np.max(neighbor_labels)
            touching_border_mask = touching_border_mask & neighbor_labels == 0
            neighbor_labels[touching_border_mask] = touching_border_object_number[
                unedited_segmented[touching_border_mask]]
        
        nobjects = np.max(labels)
        nneighbors = np.max(neighbor_labels)
        nkept_objects = objects.count
        _, object_numbers = objects.relate_labels(labels, kept_labels)
        if self.neighbors_are_objects:
            neighbor_numbers = object_numbers
        else:
            _, neighbor_numbers = neighbor_objects.relate_labels(
                neighbor_labels, neighbor_objects.segmented)
        neighbor_count = np.zeros((nobjects,))
        pixel_count = np.zeros((nobjects,))
        first_object_number = np.zeros((nobjects,),int)
        second_object_number = np.zeros((nobjects,),int)
        first_x_vector = np.zeros((nobjects,))
        second_x_vector = np.zeros((nobjects,))
        first_y_vector = np.zeros((nobjects,))
        second_y_vector = np.zeros((nobjects,))
        angle = np.zeros((nobjects,))
        percent_touching = np.zeros((nobjects,))
        expanded_labels = None
        if self.distance_method == D_EXPAND:
            # Find the i,j coordinates of the nearest foreground point
            # to every background point
            i,j = scind.distance_transform_edt(labels==0,
                                               return_distances=False,
                                               return_indices=True)
            # Assign each background pixel to the label of its nearest
            # foreground pixel. Assign label to label for foreground.
            labels = labels[i,j]
            expanded_labels = labels  # for display
            distance = 1 # dilate once to make touching edges overlap
            scale = S_EXPANDED
            if self.neighbors_are_objects:
                neighbor_labels = labels.copy()
        elif self.distance_method == D_WITHIN:
            distance = self.distance.value
            scale = str(distance)
        elif self.distance_method == D_ADJACENT:
            distance = 1
            scale = S_ADJACENT
        else:
            raise ValueError("Unknown distance method: %s" %
                             self.distance_method.value)
        if nneighbors > (1 if self.neighbors_are_objects else 0):
            first_objects = []
            second_objects = []
            object_indexes = np.arange(nobjects, dtype=np.int32)+1
            #
            # First, compute the first and second nearest neighbors,
            # and the angles between self and the first and second
            # nearest neighbors
            #
            ocenters = centers_of_labels(
                objects.small_removed_segmented).transpose()
            ncenters = centers_of_labels(
                neighbor_objects.small_removed_segmented).transpose()
            areas = fix(scind.sum(np.ones(labels.shape),labels, object_indexes))
            perimeter_outlines = outline(labels)
            perimeters = fix(scind.sum(
                np.ones(labels.shape), perimeter_outlines, object_indexes))
                                       
            i,j = np.mgrid[0:nobjects,0:nneighbors]
            distance_matrix = np.sqrt((ocenters[i,0] - ncenters[j,0])**2 +
                                      (ocenters[i,1] - ncenters[j,1])**2)
            #
            # order[:,0] should be arange(nobjects)
            # order[:,1] should be the nearest neighbor
            # order[:,2] should be the next nearest neighbor
            #
            if distance_matrix.shape[1] == 1:
                # a little buggy, lexsort assumes that a 2-d array of
                # second dimension = 1 is a 1-d array
                order = np.zeros(distance_matrix.shape, int)
            else:
                order = np.lexsort([distance_matrix])
            first_neighbor = 1 if self.neighbors_are_objects else 0
            first_object_index = order[:, first_neighbor]
            first_x_vector = ncenters[first_object_index,1] - ocenters[:,1]
            first_y_vector = ncenters[first_object_index,0] - ocenters[:,0]
            if nneighbors > first_neighbor+1:
                second_object_index = order[:, first_neighbor + 1]
                second_x_vector = ncenters[second_object_index,1] - ocenters[:,1]
                second_y_vector = ncenters[second_object_index,0] - ocenters[:,0]
                v1 = np.array((first_x_vector,first_y_vector))
                v2 = np.array((second_x_vector,second_y_vector))
                #
                # Project the unit vector v1 against the unit vector v2
                #
                dot = (np.sum(v1*v2,0) / 
                       np.sqrt(np.sum(v1**2,0)*np.sum(v2**2,0)))
                angle = np.arccos(dot) * 180. / np.pi
            
            # Make the structuring element for dilation
            strel = strel_disk(distance)
            #
            # A little bigger one to enter into the border with a structure
            # that mimics the one used to create the outline
            #
            strel_touching = strel_disk(distance + .5)
            #
            # Get the extents for each object and calculate the patch
            # that excises the part of the image that is "distance"
            # away
            i,j = np.mgrid[0:labels.shape[0],0:labels.shape[1]]
            min_i, max_i, min_i_pos, max_i_pos =\
                scind.extrema(i,labels,object_indexes)
            min_j, max_j, min_j_pos, max_j_pos =\
                scind.extrema(j,labels,object_indexes)
            min_i = np.maximum(fix(min_i)-distance,0).astype(int)
            max_i = np.minimum(fix(max_i)+distance+1,labels.shape[0]).astype(int)
            min_j = np.maximum(fix(min_j)-distance,0).astype(int)
            max_j = np.minimum(fix(max_j)+distance+1,labels.shape[1]).astype(int)
            #
            # Loop over all objects
            # Calculate which ones overlap "index"
            # Calculate how much overlap there is of others to "index"
            #
            for object_number in object_numbers:
                if object_number == 0:
                    #
                    # No corresponding object in small-removed. This means
                    # that the object has no pixels, e.g. not renumbered.
                    #
                    continue
                index = object_number - 1
                patch = labels[min_i[index]:max_i[index],
                               min_j[index]:max_j[index]]
                npatch = neighbor_labels[min_i[index]:max_i[index],
                                         min_j[index]:max_j[index]]
                #
                # Find the neighbors
                #
                patch_mask = patch==(index+1)
                extended = scind.binary_dilation(patch_mask,strel)
                neighbors = np.unique(npatch[extended])
                neighbors = neighbors[neighbors != 0]
                if self.neighbors_are_objects:
                    neighbors = neighbors[neighbors != object_number]
                nc = len(neighbors)
                neighbor_count[index] = nc
                if nc > 0:
                    first_objects.append(np.ones(nc,int) * object_number)
                    second_objects.append(neighbors)
                if self.neighbors_are_objects:
                    #
                    # Find the # of overlapping pixels. Dilate the neighbors
                    # and see how many pixels overlap our image. Use a 3x3
                    # structuring element to expand the overlapping edge
                    # into the perimeter.
                    #
                    outline_patch = perimeter_outlines[
                        min_i[index]:max_i[index],
                        min_j[index]:max_j[index]] == object_number
                    extended = scind.binary_dilation(
                        (patch != 0) & (patch != object_number), strel_touching)
                    overlap = np.sum(outline_patch & extended)
                    pixel_count[index] = overlap
            if sum([len(x) for x in first_objects]) > 0:
                first_objects = np.hstack(first_objects)
                reverse_object_numbers = np.zeros(
                    max(np.max(object_numbers), np.max(first_objects)) + 1, int)
                reverse_object_numbers[object_numbers] = np.arange(len(object_numbers)) + 1
                first_objects = reverse_object_numbers[first_objects]
    
                second_objects = np.hstack(second_objects)
                reverse_neighbor_numbers = np.zeros(
                    max(np.max(neighbor_numbers), np.max(second_objects)) + 1, int)
                reverse_neighbor_numbers[neighbor_numbers] = np.arange(len(neighbor_numbers)) + 1
                second_objects= reverse_neighbor_numbers[second_objects]
                to_keep = (first_objects > 0) & (second_objects > 0)
                first_objects = first_objects[to_keep]
                second_objects  = second_objects[to_keep]
            else:
                first_objects = np.zeros(0, int)
                second_objects = np.zeros(0, int)
            if self.neighbors_are_objects:
                percent_touching = pixel_count * 100 / perimeters
            else:
                percent_touching = pixel_count * 100.0 / areas
            object_indexes = object_numbers - 1
            neighbor_indexes = neighbor_numbers - 1
            #
            # Have to recompute nearest
            #
            first_object_number = np.zeros(nkept_objects, int)
            second_object_number = np.zeros(nkept_objects, int)
            if nkept_objects > (1 if self.neighbors_are_objects else 0):
                di = (ocenters[object_indexes[:, np.newaxis], 0] - 
                      ncenters[neighbor_indexes[np.newaxis, :], 0])
                dj = (ocenters[object_indexes[:, np.newaxis], 1] - 
                      ncenters[neighbor_indexes[np.newaxis, :], 1])
                distance_matrix = np.sqrt(di*di + dj*dj)
                distance_matrix[~ has_pixels, :] = np.inf
                distance_matrix[:, ~has_pixels] = np.inf
                #
                # order[:,0] should be arange(nobjects)
                # order[:,1] should be the nearest neighbor
                # order[:,2] should be the next nearest neighbor
                #
                order = np.lexsort([distance_matrix]).astype(
                    first_object_number.dtype)
                if self.neighbors_are_objects:
                    first_object_number[has_pixels] = order[has_pixels,1] + 1
                    if nkept_objects > 2:
                        second_object_number[has_pixels] = order[has_pixels,2] + 1
                else:
                    first_object_number[has_pixels] = order[has_pixels,0] + 1
                    if nneighbors > 1:
                        second_object_number[has_pixels] = order[has_pixels,1] + 1
        else:
            object_indexes = object_numbers - 1
            neighbor_indexes = neighbor_numbers - 1
            first_objects = np.zeros(0, int)
            second_objects = np.zeros(0, int)
        #
        # Now convert all measurements from the small-removed to
        # the final number set.
        #
        neighbor_count = neighbor_count[object_indexes]
        neighbor_count[~ has_pixels] = 0
        percent_touching = percent_touching[object_indexes]
        percent_touching[~ has_pixels] = 0
        first_x_vector = first_x_vector[object_indexes]
        second_x_vector = second_x_vector[object_indexes]
        first_y_vector = first_y_vector[object_indexes]
        second_y_vector = second_y_vector[object_indexes]
        angle = angle[object_indexes]
        #
        # Record the measurements
        #
        assert(isinstance(workspace, cpw.Workspace))
        m = workspace.measurements
        assert(isinstance(m, cpmeas.Measurements))
        image_set = workspace.image_set
        features_and_data = [
            (M_NUMBER_OF_NEIGHBORS, neighbor_count),
            (M_FIRST_CLOSEST_OBJECT_NUMBER, first_object_number),
            (M_FIRST_CLOSEST_DISTANCE, np.sqrt(first_x_vector**2+first_y_vector**2)),
            (M_SECOND_CLOSEST_OBJECT_NUMBER, second_object_number),
            (M_SECOND_CLOSEST_DISTANCE, np.sqrt(second_x_vector**2+second_y_vector**2)),
            (M_ANGLE_BETWEEN_NEIGHBORS, angle)]
        if self.neighbors_are_objects:
            features_and_data.append((M_PERCENT_TOUCHING, percent_touching))
        for feature_name, data in features_and_data:
            m.add_measurement(self.object_name.value,
                              self.get_measurement_name(feature_name),
                              data)
        if len(first_objects) > 0:
            m.add_relate_measurement(
                self.module_num, 
                cpmeas.NEIGHBORS,
                self.object_name.value,
                self.object_name.value if self.neighbors_are_objects 
                else self.neighbors_name.value,
                m.image_set_number * np.ones(first_objects.shape, int),
                first_objects,
                m.image_set_number * np.ones(second_objects.shape, int),
                second_objects)
                                 
        labels = kept_labels
        
        neighbor_count_image = np.zeros(labels.shape,int)
        object_mask = objects.segmented != 0
        object_indexes = objects.segmented[object_mask]-1
        neighbor_count_image[object_mask] = neighbor_count[object_indexes]
        workspace.display_data.neighbor_count_image = neighbor_count_image
        
        if self.neighbors_are_objects:
            percent_touching_image = np.zeros(labels.shape)
            percent_touching_image[object_mask] = percent_touching[object_indexes]
            workspace.display_data.percent_touching_image = percent_touching_image
        
        image_set = workspace.image_set
        if self.wants_count_image.value:
            neighbor_cm_name = self.count_colormap.value
            neighbor_cm = get_colormap(neighbor_cm_name)
            sm = matplotlib.cm.ScalarMappable(cmap = neighbor_cm)
            img = sm.to_rgba(neighbor_count_image)[:,:,:3]
            img[:,:,0][~ object_mask] = 0
            img[:,:,1][~ object_mask] = 0
            img[:,:,2][~ object_mask] = 0
            count_image = cpi.Image(img, masking_objects = objects)
            image_set.add(self.count_image_name.value, count_image)
        else:
            neighbor_cm_name = cpprefs.get_default_colormap()
            neighbor_cm = matplotlib.cm.get_cmap(neighbor_cm_name)
        if self.neighbors_are_objects and self.wants_percent_touching_image:
            percent_touching_cm_name = self.touching_colormap.value
            percent_touching_cm = get_colormap(percent_touching_cm_name)
            sm = matplotlib.cm.ScalarMappable(cmap = percent_touching_cm)
            img = sm.to_rgba(percent_touching_image)[:,:,:3]
            img[:,:,0][~ object_mask] = 0
            img[:,:,1][~ object_mask] = 0
            img[:,:,2][~ object_mask] = 0
            touching_image = cpi.Image(img, masking_objects = objects)
            image_set.add(self.touching_image_name.value,
                          touching_image)
        else:
            percent_touching_cm_name = cpprefs.get_default_colormap()
            percent_touching_cm = matplotlib.cm.get_cmap(percent_touching_cm_name)

        if self.show_window:
            workspace.display_data.neighbor_cm_name = neighbor_cm_name
            workspace.display_data.percent_touching_cm_name = percent_touching_cm_name
            workspace.display_data.orig_labels = objects.segmented
            workspace.display_data.expanded_labels = expanded_labels
            workspace.display_data.object_mask = object_mask
 def _extrema_x(self):
     # npg aggregate min/max is very slow, use scipy.ndimage instead.
     mi, ma, _, _ = ndi.extrema(self._xs, self._flat, self._group_idx)
     return mi, ma
def find_MPV(fit, conv=1):
    """Determine the ADC value of the MPV for each detector

    For pulseheights use conv = 1
    For pulseintegral values use conv = 10

    Returns a tuple of MPV values

    """
    MPV1, MPV2, MPV3, MPV4 = [], [], [], []

    for i in range(4): ##4 DETECTOREN
        try:
            y, bins, patches = plt.hist(fit[i], bins=linspace(0, conv * 2000 / 0.57, STEPSIZE), label="Data")

            x = bins[:-1] + .5 * (bins[1] - bins[0])

            # A first approximation of the position of the MPV and the minimum to the left is made. Used for fit bounds and initial guess of the parameters.
            guess_max_x = ndimage.extrema(y.compress((conv * 150 <= x) & (x < conv * 410)))[3][0] + len(y.compress(x < conv * 150))
            guess_max_x = x[guess_max_x]
            guess_min_x = ndimage.extrema(y.compress((conv * 53 <= x) & (x < guess_max_x)))[2][0] + len(y.compress(x < conv * 53))
            guess_min_x = max([conv * 120, x[guess_min_x]])
            guess_max_y = ndimage.extrema(y.compress((conv * 150 <= x) & (x < conv * 410)))[1]
            guess_min_y = ndimage.extrema(y.compress((conv * 53 <= x) & (x < guess_max_x)))[0]

            g0 = guess_max_y
            g1 = guess_max_x

            # The fit range. Since the right side of the ph histogram is most similar to a Gauss function, we do not want to set bound 2 too small.
            bound1 = guess_min_x + (guess_max_x - guess_min_x) / 4

            if (guess_max_x - guess_min_x) <= conv * 50:
                bound2 = guess_max_x + (guess_max_x - guess_min_x) * 1.5
            else:
                bound2 = guess_max_x + (guess_max_x - guess_min_x)

            # Fit a Gaussian to the peak.
            f = lambda x, a, b, c: a * exp(-((x - b) ** 2) / c)
            x2 = x.compress((bound1 <= x) & (x < bound2))
            y2 = y.compress((bound1 <= x) & (x < bound2))
            popt, pcov = optimize.curve_fit(f, x2, y2, (g0, g1, (guess_max_x - guess_min_x) / 2), sigma=sqrt(y2))

            # Find the x value of the peak:
            peak = popt[1]
            print ('The MPV of the pulseheight of detector %d lies at %d ADC' %
                   (i + 1, peak))

        # Safety nets: prevent the code from terminating if an error occurs
        except IndexError:
            peak = nan
            print 'Apparently there is no data'
        except RuntimeError:
            peak = nan
            print 'Unable to make a good fit'
        except TypeError:
            peak = nan
            print 'Not enough data to make a proper fit' # When it uses less than three bins to make the fit you get this error
        except ValueError:
            peak = nan
            print 'Value Error Occured'

        if i == 0:
            MIP1 = peak
        elif i == 1:
            MIP2 = peak
        elif i == 2:
            MIP3 = peak
        elif i == 3:
            MIP4 = peak

    mpv = (MIP1, MIP2, MIP3, MIP4)
    return mpv
Example #29
0
 def measure_worms(self, workspace, labels, nworms, width):
     m = workspace.measurements
     assert isinstance(m, cpmeas.Measurements)
     object_name = self.straightened_objects_name.value
     nbins_vertical = self.number_of_segments.value
     nbins_horizontal = self.number_of_stripes.value
     params = self.read_params(workspace)
     if nworms == 0:
         # # # # # # # # # # # # # # # # # # # # # #
         #
         # Record measurements if no worms
         #
         # # # # # # # # # # # # # # # # # # # # # #
         for ftr in (FTR_MEAN_INTENSITY, FTR_STD_INTENSITY):
             for group in self.images:
                 image_name = group.straightened_image_name.value
                 if nbins_vertical > 1:
                     for b in range(nbins_vertical):
                         measurement = "_".join(
                             (C_WORM, ftr, image_name, 
                              self.get_scale_name(None, b)))
                         m.add_measurement(object_name, measurement,
                                           np.zeros((0)))
                 if nbins_horizontal > 1:
                     for b in range(nbins_horizontal):
                         measurement = "_".join(
                             (C_WORM, ftr, image_name, 
                              self.get_scale_name(b, None)))
                         m.add_measurement(object_name, measurement,
                                           np.zeros((0)))
                     if nbins_vertical > 1:
                         for v in range(nbins_vertical):
                             for h in range(nbins_horizontal):
                                 measurement = "_".join(
                                     (C_WORM, ftr, image_name, 
                                      self.get_scale_name(h, v)))
                                 m.add_measurement(object_name, measurement,
                                                   np.zeros((0)))
                                 
     else:
         #
         # Find the minimum and maximum i coordinate of each worm
         #
         object_set = workspace.object_set
         assert isinstance(object_set, cpo.ObjectSet)
         orig_objects = object_set.get_objects(self.objects_name.value)
 
         i,j = np.mgrid[0:labels.shape[0], 0:labels.shape[1]]
         min_i, max_i, _, _ = extrema(i, labels, orig_objects.indices)
         min_i = np.hstack(([0], min_i))
         max_i = np.hstack(([labels.shape[0]], max_i)) + 1
         heights = max_i - min_i
         
         # # # # # # # # # # # # # # # # #
         #
         # Create up to 3 spaces which represent the gridding
         # of the worm and create a coordinate mapping into
         # this gridding for each straightened worm
         #
         # # # # # # # # # # # # # # # # #
         griddings = []
         if nbins_vertical > 1:
             scales = np.array([self.get_scale_name(None, b)
                                for b in range(nbins_vertical)])
             scales.shape = (nbins_vertical, 1)
             griddings += [(nbins_vertical, 1, scales)]
         if nbins_horizontal > 1:
             scales = np.array([self.get_scale_name(b, None)
                                for b in range(nbins_horizontal)])
             scales.shape = (1, nbins_horizontal)
             griddings += [(1, nbins_horizontal, scales)]
             if nbins_vertical > 1:
                 scales = np.array([
                     [self.get_scale_name(h,v) for h in range(nbins_horizontal)]
                     for v in range(nbins_vertical)])
                 griddings += [(nbins_vertical, nbins_horizontal, scales)]
         
         for i_dim, j_dim, scales in griddings:
             # # # # # # # # # # # # # # # # # # # # # #
             #
             # Start out mapping every point to a 1x1 space
             #
             # # # # # # # # # # # # # # # # # # # # # #
             labels1 = labels.copy()
             i,j = np.mgrid[0:labels.shape[0], 0:labels.shape[1]]
             i_frac = (i - min_i[labels]).astype(float) / heights[labels]
             i_frac_end = i_frac + 1.0 / heights[labels].astype(float)
             i_radius_frac = (i - min_i[labels]).astype(float) / (heights[labels] - 1)
             labels1[(i_frac >= 1) | (i_frac_end <= 0)] = 0
             # # # # # # # # # # # # # # # # # # # # # #
             #
             # Map the horizontal onto the grid.
             #
             # # # # # # # # # # # # # # # # # # # # # #
             radii = np.array(params.radii_from_training)
             #
             # For each pixel in the image, find the center of its worm
             # in the j direction (the width)
             #
             j_center = int(width / 2) + width * (labels-1)
             #
             # Find which segment (from the training set) per pixel in
             # a fractional form
             #
             i_index = i_radius_frac * (len(radii) - 1)
             #
             # Interpolate
             #
             i_index_frac = i_index - np.floor(i_index)
             i_index_frac[i_index >= len(radii) - 1] = 1
             i_index = np.minimum(i_index.astype(int), len(radii) - 2)
             r = np.ceil((radii[i_index] * (1 - i_index_frac) + 
                          radii[i_index+1] * i_index_frac))
             #
             # Map the worm width into the space 0-1
             #
             j_frac = (j - j_center + r) / (r * 2 + 1)
             j_frac_end = j_frac + 1.0 / (r * 2 + 1)
             labels1[(j_frac >= 1) | (j_frac_end <= 0)] = 0
             #
             # Map the worms onto the gridding.
             #
             i_mapping = np.maximum(i_frac * i_dim, 0)
             i_mapping_end = np.minimum(i_frac_end * i_dim, i_dim)
             j_mapping = np.maximum(j_frac * j_dim, 0)
             j_mapping_end = np.minimum(j_frac_end  * j_dim, j_dim)
             i_mapping = i_mapping[labels1 > 0]
             i_mapping_end = i_mapping_end[labels1 > 0]
             j_mapping = j_mapping[labels1 > 0]
             j_mapping_end = j_mapping_end[labels1 > 0]
             labels_1d = labels1[labels1 > 0]
             i = i[labels1 > 0]
             j = j[labels1 > 0]
             
             #
             # There are easy cases and hard cases. The easy cases are
             # when a pixel in the input space wholly falls in the
             # output space.
             #
             easy = ((i_mapping.astype(int) == i_mapping_end.astype(int)) &
                     (j_mapping.astype(int) == j_mapping_end.astype(int)))
             
             i_src = i[easy]
             j_src = j[easy]
             i_dest = i_mapping[easy].astype(int)
             j_dest = j_mapping[easy].astype(int)
             weight = np.ones(i_src.shape)
             labels_src = labels_1d[easy]
             #
             # The hard cases start in one pixel in the binning space,
             # possibly continue through one or more intermediate pixels
             # in horribly degenerate cases and end in a final
             # partial pixel.
             #
             # More horribly, a pixel in the straightened space
             # might span two or more in the binning space in the I
             # direction, the J direction or both.
             #
             if not np.all(easy):
                 i = i[~ easy]
                 j = j[~ easy]
                 i_mapping = i_mapping[~ easy]
                 j_mapping = j_mapping[~ easy]
                 i_mapping_end = i_mapping_end[~ easy]
                 j_mapping_end = j_mapping_end[~ easy]
                 labels_1d = labels_1d[~ easy]
                 #
                 # A pixel in the straightened space can be wholly within
                 # a pixel in the bin space, it can straddle two pixels
                 # or straddle two and span one or more. It can do different
                 # things in the I and J direction.
                 #
                 # --- The number of pixels wholly spanned ---
                 #
                 i_span = np.maximum(np.floor(i_mapping_end) - np.ceil(i_mapping), 0)
                 j_span = np.maximum(np.floor(j_mapping_end) - np.ceil(j_mapping), 0)
                 #
                 # --- The fraction of a pixel covered by the lower straddle
                 #
                 i_low_straddle = i_mapping.astype(int) + 1 - i_mapping
                 j_low_straddle = j_mapping.astype(int) + 1 - j_mapping
                 #
                 # Segments that start at exact pixel boundaries and span
                 # whole pixels have low fractions that are 1. The span
                 # length needs to have these subtracted from it.
                 #
                 i_span[i_low_straddle == 1] -= 1
                 j_span[j_low_straddle == 1] -= 1
                 #
                 # --- the fraction covered by the upper straddle
                 #
                 i_high_straddle = i_mapping_end - i_mapping_end.astype(int)
                 j_high_straddle = j_mapping_end - j_mapping_end.astype(int)
                 #
                 # --- the total distance across the binning space
                 #
                 i_total = i_low_straddle + i_span + i_high_straddle
                 j_total = j_low_straddle + j_span + j_high_straddle
                 #
                 # --- The fraction in the lower straddle
                 #
                 i_low_frac = i_low_straddle / i_total
                 j_low_frac = j_low_straddle / j_total
                 #
                 # --- The fraction in the upper straddle
                 #
                 i_high_frac = i_high_straddle / i_total
                 j_high_frac = j_high_straddle / j_total
                 #
                 # later on, the high fraction will overwrite the low fraction
                 # for i and j hitting on a single pixel in the bin space
                 #
                 i_high_frac[(i_mapping.astype(int) == i_mapping_end.astype(int))] = 1
                 j_high_frac[(j_mapping.astype(int) == j_mapping_end.astype(int))] = 1
                 #
                 # --- The fraction in spans
                 #
                 i_span_frac = i_span / i_total
                 j_span_frac = j_span / j_total
                 #
                 # --- The number of bins touched by each pixel
                 #
                 i_count = (np.ceil(i_mapping_end) - np.floor(i_mapping)).astype(int)
                 j_count = (np.ceil(j_mapping_end) - np.floor(j_mapping)).astype(int)
                 #
                 # --- For I and J, calculate the weights for each pixel
                 #     along each axis.
                 #
                 i_idx = INDEX.Indexes([i_count])
                 j_idx = INDEX.Indexes([j_count])
                 i_weights = i_span_frac[i_idx.rev_idx]
                 j_weights = j_span_frac[j_idx.rev_idx]
                 i_weights[i_idx.fwd_idx] = i_low_frac
                 j_weights[j_idx.fwd_idx] = j_low_frac
                 mask = i_high_frac > 0
                 i_weights[i_idx.fwd_idx[mask]+ i_count[mask] - 1] = \
                          i_high_frac[mask]
                 mask = j_high_frac > 0
                 j_weights[j_idx.fwd_idx[mask] + j_count[mask] - 1] = \
                          j_high_frac[mask]
                 #
                 # Get indexes for the 2-d array, i_count x j_count
                 #
                 idx = INDEX.Indexes([i_count, j_count])
                 #
                 # The coordinates in the straightened space
                 #
                 i_src_hard = i[idx.rev_idx]
                 j_src_hard = j[idx.rev_idx]
                 #
                 # The coordinates in the bin space
                 #
                 i_dest_hard = i_mapping[idx.rev_idx].astype(int) + idx.idx[0]
                 j_dest_hard = j_mapping[idx.rev_idx].astype(int) + idx.idx[1]
                 #
                 # The weights are the i-weight times the j-weight
                 #
                 # The i-weight can be found at the nth index of
                 # i_weights relative to the start of the i_weights
                 # for the pixel in the straightened space.
                 #
                 # The start is found at i_idx.fwd_idx[idx.rev_idx]
                 # the I offset is found at idx.idx[0]
                 #
                 # Similarly for J.
                 #
                 weight_hard = (i_weights[i_idx.fwd_idx[idx.rev_idx] +
                                          idx.idx[0]] *
                                j_weights[j_idx.fwd_idx[idx.rev_idx] +
                                          idx.idx[1]])
                 i_src = np.hstack((i_src, i_src_hard))
                 j_src = np.hstack((j_src, j_src_hard))
                 i_dest = np.hstack((i_dest, i_dest_hard))
                 j_dest = np.hstack((j_dest, j_dest_hard))
                 weight = np.hstack((weight, weight_hard))
                 labels_src = np.hstack((labels_src, labels_1d[idx.rev_idx]))
             
             self.measure_bins(workspace, i_src, j_src, i_dest, j_dest,
                               weight, labels_src, scales, nworms)
Example #30
0
    def new_image(self, data):
        """
        Update the window with the new image (the window is resize to have the image
        at ratio 1:1)
        data (numpy.ndarray): an 2D array containing the image (can be 3D if in RGB)
        """
        if data.ndim == 3 and 3 in data.shape:  # RGB
            rgb = img.ensureYXC(data)
        elif numpy.prod(data.shape) == 1:  # single point => show text
            text = "%g" % (data.flat[0], )
            logging.info("Data value is: %s", text)
            # Create a big enough white space (30x200 px) of BGRA format
            rgb = numpy.empty((30, 200, 4), dtype=numpy.uint8)
            rgb.fill(255)
            # Get a Cairo context for that image
            surface = cairo.ImageSurface.create_for_data(
                rgb, cairo.FORMAT_ARGB32, rgb.shape[1], rgb.shape[0])
            ctx = cairo.Context(surface)
            # Draw a black text of 20 px high
            ctx.set_source_rgb(0, 0, 0)
            ctx.select_font_face("Sans", cairo.FONT_SLANT_NORMAL)
            ctx.set_font_size(20)
            ctx.move_to(5, 20)
            ctx.show_text(text)
            del ctx  # ensure the context is flushed
        elif numpy.prod(data.shape) == data.shape[-1]:  # 1D image => bar plot
            # TODO: add "(plot)" to the window title
            # Create a simple bar plot of X x 400 px
            lenx = data.shape[-1]
            if lenx > MAX_WIDTH:
                binning = lenx // MAX_WIDTH
                data = data[..., 0::binning]
                logging.debug("Compressed data from %d to %d elements", lenx,
                              data.shape[-1])
                lenx = data.shape[-1]
            leny = 400
            miny = min(0, data.min())
            maxy = data.max()
            diffy = maxy - miny
            if diffy == 0:
                diffy = 1
            logging.info("Plot data from %s to %s", miny, maxy)
            rgb = numpy.zeros((leny, lenx, 3), dtype=numpy.uint8)
            for i, v in numpy.ndenumerate(data):
                # TODO: have the base at 0, instead of miny, so that negative values are columns going down
                h = leny - int(((v - miny) * leny) / diffy)
                rgb[h:-1, i[-1], :] = 255
        else:  # Greyscale (hopefully)
            mn, mx, mnp, mxp = ndimage.extrema(data)
            logging.info("Image data from %s to %s", mn, mx)
            rgb = img.DataArray2RGB(data)  # auto brightness/contrast

        self.app.img = NDImage2wxImage(rgb)
        disp_size = wx.Display(0).GetGeometry().GetSize()
        if disp_size[0] < rgb.shape[1] or disp_size[1] < rgb.shape[0]:
            asp_ratio = rgb.shape[1] / rgb.shape[0]
            if disp_size[0] / disp_size[1] < asp_ratio:
                self.app.magn = disp_size[0] / rgb.shape[1]
            else:
                self.app.magn = disp_size[1] / rgb.shape[0]
            self.app.img.Rescale(rgb.shape[1] * self.app.magn,
                                 rgb.shape[0] * self.app.magn, rgb.shape[2])
        else:
            self.app.magn = 1

        wx.CallAfter(self.app.update_view)
Example #31
0
    def _calculateArrayId(self):
        """
        Calculates statistics (see methods calculate) when ids are array, even
        if ids have one element only.
        """

        # make sure the result data structures are ok
        self._prepareArrays(arrays=('mean', 'std', 'min', 'max', 'minPos',
                                    'maxPos'),
                            widths=(1, 1, 1, 1, self.ndim, self.ndim),
                            dtypes=(float, float, float, float, int, int))

        # do calculations for each segment separately
        self.mean[self._ids] = ndimage.mean(input=self.data,
                                            labels=self.labels,
                                            index=self._ids)
        self.std[self._ids] = ndimage.standard_deviation(input=self.data,
                                                         labels=self.labels,
                                                         index=self._ids)
        extr = ndimage.extrema(input=self.data,
                               labels=self.labels,
                               index=self._ids)

        # figure out if 0 is the only id
        zero_id = False
        if isinstance(self._ids, (numpy.ndarray, list)):
            zero_id = (self._ids[0] == 0)
        else:
            zero_id = (self._ids == 0)

        # do calculations for all segments together
        if not zero_id:
            from .segment import Segment
            seg = Segment()
            locLabels = seg.keep(ids=self._ids, data=self.labels.copy())
            self.mean[0] = ndimage.mean(input=self.data,
                                        labels=locLabels,
                                        index=None)
            self.std[0] = ndimage.standard_deviation(input=self.data,
                                                     labels=locLabels,
                                                     index=None)
            extr0 = ndimage.extrema(input=self.data,
                                    labels=locLabels,
                                    index=None)

        # put extrema for individual labels in data arrays
        (self.min[self._ids], self.max[self._ids]) = (extr[0], extr[1])
        #self.max[self._ids] = -numpy.array(extr_bug[0])
        if (self._ids.size == 1) and not isinstance(extr[2], list):
            self.minPos[self._ids] = [extr[2]]
            self.maxPos[self._ids] = [extr[3]]
            #self.maxPos[self._ids] = [extr_bug[2]]
        else:
            self.minPos[self._ids] = extr[2]
            self.maxPos[self._ids] = extr[3]
            #self.maxPos[self._ids] = extr_bug[3]

        # put total extrema in data arrays at index 0
        if not zero_id:
            (self.min[0], self.max[0]) = (extr0[0], extr0[1])
            #self.max[0] = -extr0_bug[0]
            if self.ndim == 1:
                self.minPos[0] = extr0[2][0]
                self.maxPos[0] = extr0[3][0]
                #self.maxPos[0] = extr0_bug[2][0]
            else:
                self.minPos[0] = extr0[2]
                self.maxPos[0] = extr0[3]
Example #32
0
import scipy.misc as misc
import scipy.ndimage as ndi

img = misc.ascent()

print(ndi.minimum(img))
print(ndi.minimum_position(img))
print(ndi.maximum(img))
print(ndi.maximum_position(img))

print(ndi.extrema(img))
Example #33
0
 def measure_worms(self, workspace, labels, nworms, width):
     m = workspace.measurements
     assert isinstance(m, cpmeas.Measurements)
     object_name = self.straightened_objects_name.value
     nbins_vertical = self.number_of_segments.value
     nbins_horizontal = self.number_of_stripes.value
     params = self.read_params(workspace)
     if nworms == 0:
         # # # # # # # # # # # # # # # # # # # # # #
         #
         # Record measurements if no worms
         #
         # # # # # # # # # # # # # # # # # # # # # #
         for ftr in (FTR_MEAN_INTENSITY, FTR_STD_INTENSITY):
             for group in self.images:
                 image_name = group.straightened_image_name.value
                 if nbins_vertical > 1:
                     for b in range(nbins_vertical):
                         measurement = "_".join(
                             (C_WORM, ftr, image_name, 
                              self.get_scale_name(None, b)))
                         m.add_measurement(object_name, measurement,
                                           np.zeros((0)))
                 if nbins_horizontal > 1:
                     for b in range(nbins_horizontal):
                         measurement = "_".join(
                             (C_WORM, ftr, image_name, 
                              self.get_scale_name(b, None)))
                         m.add_measurement(object_name, measurement,
                                           np.zeros((0)))
                     if nbins_vertical > 1:
                         for v in range(nbins_vertical):
                             for h in range(nbins_horizontal):
                                 measurement = "_".join(
                                     (C_WORM, ftr, image_name, 
                                      self.get_scale_name(h, v)))
                                 m.add_measurement(object_name, measurement,
                                                   np.zeros((0)))
                                 
     else:
         #
         # Find the minimum and maximum i coordinate of each worm
         #
         object_set = workspace.object_set
         assert isinstance(object_set, cpo.ObjectSet)
         orig_objects = object_set.get_objects(self.objects_name.value)
 
         i,j = np.mgrid[0:labels.shape[0], 0:labels.shape[1]]
         min_i, max_i, _, _ = extrema(i, labels, orig_objects.indices)
         min_i = np.hstack(([0], min_i))
         max_i = np.hstack(([labels.shape[0]], max_i)) + 1
         heights = max_i - min_i
         
         # # # # # # # # # # # # # # # # #
         #
         # Create up to 3 spaces which represent the gridding
         # of the worm and create a coordinate mapping into
         # this gridding for each straightened worm
         #
         # # # # # # # # # # # # # # # # #
         griddings = []
         if nbins_vertical > 1:
             scales = np.array([self.get_scale_name(None, b)
                                for b in range(nbins_vertical)])
             scales.shape = (nbins_vertical, 1)
             griddings += [(nbins_vertical, 1, scales)]
         if nbins_horizontal > 1:
             scales = np.array([self.get_scale_name(b, None)
                                for b in range(nbins_horizontal)])
             scales.shape = (1, nbins_horizontal)
             griddings += [(1, nbins_horizontal, scales)]
             if nbins_vertical > 1:
                 scales = np.array([
                     [self.get_scale_name(h,v) for h in range(nbins_horizontal)]
                     for v in range(nbins_vertical)])
                 griddings += [(nbins_vertical, nbins_horizontal, scales)]
         
         for i_dim, j_dim, scales in griddings:
             # # # # # # # # # # # # # # # # # # # # # #
             #
             # Start out mapping every point to a 1x1 space
             #
             # # # # # # # # # # # # # # # # # # # # # #
             labels1 = labels.copy()
             i,j = np.mgrid[0:labels.shape[0], 0:labels.shape[1]]
             i_frac = (i - min_i[labels]).astype(float) / heights[labels]
             i_frac_end = i_frac + 1.0 / heights[labels].astype(float)
             i_radius_frac = (i - min_i[labels]).astype(float) / (heights[labels] - 1)
             labels1[(i_frac >= 1) | (i_frac_end <= 0)] = 0
             # # # # # # # # # # # # # # # # # # # # # #
             #
             # Map the horizontal onto the grid.
             #
             # # # # # # # # # # # # # # # # # # # # # #
             radii = np.array(params.radii_from_training)
             #
             # For each pixel in the image, find the center of its worm
             # in the j direction (the width)
             #
             j_center = int(width / 2) + width * (labels-1)
             #
             # Find which segment (from the training set) per pixel in
             # a fractional form
             #
             i_index = i_radius_frac * (len(radii) - 1)
             #
             # Interpolate
             #
             i_index_frac = i_index - np.floor(i_index)
             i_index_frac[i_index >= len(radii) - 1] = 1
             i_index = np.minimum(i_index.astype(int), len(radii) - 2)
             r = np.ceil((radii[i_index] * (1 - i_index_frac) + 
                          radii[i_index+1] * i_index_frac))
             #
             # Map the worm width into the space 0-1
             #
             j_frac = (j - j_center + r) / (r * 2 + 1)
             j_frac_end = j_frac + 1.0 / (r * 2 + 1)
             labels1[(j_frac >= 1) | (j_frac_end <= 0)] = 0
             #
             # Map the worms onto the gridding.
             #
             i_mapping = np.maximum(i_frac * i_dim, 0)
             i_mapping_end = np.minimum(i_frac_end * i_dim, i_dim)
             j_mapping = np.maximum(j_frac * j_dim, 0)
             j_mapping_end = np.minimum(j_frac_end  * j_dim, j_dim)
             i_mapping = i_mapping[labels1 > 0]
             i_mapping_end = i_mapping_end[labels1 > 0]
             j_mapping = j_mapping[labels1 > 0]
             j_mapping_end = j_mapping_end[labels1 > 0]
             labels_1d = labels1[labels1 > 0]
             i = i[labels1 > 0]
             j = j[labels1 > 0]
             
             #
             # There are easy cases and hard cases. The easy cases are
             # when a pixel in the input space wholly falls in the
             # output space.
             #
             easy = ((i_mapping.astype(int) == i_mapping_end.astype(int)) &
                     (j_mapping.astype(int) == j_mapping_end.astype(int)))
             
             i_src = i[easy]
             j_src = j[easy]
             i_dest = i_mapping[easy].astype(int)
             j_dest = j_mapping[easy].astype(int)
             weight = np.ones(i_src.shape)
             labels_src = labels_1d[easy]
             #
             # The hard cases start in one pixel in the binning space,
             # possibly continue through one or more intermediate pixels
             # in horribly degenerate cases and end in a final
             # partial pixel.
             #
             # More horribly, a pixel in the straightened space
             # might span two or more in the binning space in the I
             # direction, the J direction or both.
             #
             if not np.all(easy):
                 i = i[~ easy]
                 j = j[~ easy]
                 i_mapping = i_mapping[~ easy]
                 j_mapping = j_mapping[~ easy]
                 i_mapping_end = i_mapping_end[~ easy]
                 j_mapping_end = j_mapping_end[~ easy]
                 labels_1d = labels_1d[~ easy]
                 #
                 # A pixel in the straightened space can be wholly within
                 # a pixel in the bin space, it can straddle two pixels
                 # or straddle two and span one or more. It can do different
                 # things in the I and J direction.
                 #
                 # --- The number of pixels wholly spanned ---
                 #
                 i_span = np.maximum(np.floor(i_mapping_end) - np.ceil(i_mapping), 0)
                 j_span = np.maximum(np.floor(j_mapping_end) - np.ceil(j_mapping), 0)
                 #
                 # --- The fraction of a pixel covered by the lower straddle
                 #
                 i_low_straddle = i_mapping.astype(int) + 1 - i_mapping
                 j_low_straddle = j_mapping.astype(int) + 1 - j_mapping
                 #
                 # Segments that start at exact pixel boundaries and span
                 # whole pixels have low fractions that are 1. The span
                 # length needs to have these subtracted from it.
                 #
                 i_span[i_low_straddle == 1] -= 1
                 j_span[j_low_straddle == 1] -= 1
                 #
                 # --- the fraction covered by the upper straddle
                 #
                 i_high_straddle = i_mapping_end - i_mapping_end.astype(int)
                 j_high_straddle = j_mapping_end - j_mapping_end.astype(int)
                 #
                 # --- the total distance across the binning space
                 #
                 i_total = i_low_straddle + i_span + i_high_straddle
                 j_total = j_low_straddle + j_span + j_high_straddle
                 #
                 # --- The fraction in the lower straddle
                 #
                 i_low_frac = i_low_straddle / i_total
                 j_low_frac = j_low_straddle / j_total
                 #
                 # --- The fraction in the upper straddle
                 #
                 i_high_frac = i_high_straddle / i_total
                 j_high_frac = j_high_straddle / j_total
                 #
                 # later on, the high fraction will overwrite the low fraction
                 # for i and j hitting on a single pixel in the bin space
                 #
                 i_high_frac[(i_mapping.astype(int) == i_mapping_end.astype(int))] = 1
                 j_high_frac[(j_mapping.astype(int) == j_mapping_end.astype(int))] = 1
                 #
                 # --- The fraction in spans
                 #
                 i_span_frac = i_span / i_total
                 j_span_frac = j_span / j_total
                 #
                 # --- The number of bins touched by each pixel
                 #
                 i_count = (np.ceil(i_mapping_end) - np.floor(i_mapping)).astype(int)
                 j_count = (np.ceil(j_mapping_end) - np.floor(j_mapping)).astype(int)
                 #
                 # --- For I and J, calculate the weights for each pixel
                 #     along each axis.
                 #
                 i_idx = INDEX.Indexes([i_count])
                 j_idx = INDEX.Indexes([j_count])
                 i_weights = i_span_frac[i_idx.rev_idx]
                 j_weights = j_span_frac[j_idx.rev_idx]
                 i_weights[i_idx.fwd_idx] = i_low_frac
                 j_weights[j_idx.fwd_idx] = j_low_frac
                 mask = i_high_frac > 0
                 i_weights[i_idx.fwd_idx[mask]+ i_count[mask] - 1] = \
                          i_high_frac[mask]
                 mask = j_high_frac > 0
                 j_weights[j_idx.fwd_idx[mask] + j_count[mask] - 1] = \
                          j_high_frac[mask]
                 #
                 # Get indexes for the 2-d array, i_count x j_count
                 #
                 idx = INDEX.Indexes([i_count, j_count])
                 #
                 # The coordinates in the straightened space
                 #
                 i_src_hard = i[idx.rev_idx]
                 j_src_hard = j[idx.rev_idx]
                 #
                 # The coordinates in the bin space
                 #
                 i_dest_hard = i_mapping[idx.rev_idx].astype(int) + idx.idx[0]
                 j_dest_hard = j_mapping[idx.rev_idx].astype(int) + idx.idx[1]
                 #
                 # The weights are the i-weight times the j-weight
                 #
                 # The i-weight can be found at the nth index of
                 # i_weights relative to the start of the i_weights
                 # for the pixel in the straightened space.
                 #
                 # The start is found at i_idx.fwd_idx[idx.rev_idx]
                 # the I offset is found at idx.idx[0]
                 #
                 # Similarly for J.
                 #
                 weight_hard = (i_weights[i_idx.fwd_idx[idx.rev_idx] +
                                          idx.idx[0]] *
                                j_weights[j_idx.fwd_idx[idx.rev_idx] +
                                          idx.idx[1]])
                 i_src = np.hstack((i_src, i_src_hard))
                 j_src = np.hstack((j_src, j_src_hard))
                 i_dest = np.hstack((i_dest, i_dest_hard))
                 j_dest = np.hstack((j_dest, j_dest_hard))
                 weight = np.hstack((weight, weight_hard))
                 labels_src = np.hstack((labels_src, labels_1d[idx.rev_idx]))
             
             self.measure_bins(workspace, i_src, j_src, i_dest, j_dest,
                               weight, labels_src, scales, nworms)
Example #34
0
"""
Find at what time the temperature suddenly took off
"""

import sys, glob
import pyfits
from scipy.ndimage import extrema

runid = sys.argv[1]
pattern = "%s-te????.fits" % (runid)
filelist = glob.glob(pattern)

for file in filelist:
    Tarray = pyfits.open(file)[0].data
    Tmin, Tmax, Tminloc, Tmaxloc = extrema(Tarray)
    # switch to fortran array indexing
    Tmaxloc = [ i+1 for i in Tmaxloc[::-1] ]
    print "%s: max T = %.2e at %s" % (file, Tmax, Tmaxloc)

Example #35
0
def get_mask_period_info(hours_since_beginning,
                         lon,
                         mask,
                         lat=None,
                         verbose=False):
    ## Get Pandas data frame of east propagation periods.
    ## If lat is set to None, don't calculate latitude related stuff.
    label_im, nE = ndimage.label(mask)
    if verbose:
        print(f'Found {str(nE)} propagation periods.')

    props = {}
    begin_hours, end_hours, indx1, indx2 = ndimage.extrema(
        hours_since_beginning, label_im, range(1, nE + 1))

    props['duration'] = (np.array(end_hours) - np.array(begin_hours))
    props['begin_indx'] = np.array(indx1)[:, 0].astype(int)
    props['end_indx'] = np.array(indx2)[:, 0].astype(int)
    props['begin_lon'] = lon[props['begin_indx']]
    props['end_lon'] = lon[props['end_indx']]
    props['lon_propagation'] = lon[props['end_indx']] - lon[
        props['begin_indx']]
    props['total_zonal_spd'] = linregress(hours_since_beginning,
                                          lon)[0] * (111000 / 3600.0)

    min_lon, max_lon, indx1, indx2 = ndimage.extrema(lon, label_im,
                                                     range(1, nE + 1))
    props['min_lon'] = min_lon
    props['max_lon'] = max_lon

    props['segment_zonal_spd'] = 0.0 * np.arange(nE)
    for iii in range(nE):
        ii1 = props['begin_indx'][iii]
        ii2 = props['end_indx'][iii] + 1
        props['segment_zonal_spd'][iii] = linregress(
            hours_since_beginning[ii1:ii2],
            lon[ii1:ii2])[0] * (111000 / 3600.0)

    if not lat is None:
        props['begin_lat'] = lat[props['begin_indx']]
        props['end_lat'] = lat[props['end_indx']]
        props['lat_propagation'] = lat[props['end_indx']] - lat[
            props['begin_indx']]
        min_lat, max_lat, indx1, indx2 = ndimage.extrema(
            lat, label_im, range(1, nE + 1))
        props['min_lat'] = min_lat
        props['max_lat'] = max_lat
        props['total_meridional_spd'] = linregress(hours_since_beginning,
                                                   lat)[0] * (111000 / 3600.0)

        props['segment_meridional_spd'] = 0.0 * np.arange(nE)
        for iii in range(nE):
            ii1 = props['begin_indx'][iii]
            ii2 = props['end_indx'][iii] + 1
            props['segment_meridional_spd'][iii] = linregress(
                hours_since_beginning[ii1:ii2],
                lat[ii1:ii2])[0] * (111000 / 3600.0)

    ## Put in to Pandas DataFrame
    F = pd.DataFrame.from_dict(props)

    return F
    def run(self, workspace):
        objects = workspace.object_set.get_objects(self.object_name.value)
        assert isinstance(objects, cpo.Objects)
        has_pixels = objects.areas > 0
        labels = objects.small_removed_segmented
        kept_labels = objects.segmented
        neighbor_objects = workspace.object_set.get_objects(
            self.neighbors_name.value)
        assert isinstance(neighbor_objects, cpo.Objects)
        neighbor_labels = neighbor_objects.small_removed_segmented
        #
        # Need to add in labels touching border.
        #
        unedited_segmented = neighbor_objects.unedited_segmented
        touching_border = np.zeros(np.max(unedited_segmented) + 1, bool)
        touching_border[unedited_segmented[0, :]] = True
        touching_border[unedited_segmented[-1, :]] = True
        touching_border[unedited_segmented[:, 0]] = True
        touching_border[unedited_segmented[:, -1]] = True
        touching_border[0] = False
        touching_border_mask = touching_border[unedited_segmented]
        nobjects = np.max(labels)
        nkept_objects = objects.count
        nneighbors = np.max(neighbor_labels)
        if np.any(touching_border) and \
                np.all(~ touching_border_mask[neighbor_labels != 0]):
            # Add the border labels if any were excluded
            touching_border_object_number = np.cumsum(touching_border) + \
                                            np.max(neighbor_labels)
            touching_border_mask = touching_border_mask & (neighbor_labels
                                                           == 0)
            neighbor_labels = neighbor_labels.copy().astype(np.int32)
            neighbor_labels[
                touching_border_mask] = touching_border_object_number[
                    unedited_segmented[touching_border_mask]]

        _, object_numbers = objects.relate_labels(labels, kept_labels)
        if self.neighbors_are_objects:
            neighbor_numbers = object_numbers
            neighbor_has_pixels = has_pixels
        else:
            _, neighbor_numbers = neighbor_objects.relate_labels(
                neighbor_labels, neighbor_objects.segmented)
            neighbor_has_pixels = np.bincount(neighbor_labels.ravel())[1:] > 0
        neighbor_count = np.zeros((nobjects, ))
        pixel_count = np.zeros((nobjects, ))
        first_object_number = np.zeros((nobjects, ), int)
        second_object_number = np.zeros((nobjects, ), int)
        first_x_vector = np.zeros((nobjects, ))
        second_x_vector = np.zeros((nobjects, ))
        first_y_vector = np.zeros((nobjects, ))
        second_y_vector = np.zeros((nobjects, ))
        angle = np.zeros((nobjects, ))
        percent_touching = np.zeros((nobjects, ))
        expanded_labels = None
        if self.distance_method == D_EXPAND:
            # Find the i,j coordinates of the nearest foreground point
            # to every background point
            i, j = scind.distance_transform_edt(labels == 0,
                                                return_distances=False,
                                                return_indices=True)
            # Assign each background pixel to the label of its nearest
            # foreground pixel. Assign label to label for foreground.
            labels = labels[i, j]
            expanded_labels = labels  # for display
            distance = 1  # dilate once to make touching edges overlap
            scale = S_EXPANDED
            if self.neighbors_are_objects:
                neighbor_labels = labels.copy()
        elif self.distance_method == D_WITHIN:
            distance = self.distance.value
            scale = str(distance)
        elif self.distance_method == D_ADJACENT:
            distance = 1
            scale = S_ADJACENT
        else:
            raise ValueError("Unknown distance method: %s" %
                             self.distance_method.value)
        if nneighbors > (1 if self.neighbors_are_objects else 0):
            first_objects = []
            second_objects = []
            object_indexes = np.arange(nobjects, dtype=np.int32) + 1
            #
            # First, compute the first and second nearest neighbors,
            # and the angles between self and the first and second
            # nearest neighbors
            #
            ocenters = centers_of_labels(
                objects.small_removed_segmented).transpose()
            ncenters = centers_of_labels(
                neighbor_objects.small_removed_segmented).transpose()
            areas = fix(
                scind.sum(np.ones(labels.shape), labels, object_indexes))
            perimeter_outlines = outline(labels)
            perimeters = fix(
                scind.sum(np.ones(labels.shape), perimeter_outlines,
                          object_indexes))

            i, j = np.mgrid[0:nobjects, 0:nneighbors]
            distance_matrix = np.sqrt((ocenters[i, 0] - ncenters[j, 0])**2 +
                                      (ocenters[i, 1] - ncenters[j, 1])**2)
            #
            # order[:,0] should be arange(nobjects)
            # order[:,1] should be the nearest neighbor
            # order[:,2] should be the next nearest neighbor
            #
            if distance_matrix.shape[1] == 1:
                # a little buggy, lexsort assumes that a 2-d array of
                # second dimension = 1 is a 1-d array
                order = np.zeros(distance_matrix.shape, int)
            else:
                order = np.lexsort([distance_matrix])
            first_neighbor = 1 if self.neighbors_are_objects else 0
            first_object_index = order[:, first_neighbor]
            first_x_vector = ncenters[first_object_index, 1] - ocenters[:, 1]
            first_y_vector = ncenters[first_object_index, 0] - ocenters[:, 0]
            if nneighbors > first_neighbor + 1:
                second_object_index = order[:, first_neighbor + 1]
                second_x_vector = ncenters[second_object_index,
                                           1] - ocenters[:, 1]
                second_y_vector = ncenters[second_object_index,
                                           0] - ocenters[:, 0]
                v1 = np.array((first_x_vector, first_y_vector))
                v2 = np.array((second_x_vector, second_y_vector))
                #
                # Project the unit vector v1 against the unit vector v2
                #
                dot = (np.sum(v1 * v2, 0) /
                       np.sqrt(np.sum(v1**2, 0) * np.sum(v2**2, 0)))
                angle = np.arccos(dot) * 180. / np.pi

            # Make the structuring element for dilation
            strel = strel_disk(distance)
            #
            # A little bigger one to enter into the border with a structure
            # that mimics the one used to create the outline
            #
            strel_touching = strel_disk(distance + .5)
            #
            # Get the extents for each object and calculate the patch
            # that excises the part of the image that is "distance"
            # away
            i, j = np.mgrid[0:labels.shape[0], 0:labels.shape[1]]
            min_i, max_i, min_i_pos, max_i_pos = \
                scind.extrema(i, labels, object_indexes)
            min_j, max_j, min_j_pos, max_j_pos = \
                scind.extrema(j, labels, object_indexes)
            min_i = np.maximum(fix(min_i) - distance, 0).astype(int)
            max_i = np.minimum(fix(max_i) + distance + 1,
                               labels.shape[0]).astype(int)
            min_j = np.maximum(fix(min_j) - distance, 0).astype(int)
            max_j = np.minimum(fix(max_j) + distance + 1,
                               labels.shape[1]).astype(int)
            #
            # Loop over all objects
            # Calculate which ones overlap "index"
            # Calculate how much overlap there is of others to "index"
            #
            for object_number in object_numbers:
                if object_number == 0:
                    #
                    # No corresponding object in small-removed. This means
                    # that the object has no pixels, e.g. not renumbered.
                    #
                    continue
                index = object_number - 1
                patch = labels[min_i[index]:max_i[index],
                               min_j[index]:max_j[index]]
                npatch = neighbor_labels[min_i[index]:max_i[index],
                                         min_j[index]:max_j[index]]
                #
                # Find the neighbors
                #
                patch_mask = patch == (index + 1)
                extended = scind.binary_dilation(patch_mask, strel)
                neighbors = np.unique(npatch[extended])
                neighbors = neighbors[neighbors != 0]
                if self.neighbors_are_objects:
                    neighbors = neighbors[neighbors != object_number]
                nc = len(neighbors)
                neighbor_count[index] = nc
                if nc > 0:
                    first_objects.append(np.ones(nc, int) * object_number)
                    second_objects.append(neighbors)
                if self.neighbors_are_objects:
                    #
                    # Find the # of overlapping pixels. Dilate the neighbors
                    # and see how many pixels overlap our image. Use a 3x3
                    # structuring element to expand the overlapping edge
                    # into the perimeter.
                    #
                    outline_patch = perimeter_outlines[
                        min_i[index]:max_i[index],
                        min_j[index]:max_j[index]] == object_number
                    extended = scind.binary_dilation(
                        (patch != 0) & (patch != object_number),
                        strel_touching)
                    overlap = np.sum(outline_patch & extended)
                    pixel_count[index] = overlap
            if sum([len(x) for x in first_objects]) > 0:
                first_objects = np.hstack(first_objects)
                reverse_object_numbers = np.zeros(
                    max(np.max(object_numbers), np.max(first_objects)) + 1,
                    int)
                reverse_object_numbers[object_numbers] = np.arange(
                    len(object_numbers)) + 1
                first_objects = reverse_object_numbers[first_objects]

                second_objects = np.hstack(second_objects)
                reverse_neighbor_numbers = np.zeros(
                    max(np.max(neighbor_numbers), np.max(second_objects)) + 1,
                    int)
                reverse_neighbor_numbers[neighbor_numbers] = np.arange(
                    len(neighbor_numbers)) + 1
                second_objects = reverse_neighbor_numbers[second_objects]
                to_keep = (first_objects > 0) & (second_objects > 0)
                first_objects = first_objects[to_keep]
                second_objects = second_objects[to_keep]
            else:
                first_objects = np.zeros(0, int)
                second_objects = np.zeros(0, int)
            if self.neighbors_are_objects:
                percent_touching = pixel_count * 100 / perimeters
            else:
                percent_touching = pixel_count * 100.0 / areas
            object_indexes = object_numbers - 1
            neighbor_indexes = neighbor_numbers - 1
            #
            # Have to recompute nearest
            #
            first_object_number = np.zeros(nkept_objects, int)
            second_object_number = np.zeros(nkept_objects, int)
            if nkept_objects > (1 if self.neighbors_are_objects else 0):
                di = (ocenters[object_indexes[:, np.newaxis], 0] -
                      ncenters[neighbor_indexes[np.newaxis, :], 0])
                dj = (ocenters[object_indexes[:, np.newaxis], 1] -
                      ncenters[neighbor_indexes[np.newaxis, :], 1])
                distance_matrix = np.sqrt(di * di + dj * dj)
                distance_matrix[~has_pixels, :] = np.inf
                distance_matrix[:, ~neighbor_has_pixels] = np.inf
                #
                # order[:,0] should be arange(nobjects)
                # order[:,1] should be the nearest neighbor
                # order[:,2] should be the next nearest neighbor
                #
                order = np.lexsort([distance_matrix
                                    ]).astype(first_object_number.dtype)
                if self.neighbors_are_objects:
                    first_object_number[has_pixels] = order[has_pixels, 1] + 1
                    if nkept_objects > 2:
                        second_object_number[has_pixels] = order[has_pixels,
                                                                 2] + 1
                else:
                    first_object_number[has_pixels] = order[has_pixels, 0] + 1
                    if order.shape[1] > 1:
                        second_object_number[has_pixels] = order[has_pixels,
                                                                 1] + 1
        else:
            object_indexes = object_numbers - 1
            neighbor_indexes = neighbor_numbers - 1
            first_objects = np.zeros(0, int)
            second_objects = np.zeros(0, int)
        #
        # Now convert all measurements from the small-removed to
        # the final number set.
        #
        neighbor_count = neighbor_count[object_indexes]
        neighbor_count[~has_pixels] = 0
        percent_touching = percent_touching[object_indexes]
        percent_touching[~has_pixels] = 0
        first_x_vector = first_x_vector[object_indexes]
        second_x_vector = second_x_vector[object_indexes]
        first_y_vector = first_y_vector[object_indexes]
        second_y_vector = second_y_vector[object_indexes]
        angle = angle[object_indexes]
        #
        # Record the measurements
        #
        assert (isinstance(workspace, cpw.Workspace))
        m = workspace.measurements
        assert (isinstance(m, cpmeas.Measurements))
        image_set = workspace.image_set
        features_and_data = [
            (M_NUMBER_OF_NEIGHBORS, neighbor_count),
            (M_FIRST_CLOSEST_OBJECT_NUMBER, first_object_number),
            (M_FIRST_CLOSEST_DISTANCE,
             np.sqrt(first_x_vector**2 + first_y_vector**2)),
            (M_SECOND_CLOSEST_OBJECT_NUMBER, second_object_number),
            (M_SECOND_CLOSEST_DISTANCE,
             np.sqrt(second_x_vector**2 + second_y_vector**2)),
            (M_ANGLE_BETWEEN_NEIGHBORS, angle)
        ]
        if self.neighbors_are_objects:
            features_and_data.append((M_PERCENT_TOUCHING, percent_touching))
        for feature_name, data in features_and_data:
            m.add_measurement(self.object_name.value,
                              self.get_measurement_name(feature_name), data)
        if len(first_objects) > 0:
            m.add_relate_measurement(
                self.module_num, cpmeas.NEIGHBORS, self.object_name.value,
                self.object_name.value
                if self.neighbors_are_objects else self.neighbors_name.value,
                m.image_set_number * np.ones(first_objects.shape, int),
                first_objects,
                m.image_set_number * np.ones(second_objects.shape, int),
                second_objects)

        labels = kept_labels

        neighbor_count_image = np.zeros(labels.shape, int)
        object_mask = objects.segmented != 0
        object_indexes = objects.segmented[object_mask] - 1
        neighbor_count_image[object_mask] = neighbor_count[object_indexes]
        workspace.display_data.neighbor_count_image = neighbor_count_image

        if self.neighbors_are_objects:
            percent_touching_image = np.zeros(labels.shape)
            percent_touching_image[object_mask] = percent_touching[
                object_indexes]
            workspace.display_data.percent_touching_image = percent_touching_image

        image_set = workspace.image_set
        if self.wants_count_image.value:
            neighbor_cm_name = self.count_colormap.value
            neighbor_cm = get_colormap(neighbor_cm_name)
            sm = matplotlib.cm.ScalarMappable(cmap=neighbor_cm)
            img = sm.to_rgba(neighbor_count_image)[:, :, :3]
            img[:, :, 0][~object_mask] = 0
            img[:, :, 1][~object_mask] = 0
            img[:, :, 2][~object_mask] = 0
            count_image = cpi.Image(img, masking_objects=objects)
            image_set.add(self.count_image_name.value, count_image)
        else:
            neighbor_cm_name = cpprefs.get_default_colormap()
            neighbor_cm = matplotlib.cm.get_cmap(neighbor_cm_name)
        if self.neighbors_are_objects and self.wants_percent_touching_image:
            percent_touching_cm_name = self.touching_colormap.value
            percent_touching_cm = get_colormap(percent_touching_cm_name)
            sm = matplotlib.cm.ScalarMappable(cmap=percent_touching_cm)
            img = sm.to_rgba(percent_touching_image)[:, :, :3]
            img[:, :, 0][~object_mask] = 0
            img[:, :, 1][~object_mask] = 0
            img[:, :, 2][~object_mask] = 0
            touching_image = cpi.Image(img, masking_objects=objects)
            image_set.add(self.touching_image_name.value, touching_image)
        else:
            percent_touching_cm_name = cpprefs.get_default_colormap()
            percent_touching_cm = matplotlib.cm.get_cmap(
                percent_touching_cm_name)

        if self.show_window:
            workspace.display_data.neighbor_cm_name = neighbor_cm_name
            workspace.display_data.percent_touching_cm_name = percent_touching_cm_name
            workspace.display_data.orig_labels = objects.segmented
            workspace.display_data.expanded_labels = expanded_labels
            workspace.display_data.object_mask = object_mask