Esempio n. 1
0
def do_work():

    prefix = './%s-figs-ti_vs_tj' % gu.str_tstamp(
        fmt='%Y-%m-%d', time_sec=None)  # '%Y-%m-%dT%H:%M:%S%z'
    gu.create_directory(prefix, mode=0o775)

    path = os.path.abspath(os.path.dirname(__file__))
    print('path to npy flies dir:', path)

    ti_vs_tj = np.load('%s/ti_vs_tj.npy' % path)
    t_all = np.load('%s/t_all.npy' % path)

    trange = (1400., 2900.)

    print_ndarr(ti_vs_tj, 'ti_vs_tj:\n')
    print_ndarr(t_all, 't_all:\n')

    sum_bkg = t_all.sum()
    sum_cor = ti_vs_tj.sum()

    print('sum_bkg:', sum_bkg)
    print('sum_cor:', sum_cor)

    imrange = trange + trange  # (1400., 2900., 1400., 2900.)
    axim = gr.plotImageLarge(ti_vs_tj, img_range=imrange, amp_range=(0,500), figsize=(11,10),\
                             title='ti_vs_tj', origin='lower', window=(0.10, 0.08, 0.88, 0.88), cmap='inferno')
    gr.save('%s/fig-ti_vs_tj.png' % prefix)

    bkg = np.outer(t_all, t_all) / sum_bkg
    print_ndarr(bkg, 'bkg:\n')
    axim = gr.plotImageLarge(bkg, img_range=imrange, amp_range=(0,500), figsize=(11,10),\
                             title='bkg', origin='lower', window=(0.10, 0.08, 0.88, 0.88), cmap='inferno')
    gr.save('%s/fig-ti_vs_tj-bkg.png' % prefix)

    harr = t_all
    nbins = harr.size
    ht = HBins(trange, nbins, vtype=np.float32)  # ht.binedges()
    fig, axhi, hi = gr.hist1d(ht.bincenters(), bins=nbins, amp_range=ht.limits(), weights=harr, color='b', show_stat=True,\
                              log=True, figsize=(7,6), axwin=(0.10, 0.10, 0.88, 0.85), title='1-d bkg',\
                              xlabel='time of all hits (ns)', ylabel='number of hits', titwin='1-d bkg')
    gr.save('%s/fig-time-hits.png' % prefix)
    gr.show()
