Ejemplo n.º 1
0
def reconstruct_nfold(img, sym, polar_shape, mask=None, origin=None):
    ''' 
    Reconstruct an image assuming a certain symmetry.
        
    Parameters
    ----------
    img : the image
            
    sym : the symmetry of the sample
            
    polar_shape : the shape of the new polar coordinate image
        
    Returns
    -------
    reconstructed_image : the reconstructed  image   
    '''
    shape = 0
    shape = img.shape
    rphibinstat = RPhiBinnedStatistic(shape,
                                      bins=polar_shape,
                                      mask=mask,
                                      origin=origin)
    angles = rphibinstat.bin_centers[1]
    radii = rphibinstat.bin_centers[0]
    rphi_img = rphibinstat(img)
    # create mask from np.nans since RPhiBinnedStatistic fills masked regions with np.nans
    rphimask = np.ones_like(rphi_img)
    rphimask[np.where(np.isnan(rphi_img))] = 0

    reconstructed_image = np.zeros_like(img)
    reconstructed_image_mask = np.zeros_like(img, dtype=int)
    # symmetry
    dphi = 2 * np.pi / float(sym)
    for i in range(sym):
        anglesp = angles + dphi * i
        imgtmp = construct_rphi_avg_image(radii,
                                          anglesp,
                                          rphi_img,
                                          shape=shape,
                                          center=origin,
                                          mask=rphimask)
        w = np.where(~np.isnan(imgtmp))
        reconstructed_image[w] += imgtmp[w]
        reconstructed_image_mask += (~np.isnan(imgtmp)).astype(int)

    # the mask keeps count of included pixels. Average by this amount
    try:
        reconstructed_image /= reconstructed_image_mask
    except Exception as e:
        print 'Division failed at line 50', reconstructed_image_mask
        pass

    return reconstructed_image
Ejemplo n.º 2
0
def test_binmap():
    ''' These tests can be run in notebooks and the binmaps plotted.
        If this ever returns an error, it is suggested to plot the maps and see
        if they look sensible.
    '''
    # generate fake data on the fly
    shape = np.array([100, 100])

    R = radial_grid(shape/2, shape)
    Phi = angle_grid(shape/2., shape)

    img = R*np.cos(5*Phi)
    rs = RPhiBinnedStatistic(img.shape)

    binmap = rs.binmap.reshape((-1, img.shape[0], img.shape[1]))

    assert_array_almost_equal(binmap[0][40][::10], np.array([8, 6, 5, 4, 2, 2,
                                                             2, 4, 5, 6]))
