예제 #1
0
def test_hbins():
    print('In pyalgos.test_hbins')
    from psana.pyalgos.generic.HBins import HBins
    o = HBins((1, 6), 5)
    print('  binedges():', o.binedges())
    assert (np.array_equal(o.binedges(),
                           np.array((1, 2, 3, 4, 5, 6), dtype=np.float)))
예제 #2
0
파일: HPolar.py 프로젝트: slac-lcls/lcls2
 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)
예제 #3
0
파일: FWHist.py 프로젝트: slac-lcls/lcls2
def test_histogram():
    import psana.pyalgos.generic.NDArrGenerators as ag
    from psana.pyalgos.generic.HBins import HBins
    nbins = 1000
    arr = ag.random_standard((nbins,), mu=50, sigma=10, dtype=ag.np.float64)
    hb = HBins((0,nbins), nbins=nbins)
    hb.set_bin_data(arr, dtype=ag.np.float64)
    return hb
예제 #4
0
파일: HPolar.py 프로젝트: slac-lcls/lcls2
 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
예제 #5
0
    def proc_waveforms(self, wfs, wts) :
        """
        """
        # if waveforms are already processed
        if wfs is self._wfs_old : return

        self._init_arrays()
 
        #print_ndarr(wfs, '  waveforms : ', last=4)
        assert (self.NUM_CHANNELS==wfs.shape[0]),\
               'expected number of channels in not consistent with waveforms array shape'

        if self.VERSION == 2 : std = wfs[:,self.IOFFSETBEG:self.IOFFSETEND].std(axis=1)

        if self.VERSION == 4:
            self.wfsprep = wfs[:,self.WFBINBEG:self.WFBINEND]
        else:      
            offsets = wfs[:,self.IOFFSETBEG:self.IOFFSETEND].mean(axis=1)
            #print('  XXX offsets: %s' % str(offsets))        
            self.wfsprep = wfs[:,self.WFBINBEG:self.WFBINEND] - offsets.reshape(-1, 1) # subtract wf-offset
        self.wtsprep = wts[:,self.WFBINBEG:self.WFBINEND] # sec

        for ch in range(self.NUM_CHANNELS) :

            wf = self.wfsprep[ch,:]
            wt = self.wtsprep[ch,:]

            npeaks = None
            if self.VERSION == 3 :
                npeaks, self.wfgi, self.wff, self.wfg, self.thrg, self.edges =\
                peak_finder_v3(wf, self.SIGMABINS, self.BASEBINS, self.NSTDTHR, self.GAPBINS, self.DEADBINS,\
                                        self._pkvals[ch,:], self._pkinds[ch,:])
            elif self.VERSION == 2 :
                self.THR = self.NSTDTHR*std[ch]
                npeaks = peak_finder_v2(wf, self.SIGMABINS, self.THR, self.DEADBINS,\
                                        self._pkvals[ch,:], self._pkinds[ch,:])
            elif self.VERSION == 4 :
                t_list = self.PyCFDs[ch].CFD(wf,wt)
                npeaks = self._pkinds[ch,:].size if self._pkinds[ch,:].size<=len(t_list) else len(t_list)
                # need it in V4 to convert _pktsec to _pkinds and _pkvals
                if self.tbins is None :
                    from psana.pyalgos.generic.HBins import HBins
                    self.tbins = HBins(list(wt))

            else : # self.VERSION == 1
                npeaks = wfpkfinder_cfd(wf, self.BASE, self.THR, self.CFR, self.DEADTIME, self.LEADINGEDGE,\
                                        self._pkvals[ch,:], self._pkinds[ch,:])

            #print(' npeaks:', npeaks)
            #assert (npeaks<self.NUM_HITS), 'number of found peaks exceeds reserved array shape'
            if npeaks>=self.NUM_HITS : npeaks = self.NUM_HITS
            self._number_of_hits[ch] = npeaks
            if self.VERSION == 4 :
                self._pktsec[ch, :npeaks] = np.array(t_list)[:npeaks]
            else:
                self._pktsec[ch, :npeaks] = wt[self._pkinds[ch, :npeaks]] #sec

        self._wfs_old = wfs
예제 #6
0
    def set_histogram_from_arr(self, arr, nbins=1000, amin=None, amax=None, frmin=0.001, frmax=0.999, edgemode=0, update_hblimits=True):
        #if np.array_equal(arr, self.arr_old): return
        if arr is self.arr_old: return
        self.arr_old = arr
        if arr.size<1: return

        aravel = arr.ravel()

        vmin, vmax = self.hbins.limits() if self.hbins is not None else (None, None)

        if self.hbins is None or update_hblimits:
          vmin = amin if amin is not None else\
               aravel.min() if frmin in (0,None) else\
               np.quantile(aravel, frmin, axis=0, interpolation='lower')
          vmax = amax if amax is not None else\
               aravel.max() if frmax in (1,None) else\
               np.quantile(aravel, frmax, axis=0, interpolation='higher')
          if not vmin<vmax: vmax=vmin+1

        hb = HBins((vmin,vmax), nbins=nbins)
        hb.set_bin_data_from_array(aravel, dtype=np.float64, edgemode=edgemode)

        hmin, hmax = 0, hb.bin_data_max()
        #logger.debug('set_histogram_from_arr %s\n    vmin(%.5f%%):%.3f vmax(%.5f%%):%.3f hmin: %.3f hmax: %.3f'%\
        #             (info_ndarr(aravel, 'arr.ravel'), frmin,vmin,frmax,vmax,hmin,hmax))
        hgap = 0.05*(hmax-hmin)

        rs0 = self.scene().sceneRect()
        rsy, rsh = (hb.vmin(), hb.vmax()-hb.vmin()) if update_hblimits else (rs0.y(), rs0.height())
        rs = QRectF(hmin-hgap, rsy, hmax-hmin+2*hgap, rsh)
        self.set_rect_scene(rs, set_def=update_hblimits)

        self.update_my_scene(hbins=hb)
        self.hbins = hb