Esempio n. 2
0
class HPolar():
    def __init__(self,
                 xarr,
                 yarr,
                 mask=None,
                 radedges=None,
                 nradbins=100,
                 phiedges=(0, 360),
                 nphibins=32):
        """Parameters
           - mask     - n-d array with mask
           - xarr     - n-d array with pixel x coordinates in any units
           - yarr     - n-d array with pixel y coordinates in the same units as xarr
           - radedges - radial bin edges for corrected region in the same units of xarr;
                        default=None - all radial range
           - nradbins - number of radial bins
           - phiedges - phi angle bin edges for corrected region.
                        default=(0,360)
                        Difference of the edge limits should not exceed +/-360 degree
           - nphibins - number of angular bins
                        default=32 - bin size equal to 1 rhumb for default phiedges
        """
        self.rad, self.phi0 = cart2polar(xarr, yarr)
        self.shapeflat = (self.rad.size, )
        self.rad.shape = self.shapeflat
        self.phi0.shape = self.shapeflat
        self.mask = mask

        phimin = min(phiedges[0], phiedges[-1])

        self.phi = np.select((self.phi0 < phimin, self.phi0 >= phimin),
                             (self.phi0 + 360., self.phi0))

        self._set_rad_bins(radedges, nradbins)
        self._set_phi_bins(phiedges, nphibins)

        npbins = self.pb.nbins()
        nrbins = self.rb.nbins()
        self.ntbins = npbins * nrbins  # total number of bins in r-phi array

        self.irad = self.rb.bin_indexes(self.rad, edgemode=1)
        self.iphi = self.pb.bin_indexes(self.phi, edgemode=1)

        self.cond = np.logical_and(\
               np.logical_and(self.irad > -1, self.irad < nrbins),
               np.logical_and(self.iphi > -1, self.iphi < npbins)
               )

        if mask is not None:
            self.cond = np.logical_and(self.cond, mask.astype(np.bool).ravel())

        # index ntbins stands for overflow bin
        self.iseq = np.select((self.cond, ),
                              (self.iphi * nrbins + self.irad, ),
                              self.ntbins).ravel()

        #self.npix_per_bin = np.bincount(self.iseq, weights=None, minlength=None)
        self.npix_per_bin = np.bincount(self.iseq,
                                        weights=None,
                                        minlength=self.ntbins + 1)

        self.griddata = None

    def _set_rad_bins(self, radedges, nradbins):
        rmin = math.floor(np.amin(
            self.rad)) if radedges is None else radedges[0]
        rmax = math.ceil(np.amax(
            self.rad)) if radedges is None else radedges[-1]
        if rmin < 1: rmin = 1
        self.rb = HBins((rmin, rmax), nradbins)

    def _set_phi_bins(self, phiedges, nphibins):
        if phiedges[-1] > phiedges[0]+360\
        or phiedges[-1] < phiedges[0]-360:
            raise ValueError('Difference between angular edges should not exceed 360 degree;'\
                             ' phiedges: %.0f, %.0f' % (phiedges[0], phiedges[-1]))
        self.pb = HBins(phiedges, nphibins)
        phi1, phi2 = self.pb.limits()
        self.is360 = math.fabs(math.fabs(phi2 - phi1) - 360) < 1e-3

    def info_attrs(self):
        return '%s attrbutes:' % self.__class__.__name__\
          + self.pb.strrange(fmt='\nPhi bins:  min:%8.1f  max:%8.1f  nbins:%5d')\
          + self.rb.strrange(fmt='\nRad bins:  min:%8.1f  max:%8.1f  nbins:%5d')

    def print_attrs(self):
        print(self.info_attrs())

    def print_ndarrs(self):
        print('%s n-d arrays:' % self.__class__.__name__)
        print_ndarr(self.rad, '  rad')
        print_ndarr(self.phi, '  phi')
        print_ndarr(self.mask, '  mask')
        #print('Phi limits: ', phiedges[0], phiedges[-1])

    def obj_radbins(self):
        """Returns HBins object for radial bins."""
        return self.rb

    def obj_phibins(self):
        """Returns HBins object for angular bins."""
        return self.pb

    def pixel_rad(self):
        """Returns 1-d numpy array of pixel radial parameters."""
        return self.rad

    def pixel_irad(self):
        """Returns 1-d numpy array of pixel radial indexes [-1,nrbins] - extended edgemode."""
        return self.irad

    def pixel_phi0(self):
        """Returns 1-d numpy array of pixel angules in the range [-180,180] degree."""
        return self.phi0

    def pixel_phi(self):
        """Returns 1-d numpy array of pixel angules in the range [phi_min, phi_min+360] degree."""
        return self.phi

    def pixel_iphi(self):
        """Returns 1-d numpy array of pixel angular indexes [-1,npbins] - extended edgemode."""
        return self.iphi

    def pixel_iseq(self):
        """Returns 1-d numpy array of sequentially (in rad and phi) numerated pixel indexes [0,ntbins].
           WARNING: pixels outside the r-phi region of interest marked by the index ntbins,
                    ntbins - total number of r-phi bins, which exceeds allowed range of r-phi indices...
        """
        return self.iseq

    def bin_number_of_pixels(self):
        """Returns 1-d numpy array of number of accounted pixels per bin."""
        return self.npix_per_bin

    def _ravel_(self, nda):
        if len(nda.shape) > 1:
            #nda.shape = self.shapeflat
            return nda.ravel(
            )  # return ravel copy in order to preserve input array shape
        return nda

    def bin_intensity(self, nda):
        """Returns 1-d numpy array of total pixel intensity per bin for input array nda."""
        #return np.bincount(self.iseq, weights=self._ravel_(nda), minlength=None)
        return np.bincount(self.iseq,
                           weights=self._ravel_(nda),
                           minlength=self.ntbins + 1)  # +1 for overflow bin

    def bin_avrg(self, nda):
        """Returns 1-d numpy array of averaged in r-phi bin intensities for input image array nda.
           WARNING array range [0, nrbins*npbins + 1], where +1 bin intensity is for all off ROI pixels.
        """
        num = self.bin_intensity(self._ravel_(nda))
        den = self.bin_number_of_pixels()
        #print_ndarr(nda, name='ZZZ bin_avrg: nda', first=0, last=5)
        #print_ndarr(num, name='ZZZ bin_avrg: num', first=0, last=5)
        #print_ndarr(den, name='ZZZ bin_avrg: den', first=0, last=5)
        return divide_protected(num, den, vsub_zero=0)

    def bin_avrg_rad_phi(self, nda, do_transp=True):
        """Returns 2-d (rad,phi) numpy array of averaged in bin intensity for input array nda."""
        arr_rphi = self.bin_avrg(
            self._ravel_(nda))[:-1]  # -1 removes off ROI bin
        arr_rphi.shape = (self.pb.nbins(), self.rb.nbins())
        return np.transpose(arr_rphi) if do_transp else arr_rphi

    def pixel_avrg(self, nda, subs_value=0):
        """Makes r-phi histogram of intensities from input image array and
           projects r-phi averaged intensities back to image.
           Returns ravel 1-d numpy array of per-pixel intensities taken from r-phi histogram.
           - nda - input (2-d or 1-d-ravel) pixel array.
           - subs_value - value sabstituted for pixels out of ROI defined by the min/max in r-phi.
        """
        bin_avrg = self.bin_avrg(self._ravel_(nda))
        return np.select((self.cond, ), (bin_avrg[self.iseq], ),
                         subs_value).ravel()
        #return np.array([bin_avrg[i] for i in self.iseq]) # iseq may be outside the bin_avrg range

    def pixel_avrg_interpol(self,
                            nda,
                            method='linear',
                            verb=False,
                            subs_value=0):  # 'nearest' 'cubic'
        """Makes r-phi histogram of intensities from input image and
           projects r-phi averaged intensities back to image with per-pixel interpolation.
           Returns 1-d numpy array of per-pixel interpolated intensities taken from r-phi histogram.
           - subs_value - value sabstituted for pixels out of ROI defined by the min/max in r-phi.
        """

        #if not is360: raise ValueError('Interpolation works for 360 degree coverage ONLY')

        if self.griddata is None:
            from scipy.interpolate import griddata
            self.griddata = griddata

        # 1) get values in bin centers
        binv = self.bin_avrg_rad_phi(self._ravel_(nda), do_transp=False)

        # 2) add values in bin edges

        if verb: print('binv.shape: ', binv.shape)
        vrad_a1, vrad_a2 = binv[0, :], binv[-1, :]
        if self.is360:
            vrad_a1 = vrad_a2 = 0.5 * (binv[0, :] + binv[-1, :]
                                       )  # [iphi, irad]
        nodea = np.vstack((vrad_a1, binv, vrad_a2))

        vang_rmin, vang_rmax = nodea[:, 0], nodea[:, -1]
        vang_rmin.shape = vang_rmax.shape = (vang_rmin.size, 1
                                             )  # it should be 2d for hstack
        val_nodes = np.hstack((vang_rmin, nodea, vang_rmax))
        if verb: print('nodear.shape: ', val_nodes.shape)

        # 3) extend bin-centers by limits
        bcentsr = self.rb.bincenters()
        bcentsp = self.pb.bincenters()
        blimsr = self.rb.limits()
        blimsp = self.pb.limits()

        rad_nodes = np.concatenate(((blimsr[0], ), bcentsr, (blimsr[1], )))
        phi_nodes = np.concatenate(((blimsp[0], ), bcentsp, (blimsp[1], )))
        if verb: print('rad_nodes.shape', rad_nodes.shape)
        if verb: print('phi_nodes.shape', phi_nodes.shape)

        # 4) make point coordinate and value arrays
        points_rad, points_phi = np.meshgrid(rad_nodes, phi_nodes)
        if verb: print('points_phi.shape', points_phi.shape)
        if verb: print('points_rad.shape', points_rad.shape)
        points = np.vstack((points_phi.ravel(), points_rad.ravel())).T
        values = val_nodes.ravel()
        if verb:
            #print('points:', points)
            print('points.shape', points.shape)
            print('values.shape', values.shape)

        # 5) return interpolated data on (phi, rad) grid
        grid_vals = self.griddata(points,
                                  values, (self.phi, self.rad),
                                  method=method)
        return np.select((self.iseq < self.ntbins, ), (grid_vals, ),
                         default=subs_value)