Ejemplo n.º 3
0
    def _testRadialBinnedStatistic(self, rfac=None):
        ''' rfac : make the rgrid non-linear and supply to
            RadialBinnedStatistic.
        '''

        mykwargs = [{'origin': (0, 0),
                     'range': (10, 90)},
                    {'origin': (0, 0)},
                    {'origin': None}
                    ]
        bins, shape = 100, self.shape
        mask_ones = np.ones(self.shape)
        mask_random = np.random.randint(2, size=self.shape)

        for kwargs in mykwargs:
            for stat, stat_func in stats_list:

                if 'origin' in kwargs:
                    origin = kwargs['origin']
                else:
                    origin = None
                if origin is None:
                    origin = (self.rowsize-1)/2., (self.colsize-1)/2.

                # need to calculate these every time in loop since origin
                # changes
                # rows are y, cols are x, as in angle_grid in core.utils
                self.rgrid = np.sqrt((self.rowgrid-origin[0])**2 +
                                     (self.colgrid-origin[1])**2)
                if rfac is not None:
                    self.rgrid = self.rgrid**rfac

                self.phigrid = np.arctan2(self.rowgrid-origin[0],
                                          self.colgrid-origin[1])

                self.image = np.sinc(self.rgrid / self.oscillation_rate)

                if stat == 'sum':
                    # in this case we can compare our masked
                    # result to binned_statistic
                    mask = mask_random
                else:
                    mask = mask_ones

                # test radial case
                if rfac is None:
                    radbinstat = RadialBinnedStatistic(shape, bins,
                                                       statistic=stat,
                                                       mask=mask,
                                                       **kwargs)
                    radbinstat_f = RadialBinnedStatistic(shape, bins,
                                                         statistic=stat_func,
                                                         mask=mask,
                                                         **kwargs)
                else:
                    radbinstat = RadialBinnedStatistic(shape, bins,
                                                       statistic=stat,
                                                       mask=mask,
                                                       r_map=self.rgrid,
                                                       **kwargs)
                    radbinstat_f = RadialBinnedStatistic(shape, bins,
                                                         statistic=stat_func,
                                                         mask=mask,
                                                         r_map=self.rgrid,
                                                         **kwargs)
                binned = radbinstat(self.image)
                binned_f = radbinstat_f(self.image)

                assert_array_almost_equal(binned_f, binned)

                kwrange = kwargs.get('range', None)
                ref, edges, _ = scipy.stats.binned_statistic(
                    x=self.rgrid.ravel(),
                    values=(self.image*mask).ravel(),
                    statistic=stat,
                    range=kwrange,
                    bins=bins,
                )
                centers = bin_edges_to_centers(edges)

                assert_array_almost_equal(ref, binned)
                assert_array_almost_equal(edges, radbinstat.bin_edges)
                assert_array_almost_equal(edges, radbinstat_f.bin_edges)
                assert_array_almost_equal(centers, radbinstat.bin_centers)
                assert_array_almost_equal(centers, radbinstat_f.bin_centers)

        bins = (100, 2)
        myrphikwargs = [{'origin': (0, 0),
                         'range': ((10, 90), (0, np.pi/2))},
                        {'origin': (0, 0)},
                        {'origin': None}]
        for kwargs in myrphikwargs:
            for stat, stat_func in stats_list:
                if 'origin' in kwargs:
                    origin = kwargs['origin']
                else:
                    origin = None
                if origin is None:
                    origin = (self.rowsize-1)/2., (self.colsize-1)/2.

                # need to calculate these every time in loop since origin
                # changes
                # rows are y, cols are x, as in angle_grid in core.utils
                self.rgrid = np.sqrt((self.rowgrid-origin[0])**2 +
                                     (self.colgrid-origin[1])**2)
                self.phigrid = np.arctan2(self.rowgrid-origin[0],
                                          self.colgrid-origin[1])

                self.image = np.sinc(self.rgrid / self.oscillation_rate)

                if stat == 'sum':
                    # in this case we can compare our masked
                    # result to binned_statistic
                    mask = mask_random
                else:
                    mask = mask_ones

                # test radial case
                rphibinstat = RPhiBinnedStatistic(shape, bins,
                                                  statistic=stat,
                                                  mask=mask,
                                                  **kwargs)
                rphibinstat_f = RPhiBinnedStatistic(shape, bins,
                                                    statistic=stat_func,
                                                    mask=mask,
                                                    **kwargs)
                binned = rphibinstat(self.image)
                binned_f = rphibinstat_f(self.image)

                # this test fails only for the standard deviation where
                # there is a disagreement in the number of nan's.  I
                # don't believe this is the fault of the binned_statistic
                # code
                if stat != 'std':
                    assert_array_almost_equal(binned_f, binned)

                kwrange = kwargs.get('range', None)
                ref, redges, phiedges, _ = scipy.stats.binned_statistic_2d(
                    x=self.rgrid.ravel(),
                    y=self.phigrid.ravel(),
                    values=(self.image*mask).ravel(),
                    statistic=stat,
                    range=kwrange,
                    bins=bins,
                )

                assert_array_almost_equal(ref, binned)
                assert_array_almost_equal(redges, rphibinstat.bin_edges[0])
                assert_array_almost_equal(redges, rphibinstat_f.bin_edges[0])
                assert_array_almost_equal(phiedges, rphibinstat.bin_edges[1])
                assert_array_almost_equal(phiedges, rphibinstat_f.bin_edges[1])

        # test exception when BinnedStatistic is given array of incorrect shape
        with assert_raises(ValueError):
            radbinstat(self.image[:10, :10])

        # test exception when RadialBinnedStatistic is given 1D array
        with assert_raises(ValueError):
            RadialBinnedStatistic(self.image.shape, 10,
                                  mask=np.array([1, 2, 3, 4]))
Ejemplo n.º 4
0
from skbeam.core.accumulators.binned_statistic import RadialBinnedStatistic, RPhiBinnedStatistic
import numpy as np
img = np.reshape(np.arange(9),(3,3))
print 'Image:\n',img
mask = np.ones_like(img)
mask[1][1]=0
print '\nMask:\n',mask