예제 #7
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()
예제 #8
0
class WFPeaks :

    def __init__(self, **kwargs) :
        """Waveform peak finder wrapper.
           - wf digitizer channels (0,1,2,3,4) should be ordered for u1,u2,v1,v2[,w1,w2],mcp, respectively
        """
        logger.debug(gu.str_kwargs(kwargs, title='WFPeaks input parameters:'))
        self.set_wf_peak_finder_parameters(**kwargs)

        self._wfs_old = None

        self.tbins = None # need it in V4 to convert _pktsec to _pkinds and _pkvals

#----------

    def set_wf_peak_finder_parameters(self, **kwargs) :

        self.NUM_CHANNELS= kwargs.get('numchs',  5)
        self.NUM_HITS    = kwargs.get('numhits',16)
        self.VERSION     = kwargs.get('version', 1)
        self.DLD     = kwargs.get('DLD', False)        

        if True :
            self.BASE        = kwargs.get('cfd_base',          0.)
            self.THR         = kwargs.get('cfd_thr',        -0.05)
            self.CFR         = kwargs.get('cfd_cfr',         0.85)
            self.DEADTIME    = kwargs.get('cfd_deadtime',    10.0)
            self.LEADINGEDGE = kwargs.get('cfd_leadingedge', True)
            self.IOFFSETBEG  = kwargs.get('cfd_ioffsetbeg',  1000)
            self.IOFFSETEND  = kwargs.get('cfd_ioffsetend',  2000)
            self.WFBINBEG    = kwargs.get('cfd_wfbinbeg',    6000)
            self.WFBINEND    = kwargs.get('cfd_wfbinend',   30000)

        if self.VERSION == 2 :
            self.SIGMABINS   = kwargs.get('pf2_sigmabins',      3)
            self.NSTDTHR     = kwargs.get('pf2_nstdthr',       -5)
            self.DEADBINS    = kwargs.get('pf2_deadbins',      10)
            self.IOFFSETBEG  = kwargs.get('pf2_ioffsetbeg',  1000)
            self.IOFFSETEND  = kwargs.get('pf2_ioffsetend',  2000)
            self.WFBINBEG    = kwargs.get('pf2_wfbinbeg',    6000)
            self.WFBINEND    = kwargs.get('pf2_wfbinend',   30000)

        if self.VERSION == 3 :
            self.SIGMABINS   = kwargs.get('pf3_sigmabins',      3)
            self.BASEBINS    = kwargs.get('pf3_basebins',     100)
            self.NSTDTHR     = kwargs.get('pf3_nstdthr',        5)
            self.GAPBINS     = kwargs.get('pf3_gapbins',      200)
            self.DEADBINS    = kwargs.get('pf3_deadbins',      10)
            # used in proc_waveforms
            self.IOFFSETBEG  = kwargs.get('pf3_ioffsetbeg',  1000)
            self.IOFFSETEND  = kwargs.get('pf3_ioffsetend',  2000)
            self.WFBINBEG    = kwargs.get('pf3_wfbinbeg',    6000)
            self.WFBINEND    = kwargs.get('pf3_wfbinend',   30000)
            
        if self.VERSION == 4 :
            paramsCFD = kwargs.get('paramsCFD', {})
            
            if self.DLD:
                self.paramsCFD = {}

                if self.NUM_CHANNELS == 5:
                    self.cnls = ['x1','x2','y1','y2','mcp']
                elif self.NUM_CHANNELS == 7:
                    self.cnls = ['u1','u2','v1','v2','w1','w2','mcp']

                if isinstance(paramsCFD,list):
                    for param in paramsCFD:
                        if param['channel'] not in self.cnls:
                            raise NameError("Channel names should be chosen from ['x1','x2','y1','y2','mcp'] for QUAD and ['u1','u2','v1','v2','w1','w2','mcp'] for HEX.")
                        self.paramsCFD[param['channel']] = param
                elif isinstance(paramsCFD,dict):
                    for k,param in paramsCFD.items():
                        if param['channel'] not in self.cnls:
                            raise NameError("Channel names should be chosen from ['x1','x2','y1','y2','mcp'] for QUAD and ['u1','u2','v1','v2','w1','w2','mcp'] for HEX.")
                        self.paramsCFD[param['channel']] = param                    

                self.PyCFDs = [PyCFD(self.paramsCFD[self.cnls[i]]) for i in range(self.NUM_CHANNELS)]
            else:
                if isinstance(paramsCFD,list):            
                    self.PyCFDs = [PyCFD(paramsCFD[i]) for i in range(self.NUM_CHANNELS)] 
                elif isinstance(paramsCFD,dict):       
                    self.PyCFDs = [PyCFD(param) for k, param in paramsCFD.items()]                                             