Esempio n. 3
0
class HPolar():
    def __init__(self,
                 xarr,
                 yarr,
                 mask=None,
                 radedges=None,
                 nradbins=100,
                 phiedges=(0, 360),
                 nphibins=32):
        """Parameters
           - mask     - n-d array with mask
           - xarr     - n-d array with pixel x coordinates in any units
           - yarr     - n-d array with pixel y coordinates in the same units as xarr
           - radedges - radial bin edges for corrected region in the same units of xarr;
                        default=None - all radial range
           - nradbins - number of radial bins
           - phiedges - phi ange bin edges for corrected region.
                        default=(0,360)
                        Difference of the edge limits should not exceed +/-360 degree 
           - nphibins - number of angular bins
                        default=32 - bin size equal to 1 rhumb for default phiedges
        """
        self.rad, self.phi0 = cart2polar(xarr, yarr)
        self.shapeflat = (self.rad.size, )
        self.rad.shape = self.shapeflat
        self.phi0.shape = self.shapeflat
        self.mask = mask

        phimin = min(phiedges[0], phiedges[-1])

        self.phi = np.select((self.phi0 < phimin, self.phi0 >= phimin),
                             (self.phi0 + 360., self.phi0))

        self._set_rad_bins(radedges, nradbins)
        self._set_phi_bins(phiedges, nphibins)

        npbins = self.pb.nbins()
        nrbins = self.rb.nbins()
        ntbins = npbins * nrbins

        self.irad = self.rb.bin_indexes(self.rad, edgemode=1)
        self.iphi = self.pb.bin_indexes(self.phi, edgemode=1)

        cond = np.logical_and(\
               np.logical_and(self.irad > -1, self.irad < nrbins),
               np.logical_and(self.iphi > -1, self.iphi < npbins)
               )

        if mask is not None:
            cond = np.logical_and(cond, mask.astype(np.bool).flatten())

        self.iseq = np.select((cond, ), (self.iphi * nrbins + self.irad, ),
                              ntbins).flatten()

        self.npix_per_bin = np.bincount(self.iseq,
                                        weights=None,
                                        minlength=None)

        self.griddata = None
        self.print_ndarr = None

    def _set_rad_bins(self, radedges, nradbins):
        rmin = math.floor(np.amin(
            self.rad)) if radedges is None else radedges[0]
        rmax = math.ceil(np.amax(
            self.rad)) if radedges is None else radedges[-1]
        if rmin < 1: rmin = 1
        self.rb = HBins((rmin, rmax), nradbins)

    def _set_phi_bins(self, phiedges, nphibins):
        if phiedges[-1] > phiedges[0]+360\
        or phiedges[-1] < phiedges[0]-360:
            raise ValueError('Difference between angular edges should not exceed 360 degree;'\
                             ' phiedges: %.0f, %.0f' % (phiedges[0], phiedges[-1]))
        self.pb = HBins(phiedges, nphibins)
        phi1, phi2 = self.pb.limits()
        self.is360 = math.fabs(math.fabs(phi2 - phi1) - 360) < 1e-3

    def print_attrs(self):
        print('%s attrbutes:' % self.__class__.__name__)
        print(
            self.pb.strrange(fmt='Phi bins:  min:%8.1f  max:%8.1f  nbins:%5d'))
        print(
            self.rb.strrange(fmt='Rad bins:  min:%8.1f  max:%8.1f  nbins:%5d'))

    def print_ndarrs(self):
        print('%s n-d arrays:' % self.__class__.__name__)
        if self.print_ndarr is None:
            from psana.pyalgos.generic.NDArrUtils import print_ndarr
            self.print_ndarr = print_ndarr
        self.print_ndarr(self.rad, '  rad')
        self.print_ndarr(self.phi, '  phi')
        self.print_ndarr(self.mask, '  mask')
        #print('Phi limits: ', phiedges[0], phiedges[-1])

    def obj_radbins(self):
        """Returns HBins object for radial bins."""
        return self.rb

    def obj_phibins(self):
        """Returns HBins object for angular bins."""
        return self.pb

    def pixel_rad(self):
        """Returns 1-d numpy array of pixel radial parameters."""
        return self.rad

    def pixel_irad(self):
        """Returns 1-d numpy array of pixel radial indexes."""
        return self.irad

    def pixel_phi0(self):
        """Returns 1-d numpy array of pixel angules in the range [-180,180] degree."""
        return self.phi0

    def pixel_phi(self):
        """Returns 1-d numpy array of pixel angules in the range [phi_min, phi_min+360] degree."""
        return self.phi

    def pixel_iphi(self):
        """Returns 1-d numpy array of pixel angular indexes."""
        return self.iphi

    def pixel_iseq(self):
        """Returns 1-d numpy array of sequentially (in rad and phi) numerated pixel indexes."""
        return self.iseq

    def bin_number_of_pixels(self):
        """Returns 1-d numpy array of number of accounted pixels per bin."""
        return self.npix_per_bin

    def _flatten_(self, nda):
        if len(nda.shape) > 1:
            #nda.shape = self.shapeflat
            return nda.flatten(
            )  # return flatten copy in order to preserve input array shape
        return nda

    def bin_intensity(self, nda):
        """Returns 1-d numpy array of total pixel intensity per bin for input array nda."""
        return np.bincount(self.iseq,
                           weights=self._flatten_(nda),
                           minlength=None)

    def bin_avrg(self, nda):
        """Returns 1-d numpy array of averaged in bin intensity for input array nda."""
        num = self.bin_intensity(self._flatten_(nda))
        den = self.bin_number_of_pixels()
        return divide_protected(num, den, vsub_zero=0)

    def bin_avrg_rad_phi(self, nda, do_transp=True):
        """Returns 2-d (rad,phi) numpy array of averaged in bin intensity for input array nda."""
        arr_rphi = self.bin_avrg(self._flatten_(nda))[:-1]
        arr_rphi.shape = (self.pb.nbins(), self.rb.nbins())
        return np.transpose(arr_rphi) if do_transp else arr_rphi

    def pixel_avrg(self, nda):
        """Returns 1-d numpy array of per-pixel background for input array nda."""
        bin_avrg = self.bin_avrg(self._flatten_(nda))
        return np.array([bin_avrg[i] for i in self.iseq])

    def pixel_avrg_interpol(self,
                            nda,
                            method='linear',
                            verb=False):  # 'nearest' 'cubic'
        """Returns 1-d numpy array of per-pixel interpolated background for averaged input data."""

        #if not is360 : raise ValueError('Interpolation works for 360 degree coverage ONLY')

        if self.griddata is None:
            from scipy.interpolate import griddata
            self.griddata = griddata

        # 1) get values in bin centers
        binv = self.bin_avrg_rad_phi(self._flatten_(nda), do_transp=False)

        # 2) add values in bin edges

        if verb: print('binv.shape: ', binv.shape)
        vrad_a1, vrad_a2 = binv[0, :], binv[-1, :]
        if self.is360:
            vrad_a1 = vrad_a2 = 0.5 * (binv[0, :] + binv[-1, :]
                                       )  # [iphi, irad]
        nodea = np.vstack((vrad_a1, binv, vrad_a2))

        vang_rmin, vang_rmax = nodea[:, 0], nodea[:, -1]
        vang_rmin.shape = vang_rmax.shape = (vang_rmin.size, 1
                                             )  # it should be 2d for hstack
        val_nodes = np.hstack((vang_rmin, nodea, vang_rmax))
        if verb: print('nodear.shape: ', val_nodes.shape)

        # 3) extend bin-centers by limits
        bcentsr = self.rb.bincenters()
        bcentsp = self.pb.bincenters()
        blimsr = self.rb.limits()
        blimsp = self.pb.limits()

        rad_nodes = np.concatenate(((blimsr[0], ), bcentsr, (blimsr[1], )))
        phi_nodes = np.concatenate(((blimsp[0], ), bcentsp, (blimsp[1], )))
        if verb: print('rad_nodes.shape', rad_nodes.shape)
        if verb: print('phi_nodes.shape', phi_nodes.shape)

        # 4) make point coordinate and value arrays
        points_rad, points_phi = np.meshgrid(rad_nodes, phi_nodes)
        if verb: print('points_phi.shape', points_phi.shape)
        if verb: print('points_rad.shape', points_rad.shape)
        points = np.array(zip(points_phi.flatten(), points_rad.flatten()))
        if verb: print('points.shape', points.shape)

        values = val_nodes.flatten()
        if verb: print('values.shape', values.shape)

        # 4) return interpolated data on (phi, rad) grid
        grid_vals = self.griddata(points,
                                  values, (self.phi, self.rad),
                                  method=method)
        return np.select((self.iseq < self.pb.nbins() * self.rb.nbins(), ),
                         (grid_vals, ),
                         default=0)