radbinstat = RadialBinnedStatistic(img.shape, bins=3,
                                   statistic='sum',
                                   origin=(0,0),
                                   range = (0,2),
                                   mask=mask)
rphibinstat = RPhiBinnedStatistic(img.shape, bins=(3,1),
                                  statistic='sum',
                                  origin=(0,0),
                                  range = ((0,2),(0,np.pi/3)))
rphibinstat_mask = RPhiBinnedStatistic(img.shape, bins=(3,1),
                                       statistic='sum',
                                       origin=(0,0),
                                       range = ((0,2),(0,np.pi/3)),
                                       mask=mask)
print '\nAngular integration with mask:'
print radbinstat(img)
print '\nBin edges and centers:'
print radbinstat.bin_edges
print radbinstat.bin_centers
print '\n2D R/Phi Angular integration (1 phi bin) with phi range and mask:'
print rphibinstat_mask(img)
print '\n2D R/Phi Angular integration (1 phi bin) with phi range and no mask:'
print rphibinstat(img)
Ejemplo n.º 5
0
    mask[100:200] = 0
    mask[:, 100:200] = 0
    mask[:, 500:643] = 0
    mask[70:130] = 0

    img *= mask
    image_size = (img.nbytes / 1024) / 1024

    #print image_size  , 'MB'

    start = time.time()

    # reconstruct the image into polar grid
    ttr = time.time()
    rphibinstat = RPhiBinnedStatistic(shape,
                                      bins=(400, 360),
                                      mask=mask,
                                      origin=(y0, x0))
    rphi_img = rphibinstat(img)
    # create mask from np.nans since RPhiBinnedStatistic fills masked regions with np.nans
    rphimask = np.ones_like(rphi_img)
    rphimask[np.where(np.isnan(rphi_img))] = 0
    ttrpolar = time.time() - ttr

    ## Regenerate the image to thes the construct_rphi_image

    # get angles and radii from (q, phi) polar coordinate system
    angles = rphibinstat.bin_centers[1]
    radii = rphibinstat.bin_centers[0]

    # reproject
    Zproj = construct_rphi_avg_image(radii,
Ejemplo n.º 6
0
    def __init__(self,
                 shape,
                 origin=None,
                 mask=None,
                 maskb=None,
                 rbins=800,
                 phibins=360,
                 method='bgsub',
                 saverphis=None,
                 PF=True,
                 sigma=None,
                 r_map=None):
        ''' The initialization routine for the delta phi correlation object

            Parameters
            ----------
            shape : 2 tuple
                the shape of the images
                for ex: imgs[0].shape finds the shape
                    len(imgs) gives number of images

            origin : 2 tuple, optional
                the center (can be float), defaults to image center

            mask : 2d np.ndarray, optional
                The mask for the images

            method : str, optional
                The averaging method. There are currently 3:
                    'bgsub' : subtract the average image of the image series in
                    the correlation
                    'bgest' : estimate the average by averaging each ring of r
                    'symavg' : perform a symmetric averaging
                    None : no averaging

                These may be combined in a list. ex: ['bgsub', 'symavg']

                Note : When using a mask, it is highly recommended to use one
                of the averaging methods to suppress errors.

            rbins : int or list of floats, optional
                This specifies the bins in radius (in units of pixels)
                There are two cases:
                    - If it is an int, the image will be partitioned into that
                      number of bins
                    - If it is a list of floats, the floats will be treated as
                    the edges of the bins used for the partitioning (in pixels)
                Defaults to 800

            phibins : int or list of floats, optional
                There are two cases:
                    - If it is an int, the image will be partitioned into that
                      number of bins
                    - If it is a list of floats, the floats will be treated as
                    the edges of the bins used for the partitioning (in pixels)
                Defaults to 360

            PF : bool, optional
                Print Flag. If True, prints verbose status of the computations.

            sigma : float, optional
                the sigma for the smoothing kernel over the images
                Defaults to None (no smoothing)

            saverphis : bool, optional
                Decide whether to save the rqphi map per image
                If True, after running correlations, an array of rphis is
                saved, as obj.rphis where obj is the reference to this object.

            Returns
            -------
            An RDeltaPhiCorrelator instance.
        '''
        # TODO : add different methods
        self.PF = PF
        self.saverphis = saverphis
        self.method = method

        # the smoothing kernel, set to None to disactivate smoothing
        self.sigma = sigma

        # set up the binned statistic
        self.shape = shape

        if origin is None:
            origin = (self.shape[0] - 1) / 2, (self.shape[1] - 1) / 2

        # need this to compute the counts for the deltaphi correlation
        if mask is None:
            self.mask = np.ones(self.shape)
        else:
            self.mask = mask

        if maskb is not None:
            self.maskb = maskb
        else:
            # this costs no memory etc...
            self.maskb = self.mask

        # the statistics binner
        # TODO : here we'd need two rphibinstats for two masks
        # self.rphibinstat = mkrphibinstat(self.shape, bins=(rbins, phibins),
        # origin=origin, statistic='mean',
        # mask=mask, r_map=r_map)
        self.rphibinstat = RPhiBinnedStatistic(self.shape,
                                               bins=(rbins, phibins),
                                               origin=origin,
                                               statistic='mean',
                                               mask=mask,
                                               r_map=r_map)
        self.rphimask = self.rphibinstat(self.mask)
        self._removenans(self.rphimask)

        if maskb is not None:
            # self.rphibinstatb = mkrphibinstat(self.shape, bins=(rbins,
            # phibins),
            # origin=origin,
            # statistic='mean',
            # mask=maskb, r_map=r_map)
            self.rphibinstatb = RPhiBinnedStatistic(self.shape,
                                                    bins=(rbins, phibins),
                                                    origin=origin,
                                                    statistic='mean',
                                                    mask=maskb,
                                                    r_map=r_map)
            self.rphimaskb = self.rphibinstat(self.maskb)
            self._removenans(self.rphimaskb)
        else:
            self.rphibinstatb = self.rphibinstat
            self.rphimaskb = self.rphimask

        # need this to properly count pixels
        self.rdeltaphimask = _convol1d(self.rphimask, axis=-1)
        if maskb is not None:
            self.rdeltaphimaskb = _convol1d(self.rphimaskb, axis=-1)
        else:
            self.rdeltaphimaskb = self.rdeltaphimask

        # get number of pixels per (r,phi) wedge
        # if there are two masks, take product, else just use first mask
        self.rphibinstat.statistic = 'sum'
        self.rphimaskcnts = self.rphibinstat(self.mask)
        self._removenans(self.rphimaskcnts)
        self.rphibinstat.statistic = 'mean'

        if maskb is None:
            self.rphibinstatb.statistic = 'sum'
            self.rphimaskcntsb = self.rphibinstatb(self.maskb)
            self._removenans(self.rphimaskcntsb)
            self.rphibinstatb.statistic = 'mean'

        # where the first moment's number per bin is nonzero
        self.wsel1 = np.where(self.rphimaskcnts > .1)

        # needs to be maskb not self.maskb (already defined)
        if maskb is not None:
            self.wsel1b = np.where(self.rphimaskcntsb > .1)

        # this just finds non zero entry (most of the time this selects
        # everything) allow for numerical errors here from convolution (i.e.
        # using an FFT)
        self.wsel2 = np.where(self.rdeltaphimask * self.rdeltaphimaskb > .1)

        # number of radii and phi
        self.numrs = len(self.rphibinstat.bin_centers[0])
        self.numphis = len(self.rphibinstat.bin_centers[1])

        # save the bin centers, approx (ravg, phiavg)
        self.rvals, self.phivals = self.rphibinstat.bin_centers[0], \
            self.rphibinstat.bin_centers[1]

        # it's relative so just set first points to zero
        self.phivals = self.phivals - self.phivals[0]
        # the degree version
        self.phivalsd = np.degrees(self.phivals)

        # for computing S(q) and S2(q) during the process
        # self.rbinstat = mkrbinstat(self.shape, rbins, origin=origin,
        # statistic='mean', mask=mask,
        # r_map=r_map)
        self.rbinstat = RadialBinnedStatistic(self.shape,
                                              rbins,
                                              origin=origin,
                                              statistic='mean',
                                              mask=mask,
                                              r_map=r_map)

        # the counts per r bin, no need to use 'sum' this time
        self.Ircnts = self.rbinstat.flatcount

        # this initializes the accumulators for the correlations
        # back to zero
        self.clear_state()