#----------

    def _init_arrays(self) :
        self._number_of_hits = np.zeros((self.NUM_CHANNELS), dtype=np.int)
        self._pkvals = np.zeros((self.NUM_CHANNELS,self.NUM_HITS), dtype=np.double)
        self._pkinds = np.zeros((self.NUM_CHANNELS,self.NUM_HITS), dtype=np.uint32)
        self._pktsec = np.zeros((self.NUM_CHANNELS,self.NUM_HITS), dtype=np.double)

#----------

    def proc_waveforms(self, wfs, wts) :
        """
        """
        # if waveforms are already processed
        if wfs is self._wfs_old : return

        self._init_arrays()
 
        #print_ndarr(wfs, '  waveforms : ', last=4)
        assert (self.NUM_CHANNELS==wfs.shape[0]),\
               'expected number of channels in not consistent with waveforms array shape'

        if self.VERSION == 2 : std = wfs[:,self.IOFFSETBEG:self.IOFFSETEND].std(axis=1)

        if self.VERSION == 4:
            self.wfsprep = wfs[:,self.WFBINBEG:self.WFBINEND]
        else:      
            offsets = wfs[:,self.IOFFSETBEG:self.IOFFSETEND].mean(axis=1)
            #print('  XXX offsets: %s' % str(offsets))        
            self.wfsprep = wfs[:,self.WFBINBEG:self.WFBINEND] - offsets.reshape(-1, 1) # subtract wf-offset
        self.wtsprep = wts[:,self.WFBINBEG:self.WFBINEND] # sec

        for ch in range(self.NUM_CHANNELS) :

            wf = self.wfsprep[ch,:]
            wt = self.wtsprep[ch,:]

            npeaks = None
            if self.VERSION == 3 :
                npeaks, self.wfgi, self.wff, self.wfg, self.thrg, self.edges =\
                peak_finder_v3(wf, self.SIGMABINS, self.BASEBINS, self.NSTDTHR, self.GAPBINS, self.DEADBINS,\
                                        self._pkvals[ch,:], self._pkinds[ch,:])
            elif self.VERSION == 2 :
                self.THR = self.NSTDTHR*std[ch]
                npeaks = peak_finder_v2(wf, self.SIGMABINS, self.THR, self.DEADBINS,\
                                        self._pkvals[ch,:], self._pkinds[ch,:])
            elif self.VERSION == 4 :
                t_list = self.PyCFDs[ch].CFD(wf,wt)
                npeaks = self._pkinds[ch,:].size if self._pkinds[ch,:].size<=len(t_list) else len(t_list)
                # need it in V4 to convert _pktsec to _pkinds and _pkvals
                if self.tbins is None :
                    from psana.pyalgos.generic.HBins import HBins
                    self.tbins = HBins(list(wt))

            else : # self.VERSION == 1
                npeaks = wfpkfinder_cfd(wf, self.BASE, self.THR, self.CFR, self.DEADTIME, self.LEADINGEDGE,\
                                        self._pkvals[ch,:], self._pkinds[ch,:])

            #print(' npeaks:', npeaks)
            #assert (npeaks<self.NUM_HITS), 'number of found peaks exceeds reserved array shape'
            if npeaks>=self.NUM_HITS : npeaks = self.NUM_HITS
            self._number_of_hits[ch] = npeaks
            if self.VERSION == 4 :
                self._pktsec[ch, :npeaks] = np.array(t_list)[:npeaks]
            else:
                self._pktsec[ch, :npeaks] = wt[self._pkinds[ch, :npeaks]] #sec

        self._wfs_old = wfs

#----------

    def waveforms_preprocessed(self, wfs, wts) :
        """Returns preprocessed waveforms for selected range [WFBINBEG:WFBINEND];
           wfsprep[NUM_CHANNELS,WFBINBEG:WFBINEND] - intensities with subtracted mean evaluated
           wtsprep[NUM_CHANNELS,WFBINBEG:WFBINEND] - times in [sec] like raw data 
        """
        self.proc_waveforms(wfs, wts)
        return self.wfsprep, self.wtsprep

#----------

    def number_of_hits(self, wfs, wts) :
        self.proc_waveforms(wfs, wts)
        return self._number_of_hits

    def peak_times_sec(self, wfs, wts) :
        self.proc_waveforms(wfs, wts)
        return self._pktsec

    def peak_indexes(self, wfs, wts) :
        self.proc_waveforms(wfs, wts)
        return self._pkinds

    def peak_values(self, wfs, wts) :
        self.proc_waveforms(wfs, wts)
        return self._pkvals

    def peak_indexes_values(self, wfs, wts) :
        """ added for V4 to convert _pktsec to _pkinds and _pkvals
        """
        self.proc_waveforms(wfs, wts)
        if self.VERSION == 4 :
          # This is SLOW for V4 graphics...
          for ch in range(self.NUM_CHANNELS) :
            npeaks = self._number_of_hits[ch]
            wf = self.wfsprep[ch,:]
            self._pkinds[ch, :npeaks] = self.tbins.bin_indexes(self._pktsec[ch, :npeaks])
            self._pkvals[ch, :npeaks] = wf[self._pkinds[ch, :npeaks]]
        return self._pkinds, self._pkvals

    def __call__(self, wfs, wts) :
        self.proc_waveforms(wfs, wts)
        return self._number_of_hits,\
               self._pkinds,\
               self._pkvals,\
               self._pktsec
#----------

    def __del__(self) :
        pass
예제 #9
0
    def __init__(self, proc, **kwargs):

        self.proc = proc

        logger.info('In set_parameters, **kwargs: %s' % str(kwargs))
        self.STAT_NHITS = kwargs.get('STAT_NHITS', True)
        self.STAT_TIME_CH = kwargs.get('STAT_TIME_CH', True)
        self.STAT_UVW = kwargs.get('STAT_UVW', True)
        self.STAT_TIME_SUMS = kwargs.get('STAT_TIME_SUMS', True)
        self.STAT_CORRELATIONS = kwargs.get('STAT_CORRELATIONS', True)
        self.STAT_XY_COMPONENTS = kwargs.get('STAT_XY_COMPONENTS', True)
        self.STAT_XY_2D = kwargs.get('STAT_XY_2D', True)
        self.STAT_MISC = kwargs.get('STAT_MISC', True)
        self.STAT_REFLECTIONS = kwargs.get('STAT_REFLECTIONS', True)
        self.STAT_PHYSICS = kwargs.get('STAT_PHYSICS', True)
        self.STAT_XY_RESOLUTION = kwargs.get('STAT_XY_RESOLUTION',
                                             False)  # not available for QUAD

        if self.STAT_TIME_CH:
            self.lst_u1 = []
            self.lst_u2 = []
            self.lst_v1 = []
            self.lst_v2 = []
            self.lst_w1 = []
            self.lst_w2 = []
            self.lst_mcp = []

        if self.STAT_NHITS:
            self.lst_nhits_u1 = []
            self.lst_nhits_u2 = []
            self.lst_nhits_v1 = []
            self.lst_nhits_v2 = []
            self.lst_nhits_w1 = []
            self.lst_nhits_w2 = []
            self.lst_nhits_mcp = []
            self.lst_nparts = []

        if self.STAT_UVW or self.STAT_CORRELATIONS:
            self.lst_u_ns = []
            self.lst_v_ns = []
            self.lst_w_ns = []
            self.lst_u = []
            self.lst_v = []
            self.lst_w = []

        if self.STAT_TIME_SUMS or self.STAT_CORRELATIONS:
            self.lst_time_sum_u = []
            self.lst_time_sum_v = []
            self.lst_time_sum_w = []

            self.lst_time_sum_u_corr = []
            self.lst_time_sum_v_corr = []
            self.lst_time_sum_w_corr = []

        if self.STAT_XY_COMPONENTS:
            self.lst_Xuv = []
            self.lst_Xuw = []
            self.lst_Xvw = []
            self.lst_Yuv = []
            self.lst_Yuw = []
            self.lst_Yvw = []

        if self.STAT_MISC:
            self.list_dr = []
            self.lst_consist_indicator = []
            self.lst_rec_method = []

        if self.STAT_XY_RESOLUTION:
            self.lst_binx = []
            self.lst_biny = []
            self.lst_resol_fwhm = []

        if self.STAT_REFLECTIONS:
            self.lst_refl_u1 = []
            self.lst_refl_u2 = []
            self.lst_refl_v1 = []
            self.lst_refl_v2 = []
            self.lst_refl_w1 = []
            self.lst_refl_w2 = []

        if self.STAT_XY_2D:
            # images
            nbins = 360
            self.img_x_bins = HBins((-45., 45.), nbins, vtype=np.float32)
            self.img_y_bins = HBins((-45., 45.), nbins, vtype=np.float32)
            self.img_xy_uv = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_uw = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_vw = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_1 = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_2 = np.zeros((nbins, nbins), dtype=np.float32)

        if self.STAT_PHYSICS:
            t_ns_nbins = 300
            self.t_ns_bins = HBins((1400., 2900.),
                                   t_ns_nbins,
                                   vtype=np.float32)
            #self.t1_vs_t0 = np.zeros((t_ns_nbins, t_ns_nbins), dtype=np.float32)

            self.ti_vs_tj = np.zeros((t_ns_nbins, t_ns_nbins),
                                     dtype=np.float32)
            self.t_all = np.zeros((t_ns_nbins, ), dtype=np.float32)
            self.lst_t_all = []

            x_mm_nbins = 200
            y_mm_nbins = 200
            r_mm_nbins = 200
            self.x_mm_bins = HBins((-50., 50.), x_mm_nbins, vtype=np.float32)
            self.y_mm_bins = HBins((-50., 50.), y_mm_nbins, vtype=np.float32)
            self.r_mm_bins = HBins((-50., 50.), r_mm_nbins, vtype=np.float32)
            #self.x_vs_t0 = np.zeros((x_mm_nbins, t_ns_nbins), dtype=np.float32)
            #self.y_vs_t0 = np.zeros((y_mm_nbins, t_ns_nbins), dtype=np.float32)
            self.rsx_vs_t = np.zeros((r_mm_nbins, t_ns_nbins),
                                     dtype=np.float32)
            self.rsy_vs_t = np.zeros((r_mm_nbins, t_ns_nbins),
                                     dtype=np.float32)
예제 #10
0
class DLDStatistics:
    """ holds, fills, and provide access to statistical arrays for MCP DLD data processing
    """
    def __init__(self, proc, **kwargs):

        self.proc = proc

        logger.info('In set_parameters, **kwargs: %s' % str(kwargs))
        self.STAT_NHITS = kwargs.get('STAT_NHITS', True)
        self.STAT_TIME_CH = kwargs.get('STAT_TIME_CH', True)
        self.STAT_UVW = kwargs.get('STAT_UVW', True)
        self.STAT_TIME_SUMS = kwargs.get('STAT_TIME_SUMS', True)
        self.STAT_CORRELATIONS = kwargs.get('STAT_CORRELATIONS', True)
        self.STAT_XY_COMPONENTS = kwargs.get('STAT_XY_COMPONENTS', True)
        self.STAT_XY_2D = kwargs.get('STAT_XY_2D', True)
        self.STAT_MISC = kwargs.get('STAT_MISC', True)
        self.STAT_REFLECTIONS = kwargs.get('STAT_REFLECTIONS', True)
        self.STAT_PHYSICS = kwargs.get('STAT_PHYSICS', True)
        self.STAT_XY_RESOLUTION = kwargs.get('STAT_XY_RESOLUTION',
                                             False)  # not available for QUAD

        if self.STAT_TIME_CH:
            self.lst_u1 = []
            self.lst_u2 = []
            self.lst_v1 = []
            self.lst_v2 = []
            self.lst_w1 = []
            self.lst_w2 = []
            self.lst_mcp = []

        if self.STAT_NHITS:
            self.lst_nhits_u1 = []
            self.lst_nhits_u2 = []
            self.lst_nhits_v1 = []
            self.lst_nhits_v2 = []
            self.lst_nhits_w1 = []
            self.lst_nhits_w2 = []
            self.lst_nhits_mcp = []
            self.lst_nparts = []

        if self.STAT_UVW or self.STAT_CORRELATIONS:
            self.lst_u_ns = []
            self.lst_v_ns = []
            self.lst_w_ns = []
            self.lst_u = []
            self.lst_v = []
            self.lst_w = []

        if self.STAT_TIME_SUMS or self.STAT_CORRELATIONS:
            self.lst_time_sum_u = []
            self.lst_time_sum_v = []
            self.lst_time_sum_w = []

            self.lst_time_sum_u_corr = []
            self.lst_time_sum_v_corr = []
            self.lst_time_sum_w_corr = []

        if self.STAT_XY_COMPONENTS:
            self.lst_Xuv = []
            self.lst_Xuw = []
            self.lst_Xvw = []
            self.lst_Yuv = []
            self.lst_Yuw = []
            self.lst_Yvw = []

        if self.STAT_MISC:
            self.list_dr = []
            self.lst_consist_indicator = []
            self.lst_rec_method = []

        if self.STAT_XY_RESOLUTION:
            self.lst_binx = []
            self.lst_biny = []
            self.lst_resol_fwhm = []

        if self.STAT_REFLECTIONS:
            self.lst_refl_u1 = []
            self.lst_refl_u2 = []
            self.lst_refl_v1 = []
            self.lst_refl_v2 = []
            self.lst_refl_w1 = []
            self.lst_refl_w2 = []

        if self.STAT_XY_2D:
            # images
            nbins = 360
            self.img_x_bins = HBins((-45., 45.), nbins, vtype=np.float32)
            self.img_y_bins = HBins((-45., 45.), nbins, vtype=np.float32)
            self.img_xy_uv = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_uw = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_vw = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_1 = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_2 = np.zeros((nbins, nbins), dtype=np.float32)

        if self.STAT_PHYSICS:
            t_ns_nbins = 300
            self.t_ns_bins = HBins((1400., 2900.),
                                   t_ns_nbins,
                                   vtype=np.float32)
            #self.t1_vs_t0 = np.zeros((t_ns_nbins, t_ns_nbins), dtype=np.float32)

            self.ti_vs_tj = np.zeros((t_ns_nbins, t_ns_nbins),
                                     dtype=np.float32)
            self.t_all = np.zeros((t_ns_nbins, ), dtype=np.float32)
            self.lst_t_all = []

            x_mm_nbins = 200
            y_mm_nbins = 200
            r_mm_nbins = 200
            self.x_mm_bins = HBins((-50., 50.), x_mm_nbins, vtype=np.float32)
            self.y_mm_bins = HBins((-50., 50.), y_mm_nbins, vtype=np.float32)
            self.r_mm_bins = HBins((-50., 50.), r_mm_nbins, vtype=np.float32)
            #self.x_vs_t0 = np.zeros((x_mm_nbins, t_ns_nbins), dtype=np.float32)
            #self.y_vs_t0 = np.zeros((y_mm_nbins, t_ns_nbins), dtype=np.float32)
            self.rsx_vs_t = np.zeros((r_mm_nbins, t_ns_nbins),
                                     dtype=np.float32)
            self.rsy_vs_t = np.zeros((r_mm_nbins, t_ns_nbins),
                                     dtype=np.float32)

#----------

    def fill_data(self, number_of_hits, tdc_sec):
        if self.fill_corrected_data():
            self.fill_raw_data(number_of_hits, tdc_sec)

#----------

    def fill_raw_data(self, number_of_hits, tdc_sec):

        tdc_ns = tdc_sec * SEC_TO_NS  # sec -> ns

        sorter = self.proc.sorter
        Cu1, Cu2, Cv1, Cv2, Cw1, Cw2, Cmcp = sorter.channel_indexes

        if self.STAT_NHITS:
            self.lst_nhits_mcp.append(number_of_hits[Cmcp])
            self.lst_nhits_u1.append(number_of_hits[Cu1])
            self.lst_nhits_u2.append(number_of_hits[Cu2])
            self.lst_nhits_v1.append(number_of_hits[Cv1])
            self.lst_nhits_v2.append(number_of_hits[Cv2])
            if sorter.use_hex:
                self.lst_nhits_w1.append(number_of_hits[Cw1])
                self.lst_nhits_w2.append(number_of_hits[Cw2])

        if self.STAT_TIME_CH:
            self.lst_mcp.append(tdc_ns[Cmcp, 0])
            self.lst_u1.append(tdc_ns[Cu1, 0])
            self.lst_u2.append(tdc_ns[Cu2, 0])
            self.lst_v1.append(tdc_ns[Cv1, 0])
            self.lst_v2.append(tdc_ns[Cv2, 0])
            if sorter.use_hex:
                self.lst_w1.append(tdc_ns[Cw1, 0])
                self.lst_w2.append(tdc_ns[Cw2, 0])

        if self.STAT_REFLECTIONS:
            if number_of_hits[Cu2] > 1:
                self.lst_refl_u1.append(tdc_ns[Cu2, 1] - tdc_ns[Cu1, 0])
            if number_of_hits[Cu1] > 1:
                self.lst_refl_u2.append(tdc_ns[Cu1, 1] - tdc_ns[Cu2, 0])
            if number_of_hits[Cv2] > 1:
                self.lst_refl_v1.append(tdc_ns[Cv2, 1] - tdc_ns[Cv1, 0])
            if number_of_hits[Cv1] > 1:
                self.lst_refl_v2.append(tdc_ns[Cv1, 1] - tdc_ns[Cv2, 0])
            if sorter.use_hex:
                if number_of_hits[Cw2] > 1:
                    self.lst_refl_w1.append(tdc_ns[Cw2, 1] - tdc_ns[Cw1, 0])
                if number_of_hits[Cw1] > 1:
                    self.lst_refl_w2.append(tdc_ns[Cw1, 1] - tdc_ns[Cw2, 0])

        time_sum_u = tdc_ns[Cu1, 0] + tdc_ns[Cu2, 0] - 2 * tdc_ns[Cmcp, 0]
        time_sum_v = tdc_ns[Cv1, 0] + tdc_ns[Cv2, 0] - 2 * tdc_ns[Cmcp, 0]
        time_sum_w = tdc_ns[Cw1, 0] + tdc_ns[
            Cw2, 0] - 2 * tdc_ns[Cmcp, 0] if sorter.use_hex else 0

        #logger.info("RAW time_sum_u: %.2f _v: %.2f _w: %.2f " % (time_sum_u, time_sum_v, time_sum_w))

        if self.STAT_TIME_SUMS or self.STAT_CORRELATIONS:
            self.lst_time_sum_u.append(time_sum_u)
            self.lst_time_sum_v.append(time_sum_v)
            if sorter.use_hex:
                self.lst_time_sum_w.append(time_sum_w)

        #if self.STAT_XY_RESOLUTION :
        # NOT VALID FOR QUAD
        #sfco = hexanode.py_scalefactors_calibration_class(sorter) # NOT FOR QUAD
        #    #logger.info("    binx: %d  biny: %d  resolution(FWHM): %.6f" % (sfco.binx, sfco.biny, sfco.detector_map_resol_FWHM_fill))
        #    if sfco.binx>=0 and sfco.biny>=0 :
        #        self.lst_binx.append(sfco.binx)
        #        self.lst_biny.append(sfco.biny)
        #        self.lst_resol_fwhm.append(sfco.detector_map_resol_FWHM_fill)

#----------

    def fill_corrected_data(self):

        sorter = self.proc.sorter
        Cu1, Cu2, Cv1, Cv2, Cw1, Cw2, Cmcp = sorter.channel_indexes
        number_of_particles = sorter.output_number_of_hits

        if self.STAT_NHITS:
            self.lst_nparts.append(number_of_particles)

        # Discards most of events in command>1
        #=====================
        if number_of_particles < 1:
            logger.debug('no hits found in event ')
            return False
        #=====================

        tdc_ns = self.proc.tdc_ns

        u_ns = tdc_ns[Cu1, 0] - tdc_ns[Cu2, 0]
        v_ns = tdc_ns[Cv1, 0] - tdc_ns[Cv2, 0]
        w_ns = 0  #tdc_ns[Cw1,0] - tdc_ns[Cw2,0]

        u = u_ns * sorter.fu
        v = v_ns * sorter.fv
        w = 0  #(w_ns + self.w_offset) * sorter.fw

        Xuv = u
        Xuw = 0  #u
        Xvw = 0  #v + w
        Yuv = v  #(u - 2*v)*OSQRT3
        Yuw = 0  #(2*w - u)*OSQRT3
        Yvw = 0  # (w - v)*OSQRT3

        dX = 0  # Xuv - Xvw
        dY = 0  # Yuv - Yvw

        time_sum_u_corr = tdc_ns[Cu1, 0] + tdc_ns[Cu2, 0] - 2 * tdc_ns[Cmcp, 0]
        time_sum_v_corr = tdc_ns[Cv1, 0] + tdc_ns[Cv2, 0] - 2 * tdc_ns[Cmcp, 0]
        time_sum_w_corr = 0  # tdc_ns[Cw1,0] + tdc_ns[Cw2,0] - 2*tdc_ns[Cmcp,0]

        if sorter.use_hex:
            w_ns = tdc_ns[Cw1, 0] - tdc_ns[Cw2, 0]
            w = (w_ns + self.w_offset) * sorter.fw

            Xuw = u
            Xvw = v + w
            Yuv = (u - 2 * v) * OSQRT3
            Yuw = (2 * w - u) * OSQRT3
            Yvw = (w - v) * OSQRT3

            dX = Xuv - Xvw
            dY = Yuv - Yvw

            time_sum_w_corr = tdc_ns[Cw1, 0] + tdc_ns[Cw2,
                                                      0] - 2 * tdc_ns[Cmcp, 0]

        #---------

        if self.STAT_UVW or self.STAT_CORRELATIONS:
            self.lst_u_ns.append(u_ns)
            self.lst_v_ns.append(v_ns)
            self.lst_w_ns.append(w_ns)
            self.lst_u.append(u)
            self.lst_v.append(v)
            self.lst_w.append(w)

        if self.STAT_TIME_SUMS or self.STAT_CORRELATIONS:
            self.lst_time_sum_u_corr.append(time_sum_u_corr)
            self.lst_time_sum_v_corr.append(time_sum_v_corr)
            self.lst_time_sum_w_corr.append(time_sum_w_corr)

        if self.STAT_XY_COMPONENTS:
            self.lst_Xuv.append(Xuv)
            self.lst_Xuw.append(Xuw)
            self.lst_Xvw.append(Xvw)

            self.lst_Yuv.append(Yuv)
            self.lst_Yuw.append(Yuw)
            self.lst_Yvw.append(Yvw)

        hco = py_hit_class(sorter, 0)

        if self.STAT_MISC:
            inds_incr = ((Cu1,1), (Cu2,2), (Cv1,4), (Cv2,8), (Cw1,16), (Cw2,32), (Cmcp,64)) if sorter.use_hex else\
                        ((Cu1,1), (Cu2,2), (Cv1,4), (Cv2,8), (Cmcp,16))

            dR = sqrt(dX * dX + dY * dY)
            self.list_dr.append(dR)

            # fill Consistence Indicator
            consistenceIndicator = 0
            for (ind, incr) in inds_incr:
                if self.proc.number_of_hits[ind] > 0:
                    consistenceIndicator += incr
            self.lst_consist_indicator.append(consistenceIndicator)

            self.lst_rec_method.append(hco.method)
            #logger.info('reconstruction method %d' % hco.method)

        if self.STAT_XY_2D:

            # fill 2-d images
            x1, y1 = hco.x, hco.y

            x2, y2 = (-10, -10)
            if number_of_particles > 1:
                hco2 = py_hit_class(sorter, 1)
                x2, y2 = hco2.x, hco2.y

            ix1, ix2, ixuv, ixuw, ixvw = self.img_x_bins.bin_indexes(
                (x1, x2, Xuv, Xuw, Xvw))
            iy1, iy2, iyuv, iyuw, iyvw = self.img_y_bins.bin_indexes(
                (y1, y2, Yuv, Yuw, Yvw))

            self.img_xy_1[iy1, ix1] += 1
            self.img_xy_2[iy2, ix2] += 1
            self.img_xy_uv[iyuv, ixuv] += 1
            self.img_xy_uw[iyuw, ixuw] += 1
            self.img_xy_vw[iyvw, ixvw] += 1

        if self.STAT_PHYSICS:
            if self.proc.number_of_hits[Cmcp] > 1:
                #t0, t1 = tdc_ns[Cmcp,:2]
                #it0, it1 = self.t_ns_bins.bin_indexes((t0, t1))
                #self.t1_vs_t0[it1, it0] += 1

                #ix, iy = self.x_mm_bins.bin_indexes((Xuv,Yuv))
                #self.x_vs_t0[ix, it0] += 1
                #self.y_vs_t0[iy, it0] += 1

                #logger.info("  Event %5i  number_of_particles: %i" % (evnum, number_of_particles))
                #for i in range(number_of_particles) :
                #    hco = py_hit_class(sorter, i)
                #    #logger.info("    p:%2i x:%7.3f y:%7.3f t:%7.3f met:%d" % (i, hco.x, hco.y, hco.time, hco.method))
                #    x,y,t = hco.x, hco.y, hco.time
                #    r = sqrt(x*x+y*y)
                #    if x<0 : r=-r
                #    ir = self.r_mm_bins.bin_indexes((r,))
                #    it = self.t_ns_bins.bin_indexes((t,))
                #    self.r_vs_t[ir, it] += 1

                for x, y, r, t in sorter.xyrt_list():
                    #irx, iry = self.r_mm_bins.bin_indexes((r if x>0 else -r, r if y>0 else -r))
                    iry = self.r_mm_bins.bin_indexes((r if y > 0 else -r, ))
                    it = self.t_ns_bins.bin_indexes((t * SEC_TO_NS, ))
                    #self.rsx_vs_t[irx, it] += 1
                    self.rsy_vs_t[iry, it] += 1

                times = np.array(sorter.t_list()) * SEC_TO_NS
                tinds = self.t_ns_bins.bin_indexes(
                    times)  # INDEXES SHOULD BE np.array
                #print_ndarr(times, '\n    XXX times')
                #print_ndarr(tinds, '\n    XXX tinds')

                # accumulate times in the list
                for t in times:
                    self.lst_t_all.append(t)

                # accumulate times directly in histogram to evaluate average
                self.t_all[tinds] += 1

                # accumulate times in correlation matrix
                for i in tinds:
                    self.ti_vs_tj[i, tinds] += 1

        return True
예제 #11
0
파일: HPolar.py 프로젝트: slac-lcls/lcls2
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)
예제 #12
0
    def __init__(self):

        # set default parameters
        self.set_parameters()

        if self.PLOT_TIME_CH:
            self.lst_u1 = []
            self.lst_u2 = []
            self.lst_v1 = []
            self.lst_v2 = []
            self.lst_w1 = []
            self.lst_w2 = []
            self.lst_mcp = []

        if self.PLOT_NHITS:
            self.lst_nhits_u1 = []
            self.lst_nhits_u2 = []
            self.lst_nhits_v1 = []
            self.lst_nhits_v2 = []
            self.lst_nhits_w1 = []
            self.lst_nhits_w2 = []
            self.lst_nhits_mcp = []
            self.lst_nparts = []

        if self.PLOT_UVW or self.PLOT_CORRELATIONS:
            self.lst_u_ns = []
            self.lst_v_ns = []
            self.lst_w_ns = []
            self.lst_u = []
            self.lst_v = []
            self.lst_w = []

        if self.PLOT_TIME_SUMS or self.PLOT_CORRELATIONS:
            self.lst_time_sum_u = []
            self.lst_time_sum_v = []
            self.lst_time_sum_w = []

            self.lst_time_sum_u_corr = []
            self.lst_time_sum_v_corr = []
            self.lst_time_sum_w_corr = []

        if self.PLOT_XY_COMPONENTS:
            self.lst_Xuv = []
            self.lst_Xuw = []
            self.lst_Xvw = []
            self.lst_Yuv = []
            self.lst_Yuw = []
            self.lst_Yvw = []

        if self.PLOT_MISC:
            self.list_dr = []
            self.lst_consist_indicator = []
            self.lst_rec_method = []

        #if self.PLOT_XY_RESOLUTION :
        #    self.lst_binx = []
        #    self.lst_biny = []
        #    self.lst_resol_fwhm = []

        if self.PLOT_REFLECTIONS:
            self.lst_refl_u1 = []
            self.lst_refl_u2 = []
            self.lst_refl_v1 = []
            self.lst_refl_v2 = []
            self.lst_refl_w1 = []
            self.lst_refl_w2 = []

        if self.PLOT_XY_2D:
            # images
            nbins = 360
            self.img_x_bins = HBins((-45., 45.), nbins, vtype=np.float32)
            self.img_y_bins = HBins((-45., 45.), nbins, vtype=np.float32)
            self.img_xy_uv = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_uw = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_vw = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_1 = np.zeros((nbins, nbins), dtype=np.float32)
            self.img_xy_2 = np.zeros((nbins, nbins), dtype=np.float32)

        if self.PLOT_PHYSICS:
            t_ns_nbins = 300
            self.t_ns_bins = HBins((1400., 2900.),
                                   t_ns_nbins,
                                   vtype=np.float32)
            #self.t1_vs_t0 = np.zeros((t_ns_nbins, t_ns_nbins), dtype=np.float32)

            self.ti_vs_tj = np.zeros((t_ns_nbins, t_ns_nbins),
                                     dtype=np.float32)
            self.t_all = np.zeros((t_ns_nbins, ), dtype=np.float32)
            self.lst_t_all = []

            x_mm_nbins = 200
            y_mm_nbins = 200
            r_mm_nbins = 200
            self.x_mm_bins = HBins((-50., 50.), x_mm_nbins, vtype=np.float32)
            self.y_mm_bins = HBins((-50., 50.), y_mm_nbins, vtype=np.float32)
            self.r_mm_bins = HBins((-50., 50.), r_mm_nbins, vtype=np.float32)
            #self.x_vs_t0 = np.zeros((x_mm_nbins, t_ns_nbins), dtype=np.float32)
            #self.y_vs_t0 = np.zeros((y_mm_nbins, t_ns_nbins), dtype=np.float32)
            self.rsx_vs_t = np.zeros((r_mm_nbins, t_ns_nbins),
                                     dtype=np.float32)
            self.rsy_vs_t = np.zeros((r_mm_nbins, t_ns_nbins),
                                     dtype=np.float32)
예제 #13
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)