示例#1
0
class PeakFinder:
    def __init__(self,
                 exp,
                 run,
                 detname,
                 evt,
                 detector,
                 algorithm,
                 hitParam_alg_npix_min,
                 hitParam_alg_npix_max,
                 hitParam_alg_amax_thr,
                 hitParam_alg_atot_thr,
                 hitParam_alg_son_min,
                 streakMask_on,
                 streakMask_sigma,
                 streakMask_width,
                 userMask_path,
                 psanaMask_on,
                 psanaMask_calib,
                 psanaMask_status,
                 psanaMask_edges,
                 psanaMask_central,
                 psanaMask_unbond,
                 psanaMask_unbondnrs,
                 medianFilterOn=0,
                 medianRank=5,
                 radialFilterOn=0,
                 distance=0.0,
                 windows=None,
                 **kwargs):
        self.exp = exp
        self.run = run
        self.detname = detname
        self.det = detector
        self.algorithm = algorithm
        self.maxRes = 0

        self.npix_min = hitParam_alg_npix_min
        self.npix_max = hitParam_alg_npix_max
        self.amax_thr = hitParam_alg_amax_thr
        self.atot_thr = hitParam_alg_atot_thr
        self.son_min = hitParam_alg_son_min

        self.streakMask_on = str2bool(streakMask_on)
        self.streakMask_sigma = streakMask_sigma
        self.streakMask_width = streakMask_width
        self.userMask_path = userMask_path
        self.psanaMask_on = str2bool(psanaMask_on)
        self.psanaMask_calib = str2bool(psanaMask_calib)
        self.psanaMask_status = str2bool(psanaMask_status)
        self.psanaMask_edges = str2bool(psanaMask_edges)
        self.psanaMask_central = str2bool(psanaMask_central)
        self.psanaMask_unbond = str2bool(psanaMask_unbond)
        self.psanaMask_unbondnrs = str2bool(psanaMask_unbondnrs)

        self.medianFilterOn = medianFilterOn
        self.medianRank = medianRank
        self.radialFilterOn = radialFilterOn
        self.distance = distance

        self.windows = windows

        self.userMask = None
        self.psanaMask = None
        self.streakMask = None
        self.userPsanaMask = None
        self.combinedMask = None

        # Make user mask
        if self.userMask_path is not None:
            self.userMask = np.load(self.userMask_path)

        # Make psana mask
        if self.psanaMask_on:
            self.psanaMask = detector.mask(evt,
                                           calib=self.psanaMask_calib,
                                           status=self.psanaMask_status,
                                           edges=self.psanaMask_edges,
                                           central=self.psanaMask_central,
                                           unbond=self.psanaMask_unbond,
                                           unbondnbrs=self.psanaMask_unbondnrs)

        # Combine userMask and psanaMask
        self.userPsanaMask = np.ones_like(self.det.calib(evt))
        if self.userMask is not None:
            self.userPsanaMask *= self.userMask
        if self.psanaMask is not None:
            self.userPsanaMask *= self.psanaMask

        # Powder of hits and misses
        self.powderHits = np.zeros_like(self.userPsanaMask)
        self.powderMisses = np.zeros_like(self.userPsanaMask)

        self.alg = PyAlgos(windows=self.windows,
                           mask=self.userPsanaMask,
                           pbits=0)
        # set peak-selector parameters:
        self.alg.set_peak_selection_pars(npix_min=self.npix_min, npix_max=self.npix_max, \
                                        amax_thr=self.amax_thr, atot_thr=self.atot_thr, \
                                        son_min=self.son_min)
        # set algorithm specific parameters
        if algorithm == 1:
            self.hitParam_alg1_thr_low = kwargs["alg1_thr_low"]
            self.hitParam_alg1_thr_high = kwargs["alg1_thr_high"]
            self.hitParam_alg1_rank = int(kwargs["alg1_rank"])
            self.hitParam_alg1_radius = int(kwargs["alg1_radius"])
            self.hitParam_alg1_dr = kwargs["alg1_dr"]
        elif algorithm == 3:
            self.hitParam_alg3_rank = kwargs["alg3_rank"]
            self.hitParam_alg3_r0 = int(kwargs["alg3_r0"])
            self.hitParam_alg3_dr = kwargs["alg3_dr"]
        elif algorithm == 4:
            self.hitParam_alg4_thr_low = kwargs["alg4_thr_low"]
            self.hitParam_alg4_thr_high = kwargs["alg4_thr_high"]
            self.hitParam_alg4_rank = int(kwargs["alg4_rank"])
            self.hitParam_alg4_r0 = int(kwargs["alg4_r0"])
            self.hitParam_alg4_dr = kwargs["alg4_dr"]

        self.maxNumPeaks = 2048
        self.StreakMask = myskbeam.StreakMask(self.det,
                                              evt,
                                              width=self.streakMask_width,
                                              sigma=self.streakMask_sigma)
        self.cx, self.cy = self.det.point_indexes(evt, pxy_um=(0, 0))
        self.iX = np.array(self.det.indexes_x(evt), dtype=np.int64)
        self.iY = np.array(self.det.indexes_y(evt), dtype=np.int64)
        if len(self.iX.shape) == 2:
            self.iX = np.expand_dims(self.iX, axis=0)
            self.iY = np.expand_dims(self.iY, axis=0)

        # Initialize radial background subtraction
        self.setupExperiment()
        if self.radialFilterOn:
            self.setupRadialBackground()
            self.updatePolarizationFactor()

    def setupExperiment(self):
        self.ds = psana.DataSource('exp=' + str(self.exp) + ':run=' +
                                   str(self.run) + ':idx')
        self.run = self.ds.runs().next()
        self.times = self.run.times()
        self.eventTotal = len(self.times)
        self.env = self.ds.env()
        self.evt = self.run.event(self.times[0])
        self.det = psana.Detector(str(self.detname), self.env)
        self.det.do_reshape_2d_to_3d(flag=True)

    def setupRadialBackground(self):
        self.geo = self.det.geometry(
            self.run
        )  # self.geo = GeometryAccess(self.parent.geom.calibPath+'/'+self.parent.geom.calibFile)
        self.xarr, self.yarr, self.zarr = self.geo.get_pixel_coords()
        self.ix = self.det.indexes_x(self.evt)
        self.iy = self.det.indexes_y(self.evt)
        if self.ix is None:
            self.iy = np.tile(np.arange(self.userMask.shape[1]),
                              [self.userMask.shape[2], 1])
            self.ix = np.transpose(self.iy)
        self.iX = np.array(self.ix, dtype=np.int64)
        self.iY = np.array(self.iy, dtype=np.int64)
        if len(self.iX.shape) == 2:
            self.iX = np.expand_dims(self.iX, axis=0)
            self.iY = np.expand_dims(self.iY, axis=0)
        self.mask = self.geo.get_pixel_mask(
            mbits=0377
        )  # mask for 2x1 edges, two central columns, and unbound pixels with their neighbours
        self.rb = RadialBkgd(self.xarr,
                             self.yarr,
                             mask=self.mask,
                             radedges=None,
                             nradbins=100,
                             phiedges=(0, 360),
                             nphibins=1)

    def updatePolarizationFactor(self):
        self.pf = polarization_factor(self.rb.pixel_rad(), self.rb.pixel_phi(),
                                      self.distance * 1e6)  # convert to um

    def findPeaks(self, calib, evt):

        if self.streakMask_on:  # make new streak mask
            self.streakMask = self.StreakMask.getStreakMaskCalib(evt)

        # Apply background correction
        if self.medianFilterOn:
            calib -= median_filter_ndarr(calib, self.medianRank)

        if self.radialFilterOn:
            self.pf.shape = calib.shape  # FIXME: shape is 1d
            calib = self.rb.subtract_bkgd(calib * self.pf)
            calib.shape = self.userPsanaMask.shape  # FIXME: shape is 1d

        if self.streakMask is not None:
            self.combinedMask = self.userPsanaMask * self.streakMask
        else:
            self.combinedMask = self.userPsanaMask
        # set new mask
        #self.alg = PyAlgos(windows=self.windows, mask=self.combinedMask, pbits=0)
        # set peak-selector parameters:
        #self.alg.set_peak_selection_pars(npix_min=self.npix_min, npix_max=self.npix_max, \
        #                                amax_thr=self.amax_thr, atot_thr=self.atot_thr, \
        #                                son_min=self.son_min)
        self.alg.set_mask(self.combinedMask)  # This doesn't work reliably
        # set algorithm specific parameters
        if self.algorithm == 1:
            # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region
            #                           around pixel with maximal intensity.
            self.peaks = self.alg.peak_finder_v4r2(
                calib,
                thr_low=self.hitParam_alg1_thr_low,
                thr_high=self.hitParam_alg1_thr_high,
                rank=self.hitParam_alg1_rank,
                r0=self.hitParam_alg1_radius,
                dr=self.hitParam_alg1_dr)
        elif self.algorithm == 3:
            self.peaks = self.alg.peak_finder_v3(calib,
                                                 rank=self.hitParam_alg3_rank,
                                                 r0=self.hitParam_alg3_r0,
                                                 dr=self.hitParam_alg3_dr)
        elif self.algorithm == 4:
            # v4 - aka iDroplet Finder - two-threshold peak-finding algorithm in restricted region
            #                            around pixel with maximal intensity.
            self.peaks = self.alg.peak_finder_v4(calib, thr_low=self.hitParam_alg4_thr_low, thr_high=self.hitParam_alg4_thr_high, \
                                   rank=self.hitParam_alg4_rank, r0=self.hitParam_alg4_r0, dr=self.hitParam_alg4_dr)
        self.numPeaksFound = self.peaks.shape[0]

        if self.numPeaksFound > 0:
            cenX = self.iX[np.array(self.peaks[:, 0], dtype=np.int64),
                           np.array(self.peaks[:, 1], dtype=np.int64),
                           np.array(self.peaks[:, 2], dtype=np.int64)] + 0.5
            cenY = self.iY[np.array(self.peaks[:, 0], dtype=np.int64),
                           np.array(self.peaks[:, 1], dtype=np.int64),
                           np.array(self.peaks[:, 2], dtype=np.int64)] + 0.5
            self.maxRes = getMaxRes(cenX, cenY, self.cx, self.cy)
        else:
            self.maxRes = 0

        if self.numPeaksFound >= 15:
            self.powderHits = np.maximum(self.powderHits, calib)
        else:
            self.powderMisses = np.maximum(self.powderMisses, calib)
示例#2
0
class PeakFinding(object):
    def __init__(self, parent = None):
        self.parent = parent

        self.d9 = Dock("Peak Finder", size=(1, 1))
        ## Dock 9: Peak finder
        self.w10 = ParameterTree()
        self.d9.addWidget(self.w10)
        #self.w11 = pg.LayoutWidget()
        #self.generatePowderBtn = QtGui.QPushButton('Generate Powder')
        #self.launchBtn = QtGui.QPushButton('Launch peak finder')
        #self.w11.addWidget(self.launchBtn, row=0,col=0)
        #self.w11.addWidget(self.generatePowderBtn, row=0, col=0)
        #self.d9.addWidget(self.w11)

        self.userUpdate = None
        self.doingUpdate = False

        # Peak finding
        self.hitParam_grp = 'Peak finder'
        self.hitParam_showPeaks_str = 'Show peaks found'
        self.hitParam_algorithm_str = 'Algorithm'
        # algorithm 0
        self.hitParam_algorithm0_str = 'None'
        # algorithm 1
        self.hitParam_alg1_npix_min_str = 'npix_min'
        self.hitParam_alg1_npix_max_str = 'npix_max'
        self.hitParam_alg1_amax_thr_str = 'amax_thr'
        self.hitParam_alg1_atot_thr_str = 'atot_thr'
        self.hitParam_alg1_son_min_str = 'son_min'
        self.hitParam_algorithm1_str = 'Droplet'
        self.hitParam_alg1_thr_low_str = 'thr_low'
        self.hitParam_alg1_thr_high_str = 'thr_high'
        self.hitParam_alg1_rank_str = 'rank'
        self.hitParam_alg1_radius_str = 'radius'
        self.hitParam_alg1_dr_str = 'dr'
        # algorithm 2
        self.hitParam_alg2_npix_min_str = 'npix_min'
        self.hitParam_alg2_npix_max_str = 'npix_max'
        self.hitParam_alg2_amax_thr_str = 'amax_thr'
        self.hitParam_alg2_atot_thr_str = 'atot_thr'
        self.hitParam_alg2_son_min_str = 'son_min'
        self.hitParam_algorithm2_str = 'FloodFill'
        self.hitParam_alg2_thr_str = 'thr'
        self.hitParam_alg2_r0_str = 'r0'
        self.hitParam_alg2_dr_str = 'dr'
        # algorithm 3
        self.hitParam_alg3_npix_min_str = 'npix_min'
        self.hitParam_alg3_npix_max_str = 'npix_max'
        self.hitParam_alg3_amax_thr_str = 'amax_thr'
        self.hitParam_alg3_atot_thr_str = 'atot_thr'
        self.hitParam_alg3_son_min_str = 'son_min'
        self.hitParam_algorithm3_str = 'Ranker'
        self.hitParam_alg3_rank_str = 'rank'
        self.hitParam_alg3_r0_str = 'r0'
        self.hitParam_alg3_dr_str = 'dr'
        # algorithm 4
        self.hitParam_alg4_npix_min_str = 'npix_min'
        self.hitParam_alg4_npix_max_str = 'npix_max'
        self.hitParam_alg4_amax_thr_str = 'amax_thr'
        self.hitParam_alg4_atot_thr_str = 'atot_thr'
        self.hitParam_alg4_son_min_str = 'son_min'
        self.hitParam_algorithm4_str = 'iDroplet'
        self.hitParam_alg4_thr_low_str = 'thr_low'
        self.hitParam_alg4_thr_high_str = 'thr_high'
        self.hitParam_alg4_rank_str = 'rank'
        self.hitParam_alg4_r0_str = 'radius'
        self.hitParam_alg4_dr_str = 'dr'

        self.hitParam_outDir_str = 'Output directory'
        self.hitParam_runs_str = 'Run(s)'
        self.hitParam_queue_str = 'queue'
        self.hitParam_cpu_str = 'CPUs'
        self.hitParam_psanaq_str = 'psanaq'
        self.hitParam_psnehq_str = 'psnehq'
        self.hitParam_psfehq_str = 'psfehq'
        self.hitParam_psnehprioq_str = 'psnehprioq'
        self.hitParam_psfehprioq_str = 'psfehprioq'
        self.hitParam_psnehhiprioq_str = 'psnehhiprioq'
        self.hitParam_psfehhiprioq_str = 'psfehhiprioq'
        self.hitParam_psdebugq_str = 'psdebugq'
        self.hitParam_noe_str = 'Number of events to process'
        self.hitParam_threshold_str = 'Indexable number of peaks'
        self.hitParam_launch_str = 'Launch peak finder'
        self.hitParam_extra_str = 'Extra parameters'

        self.save_minPeaks_str = 'Minimum number of peaks'
        self.save_maxPeaks_str = 'Maximum number of peaks'
        self.save_minRes_str = 'Minimum resolution (pixels)'
        self.save_sample_str = 'Sample name'

        self.showPeaks = True
        self.peaks = None
        self.numPeaksFound = 0
        self.algorithm = 0
        self.algInitDone = False
        self.peaksMaxRes = 0
        self.classify = False

        self.hitParam_alg1_npix_min = 2.
        self.hitParam_alg1_npix_max = 20.
        self.hitParam_alg1_amax_thr = 0.
        self.hitParam_alg1_atot_thr = 1000.
        self.hitParam_alg1_son_min = 7.
        self.hitParam_alg1_thr_low = 250.
        self.hitParam_alg1_thr_high = 600.
        self.hitParam_alg1_rank = 2
        self.hitParam_alg1_radius = 2
        self.hitParam_alg1_dr = 1
        # self.hitParam_alg2_npix_min = 1.
        # self.hitParam_alg2_npix_max = 5000.
        # self.hitParam_alg2_amax_thr = 1.
        # self.hitParam_alg2_atot_thr = 1.
        # self.hitParam_alg2_son_min = 1.
        # self.hitParam_alg2_thr = 10.
        # self.hitParam_alg2_r0 = 1.
        # self.hitParam_alg2_dr = 0.05
        # self.hitParam_alg3_npix_min = 5.
        # self.hitParam_alg3_npix_max = 5000.
        # self.hitParam_alg3_amax_thr = 0.
        # self.hitParam_alg3_atot_thr = 0.
        # self.hitParam_alg3_son_min = 4.
        # self.hitParam_alg3_rank = 3
        # self.hitParam_alg3_r0 = 5.
        # self.hitParam_alg3_dr = 0.05
        # self.hitParam_alg4_npix_min = 1.
        # self.hitParam_alg4_npix_max = 45.
        # self.hitParam_alg4_amax_thr = 800.
        # self.hitParam_alg4_atot_thr = 0
        # self.hitParam_alg4_son_min = 7.
        # self.hitParam_alg4_thr_low = 200.
        # self.hitParam_alg4_thr_high = self.hitParam_alg1_thr_high
        # self.hitParam_alg4_rank = 3
        # self.hitParam_alg4_r0 = 2
        # self.hitParam_alg4_dr = 1
        self.hitParam_outDir = self.parent.psocakeDir
        self.hitParam_outDir_overridden = False
        self.hitParam_runs = ''
        self.hitParam_queue = self.hitParam_psanaq_str
        self.hitParam_cpus = 24
        self.hitParam_noe = -1
        self.hitParam_threshold = 15 # usually crystals with less than 15 peaks are not indexable

        self.minPeaks = 15
        self.maxPeaks = 2048
        self.minRes = -1
        self.sample = 'sample'
        self.profile = 0
        self.hitParam_extra = ''

        self.params = [
            {'name': self.hitParam_grp, 'type': 'group', 'children': [
                {'name': self.hitParam_showPeaks_str, 'type': 'bool', 'value': self.showPeaks,
                 'tip': "Show peaks found shot-to-shot"},
                {'name': self.hitParam_algorithm_str, 'type': 'list', 'values': {self.hitParam_algorithm1_str: 1,
                                                                                 self.hitParam_algorithm0_str: 0},
                 'value': self.algorithm},
                {'name': self.hitParam_algorithm1_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "",
                 'readonly': True, 'children': [
                    {'name': self.hitParam_alg1_npix_min_str, 'type': 'float', 'value': self.hitParam_alg1_npix_min,
                     'tip': "Only keep the peak if number of pixels above thr_low is above this value"},
                    {'name': self.hitParam_alg1_npix_max_str, 'type': 'float', 'value': self.hitParam_alg1_npix_max,
                     'tip': "Only keep the peak if number of pixels above thr_low is below this value"},
                    {'name': self.hitParam_alg1_amax_thr_str, 'type': 'float', 'value': self.hitParam_alg1_amax_thr,
                     'tip': "Only keep the peak if max value is above this value"},
                    {'name': self.hitParam_alg1_atot_thr_str, 'type': 'float', 'value': self.hitParam_alg1_atot_thr,
                     'tip': "Only keep the peak if integral inside region of interest is above this value"},
                    {'name': self.hitParam_alg1_son_min_str, 'type': 'float', 'value': self.hitParam_alg1_son_min,
                     'tip': "Only keep the peak if signal-over-noise is above this value"},
                    {'name': self.hitParam_alg1_thr_low_str, 'type': 'float', 'value': self.hitParam_alg1_thr_low,
                     'tip': "Grow a seed peak if above this value"},
                    {'name': self.hitParam_alg1_thr_high_str, 'type': 'float', 'value': self.hitParam_alg1_thr_high,
                     'tip': "Start a seed peak if above this value"},
                    {'name': self.hitParam_alg1_rank_str, 'type': 'int', 'value': self.hitParam_alg1_rank,
                     'tip': "region of integration is a square, (2r+1)x(2r+1)"},
                    {'name': self.hitParam_alg1_radius_str, 'type': 'int', 'value': self.hitParam_alg1_radius,
                     'tip': "region inside the region of interest"},
                    {'name': self.hitParam_alg1_dr_str, 'type': 'float', 'value': self.hitParam_alg1_dr,
                     'tip': "background region outside the region of interest"},
                ]},
                {'name': self.save_minPeaks_str, 'type': 'int', 'value': self.minPeaks,
                 'tip': "Index only if there are more Bragg peaks found"},
                {'name': self.save_maxPeaks_str, 'type': 'int', 'value': self.maxPeaks,
                 'tip': "Index only if there are less Bragg peaks found"},
                {'name': self.save_minRes_str, 'type': 'int', 'value': self.minRes,
                 'tip': "Index only if Bragg peak resolution is at least this"},
                {'name': self.save_sample_str, 'type': 'str', 'value': self.sample,
                 'tip': "Sample name saved inside cxi"},
                {'name': self.hitParam_outDir_str, 'type': 'str', 'value': self.hitParam_outDir},
                {'name': self.hitParam_runs_str, 'type': 'str', 'value': self.hitParam_runs},
                {'name': self.hitParam_queue_str, 'type': 'list', 'values': {self.hitParam_psfehhiprioq_str: 'psfehhiprioq',
                                                                             self.hitParam_psnehhiprioq_str: 'psnehhiprioq',
                                                                             self.hitParam_psfehprioq_str: 'psfehprioq',
                                                                             self.hitParam_psnehprioq_str: 'psnehprioq',
                                                                             self.hitParam_psfehq_str: 'psfehq',
                                                                             self.hitParam_psnehq_str: 'psnehq',
                                                                             self.hitParam_psanaq_str: 'psanaq',
                                                                             self.hitParam_psdebugq_str: 'psdebugq'},
                 'value': self.hitParam_queue, 'tip': "Choose queue"},
                {'name': self.hitParam_cpu_str, 'type': 'int', 'value': self.hitParam_cpus},
                {'name': self.hitParam_noe_str, 'type': 'int', 'value': self.hitParam_noe,
                 'tip': "number of events to process, default=-1 means process all events"},
                {'name': self.hitParam_extra_str, 'type': 'str', 'value': self.hitParam_extra, 'tip': "Extra peak finding flags"},
                {'name': self.hitParam_launch_str, 'type': 'action'},
            ]},
        ]

        self.p3 = Parameter.create(name='paramsPeakFinder', type='group', \
                                   children=self.params, expanded=True)
        self.w10.setParameters(self.p3, showTop=False)
        self.p3.sigTreeStateChanged.connect(self.change)
        #self.parent.connect(self.launchBtn, QtCore.SIGNAL("clicked()"), self.findPeaks)

    def digestRunList(self, runList):
        runsToDo = []
        if not runList:
            print "Run(s) is empty. Please type in the run number(s)."
            return runsToDo
        runLists = str(runList).split(",")
        for list in runLists:
            temp = list.split(":")
            if len(temp) == 2:
                for i in np.arange(int(temp[0]),int(temp[1])+1):
                    runsToDo.append(i)
            elif len(temp) == 1:
                runsToDo.append(int(temp[0]))
        return runsToDo

    def updateParam(self):
        if self.userUpdate is None:
            if self.parent.psocakeRunDir is not None:
                peakParamFname = self.parent.psocakeRunDir + '/peakParam.json'
                if os.path.exists(peakParamFname):
                    with open(peakParamFname) as infile:
                        d = json.load(infile)
                        if d[self.hitParam_algorithm_str] == 1:
                            # Update variables
                            try:
                                self.hitParam_alg1_npix_min = d[self.hitParam_alg1_npix_min_str]
                                self.hitParam_alg1_npix_max = d[self.hitParam_alg1_npix_max_str]
                                self.hitParam_alg1_amax_thr = d[self.hitParam_alg1_amax_thr_str]
                                self.hitParam_alg1_atot_thr = d[self.hitParam_alg1_atot_thr_str]
                                self.hitParam_alg1_son_min = d[self.hitParam_alg1_son_min_str]
                                self.hitParam_alg1_thr_low = d[self.hitParam_alg1_thr_low_str]
                                self.hitParam_alg1_thr_high = d[self.hitParam_alg1_thr_high_str]
                                self.hitParam_alg1_rank = int(d[self.hitParam_alg1_rank_str])
                                self.hitParam_alg1_radius = int(d[self.hitParam_alg1_radius_str])
                                self.hitParam_alg1_dr = d[self.hitParam_alg1_dr_str]
                                # Update GUI
                                self.doingUpdate = True
                                #self.p3.param(self.hitParam_grp, self.hitParam_algorithm_str).setValue(self.algorithm)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_npix_min_str).setValue(
                                    self.hitParam_alg1_npix_min)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_npix_max_str).setValue(
                                    self.hitParam_alg1_npix_max)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_amax_thr_str).setValue(
                                    self.hitParam_alg1_amax_thr)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_atot_thr_str).setValue(
                                    self.hitParam_alg1_atot_thr)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_son_min_str).setValue(
                                    self.hitParam_alg1_son_min)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_thr_low_str).setValue(
                                    self.hitParam_alg1_thr_low)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_thr_high_str).setValue(
                                    self.hitParam_alg1_thr_high)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_rank_str).setValue(
                                    self.hitParam_alg1_rank)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_radius_str).setValue(
                                    self.hitParam_alg1_radius)
                                self.doingUpdate = False
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_dr_str).setValue(
                                    self.hitParam_alg1_dr)
                            except:
                                pass

    def writeStatus(self, fname, d):
        json.dump(d, open(fname, 'w'))

    # Launch peak finding
    def findPeaks(self):
        self.parent.thread.append(LaunchPeakFinder.LaunchPeakFinder(self.parent)) # send parent parameters with self
        self.parent.thread[self.parent.threadCounter].launch(self.parent.experimentName, self.parent.detInfo)
        self.parent.threadCounter+=1
        # Save peak finding parameters
        runsToDo = self.digestRunList(self.hitParam_runs)
        for run in runsToDo:
            peakParamFname = self.parent.psocakeDir+'/r'+str(run).zfill(4)+'/peakParam.json'
            d = {self.hitParam_algorithm_str: self.algorithm,
                 self.hitParam_alg1_npix_min_str: self.hitParam_alg1_npix_min,
                 self.hitParam_alg1_npix_max_str: self.hitParam_alg1_npix_max,
                 self.hitParam_alg1_amax_thr_str: self.hitParam_alg1_amax_thr,
                 self.hitParam_alg1_atot_thr_str: self.hitParam_alg1_atot_thr,
                 self.hitParam_alg1_son_min_str: self.hitParam_alg1_son_min,
                 self.hitParam_alg1_thr_low_str: self.hitParam_alg1_thr_low,
                 self.hitParam_alg1_thr_high_str: self.hitParam_alg1_thr_high,
                 self.hitParam_alg1_rank_str: self.hitParam_alg1_rank,
                 self.hitParam_alg1_radius_str: self.hitParam_alg1_radius,
                 self.hitParam_alg1_dr_str: self.hitParam_alg1_dr}
            self.writeStatus(peakParamFname, d)

    # If anything changes in the parameter tree, print a message
    def change(self, panel, changes):
        for param, change, data in changes:
            path = panel.childPath(param)
            if self.parent.args.v >= 1:
                print('  path: %s' % path)
                print('  change:    %s' % change)
                print('  data:      %s' % str(data))
                print('  ----------')
            self.paramUpdate(path, change, data)

    ##############################
    # Mandatory parameter update #
    ##############################
    def paramUpdate(self, path, change, data):
        if path[0] == self.hitParam_grp:
            if path[1] == self.hitParam_algorithm_str:
                self.algInitDone = False
                self.updateAlgorithm(data)
            elif path[1] == self.hitParam_showPeaks_str:
                self.showPeaks = data
                self.drawPeaks()
            elif path[1] == self.hitParam_outDir_str:
                self.hitParam_outDir = data
                self.hitParam_outDir_overridden = True
            elif path[1] == self.hitParam_runs_str:
                self.hitParam_runs = data
            elif path[1] == self.hitParam_queue_str:
                self.hitParam_queue = data
            elif path[1] == self.hitParam_cpu_str:
                self.hitParam_cpus = data
            elif path[1] == self.hitParam_noe_str:
                self.hitParam_noe = data
            elif path[1] == self.hitParam_threshold_str:
                self.hitParam_threshold = data
            elif path[1] == self.hitParam_launch_str:
                self.findPeaks()
            elif path[1] == self.save_minPeaks_str:
                self.minPeaks = data
            elif path[1] == self.save_maxPeaks_str:
                self.maxPeaks = data
            elif path[1] == self.save_minRes_str:
                self.minRes = data
            elif path[1] == self.save_sample_str:
                self.sample = data
            elif path[1] == self.hitParam_extra_str:
                self.hitParam_extra = data
            elif path[2] == self.hitParam_alg1_npix_min_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_npix_min = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_npix_max_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_npix_max = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_amax_thr_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_amax_thr = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_atot_thr_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_atot_thr = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_son_min_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_son_min = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_thr_low_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_thr_low = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_thr_high_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_thr_high = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_rank_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_rank = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_radius_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_radius = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_dr_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_dr = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()

    def updateAlgorithm(self, data):
        self.algorithm = data
        self.algInitDone = False
        self.updateClassification()
        if self.parent.args.v >= 1: print "##### Done updateAlgorithm: ", self.algorithm

    def saveCheetahFormat(self, arg):
        if arg == 'lcls':
            if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName:
                dim0 = 8 * 185
                dim1 = 4 * 388
            elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName:
                dim0 = 1920 #FIXME: rayonix can be binned
                dim1 = 1920
            elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName:
                dim0 = 1920 #FIXME: rayonix can be binned
                dim1 = 1920
            else:
                dim0 = 0
                dim1 = 0

            if dim0 > 0:
                maxNumPeaks = 2048
                if self.parent.index.hiddenCXI is not None:
                    myHdf5 = h5py.File(self.parent.index.hiddenCXI, 'w')
                    grpName = "/entry_1/result_1"
                    dset_nPeaks = "/nPeaks"
                    dset_posX = "/peakXPosRaw"
                    dset_posY = "/peakYPosRaw"
                    dset_atot = "/peakTotalIntensity"
                    if grpName in myHdf5:
                        del myHdf5[grpName]
                    grp = myHdf5.create_group(grpName)
                    myHdf5.create_dataset(grpName + dset_nPeaks, (1,), dtype='int')
                    myHdf5.create_dataset(grpName + dset_posX, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks))
                    myHdf5.create_dataset(grpName + dset_posY, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks))
                    myHdf5.create_dataset(grpName + dset_atot, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks))

                    myHdf5.create_dataset("/LCLS/detector_1/EncoderValue", (1,), dtype=float)
                    myHdf5.create_dataset("/LCLS/photon_energy_eV", (1,), dtype=float)
                    dset = myHdf5.create_dataset("/entry_1/data_1/data", (1, dim0, dim1), dtype=float)

                    # Convert calib image to cheetah image
                    img = np.zeros((dim0, dim1))
                    counter = 0
                    if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName:
                        for quad in range(4):
                            for seg in range(8):
                                img[seg * 185:(seg + 1) * 185, quad * 388:(quad + 1) * 388] = self.parent.calib[counter, :, :]
                                counter += 1
                    elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName:
                        img = self.parent.calib[:, :] # psana format
                    elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName:
                        img = self.parent.calib[:, :]  # psana format
                    else:
                        print "saveCheetahFormat not implemented"

                    peaks = self.peaks.copy()
                    nPeaks = peaks.shape[0]

                    if nPeaks > maxNumPeaks:
                        peaks = peaks[:maxNumPeaks]
                        nPeaks = maxNumPeaks
                    for i, peak in enumerate(peaks):
                        seg, row, col, npix, amax, atot, rcent, ccent, rsigma, csigma, rmin, rmax, cmin, cmax, bkgd, rms, son = peak[0:17]
                        if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName:
                            cheetahRow, cheetahCol = self.convert_peaks_to_cheetah(seg, row, col)
                            myHdf5[grpName + dset_posX][0, i] = cheetahCol
                            myHdf5[grpName + dset_posY][0, i] = cheetahRow
                            myHdf5[grpName + dset_atot][0, i] = atot
                        elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName:
                            myHdf5[grpName + dset_posX][0, i] = col
                            myHdf5[grpName + dset_posY][0, i] = row
                            myHdf5[grpName + dset_atot][0, i] = atot
                        elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName:
                            myHdf5[grpName + dset_posX][0, i] = col
                            myHdf5[grpName + dset_posY][0, i] = row
                            myHdf5[grpName + dset_atot][0, i] = atot
                    myHdf5[grpName + dset_nPeaks][0] = nPeaks

                    if self.parent.args.v >= 1: print "hiddenCXI clen (mm): ", self.parent.clen * 1000.
                    myHdf5["/LCLS/detector_1/EncoderValue"][0] = self.parent.clen * 1000.  # mm
                    myHdf5["/LCLS/photon_energy_eV"][0] = self.parent.photonEnergy
                    dset[0, :, :] = img
                    myHdf5.close()

    def updateClassification(self):
        if self.parent.calib is not None:
            if self.parent.mk.streakMaskOn:
                self.parent.mk.initMask()
                self.parent.mk.streakMask = self.parent.mk.StreakMask.getStreakMaskCalib(self.parent.evt)
                if self.parent.mk.streakMask is None:
                    self.parent.mk.streakMaskAssem = None
                else:
                    self.parent.mk.streakMaskAssem = self.parent.det.image(self.parent.evt, self.parent.mk.streakMask)
                self.algInitDone = False

            self.parent.mk.displayMask()

            # update combined mask
            self.parent.mk.combinedMask = np.ones_like(self.parent.calib)
            if self.parent.mk.streakMask is not None and self.parent.mk.streakMaskOn is True:
                self.parent.mk.combinedMask *= self.parent.mk.streakMask
            if self.parent.mk.userMask is not None and self.parent.mk.userMaskOn is True:
                self.parent.mk.combinedMask *= self.parent.mk.userMask
            if self.parent.mk.psanaMask is not None and self.parent.mk.psanaMaskOn is True:
                self.parent.mk.combinedMask *= self.parent.mk.psanaMask

            # Peak output (0-16):
            # 0 seg
            # 1 row
            # 2 col
            # 3 npix: no. of pixels in the ROI intensities above threshold
            # 4 amp_max: max intensity
            # 5 amp_tot: sum of intensities
            # 6,7: row_cgrav: center of mass
            # 8,9: row_sigma
            # 10,11,12,13: minimum bounding box
            # 14: background
            # 15: noise
            # 16: signal over noise
            if self.algorithm == 0: # No peak algorithm
                self.peaks = None
                self.drawPeaks()
            else:
                # Only initialize the hit finder algorithm once
                if self.algInitDone is False:
                    self.windows = None
                    self.alg = []
                    self.alg = PyAlgos(windows=self.windows, mask=self.parent.mk.combinedMask, pbits=0)

                    # set peak-selector parameters:
                    if self.algorithm == 1:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg1_npix_min, npix_max=self.hitParam_alg1_npix_max, \
                                                amax_thr=self.hitParam_alg1_amax_thr, atot_thr=self.hitParam_alg1_atot_thr, \
                                                son_min=self.hitParam_alg1_son_min)
                    elif self.algorithm == 2:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg2_npix_min, npix_max=self.hitParam_alg2_npix_max, \
                                                amax_thr=self.hitParam_alg2_amax_thr, atot_thr=self.hitParam_alg2_atot_thr, \
                                                son_min=self.hitParam_alg2_son_min)
                    elif self.algorithm == 3:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg3_npix_min, npix_max=self.hitParam_alg3_npix_max, \
                                                amax_thr=self.hitParam_alg3_amax_thr, atot_thr=self.hitParam_alg3_atot_thr, \
                                                son_min=self.hitParam_alg3_son_min)
                    elif self.algorithm == 4:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg4_npix_min, npix_max=self.hitParam_alg4_npix_max, \
                                                amax_thr=self.hitParam_alg4_amax_thr, atot_thr=self.hitParam_alg4_atot_thr, \
                                                son_min=self.hitParam_alg4_son_min)
                    self.algInitDone = True

                self.parent.calib = self.parent.calib * 1.0 # Neccessary when int is returned
                if self.algorithm == 1:
                    # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region
                    #                           around pixel with maximal intensity.
                    self.peakRadius = int(self.hitParam_alg1_radius)
                    self.peaks = self.alg.peak_finder_v4r2(self.parent.calib,
                                                           thr_low=self.hitParam_alg1_thr_low,
                                                           thr_high=self.hitParam_alg1_thr_high,
                                                           rank=int(self.hitParam_alg1_rank),
                                                           r0=self.peakRadius,
                                                           dr=self.hitParam_alg1_dr)
                elif self.algorithm == 2:
                    # v2 - define peaks for regions of connected pixels above threshold
                    self.peakRadius = int(self.hitParam_alg2_r0)
                    self.peaks = self.alg.peak_finder_v2(self.parent.calib, thr=self.hitParam_alg2_thr, r0=self.peakRadius, dr=self.hitParam_alg2_dr)
                elif self.algorithm == 3:
                    self.peakRadius = int(self.hitParam_alg3_r0)
                    self.peaks = self.alg.peak_finder_v3(self.parent.calib, rank=self.hitParam_alg3_rank, r0=self.peakRadius, dr=self.hitParam_alg3_dr)
                elif self.algorithm == 4:
                    # v4 - aka Droplet Finder - the same as v1, but uses rank and r0 parameters in stead of common radius.
                    self.peakRadius = int(self.hitParam_alg4_r0)
                    self.peaks = self.alg.peak_finder_v4(self.parent.calib, thr_low=self.hitParam_alg4_thr_low, thr_high=self.hitParam_alg4_thr_high,
                                               rank=self.hitParam_alg4_rank, r0=self.peakRadius,  dr=self.hitParam_alg4_dr)
                self.numPeaksFound = self.peaks.shape[0]

                if self.parent.args.v >= 1: print "Num peaks found: ", self.numPeaksFound, self.peaks.shape

                # update clen
                self.parent.geom.updateClen('lcls')

                self.parent.index.clearIndexedPeaks()

                # Save image and peaks in cheetah cxi file
                self.saveCheetahFormat('lcls')

                if self.parent.index.showIndexedPeaks: self.parent.index.updateIndex()

                self.drawPeaks()
            if self.parent.args.v >= 1: print "Done updateClassification"

    def convert_peaks_to_cheetah(self, s, r, c) :
        """Converts seg, row, col assuming (32,185,388)
           to cheetah 2-d table row and col (8*185, 4*388)
        """
        segs, rows, cols = (32,185,388)
        row2d = (int(s)%8) * rows + int(r) # where s%8 is a segment in quad number [0,7]
        col2d = (int(s)/8) * cols + int(c) # where s/8 is a quad number [0,3]
        return row2d, col2d

    def getMaxRes(self, posX, posY, centerX, centerY):
        maxRes = np.max(np.sqrt((posX-centerX)**2 + (posY-centerY)**2))
        if self.parent.args.v >= 1: print "maxRes: ", maxRes
        return maxRes # in pixels

    def drawPeaks(self):
        self.parent.img.clearPeakMessage()
        if self.showPeaks:
            if self.peaks is not None and self.numPeaksFound > 0:
                self.ix = self.parent.det.indexes_x(self.parent.evt)
                self.iy = self.parent.det.indexes_y(self.parent.evt)
                if self.ix is None:
                    (_, dim0, dim1) = self.parent.calib.shape
                    self.iy = np.tile(np.arange(dim0),[dim1, 1])
                    self.ix = np.transpose(self.iy)
                self.iX = np.array(self.ix, dtype=np.int64)
                self.iY = np.array(self.iy, dtype=np.int64)
                if len(self.iX.shape)==2:
                    self.iX = np.expand_dims(self.iX,axis=0)
                    self.iY = np.expand_dims(self.iY,axis=0)
                cenX = self.iX[np.array(self.peaks[:,0],dtype=np.int64),np.array(self.peaks[:,1],dtype=np.int64),np.array(self.peaks[:,2],dtype=np.int64)] + 0.5
                cenY = self.iY[np.array(self.peaks[:,0],dtype=np.int64),np.array(self.peaks[:,1],dtype=np.int64),np.array(self.peaks[:,2],dtype=np.int64)] + 0.5
                self.peaksMaxRes = self.getMaxRes(cenX, cenY, self.parent.cx, self.parent.cy)
                diameter = self.peakRadius*2+1
                self.parent.img.peak_feature.setData(cenX, cenY, symbol='s', \
                                          size=diameter, brush=(255,255,255,0), \
                                          pen=pg.mkPen({'color': "c", 'width': 4}), pxMode=False) #FF0
                # Write number of peaks found
                xMargin = 5 # pixels
                yMargin = 0  # pixels
                maxX = np.max(self.ix) + xMargin
                maxY = np.max(self.iy) - yMargin
                myMessage = '<div style="text-align: center"><span style="color: cyan; font-size: 12pt;">Peaks=' + \
                            str(self.numPeaksFound) + ' <br>Res=' + str(int(self.peaksMaxRes)) + '<br></span></div>'
                self.parent.img.peak_text = pg.TextItem(html=myMessage, anchor=(0, 0))
                self.parent.img.w1.getView().addItem(self.parent.img.peak_text)
                self.parent.img.peak_text.setPos(maxX, maxY)
            else:
                self.parent.img.peak_feature.setData([], [], pxMode=False)
                self.parent.img.peak_text = pg.TextItem(html='', anchor=(0, 0))
                self.parent.img.w1.getView().addItem(self.parent.img.peak_text)
                self.parent.img.peak_text.setPos(0,0)
        else:
            self.parent.img.peak_feature.setData([], [], pxMode=False)
        if self.parent.args.v >= 1: print "Done updatePeaks"
示例#3
0
class MCPGate():
    def __init__(self, parent, gateName, tofs, tofl,tofs_dict,tofl_dict):
        self.parent = parent
        self.gateName = gateName
        self.tofs = tofs
        self.tofl = tofl
        self.tofs_dict = tofs_dict
        self.tofl_dict = tofl_dict
        self.tofbin = self.parent.monitor_params['t']['bin']
        
        print self.tofs_dict,self.tofl_dict        
        self.tof_ind = (self.parent.TaxisM>self.tofs) & (self.parent.TaxisM<self.tofl)
        

        self.particle = self.gateName
        
        self.extractE = extractE
        
        self.alg = PyAlgos()        
        self.alg.set_peak_selection_pars(npix_min=self.parent.npix_min, npix_max=self.parent.npix_max, amax_thr=self.parent.amax_thr, atot_thr=self.parent.atot_thr, son_min=self.parent.son_min)           
        
        self.init_vars()
    
    def init_vars(self):
    
    

        self.P = {}     
        for pt in ['2n1','n1','n2','n3','n4']:
            self.P[pt] = 0
        
        self.temp_irun = -1
        
        self.tempXef1 = []
        self.tempYef1 = []
        self.tempXef2 = []
        self.tempYef2 = []        

        self.tempErf1 = []

        self.tempErf2 = []        

        self.hists_tof = {}
        
        self.hists_tof_all = {}         
        
        
        for hist_name in self.parent.hist_names_mcp:

            if hist_name == 'frag_stat':
                     
                x_name = self.parent.monitor_params[hist_name]['x']
                x_binnum = self.parent.monitor_params[x_name]['num']   
                     
                y_name = self.parent.monitor_params[hist_name]['y']
                y_binnum = self.parent.monitor_params[y_name]['num']  
                
                z_name = self.parent.monitor_params[hist_name]['z']
                z_binnum = self.parent.monitor_params[z_name]['num']   
                
                m_name = self.parent.monitor_params[hist_name]['m']
                m_binnum = self.parent.monitor_params[m_name]['num']
                
                n_name = self.parent.monitor_params[hist_name]['n']
                n_binnum = self.parent.monitor_params[n_name]['num']                
                                             
                self.hists_tof[hist_name] = np.zeros([x_binnum, y_binnum, z_binnum, m_binnum, n_binnum])                      
                if self.parent.role == 'master':
                    self.hists_tof_all[hist_name] = np.zeros([x_binnum, y_binnum, z_binnum, m_binnum, n_binnum])  
                else:
                    self.hists_tof_all[hist_name] = None   
                continue
                               
            x_name = self.parent.monitor_params[hist_name]['x']
            x_binnum = self.parent.vars_binnum[x_name]
            if 'y' in self.parent.monitor_params[hist_name].keys():
                y_name = self.parent.monitor_params[hist_name]['y']
                y_binnum = self.parent.vars_binnum[y_name]
                if 'z' in self.parent.monitor_params[hist_name].keys():
                    z_name = self.parent.monitor_params[hist_name]['z']
                    z_binnum = self.parent.vars_binnum[z_name] 
                    self.hists_tof[hist_name] = np.zeros([x_binnum-1, y_binnum-1, z_binnum-1])
                    if self.parent.role == 'master':
                        self.hists_tof_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1, z_binnum-1])
                    else:
                        self.hists_tof_all[hist_name] = None
                    
                else:
                    self.hists_tof[hist_name] = np.zeros([x_binnum-1, y_binnum-1])     
                    if self.parent.role == 'master':
                        self.hists_tof_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1])
                    else:
                        self.hists_tof_all[hist_name] = None                        
            else:
                self.hists_tof[hist_name] = np.zeros([x_binnum-1])
                if self.parent.role == 'master':
                    self.hists_tof_all[hist_name] = np.zeros([x_binnum-1])
                else:
                    self.hists_tof_all[hist_name] = None     
                    

            
                                    

                                       
                                       
       
    def update_electron(self, eAind, eRind, eXind, eYind):
            
        pass
                   
         
        
    def update_ion(self,Tofele):
        
        for pt in ['2n1','n1','n2','n3','n4']:
            if (Tofele > self.tofs_dict[pt] and Tofele < self.tofl_dict[pt]):                     
                self.P[pt] += 1    
                break
  

            
        
            
              
        
    def is_coin(self):
      #  a = 0
      #  for pt in ['2n1','n1','n2','n3','n4']:
      #      a += self.P[pt]
     
        return True 
                        
        
                
    def update_shotinfo(self, pho_ind, pls_ind):  
 #       if self.parent.mpi_rank == 0:  
  #          print 'MCP***********************update',self.P     
                    
        self.hists_tof['frag_stat'][min(self.P['2n1'],9),min(self.P['n1'],9),min(self.P['n2'],9),min(self.P['n3'],9),min(self.P['n4'],9)] += 1                   

            
                  
        
        
           
        
    def reset_coin_var(self):
#        if self.parent.mpi_rank == 0: 
#            print 'MCP**********************reset',self.P
        for pt in ['2n1','n1','n2','n3','n4']:
            self.P[pt] = 0

  
                
    def save_var(self, h5f):
        grp = h5f.create_group('MCPGate_'+self.gateName)   
        
        grp.create_dataset('gateInfo_tofs_tofl_tofbin', data=np.array([self.tofs,self.tofl,self.tofbin]))  
        
        for histname in self.parent.hist_names_mcp:   
            try:
                grp.create_dataset(histname,data = self.hists_tof_all[histname])    
            except Exception as e:
                print(histname+' failed to be saved.')
                print(e)  


    def reduce(self):
        for histname in self.parent.hist_names_mcp:  
            try:
                self.time_a = time.time()         
                MPI.COMM_WORLD.Reduce(self.hists_tof[histname],self.hists_tof_all[histname])   
                self.time_b = time.time()             
                print(histname+' reduced by '+'Rank {0} in {1:.2f} seconds'.format(self.parent.mpi_rank,self.time_b - self.time_a)) 
            except Exception as e:
                print(histname+' failed to be redueced by '+str(self.parent.mpi_rank))  
                print(e)
示例#4
0
class TofGate():
    def __init__(self, parent, gateName, tofs, tofl):
        self.parent = parent
        self.gateName = gateName
        self.tofs = tofs
        self.tofl = tofl
        self.tofbin = self.parent.monitor_params['t']['bin']
        
        
        self.tof_ind = (self.parent.TaxisM>self.tofs) & (self.parent.TaxisM<self.tofl)
        

        self.particle = self.gateName
        
        self.extractE = extractE
        
        self.alg = PyAlgos()        
        self.alg.set_peak_selection_pars(npix_min=self.parent.npix_min, npix_max=self.parent.npix_max, amax_thr=self.parent.amax_thr, atot_thr=self.parent.atot_thr, son_min=self.parent.son_min)           
        
        self.init_vars()
    
    def init_vars(self):
    
    
        self.num_events = 0
             
        self.P = 0
        
        self.temp_irun = -1
        
        self.tempXef1 = []
        self.tempYef1 = []
        self.tempXef2 = []
        self.tempYef2 = []        

        self.tempErf1 = []

        self.tempErf2 = []        

        self.hists_tof = {}
        
        self.hists_tof_all = {}         
        
        
        for hist_name in self.parent.hist_names_tof:


                               
            x_name = self.parent.monitor_params[hist_name]['x']
            x_binnum = self.parent.vars_binnum[x_name]
            if 'y' in self.parent.monitor_params[hist_name].keys():
                y_name = self.parent.monitor_params[hist_name]['y']
                y_binnum = self.parent.vars_binnum[y_name]
                if 'z' in self.parent.monitor_params[hist_name].keys():
                    z_name = self.parent.monitor_params[hist_name]['z']
                    z_binnum = self.parent.vars_binnum[z_name] 
                    self.hists_tof[hist_name] = np.zeros([x_binnum-1, y_binnum-1, z_binnum-1])
                    if self.parent.role == 'master':
                        self.hists_tof_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1, z_binnum-1])
                    else:
                        self.hists_tof_all[hist_name] = None
                    
                else:
                    self.hists_tof[hist_name] = np.zeros([x_binnum-1, y_binnum-1])     
                    if self.parent.role == 'master':
                        self.hists_tof_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1])
                    else:
                        self.hists_tof_all[hist_name] = None                        
            else:
                self.hists_tof[hist_name] = np.zeros([x_binnum-1])
                if self.parent.role == 'master':
                    self.hists_tof_all[hist_name] = np.zeros([x_binnum-1])
                else:
                    self.hists_tof_all[hist_name] = None          

                                       
                                       
       
    def update_electron(self, eAind, eRind, eXind, eYind):
            
     #   self.eA[eAind,0] += 1            
     #   self.eR[eRind,0] += 1
        self.hists_tof['ex_ey_tg'][eXind, eYind] += 1
     #   self.eAR[eAind, eRind] += 1  
                   
         
        
    def update_ion(self, Tofind, Xind, Yind, Tofele, Xele, Yele):
        
        
        if (self.parent.TaxisM[Tofind] > self.tofs and self.parent.TaxisM[Tofind] < self.tofl):                     

            self.P += 1    
            self.hists_tof['x_y_tg'][Xind, Yind] += 1
      #      self.XT[Tofind, Xind] += 1
      #      self.YT[Tofind, Yind] += 1    

            
        
            
              
        
    def is_coin(self):
     
        return self.P > 0  
                        
        
                
    def update_shotinfo(self, pho_ind, pls_ind):
   
        self.hists_tof['pho_pls_eng_tg'][pho_ind, pls_ind] += 1   
        self.num_events += 1      
        

        
        temp_num_particles_ind = next((tNP_ind for tNP_ind, tNP_ele in enumerate(self.parent.vars_axis['num_particles']) if tNP_ele > self.P),0)-1 
               
        if temp_num_particles_ind != -1:
            self.hists_tof['num_particles_tg'][temp_num_particles_ind] += 1
            
        self.tempXef1, self.tempYef1,self.tempErf1,self.pho_ind_f1,self.pls_ind_f1 = self.processDataE(self.parent.irun,self.parent.ievt-1)
        self.tempXef2, self.tempYef2,self.tempErf2,self.pho_ind_f2,self.pls_ind_f2 = self.processDataE(self.parent.irun,self.parent.ievt+1)
        
        if len(self.tempXef1) > 0:
            for itemp in range(len(self.tempXef1)):
                self.hists_tof['ex_ey_tg_fls1'][self.tempXef1[itemp],self.tempYef1[itemp]] += 1  
                self.hists_tof['pho_pls_eng_tg_fls1'][self.pho_ind_f1, self.pls_ind_f1] += 1                   
                    
        if len(self.tempXef2) > 0:
            for itemp in range(len(self.tempXef2)):
                self.hists_tof['ex_ey_tg_fls2'][self.tempXef2[itemp],self.tempYef2[itemp]] += 1  
                self.hists_tof['pho_pls_eng_tg_fls2'][self.pho_ind_f2, self.pls_ind_f2] += 1                   
        
        
           
        
    def reset_coin_var(self):
            

              
        self.P = 0

  
                
    def save_var(self, h5f):
        grp = h5f.create_group('TofGate_'+self.gateName)   
        
        grp.create_dataset('gateInfo_tofs_tofl_tofbin', data=np.array([self.tofs,self.tofl,self.tofbin]))  
        
        for histname in self.parent.hist_names_tof:   
            try:
                grp.create_dataset(histname,data = self.hists_tof_all[histname])    
            except Exception as e:
                print(histname+' failed to be saved.')
                print(e)  


    def reduce(self):
        for histname in self.parent.hist_names_tof:  
            try:
                self.time_a = time.time()         
                MPI.COMM_WORLD.Reduce(self.hists_tof[histname],self.hists_tof_all[histname])   
                self.time_b = time.time()             
                print(histname+' reduced by '+'Rank {0} in {1:.2f} seconds'.format(self.parent.mpi_rank,self.time_b - self.time_a)) 
            except Exception as e:
                print(histname+' failed to be redueced by '+str(self.parent.mpi_rank))  
                print(e)

    def processDataE(self,irun,ievt):
        
        if self.temp_irun != irun:
            self.psana_source = psana.DataSource(self.parent.source)
            for ii, rr in enumerate(self.psana_source.runs()):

                if ii==irun:
                    self.temp_irun = irun
                    self.temprun = rr
                    break

            self.temptimes = self.temprun.times()
            self.temp_len_run = len(self.temptimes)
            
        if ievt<0 or ievt>=self.temp_len_run:
            return [], [], [],None,None
                        
        event = {'evt': self.temprun.event(self.temptimes[ievt])}
        if event['evt'] is None:
            return [], [], [],None,None
                                                
        self.extractE(event,self)
        if self.eImage_f is None or self.pulse_eng_f is None or self.photon_eng_f is None:
            return [], [], [],None, None
            

        photon_eng_ind = next((pho_eng_ind for pho_eng_ind, pho_eng_ele in enumerate(self.parent.vars_axis['phoeng']) if pho_eng_ele > self.photon_eng_f),0)-1      
           
        pulse_eng_ind = next((pls_eng_ind for pls_eng_ind, pls_eng_ele in enumerate(self.parent.vars_axis['plseng']) if pls_eng_ele > self.pulse_eng_f),0)-1

        
        if photon_eng_ind ==-1 or pulse_eng_ind == -1:
            return [], [], [],None, None    
    
        eXinds = []
        eYinds = []
        eRinds = []
        e_peaks = self.alg.peak_finder_v4r2(self.eImage_f, thr_low=self.parent.thr_low, thr_high=self.parent.thr_high, rank=self.parent.rank, r0=self.parent.r0, dr=self.parent.dr)
        
        eXs = e_peaks[:,1].astype(int)
        eYs = e_peaks[:,2].astype(int)

        eRadius, eAngle =self.parent.cart2polar(eXs, eYs)
        
        for e_ind in range(len(eXs)):
            tempRind = next((eR_ind for eR_ind, eR_ele in enumerate(self.parent.vars_axis['er']) if eR_ele > eRadius[e_ind]),0)-1
         #   tempAind = next((eA_ind for eA_ind, eA_ele in enumerate(self.eAaxis) if eA_ele > eAngle[e_ind]),0)
            tempXind = next((eX_ind for eX_ind, eX_ele in enumerate(self.parent.vars_axis['ex']) if eX_ele > eXs[e_ind]),0)-1
            tempYind = next((eY_ind for eY_ind, eY_ele in enumerate(self.parent.vars_axis['ey']) if eY_ele > eYs[e_ind]),0)-1
           # if tempRind != 0 and tempAind != 0 and tempXind != 0 and tempYind != 0:       
            if tempXind != -1 and tempYind != -1:                  
                eXinds.append(tempXind)                 
                eYinds.append(tempYind)    
                eRinds.append(tempRind)
        if len(eXinds) > 0:
            return eXinds, eYinds, eRinds, photon_eng_ind, pulse_eng_ind
            
        else:
            return [], [],[],None,None      
示例#5
0
class PeakFinding(object):
    def __init__(self, parent = None):
        self.parent = parent

        self.d9 = Dock("Peak Finder", size=(1, 1))
        ## Dock 9: Peak finder
        self.w10 = ParameterTree()
        self.d9.addWidget(self.w10)
        #self.w11 = pg.LayoutWidget()
        #self.generatePowderBtn = QtGui.QPushButton('Generate Powder')
        #self.launchBtn = QtGui.QPushButton('Launch peak finder')
        #self.w11.addWidget(self.launchBtn, row=0,col=0)
        #self.w11.addWidget(self.generatePowderBtn, row=0, col=0)
        #self.d9.addWidget(self.w11)

        self.userUpdate = None
        self.doingUpdate = False

        # Peak finding
        self.hitParam_grp = 'Peak finder'
        self.hitParam_showPeaks_str = 'Show peaks found'
        self.hitParam_algorithm_str = 'Algorithm'
        # algorithm 0
        self.hitParam_algorithm0_str = 'None'
        # algorithm 1
        self.hitParam_alg1_npix_min_str = 'npix_min'
        self.hitParam_alg1_npix_max_str = 'npix_max'
        self.hitParam_alg1_amax_thr_str = 'amax_thr'
        self.hitParam_alg1_atot_thr_str = 'atot_thr'
        self.hitParam_alg1_son_min_str = 'son_min'
        self.hitParam_algorithm1_str = 'Droplet'
        self.hitParam_alg1_thr_low_str = 'thr_low'
        self.hitParam_alg1_thr_high_str = 'thr_high'
        self.hitParam_alg1_rank_str = 'rank'
        self.hitParam_alg1_radius_str = 'radius'
        self.hitParam_alg1_dr_str = 'dr'
        # algorithm 2
        self.hitParam_alg2_npix_min_str = 'npix_min'
        self.hitParam_alg2_npix_max_str = 'npix_max'
        self.hitParam_alg2_amax_thr_str = 'amax_thr'
        self.hitParam_alg2_atot_thr_str = 'atot_thr'
        self.hitParam_alg2_son_min_str = 'son_min'
        self.hitParam_algorithm2_str = 'FloodFill'
        self.hitParam_alg2_thr_str = 'thr'
        self.hitParam_alg2_r0_str = 'r0'
        self.hitParam_alg2_dr_str = 'dr'
        # algorithm 3
        self.hitParam_alg3_npix_min_str = 'npix_min'
        self.hitParam_alg3_npix_max_str = 'npix_max'
        self.hitParam_alg3_amax_thr_str = 'amax_thr'
        self.hitParam_alg3_atot_thr_str = 'atot_thr'
        self.hitParam_alg3_son_min_str = 'son_min'
        self.hitParam_algorithm3_str = 'Ranker'
        self.hitParam_alg3_rank_str = 'rank'
        self.hitParam_alg3_r0_str = 'r0'
        self.hitParam_alg3_dr_str = 'dr'
        # algorithm 4
        self.hitParam_alg4_npix_min_str = 'npix_min'
        self.hitParam_alg4_npix_max_str = 'npix_max'
        self.hitParam_alg4_amax_thr_str = 'amax_thr'
        self.hitParam_alg4_atot_thr_str = 'atot_thr'
        self.hitParam_alg4_son_min_str = 'son_min'
        self.hitParam_algorithm4_str = 'iDroplet'
        self.hitParam_alg4_thr_low_str = 'thr_low'
        self.hitParam_alg4_thr_high_str = 'thr_high'
        self.hitParam_alg4_rank_str = 'rank'
        self.hitParam_alg4_r0_str = 'radius'
        self.hitParam_alg4_dr_str = 'dr'

        self.hitParam_outDir_str = 'Output directory'
        self.hitParam_runs_str = 'Run(s)'
        self.hitParam_queue_str = 'queue'
        self.hitParam_cpu_str = 'CPUs'
        self.hitParam_psanaq_str = 'psanaq'
        self.hitParam_psnehq_str = 'psnehq'
        self.hitParam_psfehq_str = 'psfehq'
        self.hitParam_psnehprioq_str = 'psnehprioq'
        self.hitParam_psfehprioq_str = 'psfehprioq'
        self.hitParam_psnehhiprioq_str = 'psnehhiprioq'
        self.hitParam_psfehhiprioq_str = 'psfehhiprioq'
        self.hitParam_psdebugq_str = 'psdebugq'
        self.hitParam_noe_str = 'Number of events to process'
        self.hitParam_threshold_str = 'Indexable number of peaks'
        self.hitParam_launch_str = 'Launch peak finder'
        self.hitParam_extra_str = 'Extra parameters'

        self.save_minPeaks_str = 'Minimum number of peaks'
        self.save_maxPeaks_str = 'Maximum number of peaks'
        self.save_minRes_str = 'Minimum resolution (pixels)'
        self.save_sample_str = 'Sample name'

        self.showPeaks = True
        self.peaks = None
        self.numPeaksFound = 0
        self.algorithm = 0
        self.algInitDone = False
        self.peaksMaxRes = 0
        self.classify = False

        self.hitParam_alg1_npix_min = 2.
        self.hitParam_alg1_npix_max = 20.
        self.hitParam_alg1_amax_thr = 0.
        self.hitParam_alg1_atot_thr = 1000.
        self.hitParam_alg1_son_min = 7.
        self.hitParam_alg1_thr_low = 250.
        self.hitParam_alg1_thr_high = 600.
        self.hitParam_alg1_rank = 2
        self.hitParam_alg1_radius = 2
        self.hitParam_alg1_dr = 1
        # self.hitParam_alg2_npix_min = 1.
        # self.hitParam_alg2_npix_max = 5000.
        # self.hitParam_alg2_amax_thr = 1.
        # self.hitParam_alg2_atot_thr = 1.
        # self.hitParam_alg2_son_min = 1.
        # self.hitParam_alg2_thr = 10.
        # self.hitParam_alg2_r0 = 1.
        # self.hitParam_alg2_dr = 0.05
        # self.hitParam_alg3_npix_min = 5.
        # self.hitParam_alg3_npix_max = 5000.
        # self.hitParam_alg3_amax_thr = 0.
        # self.hitParam_alg3_atot_thr = 0.
        # self.hitParam_alg3_son_min = 4.
        # self.hitParam_alg3_rank = 3
        # self.hitParam_alg3_r0 = 5.
        # self.hitParam_alg3_dr = 0.05
        # self.hitParam_alg4_npix_min = 1.
        # self.hitParam_alg4_npix_max = 45.
        # self.hitParam_alg4_amax_thr = 800.
        # self.hitParam_alg4_atot_thr = 0
        # self.hitParam_alg4_son_min = 7.
        # self.hitParam_alg4_thr_low = 200.
        # self.hitParam_alg4_thr_high = self.hitParam_alg1_thr_high
        # self.hitParam_alg4_rank = 3
        # self.hitParam_alg4_r0 = 2
        # self.hitParam_alg4_dr = 1
        self.hitParam_outDir = self.parent.psocakeDir
        self.hitParam_outDir_overridden = False
        self.hitParam_runs = ''
        self.hitParam_queue = self.hitParam_psanaq_str
        self.hitParam_cpus = 24
        self.hitParam_noe = -1
        self.hitParam_threshold = 15 # usually crystals with less than 15 peaks are not indexable

        self.minPeaks = 15
        self.maxPeaks = 2048
        self.minRes = -1
        self.sample = 'sample'
        self.profile = 0
        self.hitParam_extra = ''

        self.params = [
            {'name': self.hitParam_grp, 'type': 'group', 'children': [
                {'name': self.hitParam_showPeaks_str, 'type': 'bool', 'value': self.showPeaks,
                 'tip': "Show peaks found shot-to-shot"},
                {'name': self.hitParam_algorithm_str, 'type': 'list', 'values': {self.hitParam_algorithm1_str: 1,
                                                                                 self.hitParam_algorithm0_str: 0},
                 'value': self.algorithm},
                {'name': self.hitParam_algorithm1_str, 'visible': True, 'expanded': False, 'type': 'str', 'value': "",
                 'readonly': True, 'children': [
                    {'name': self.hitParam_alg1_npix_min_str, 'type': 'float', 'value': self.hitParam_alg1_npix_min,
                     'tip': "Only keep the peak if number of pixels above thr_low is above this value"},
                    {'name': self.hitParam_alg1_npix_max_str, 'type': 'float', 'value': self.hitParam_alg1_npix_max,
                     'tip': "Only keep the peak if number of pixels above thr_low is below this value"},
                    {'name': self.hitParam_alg1_amax_thr_str, 'type': 'float', 'value': self.hitParam_alg1_amax_thr,
                     'tip': "Only keep the peak if max value is above this value"},
                    {'name': self.hitParam_alg1_atot_thr_str, 'type': 'float', 'value': self.hitParam_alg1_atot_thr,
                     'tip': "Only keep the peak if integral inside region of interest is above this value"},
                    {'name': self.hitParam_alg1_son_min_str, 'type': 'float', 'value': self.hitParam_alg1_son_min,
                     'tip': "Only keep the peak if signal-over-noise is above this value"},
                    {'name': self.hitParam_alg1_thr_low_str, 'type': 'float', 'value': self.hitParam_alg1_thr_low,
                     'tip': "Grow a seed peak if above this value"},
                    {'name': self.hitParam_alg1_thr_high_str, 'type': 'float', 'value': self.hitParam_alg1_thr_high,
                     'tip': "Start a seed peak if above this value"},
                    {'name': self.hitParam_alg1_rank_str, 'type': 'int', 'value': self.hitParam_alg1_rank,
                     'tip': "region of integration is a square, (2r+1)x(2r+1)"},
                    {'name': self.hitParam_alg1_radius_str, 'type': 'int', 'value': self.hitParam_alg1_radius,
                     'tip': "region inside the region of interest"},
                    {'name': self.hitParam_alg1_dr_str, 'type': 'float', 'value': self.hitParam_alg1_dr,
                     'tip': "background region outside the region of interest"},
                ]},
                {'name': self.save_minPeaks_str, 'type': 'int', 'value': self.minPeaks,
                 'tip': "Index only if there are more Bragg peaks found"},
                {'name': self.save_maxPeaks_str, 'type': 'int', 'value': self.maxPeaks,
                 'tip': "Index only if there are less Bragg peaks found"},
                {'name': self.save_minRes_str, 'type': 'int', 'value': self.minRes,
                 'tip': "Index only if Bragg peak resolution is at least this"},
                {'name': self.save_sample_str, 'type': 'str', 'value': self.sample,
                 'tip': "Sample name saved inside cxi"},
                {'name': self.hitParam_outDir_str, 'type': 'str', 'value': self.hitParam_outDir},
                {'name': self.hitParam_runs_str, 'type': 'str', 'value': self.hitParam_runs},
                {'name': self.hitParam_queue_str, 'type': 'list', 'values': {self.hitParam_psfehhiprioq_str: 'psfehhiprioq',
                                                                             self.hitParam_psnehhiprioq_str: 'psnehhiprioq',
                                                                             self.hitParam_psfehprioq_str: 'psfehprioq',
                                                                             self.hitParam_psnehprioq_str: 'psnehprioq',
                                                                             self.hitParam_psfehq_str: 'psfehq',
                                                                             self.hitParam_psnehq_str: 'psnehq',
                                                                             self.hitParam_psanaq_str: 'psanaq',
                                                                             self.hitParam_psdebugq_str: 'psdebugq'},
                 'value': self.hitParam_queue, 'tip': "Choose queue"},
                {'name': self.hitParam_cpu_str, 'type': 'int', 'value': self.hitParam_cpus},
                {'name': self.hitParam_noe_str, 'type': 'int', 'value': self.hitParam_noe,
                 'tip': "number of events to process, default=-1 means process all events"},
                {'name': self.hitParam_extra_str, 'type': 'str', 'value': self.hitParam_extra, 'tip': "Extra peak finding flags"},
                {'name': self.hitParam_launch_str, 'type': 'action'},
            ]},
        ]

        self.p3 = Parameter.create(name='paramsPeakFinder', type='group', \
                                   children=self.params, expanded=True)
        self.w10.setParameters(self.p3, showTop=False)
        self.p3.sigTreeStateChanged.connect(self.change)
        #self.parent.connect(self.launchBtn, QtCore.SIGNAL("clicked()"), self.findPeaks)

    def digestRunList(self, runList):
        runsToDo = []
        if not runList:
            print "Run(s) is empty. Please type in the run number(s)."
            return runsToDo
        runLists = str(runList).split(",")
        for list in runLists:
            temp = list.split(":")
            if len(temp) == 2:
                for i in np.arange(int(temp[0]),int(temp[1])+1):
                    runsToDo.append(i)
            elif len(temp) == 1:
                runsToDo.append(int(temp[0]))
        return runsToDo

    def updateParam(self):
        if self.userUpdate is None:
            if self.parent.psocakeRunDir is not None:
                peakParamFname = self.parent.psocakeRunDir + '/peakParam.json'
                if os.path.exists(peakParamFname):
                    with open(peakParamFname) as infile:
                        d = json.load(infile)
                        if d[self.hitParam_algorithm_str] == 1:
                            # Update variables
                            try:
                                self.hitParam_alg1_npix_min = d[self.hitParam_alg1_npix_min_str]
                                self.hitParam_alg1_npix_max = d[self.hitParam_alg1_npix_max_str]
                                self.hitParam_alg1_amax_thr = d[self.hitParam_alg1_amax_thr_str]
                                self.hitParam_alg1_atot_thr = d[self.hitParam_alg1_atot_thr_str]
                                self.hitParam_alg1_son_min = d[self.hitParam_alg1_son_min_str]
                                self.hitParam_alg1_thr_low = d[self.hitParam_alg1_thr_low_str]
                                self.hitParam_alg1_thr_high = d[self.hitParam_alg1_thr_high_str]
                                self.hitParam_alg1_rank = int(d[self.hitParam_alg1_rank_str])
                                self.hitParam_alg1_radius = int(d[self.hitParam_alg1_radius_str])
                                self.hitParam_alg1_dr = d[self.hitParam_alg1_dr_str]
                                # Update GUI
                                self.doingUpdate = True
                                #self.p3.param(self.hitParam_grp, self.hitParam_algorithm_str).setValue(self.algorithm)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_npix_min_str).setValue(
                                    self.hitParam_alg1_npix_min)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_npix_max_str).setValue(
                                    self.hitParam_alg1_npix_max)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_amax_thr_str).setValue(
                                    self.hitParam_alg1_amax_thr)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_atot_thr_str).setValue(
                                    self.hitParam_alg1_atot_thr)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_son_min_str).setValue(
                                    self.hitParam_alg1_son_min)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_thr_low_str).setValue(
                                    self.hitParam_alg1_thr_low)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_thr_high_str).setValue(
                                    self.hitParam_alg1_thr_high)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_rank_str).setValue(
                                    self.hitParam_alg1_rank)
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_radius_str).setValue(
                                    self.hitParam_alg1_radius)
                                self.doingUpdate = False
                                self.p3.param(self.hitParam_grp, self.hitParam_algorithm1_str, self.hitParam_alg1_dr_str).setValue(
                                    self.hitParam_alg1_dr)
                            except:
                                pass

    def writeStatus(self, fname, d):
        json.dump(d, open(fname, 'w'))

    # Launch peak finding
    def findPeaks(self):
        self.parent.thread.append(LaunchPeakFinder.LaunchPeakFinder(self.parent)) # send parent parameters with self
        self.parent.thread[self.parent.threadCounter].launch(self.parent.experimentName, self.parent.detInfo)
        self.parent.threadCounter+=1
        # Save peak finding parameters
        runsToDo = self.digestRunList(self.hitParam_runs)
        for run in runsToDo:
            peakParamFname = self.parent.psocakeDir+'/r'+str(run).zfill(4)+'/peakParam.json'
            d = {self.hitParam_algorithm_str: self.algorithm,
                 self.hitParam_alg1_npix_min_str: self.hitParam_alg1_npix_min,
                 self.hitParam_alg1_npix_max_str: self.hitParam_alg1_npix_max,
                 self.hitParam_alg1_amax_thr_str: self.hitParam_alg1_amax_thr,
                 self.hitParam_alg1_atot_thr_str: self.hitParam_alg1_atot_thr,
                 self.hitParam_alg1_son_min_str: self.hitParam_alg1_son_min,
                 self.hitParam_alg1_thr_low_str: self.hitParam_alg1_thr_low,
                 self.hitParam_alg1_thr_high_str: self.hitParam_alg1_thr_high,
                 self.hitParam_alg1_rank_str: self.hitParam_alg1_rank,
                 self.hitParam_alg1_radius_str: self.hitParam_alg1_radius,
                 self.hitParam_alg1_dr_str: self.hitParam_alg1_dr}
            self.writeStatus(peakParamFname, d)

    # If anything changes in the parameter tree, print a message
    def change(self, panel, changes):
        for param, change, data in changes:
            path = panel.childPath(param)
            if self.parent.args.v >= 1:
                print('  path: %s' % path)
                print('  change:    %s' % change)
                print('  data:      %s' % str(data))
                print('  ----------')
            self.paramUpdate(path, change, data)

    ##############################
    # Mandatory parameter update #
    ##############################
    def paramUpdate(self, path, change, data):
        if path[0] == self.hitParam_grp:
            if path[1] == self.hitParam_algorithm_str:
                self.algInitDone = False
                self.updateAlgorithm(data)
            elif path[1] == self.hitParam_showPeaks_str:
                self.showPeaks = data
                self.drawPeaks()
            elif path[1] == self.hitParam_outDir_str:
                self.hitParam_outDir = data
                self.hitParam_outDir_overridden = True
            elif path[1] == self.hitParam_runs_str:
                self.hitParam_runs = data
            elif path[1] == self.hitParam_queue_str:
                self.hitParam_queue = data
            elif path[1] == self.hitParam_cpu_str:
                self.hitParam_cpus = data
            elif path[1] == self.hitParam_noe_str:
                self.hitParam_noe = data
            elif path[1] == self.hitParam_threshold_str:
                self.hitParam_threshold = data
            elif path[1] == self.hitParam_launch_str:
                self.findPeaks()
            elif path[1] == self.save_minPeaks_str:
                self.minPeaks = data
            elif path[1] == self.save_maxPeaks_str:
                self.maxPeaks = data
            elif path[1] == self.save_minRes_str:
                self.minRes = data
            elif path[1] == self.save_sample_str:
                self.sample = data
            elif path[1] == self.hitParam_extra_str:
                self.hitParam_extra = data
            elif path[2] == self.hitParam_alg1_npix_min_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_npix_min = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_npix_max_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_npix_max = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_amax_thr_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_amax_thr = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_atot_thr_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_atot_thr = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_son_min_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_son_min = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_thr_low_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_thr_low = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_thr_high_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_thr_high = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_rank_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_rank = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_radius_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_radius = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()
            elif path[2] == self.hitParam_alg1_dr_str and path[1] == self.hitParam_algorithm1_str:
                self.hitParam_alg1_dr = data
                self.algInitDone = False
                self.userUpdate = True
                if self.showPeaks and self.doingUpdate is False:
                    self.updateClassification()

    def updateAlgorithm(self, data):
        self.algorithm = data
        self.algInitDone = False
        self.updateClassification()
        if self.parent.args.v >= 1: print "##### Done updateAlgorithm: ", self.algorithm

    def saveCheetahFormat(self, arg):
        if arg == 'lcls':
            if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName:
                dim0 = 8 * 185
                dim1 = 4 * 388
            elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName:
                dim0 = 1920 #FIXME: rayonix can be binned
                dim1 = 1920
            elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName:
                dim0 = 1920 #FIXME: rayonix can be binned
                dim1 = 1920
            else:
                dim0 = 0
                dim1 = 0

            if dim0 > 0:
                maxNumPeaks = 2048
                if self.parent.index.hiddenCXI is not None:
                    myHdf5 = h5py.File(self.parent.index.hiddenCXI, 'w')
                    grpName = "/entry_1/result_1"
                    dset_nPeaks = "/nPeaks"
                    dset_posX = "/peakXPosRaw"
                    dset_posY = "/peakYPosRaw"
                    dset_atot = "/peakTotalIntensity"
                    if grpName in myHdf5:
                        del myHdf5[grpName]
                    grp = myHdf5.create_group(grpName)
                    myHdf5.create_dataset(grpName + dset_nPeaks, (1,), dtype='int')
                    myHdf5.create_dataset(grpName + dset_posX, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks))
                    myHdf5.create_dataset(grpName + dset_posY, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks))
                    myHdf5.create_dataset(grpName + dset_atot, (1, maxNumPeaks), dtype='float32', chunks=(1, maxNumPeaks))

                    myHdf5.create_dataset("/LCLS/detector_1/EncoderValue", (1,), dtype=float)
                    myHdf5.create_dataset("/LCLS/photon_energy_eV", (1,), dtype=float)
                    dset = myHdf5.create_dataset("/entry_1/data_1/data", (1, dim0, dim1), dtype=float)

                    # Convert calib image to cheetah image
                    img = np.zeros((dim0, dim1))
                    counter = 0
                    if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName:
                        for quad in range(4):
                            for seg in range(8):
                                img[seg * 185:(seg + 1) * 185, quad * 388:(quad + 1) * 388] = self.parent.calib[counter, :, :]
                                counter += 1
                    elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName:
                        img = self.parent.calib[:, :] # psana format
                    elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName:
                        img = self.parent.calib[:, :]  # psana format
                    else:
                        print "saveCheetahFormat not implemented"

                    peaks = self.peaks.copy()
                    nPeaks = peaks.shape[0]

                    if nPeaks > maxNumPeaks:
                        peaks = peaks[:maxNumPeaks]
                        nPeaks = maxNumPeaks
                    for i, peak in enumerate(peaks):
                        seg, row, col, npix, amax, atot, rcent, ccent, rsigma, csigma, rmin, rmax, cmin, cmax, bkgd, rms, son = peak[0:17]
                        if 'cspad' in self.parent.detInfo.lower() and 'cxi' in self.parent.experimentName:
                            cheetahRow, cheetahCol = self.convert_peaks_to_cheetah(seg, row, col)
                            myHdf5[grpName + dset_posX][0, i] = cheetahCol
                            myHdf5[grpName + dset_posY][0, i] = cheetahRow
                            myHdf5[grpName + dset_atot][0, i] = atot
                        elif 'rayonix' in self.parent.detInfo.lower() and 'mfx' in self.parent.experimentName:
                            myHdf5[grpName + dset_posX][0, i] = col
                            myHdf5[grpName + dset_posY][0, i] = row
                            myHdf5[grpName + dset_atot][0, i] = atot
                        elif 'rayonix' in self.parent.detInfo.lower() and 'xpp' in self.parent.experimentName:
                            myHdf5[grpName + dset_posX][0, i] = col
                            myHdf5[grpName + dset_posY][0, i] = row
                            myHdf5[grpName + dset_atot][0, i] = atot
                    myHdf5[grpName + dset_nPeaks][0] = nPeaks

                    if self.parent.args.v >= 1: print "hiddenCXI clen (mm): ", self.parent.clen * 1000.
                    myHdf5["/LCLS/detector_1/EncoderValue"][0] = self.parent.clen * 1000.  # mm
                    myHdf5["/LCLS/photon_energy_eV"][0] = self.parent.photonEnergy
                    dset[0, :, :] = img
                    myHdf5.close()

    def updateClassification(self):
        if self.parent.calib is not None:
            if self.parent.mk.streakMaskOn:
                self.parent.mk.initMask()
                self.parent.mk.streakMask = self.parent.mk.StreakMask.getStreakMaskCalib(self.parent.evt)
                if self.parent.mk.streakMask is None:
                    self.parent.mk.streakMaskAssem = None
                else:
                    self.parent.mk.streakMaskAssem = self.parent.det.image(self.parent.evt, self.parent.mk.streakMask)
                self.algInitDone = False

            self.parent.mk.displayMask()

            # update combined mask
            self.parent.mk.combinedMask = np.ones_like(self.parent.calib)
            if self.parent.mk.streakMask is not None and self.parent.mk.streakMaskOn is True:
                self.parent.mk.combinedMask *= self.parent.mk.streakMask
            if self.parent.mk.userMask is not None and self.parent.mk.userMaskOn is True:
                self.parent.mk.combinedMask *= self.parent.mk.userMask
            if self.parent.mk.psanaMask is not None and self.parent.mk.psanaMaskOn is True:
                self.parent.mk.combinedMask *= self.parent.mk.psanaMask

            # Peak output (0-16):
            # 0 seg
            # 1 row
            # 2 col
            # 3 npix: no. of pixels in the ROI intensities above threshold
            # 4 amp_max: max intensity
            # 5 amp_tot: sum of intensities
            # 6,7: row_cgrav: center of mass
            # 8,9: row_sigma
            # 10,11,12,13: minimum bounding box
            # 14: background
            # 15: noise
            # 16: signal over noise
            if self.algorithm == 0: # No peak algorithm
                self.peaks = None
                self.drawPeaks()
            else:
                # Only initialize the hit finder algorithm once
                if self.algInitDone is False:
                    self.windows = None
                    self.alg = []
                    self.alg = PyAlgos(windows=self.windows, mask=self.parent.mk.combinedMask, pbits=0)

                    # set peak-selector parameters:
                    if self.algorithm == 1:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg1_npix_min, npix_max=self.hitParam_alg1_npix_max, \
                                                amax_thr=self.hitParam_alg1_amax_thr, atot_thr=self.hitParam_alg1_atot_thr, \
                                                son_min=self.hitParam_alg1_son_min)
                    elif self.algorithm == 2:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg2_npix_min, npix_max=self.hitParam_alg2_npix_max, \
                                                amax_thr=self.hitParam_alg2_amax_thr, atot_thr=self.hitParam_alg2_atot_thr, \
                                                son_min=self.hitParam_alg2_son_min)
                    elif self.algorithm == 3:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg3_npix_min, npix_max=self.hitParam_alg3_npix_max, \
                                                amax_thr=self.hitParam_alg3_amax_thr, atot_thr=self.hitParam_alg3_atot_thr, \
                                                son_min=self.hitParam_alg3_son_min)
                    elif self.algorithm == 4:
                        self.alg.set_peak_selection_pars(npix_min=self.hitParam_alg4_npix_min, npix_max=self.hitParam_alg4_npix_max, \
                                                amax_thr=self.hitParam_alg4_amax_thr, atot_thr=self.hitParam_alg4_atot_thr, \
                                                son_min=self.hitParam_alg4_son_min)
                    self.algInitDone = True

                self.parent.calib = self.parent.calib * 1.0 # Neccessary when int is returned
                if self.algorithm == 1:
                    # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region
                    #                           around pixel with maximal intensity.
                    self.peakRadius = int(self.hitParam_alg1_radius)
                    self.peaks = self.alg.peak_finder_v4r2(self.parent.calib,
                                                           thr_low=self.hitParam_alg1_thr_low,
                                                           thr_high=self.hitParam_alg1_thr_high,
                                                           rank=int(self.hitParam_alg1_rank),
                                                           r0=self.peakRadius,
                                                           dr=self.hitParam_alg1_dr)
                elif self.algorithm == 2:
                    # v2 - define peaks for regions of connected pixels above threshold
                    self.peakRadius = int(self.hitParam_alg2_r0)
                    self.peaks = self.alg.peak_finder_v2(self.parent.calib, thr=self.hitParam_alg2_thr, r0=self.peakRadius, dr=self.hitParam_alg2_dr)
                elif self.algorithm == 3:
                    self.peakRadius = int(self.hitParam_alg3_r0)
                    self.peaks = self.alg.peak_finder_v3(self.parent.calib, rank=self.hitParam_alg3_rank, r0=self.peakRadius, dr=self.hitParam_alg3_dr)
                elif self.algorithm == 4:
                    # v4 - aka Droplet Finder - the same as v1, but uses rank and r0 parameters in stead of common radius.
                    self.peakRadius = int(self.hitParam_alg4_r0)
                    self.peaks = self.alg.peak_finder_v4(self.parent.calib, thr_low=self.hitParam_alg4_thr_low, thr_high=self.hitParam_alg4_thr_high,
                                               rank=self.hitParam_alg4_rank, r0=self.peakRadius,  dr=self.hitParam_alg4_dr)
                self.numPeaksFound = self.peaks.shape[0]

                if self.parent.args.v >= 1: print "Num peaks found: ", self.numPeaksFound, self.peaks.shape

                # update clen
                self.parent.geom.updateClen('lcls')

                self.parent.index.clearIndexedPeaks()

                # Save image and peaks in cheetah cxi file
                self.saveCheetahFormat('lcls')

                if self.parent.index.showIndexedPeaks: self.parent.index.updateIndex()

                self.drawPeaks()
            if self.parent.args.v >= 1: print "Done updateClassification"

    def convert_peaks_to_cheetah(self, s, r, c) :
        """Converts seg, row, col assuming (32,185,388)
           to cheetah 2-d table row and col (8*185, 4*388)
        """
        segs, rows, cols = (32,185,388)
        row2d = (int(s)%8) * rows + int(r) # where s%8 is a segment in quad number [0,7]
        col2d = (int(s)/8) * cols + int(c) # where s/8 is a quad number [0,3]
        return row2d, col2d

    def getMaxRes(self, posX, posY, centerX, centerY):
        maxRes = np.max(np.sqrt((posX-centerX)**2 + (posY-centerY)**2))
        if self.parent.args.v >= 1: print "maxRes: ", maxRes
        return maxRes # in pixels

    def drawPeaks(self):
        self.parent.img.clearPeakMessage()
        if self.showPeaks:
            if self.peaks is not None and self.numPeaksFound > 0:
                self.ix = self.parent.det.indexes_x(self.parent.evt)
                self.iy = self.parent.det.indexes_y(self.parent.evt)
                if self.ix is None:
                    (_, dim0, dim1) = self.parent.calib.shape
                    self.iy = np.tile(np.arange(dim0),[dim1, 1])
                    self.ix = np.transpose(self.iy)
                self.iX = np.array(self.ix, dtype=np.int64)
                self.iY = np.array(self.iy, dtype=np.int64)
                if len(self.iX.shape)==2:
                    self.iX = np.expand_dims(self.iX,axis=0)
                    self.iY = np.expand_dims(self.iY,axis=0)
                cenX = self.iX[np.array(self.peaks[:,0],dtype=np.int64),np.array(self.peaks[:,1],dtype=np.int64),np.array(self.peaks[:,2],dtype=np.int64)] + 0.5
                cenY = self.iY[np.array(self.peaks[:,0],dtype=np.int64),np.array(self.peaks[:,1],dtype=np.int64),np.array(self.peaks[:,2],dtype=np.int64)] + 0.5
                self.peaksMaxRes = self.getMaxRes(cenX, cenY, self.parent.cx, self.parent.cy)
                diameter = self.peakRadius*2+1
                self.parent.img.peak_feature.setData(cenX, cenY, symbol='s', \
                                          size=diameter, brush=(255,255,255,0), \
                                          pen=pg.mkPen({'color': "c", 'width': 4}), pxMode=False) #FF0
                # Write number of peaks found
                xMargin = 5 # pixels
                yMargin = 0  # pixels
                maxX = np.max(self.ix) + xMargin
                maxY = np.max(self.iy) - yMargin
                myMessage = '<div style="text-align: center"><span style="color: cyan; font-size: 12pt;">Peaks=' + \
                            str(self.numPeaksFound) + ' <br>Res=' + str(int(self.peaksMaxRes)) + '<br></span></div>'
                self.parent.img.peak_text = pg.TextItem(html=myMessage, anchor=(0, 0))
                self.parent.img.w1.getView().addItem(self.parent.img.peak_text)
                self.parent.img.peak_text.setPos(maxX, maxY)
            else:
                self.parent.img.peak_feature.setData([], [], pxMode=False)
                self.parent.img.peak_text = pg.TextItem(html='', anchor=(0, 0))
                self.parent.img.w1.getView().addItem(self.parent.img.peak_text)
                self.parent.img.peak_text.setPos(0,0)
        else:
            self.parent.img.peak_feature.setData([], [], pxMode=False)
        if self.parent.args.v >= 1: print "Done updatePeaks"
class Coin(Workers):

    def init_params(self,monitor_params):
    
        
        self.npix_min, self.npix_max= monitor_params['Opal']['npix_min'],monitor_params['Opal']['npix_max']
        self.amax_thr, self.atot_thr, self.son_min = monitor_params['Opal']['amax_thr'], monitor_params['Opal']['atot_thr'], monitor_params['Opal']['son_min']
        self.thr_low, self.thr_high  = monitor_params['Opal']['thr_low'], monitor_params['Opal']['thr_high']
        self.rank, self.r0, self.dr = monitor_params['Opal']['rank'], monitor_params['Opal']['r0'], monitor_params['Opal']['dr']
        
        self.eimg_center_x, self.eimg_center_y = monitor_params['Opal']['eimg_center_x'],monitor_params['Opal']['eimg_center_y']   
        self.e_radius = monitor_params['Opal']['e_radius'] 
        
        self.params_gen = monitor_params['General']



        
        
        self.output_path = monitor_params['OutputLayer']['output_path']   
        
           
                      
        
  #################################################################   
        self.output_params = monitor_params['OutputLayer']
        
        self.vars = monitor_params['OutputLayer']['vars'].split(',')       
        self.hist_names_all = monitor_params['OutputLayer']['hist_names_all'].split(',')      
        
        self.hist1_names_all = monitor_params['OutputLayer']['hist1_names_all'].split(',')                  
     
        #self.vars_min = {}; self.vars_max = {}; self.vars_bin= {}; 
        self.vars_binnum = {}; self.vars_axis={}
        self.hists_all = {}    
        self.hists_all_all = {}                           
                       
        
        for var in self.vars:
            var_min= monitor_params[var]['min']
            var_max = monitor_params[var]['max']
            var_bin = monitor_params[var]['bin']  
            var_binnum = int((var_max - var_min)/var_bin)+1
            self.vars_binnum[var] = var_binnum
            self.vars_axis[var] = np.linspace(var_min, var_max, var_binnum)

        for hist_name in self.hist_names_all:
            if hist_name=='pipico':
                x_name = self.monitor_params[hist_name]['x']
                x_binnum = self.vars_binnum[x_name]        
                y_name = self.monitor_params[hist_name]['y']
                y_binnum = self.vars_binnum[y_name]                    
                self.hists_all[hist_name] = np.zeros([x_binnum-2, y_binnum-2])      
                if self.role == 'master':
                    self.hists_all_all[hist_name] = np.zeros([x_binnum-2, y_binnum-2]) 
                else:
                    self.hists_all_all[hist_name] = None   
                continue

                               
            x_name = self.monitor_params[hist_name]['x']
            x_binnum = self.vars_binnum[x_name]
            if 'y' in self.monitor_params[hist_name].keys():
                y_name = self.monitor_params[hist_name]['y']
                y_binnum = self.vars_binnum[y_name]
                if 'z' in self.monitor_params[hist_name].keys():
                    z_name = self.monitor_params[hist_name]['z']
                    z_binnum = self.vars_binnum[z_name] 
                    self.hists_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1, z_binnum-1])
                    if self.role == 'master':
                        self.hists_all_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1, z_binnum-1])
                    else:
                        self.hists_all_all[hist_name] = None
                    
                else:
                    self.hists_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1])     
                    if self.role == 'master':
                        self.hists_all_all[hist_name] = np.zeros([x_binnum-1, y_binnum-1])
                    else:
                        self.hists_all_all[hist_name] = None                        
            else:
                self.hists_all[hist_name] = np.zeros([x_binnum-1])
                if self.role == 'master':
                    self.hists_all_all[hist_name] = np.zeros([x_binnum-1])
                else:
                    self.hists_all_all[hist_name] = None  
          #  print self.hists_all[hist_name].dtype,self.hists_all_all[hist_name].dtype
                     
                    
        for hist1_name in self.hist1_names_all:
         #   print 'hist1_name',hist1_name
            self.hists_all[hist1_name] = np.array([0],dtype=np.float64)
            if self.role == 'master':
                self.hists_all_all[hist1_name] = np.array([0],dtype=np.float64)  
            else:
                self.hists_all_all[hist1_name] = None  
            self.hist_names_all.append(hist1_name)   
          #  print self.hists_all[hist_name].dtype,self.hists_all_all[hist_name].dtype
        
                            
        
                    
        
            

    def __init__(self, source, monitor_params):

        super(Coin, self).__init__(map_func=self.process_data,
                                   reduce_func=self.reduce,save_func=self.save_data,
                                   source=source, monitor_params=monitor_params)
        
        

        import psana
 
        self.monitor_params = monitor_params
        self.init_params(monitor_params)
        
        self.e_cols = self.eimg_center_y - self.e_radius     
        self.e_coll = self.eimg_center_y + self.e_radius+1   
        
        self.e_rows = self.eimg_center_x - self.e_radius     
        self.e_rowl = self.eimg_center_x + self.e_radius+1         
        
        self.e_center_y = self.eimg_center_y
        self.e_center_x = self.eimg_center_x          
        
                                            
        

        self.mask = np.ones([1024,1024])
        self.mask[350:650, 350:650] = 0
        self.mask[:, :350] = 0        
        
        #self.alg = PyAlgos(mask = self.mask)
        self.alg = PyAlgos()        
        self.alg.set_peak_selection_pars(npix_min=self.npix_min, npix_max=self.npix_max, amax_thr=self.amax_thr, atot_thr=self.atot_thr, son_min=self.son_min)        




        self.speed_rep_int = self.params_gen['speed_report_interval']


        self.old_time = time.time()

        self.time = None



        print('Starting worker: {0}.'.format(self.mpi_rank))
        sys.stdout.flush()

        return

        
    def cart2polar_img(self, x, y, intensity):
    
        x1 = x-self.e_center_x
        y1 = y-self.e_center_y
        r = np.sqrt(x1**2 + y1**2)

        angle = np.arctan2(y1, x1)
        return r, angle, intensity*r    
        
    def cart2polar(self, x, y):
    
        x1 = x-self.e_center_x
        y1 = y-self.e_center_y
        r = np.sqrt(x1**2 + y1**2)

        angle = np.arctan2(y1, x1)
        return r, angle         



    def process_data(self):
    
        
        self.pls_ind = next((pls_eng_ind for pls_eng_ind, pls_eng_ele in enumerate(self.vars_axis['plseng']) if pls_eng_ele > self.pulse_eng),0)-1
        self.pho_ind = next((pho_eng_ind for pho_eng_ind, pho_eng_ele in enumerate(self.vars_axis['phoeng']) if pho_eng_ele > self.photon_eng),0)-1       
        self.ebm_ind = next((ebm_eng_ind for ebm_eng_ind, ebm_eng_ele in enumerate(self.vars_axis['ebmeng']) if ebm_eng_ele > self.ebeam_eng),0)-1 
                           
       # self.hists_all['num_events'][0] += 1          
        if (self.ebm_ind != -1 and self.pls_ind != -1):

            self.sortDataE(self.ebm_ind)
                            
                               
            self.hists_all['ebm_pls_eng'][self.ebm_ind, self.pls_ind] += 1   
            if self.pho_ind != -1:  
                self.hists_all['ebm_pho_eng'][self.ebm_ind, self.pho_ind] += 1 
                

            self.hists_all['num_events'][0] += 1  
            

     #   print self.mpi_rank, self.hists_all['num_events'][0] 


        if self.role == 'master' and (self.hists_all['num_events'][0]*self.mpi_size) % self.speed_rep_int == 0:
            self.time = time.time()
            print('Processed: {0} in {1:.2f} seconds ({2:.2f} Hz)'.format(
                self.mpi_size*self.hists_all['num_events'][0],
                self.time - self.old_time,
                float(self.speed_rep_int)/float(self.time-self.old_time)))
            sys.stdout.flush()
            self.old_time = self.time

        if self.role == 'master' and self.mpi_size*self.hists_all['num_events'][0] == self.output_params['max_events'] :
            self.save_data()
          
            self.shutdown(msg='maximum number of events reached.')


        return 
        
        

        
 
    def sortDataE(self,ebm_ind):
          
        e_peaks = self.alg.peak_finder_v4r2(self.eImage, thr_low=self.thr_low, thr_high=self.thr_high, rank=self.rank, r0=self.r0, dr=self.dr)
        
        eXs = e_peaks[:,1].astype(int)
        eYs = e_peaks[:,2].astype(int)
        eRadius, eAngle =self.cart2polar(eXs, eYs)

        for e_ind in range(len(eXs)):

            tempXind = next((eX_ind for eX_ind, eX_ele in enumerate(self.vars_axis['ex']) if eX_ele > eXs[e_ind]),0)-1
            tempYind = next((eY_ind for eY_ind, eY_ele in enumerate(self.vars_axis['ey']) if eY_ele > eYs[e_ind]),0)-1

            if tempXind != -1 and tempYind != -1:    

                self.hists_all['ebm_ex_ey'][ebm_ind,tempXind, tempYind] += 1



            
    def sortDataIon(self):
    
        self.tof_inds = []
   
        self.acqiris_data_wf[2:7] = self.acqiris_data_wf[2:7] - np.mean(self.acqiris_data_wf[2:7,self.acqiris_data_wt[6,:]>8000], axis=1)[:,np.newaxis]
        #self.acqiris_data_wf[self.t_channel] = -self.acqiris_data_wf[self.t_channel]
        t_peaks = np.array(self.PeakFinderT.cfd(self.acqiris_data_wf[self.t_channel],self.acqiris_data_wt[self.t_channel]))        
        if len(t_peaks) > 0:        
           # for t_peak in t_peaks:
            #    tempMCPind = next((MCP_ind for MCP_ind, MCP_ele in enumerate(self.vars_axis['t']) if MCP_ele > t_peak),0)-1
           #     if tempMCPind != -1:
          #          self.MCPTof[tempMCPind] += 1                 
         #           self.updateMCPGatesIon(tempMCPind)                                  
                                   
            x1_peaks = np.array(self.PeakFinderX.cfd(self.acqiris_data_wf[self.x1_channel],self.acqiris_data_wt[self.x1_channel]))
            x2_peaks = np.array(self.PeakFinderX.cfd(self.acqiris_data_wf[self.x2_channel],self.acqiris_data_wt[self.x2_channel]))
            y1_peaks = np.array(self.PeakFinderY.cfd(self.acqiris_data_wf[self.y1_channel],self.acqiris_data_wt[self.y1_channel]))
            y2_peaks = np.array(self.PeakFinderY.cfd(self.acqiris_data_wf[self.y2_channel],self.acqiris_data_wt[self.y2_channel]))        
            
        # [(mcp_peak, (x, y,), (x1, x2, y1, y2)), ...]
            ion_hits = self.HitFinder.FindHits(t_peaks, x1_peaks, x2_peaks, y1_peaks, y2_peaks)
        
            for ion_hit in ion_hits:
                tempTofind = next((Tof_ind for Tof_ind, Tof_ele in enumerate(self.vars_axis['t']) if Tof_ele > ion_hit[0]),0)-1
                tempXind = next((X_ind for X_ind, X_ele in enumerate(self.vars_axis['x']) if X_ele > ion_hit[1]),0)-1
                tempYind = next((Y_ind for Y_ind, Y_ele in enumerate(self.vars_axis['y']) if Y_ele > ion_hit[2]),0)-1
                if tempTofind != -1 and tempXind != -1 and tempYind != -1:                  
        
                    self.tof_inds.append(tempTofind)
            
                    self.hists_all['t_'][tempTofind] += 1
                    self.hists_all['x_y'][tempXind, tempYind] += 1
                 #   self.XT[tempTofind, tempXind] += 1
                 #   self.YT[tempTofind, tempYind] += 1  
                
                
                
                    self.updateTofGatesIon(tempTofind, tempXind, tempYind, ion_hit[0], ion_hit[1], ion_hit[2])
                    self.updatePiPiCoGatesIon(tempTofind, tempXind, tempYind, ion_hit[0], ion_hit[1], ion_hit[2])   
                
            self.tof_inds = sorted(self.tof_inds)    
            if len(self.tof_inds) > 1:
                for i_tof_ind in range(len(self.tof_inds)-1):
             #   print '****************************************',self.PiPiCo.shape, len(self.tof_inds)
                    self.hists_all['pipico'][self.tof_inds[i_tof_ind],self.tof_inds[(i_tof_ind+1):]]  += 1                                                             
                    
            if len(self.tof_inds) > 0:     
        
                F_sum,_  = np.histogram(self.HitFinder.F_sum, bins=self.TSum_axis)
                S_sum,_  = np.histogram(self.HitFinder.S_sum, bins=self.TSum_axis)
   
                
                self.hists_all['F_sum'] += F_sum
                self.hists_all['S_sum'] += S_sum
                        
                           

        
        
    def updateMCPGatesIon(self, t_ind):
        for M_key, M_item in self.MCPGates.iteritems():
            M_item.update_ion(t_ind)
            
    def updateTofGatesIon(self, t_ind,x_ind,y_ind,tele,xele,yele):
        for T_key, T_item in self.TofGates.iteritems():
            T_item.update_ion(t_ind, x_ind, y_ind,tele,xele,yele)            
            
    def updatePiPiCoGatesIon(self, t_ind, xind, yind,tele,xele,yele):
        for P_key, P_item in self.PiPiCoGates.iteritems():
            P_item.update_ion(t_ind, xind, yind,tele,xele,yele) 
            
    def updateMCPGatesE(self, eAind, eRind, eXind, eYind):
        for M_key, M_item in self.MCPGates.iteritems():
            if M_item.is_coin():
                M_item.update_electron(eAind, eRind, eXind, eYind)
            
    def updateTofGatesE(self, eAind, eRind, eXind, eYind):
        for T_key, T_item in self.TofGates.iteritems():
            if T_item.is_coin():
                T_item.update_electron(eAind, eRind, eXind, eYind)            
            
    def updatePiPiCoGatesE(self, eAind, eRind, eXind, eYind, pho_ind, pls_ind):
        for P_key, P_item in self.PiPiCoGates.iteritems():
            if P_item.is_coin():
                P_item.update_electron(eAind, eRind, eXind, eYind, pho_ind, pls_ind)     
                
                
    def updateShotInfo(self,phoInd, plsInd,phoEng,plsEng):
       for M_key, M_item in self.MCPGates.iteritems():
           if M_item.is_coin():
               M_item.update_shotinfo(phoInd, plsInd)  
           M_item.reset_coin_var()  
               
       for T_key, T_item in self.TofGates.iteritems():
           if T_item.is_coin():
               T_item.update_shotinfo(phoInd, plsInd)  
           T_item.reset_coin_var()     
               
       for P_key, P_item in self.PiPiCoGates.iteritems():
           if P_item.is_coin():
               P_item.update_shotinfo(phoInd, plsInd,phoEng,plsEng)    
           P_item.reset_coin_var()            
           
           
    def reduce(self):
        print(str(self.mpi_rank)+' starts reduce.')
        for histname in self.hist_names_all:
         #   self.time_a = time.time()
            try:
                self.time_a = time.time()
                MPI.COMM_WORLD.Reduce(self.hists_all[histname],self.hists_all_all[histname])  
                self.time_b = time.time() 
                print(histname+' reduced by '+'Rank {0} in {1:.2f} seconds'.format(self.mpi_rank,self.time_b - self.time_a))
            except Exception as e:
                print(histname+' failed to be redueced by '+str(self.mpi_rank))
                print(e) 
         #   self.time_b = time.time()  
         #   print(histname+' reduced by '+'Rank {0} in {1:.2f} seconds'.format(self.mpi_rank,self.time_b - self.time_a))
          
                            
        
        
    def save_data(self,num_lost_events_timecond,num_lost_events_datacond,num_lost_events_evtcond,num_failed_events,num_reduced_events):
        print 'saving hdf5 file'
        h5f = h5py.File(self.output_path,'w')

        
        grp = h5f.create_group('all') 
        
        try:  
              
            grp.create_dataset('num_lost_events_timecond',data = num_lost_events_timecond)    
            grp.create_dataset('num_lost_events_datacond',data = num_lost_events_datacond)              
            grp.create_dataset('num_lost_events_evtcond',data = num_lost_events_evtcond)  
            grp.create_dataset('num_failed_events',data = num_failed_events)                
            grp.create_dataset('num_reduced_events',data = num_reduced_events)  
        except Exception as e:
            print('events stats'+' failed to be saved.')
            print(e) 
        
        for histname in self.hist_names_all:
            try:
                grp.create_dataset(histname,data = self.hists_all_all[histname])   
            except Exception as e:
                print(histname+' failed to be saved.')
                print(e)                                               
            
                      


        grp1 = h5f.create_group('axis') 
        
        for var in self.vars:  
            try:
                grp1.create_dataset(var+'_axis',data = self.vars_axis[var])  
            except Exception as e:
                print(var+'_axis failed to be saved.')
                print(e)                
                    
             
                                                                                                    
        h5f.close()    
        print 'saved hdf5 file'        
        
        
    def init_gates(self):
    

        self.PiPiCoGates = {}
        for PPG in range(self.PiPiCoGates_params['num_gates']):
            gateName = self.PiPiCoGates_params['gate'+str(PPG+1)+'_name'] 
            tof1s = self.PiPiCoGates_params['gate'+str(PPG+1)+'_tof1s']
            tof1l = self.PiPiCoGates_params['gate'+str(PPG+1)+'_tof1l'] 
            tof2s = self.PiPiCoGates_params['gate'+str(PPG+1)+'_tof2s']  
            tof2l = self.PiPiCoGates_params['gate'+str(PPG+1)+'_tof2l'] 
            tof3s = self.PiPiCoGates_params['gate'+str(PPG+1)+'_tof3s']  
            tof3l = self.PiPiCoGates_params['gate'+str(PPG+1)+'_tof3l']             
            thresh1_n3n1 = self.PiPiCoGates_params['gate'+str(PPG+1)+'_thresh1_n3n1']       
            thresh2_n3n1 = self.PiPiCoGates_params['gate'+str(PPG+1)+'_thresh2_n3n1']    
            thresh1_n3n2 = self.PiPiCoGates_params['gate'+str(PPG+1)+'_thresh1_n3n2']       
            thresh2_n3n2 = self.PiPiCoGates_params['gate'+str(PPG+1)+'_thresh2_n3n2']                  
            self.PiPiCoGates[gateName] = PiPiCoGate(self, gateName, tof1s, tof1l, tof2s, tof2l,tof3s, tof3l,thresh1_n3n1,thresh2_n3n1,thresh1_n3n2,thresh2_n3n2,self.ang_f)
            
      
        self.TofGates = {}
        for TofG in range(self.TofGates_params['num_gates']):
            gateName = self.TofGates_params['gate'+str(TofG+1)+'_name'] 
            tofs = self.TofGates_params['gate'+str(TofG+1)+'_tofs']
            tofl = self.TofGates_params['gate'+str(TofG+1)+'_tofl'] 
            thresh1_tof = self.TofGates_params['gate'+str(TofG+1)+'_thresh1']       
            thresh2_tof = self.TofGates_params['gate'+str(TofG+1)+'_thresh2'] 
            self.TofGates[gateName] = TofGate(self, gateName, tofs, tofl,thresh1_tof,thresh2_tof)   
            

        self.MCPGates = {}
        for MCPG in range(self.MCPGates_params['num_gates']):
            gateName = self.MCPGates_params['gate'+str(MCPG+1)+'_name'] 
            tofs = self.MCPGates_params['gate'+str(MCPG+1)+'_tofs']
            tofl = self.MCPGates_params['gate'+str(MCPG+1)+'_tofl'] 

            self.MCPGates[gateName] = MCPGate(self, gateName, tofs, tofl)     
示例#7
0
class PiPiCoGate():
    def __init__(self, parent, gateName, tof1s, tof1l, tof2s, tof2l, thresh1,
                 thresh2, ang_f):
        self.parent = parent
        self.gateName = gateName
        self.tof1s = tof1s
        self.tof1l = tof1l
        self.tof2s = tof2s
        self.tof2l = tof2l

        self.extractE = extractE

        self.PiPiCo_ind1 = (self.parent.TaxisM >
                            self.tof1s) & (self.parent.TaxisM < self.tof1l)
        self.PiPiCo_ind2 = (self.parent.TaxisM >
                            self.tof2s) & (self.parent.TaxisM < self.tof2l)

        self.thresh1 = thresh1
        self.thresh2 = thresh2
        self.ang_f = ang_f

        self.cos_theta_f1 = np.cos(0.5 * self.ang_f * np.pi / 180)
        self.cos_theta_f2 = np.cos((90 - 0.5 * self.ang_f) * np.pi / 180)
        self.cos_theta_f3 = -np.cos((90 - 0.5 * self.ang_f) * np.pi / 180)
        self.cos_theta_f4 = -np.cos(0.5 * self.ang_f * np.pi / 180)

        self.particle1 = self.gateName[:2]
        self.particle2 = self.gateName[2:4]

        self.alg = PyAlgos()
        self.alg.set_peak_selection_pars(npix_min=self.parent.npix_min,
                                         npix_max=self.parent.npix_max,
                                         amax_thr=self.parent.amax_thr,
                                         atot_thr=self.parent.atot_thr,
                                         son_min=self.parent.son_min)

        self.init_vars()

    def init_vars(self):

        self.temp_len_run = -1
        self.temp_irun = -1

        self.num_events = 0

        self.num_eventss = 0

        self.num_eventsl = 0

        self.num_eventsm = 0
        self.num_events_orth = 0
        self.num_events_para = 0

        self.num_events_f = 0

        self.num_eventss_f = 0

        self.num_eventsl_f = 0

        self.num_eventsm_f = 0
        self.num_events_orth_f = 0
        self.num_events_para_f = 0

        self.P1 = 0
        self.P2 = 0
        self.P12 = 0

        self.Ps = 0
        self.Pl = 0

        self.Pm = 0
        self.P_orth = 0
        self.P_para = 0

        #      self.XY = np.zeros([self.parent.Xbinnum-1, self.parent.Ybinnum-1])
        #      self.XT = np.zeros([self.parent.Tbinnum-1, self.parent.Xbinnum-1])
        #      self.YT = np.zeros([self.parent.Tbinnum-1, self.parent.Ybinnum-1])
        #     self.PiPiCo = np.zeros([self.parent.Tbinnum-2,self.parent.Tbinnum-2])

        self.tempX1ind = []
        self.tempY1ind = []

        self.tempX2ind = []
        self.tempY2ind = []

        self.tempX1 = []
        self.tempY1 = []
        self.tempT1 = []
        self.tempT1_f = []

        self.tempX2 = []
        self.tempY2 = []
        self.tempT2 = []
        self.tempT2_f = []

        self.tempXe = []
        self.tempYe = []

        self.tempXef1 = []
        self.tempYef1 = []
        self.tempXef2 = []
        self.tempYef2 = []

        self.tempEr = []

        self.tempErf1 = []

        self.tempErf2 = []

        self.tempEng1_arr = []
        self.tempPx1_arr = []
        self.tempPy1_arr = []
        self.tempPz1_arr = []

        self.tempEng2_arr = []
        self.tempPx2_arr = []
        self.tempPy2_arr = []
        self.tempPz2_arr = []

        self.tempEng1ind_arr = []
        self.tempPx1ind_arr = []
        self.tempPy1ind_arr = []
        self.tempPz1ind_arr = []

        self.tempEng2ind_arr = []
        self.tempPx2ind_arr = []
        self.tempPy2ind_arr = []
        self.tempPz2ind_arr = []

        self.tempX1ind_arr = []
        self.tempY1ind_arr = []

        self.tempX2ind_arr = []
        self.tempY2ind_arr = []

        self.hists_pipico = {}

        self.hists_pipico_all = {}

        for hist_name in self.parent.hist_names_pipico:
            if hist_name == 'pipico':
                x_name = self.parent.monitor_params[hist_name]['x']
                x_bin = self.parent.monitor_params[x_name]['bin']
                y_name = self.parent.monitor_params[hist_name]['y']
                y_bin = self.parent.monitor_params[y_name]['bin']

                self.pipico_xbin = x_bin
                self.pipico_ybin = y_bin

                x_binnum = int((self.tof1l - self.tof1s) / x_bin) + 1
                y_binnum = int((self.tof2l - self.tof2s) / y_bin) + 1

                self.pipico_xaxis = np.linspace(self.tof1s, self.tof1l,
                                                x_binnum)
                self.pipico_yaxis = np.linspace(self.tof2s, self.tof2l,
                                                y_binnum)

                self.hists_pipico[hist_name] = np.zeros(
                    [x_binnum - 1, y_binnum - 1])
                if self.parent.role == 'master':
                    self.hists_pipico_all[hist_name] = np.zeros(
                        [x_binnum - 1, y_binnum - 1])
                else:
                    self.hists_pipico_all[hist_name] = None
                continue

            x_name = self.parent.monitor_params[hist_name]['x']
            x_binnum = self.parent.vars_binnum[x_name]
            if 'y' in self.parent.monitor_params[hist_name].keys():
                y_name = self.parent.monitor_params[hist_name]['y']
                y_binnum = self.parent.vars_binnum[y_name]
                if 'z' in self.parent.monitor_params[hist_name].keys():
                    z_name = self.parent.monitor_params[hist_name]['z']
                    z_binnum = self.parent.vars_binnum[z_name]
                    self.hists_pipico[hist_name] = np.zeros(
                        [x_binnum - 1, y_binnum - 1, z_binnum - 1])
                    if self.parent.role == 'master':
                        self.hists_pipico_all[hist_name] = np.zeros(
                            [x_binnum - 1, y_binnum - 1, z_binnum - 1])
                    else:
                        self.hists_pipico_all[hist_name] = None

                else:
                    self.hists_pipico[hist_name] = np.zeros(
                        [x_binnum - 1, y_binnum - 1])
                    if self.parent.role == 'master':
                        self.hists_pipico_all[hist_name] = np.zeros(
                            [x_binnum - 1, y_binnum - 1])
                    else:
                        self.hists_pipico_all[hist_name] = None
            else:
                self.hists_pipico[hist_name] = np.zeros([x_binnum - 1])
                if self.parent.role == 'master':
                    self.hists_pipico_all[hist_name] = np.zeros([x_binnum - 1])
                else:
                    self.hists_pipico_all[hist_name] = None

    def update_ion(self, Tofind, Xind, Yind, Tofele, Xele, Yele):

        if (self.parent.TaxisM[Tofind] > self.tof1s
                and self.parent.TaxisM[Tofind] < self.tof1l):

            self.P1 += 1

            #    self.tempX1ind.append(Xind)
            #    self.tempY1ind.append(Yind)

            self.tempX1.append(Xele)
            self.tempY1.append(Yele)
            self.tempT1.append(Tofele)

        if (self.parent.TaxisM[Tofind] > self.tof2s
                and self.parent.TaxisM[Tofind] < self.tof2l):

            self.P2 += 1

            #     self.tempX2ind.append(Xind)
            #     self.tempY2ind.append(Yind)

            self.tempX2.append(Xele)
            self.tempY2.append(Yele)
            self.tempT2.append(Tofele)

        if (self.parent.TaxisM[Tofind] > self.tof1s
                and self.parent.TaxisM[Tofind] < self.tof1l) and (
                    self.parent.TaxisM[Tofind] > self.tof2s
                    and self.parent.TaxisM[Tofind] < self.tof2l):

            self.P12 += 1

    def is_coin(self):

        return (self.P1 > 0 and self.P2 > 0 and self.P12 == 0) or self.P12 > 1

    def update_electron(self, eAind, eRind, eXind, eYind, pho_ind, pls_ind):

        self.tempXe.append(eXind)
        self.tempYe.append(eYind)
        self.tempEr.append(eRind)

#  def update_ion(self, Tofind, Xind, Yind):
#
#     self.XY[Xind, Yind] += 1
#     self.XT[Tind, Xind] += 1
#     self.YT[Tind, Yind] += 1

    def update_shotinfo(self, pho_ind, pls_ind, pho_eng, pls_eng):

        temp_num_particles_ind1 = next(
            (tNP_ind1 for tNP_ind1, tNP_ele1 in enumerate(
                self.parent.vars_axis['num_particles']) if tNP_ele1 > self.P1),
            0) - 1
        temp_num_particles_ind2 = next(
            (tNP_ind2 for tNP_ind2, tNP_ele2 in enumerate(
                self.parent.vars_axis['num_particles']) if tNP_ele2 > self.P2),
            0) - 1

        if temp_num_particles_ind1 != -1:
            self.hists_pipico['num_particles1_'][temp_num_particles_ind1] += 1

        if temp_num_particles_ind2 != -1:
            self.hists_pipico['num_particles2_'][temp_num_particles_ind2] += 1

        for itemp1 in range(len(self.tempX1)):

            tempEng1, tempPx1, tempPy1, tempPz1 = EngMo(
                self.tempT1[itemp1], self.tempX1[itemp1], self.tempY1[itemp1],
                self.parent.tsim[self.particle1], self.parent.xcenter,
                self.parent.ycenter, self.parent.toff[self.particle1],
                self.particle1)

            tempEng_ind1 = next(
                (tEng_ind1 for tEng_ind1, tEng_ele1 in enumerate(
                    self.parent.vars_axis['eng']) if tEng_ele1 > tempEng1),
                0) - 1
            tempPx_ind1 = next((tPx_ind1 for tPx_ind1, tPx_ele1 in enumerate(
                self.parent.vars_axis['px']) if tPx_ele1 > tempPx1), 0) - 1
            tempPy_ind1 = next((tPy_ind1 for tPy_ind1, tPy_ele1 in enumerate(
                self.parent.vars_axis['py']) if tPy_ele1 > tempPy1), 0) - 1
            tempPz_ind1 = next((tPz_ind1 for tPz_ind1, tPz_ele1 in enumerate(
                self.parent.vars_axis['pz']) if tPz_ele1 > tempPz1), 0) - 1

            if tempEng_ind1 != -1 and tempPx_ind1 != -1 and tempPy_ind1 != -1 and tempPz_ind1 != -1:

                #  self.Eng1[tempEng_ind1-1] += 1
                #    self.Momen1[tempPx_ind1-1, tempPy_ind1-1, tempPz_ind1-1] += 1

                self.tempEng1_arr.append(tempEng1)
                self.tempPx1_arr.append(tempPx1)
                self.tempPy1_arr.append(tempPy1)
                self.tempPz1_arr.append(tempPz1)

                self.tempEng1ind_arr.append(tempEng_ind1)
                self.tempPx1ind_arr.append(tempPx_ind1)
                self.tempPy1ind_arr.append(tempPy_ind1)
                self.tempPz1ind_arr.append(tempPz_ind1)

                self.tempT1_f.append(self.tempT1[itemp1])

        #      self.tempX1ind_arr.append(self.tempX1ind[itemp1])
        #     self.tempY1ind_arr.append(self.tempY1ind[itemp1])

        for itemp2 in range(len(self.tempX2)):

            tempEng2, tempPx2, tempPy2, tempPz2 = EngMo(
                self.tempT2[itemp2], self.tempX2[itemp2], self.tempY2[itemp2],
                self.parent.tsim[self.particle2], self.parent.xcenter,
                self.parent.ycenter, self.parent.toff[self.particle2],
                self.particle2)

            tempEng_ind2 = next(
                (tEng_ind2 for tEng_ind2, tEng_ele2 in enumerate(
                    self.parent.vars_axis['eng']) if tEng_ele2 > tempEng2),
                0) - 1
            tempPx_ind2 = next((tPx_ind2 for tPx_ind2, tPx_ele2 in enumerate(
                self.parent.vars_axis['px']) if tPx_ele2 > tempPx2), 0) - 1
            tempPy_ind2 = next((tPy_ind2 for tPy_ind2, tPy_ele2 in enumerate(
                self.parent.vars_axis['py']) if tPy_ele2 > tempPy2), 0) - 1
            tempPz_ind2 = next((tPz_ind2 for tPz_ind2, tPz_ele2 in enumerate(
                self.parent.vars_axis['pz']) if tPz_ele2 > tempPz2), 0) - 1

            if tempEng_ind2 != -1 and tempPx_ind2 != -1 and tempPy_ind2 != -1 and tempPz_ind2 != -1:

                #  self.Eng2[tempEng_ind2-1] += 1
                #   self.Momen2[tempPx_ind2-1, tempPy_ind2-1, tempPz_ind2-1] += 1

                self.tempEng2_arr.append(tempEng2)
                self.tempPx2_arr.append(tempPx2)
                self.tempPy2_arr.append(tempPy2)
                self.tempPz2_arr.append(tempPz2)

                self.tempEng2ind_arr.append(tempEng_ind2)
                self.tempPx2ind_arr.append(tempPx_ind2)
                self.tempPy2ind_arr.append(tempPy_ind2)
                self.tempPz2ind_arr.append(tempPz_ind2)

                self.tempT2_f.append(self.tempT2[itemp2])

        #      self.tempX2ind_arr.append(self.tempX2ind[itemp2])
        #      self.tempY2ind_arr.append(self.tempY2ind[itemp2])

        for i1 in range(len(self.tempEng1_arr)):
            for i2 in range(len(self.tempEng2_arr)):
                tempEng = self.tempEng1_arr[i1] + self.tempEng2_arr[i2]
                tempPx = self.tempPx1_arr[i1] + self.tempPx2_arr[i2]
                tempPy = self.tempPy1_arr[i1] + self.tempPy2_arr[i2]
                tempPz = self.tempPz1_arr[i1] + self.tempPz2_arr[i2]

                if np.abs(tempPx) > self.parent.pxf or np.abs(
                        tempPy) > self.parent.pyf or np.abs(
                            tempPz) > self.parent.pzf or tempEng < 1:
                    continue

                tempT1_ind = next(
                    (t1_ind for t1_ind, t1_ele in enumerate(self.pipico_xaxis)
                     if t1_ele > self.tempT1_f[i1]), 0) - 1
                tempT2_ind = next(
                    (t2_ind for t2_ind, t2_ele in enumerate(self.pipico_yaxis)
                     if t2_ele > self.tempT2_f[i2]), 0) - 1

                if tempT1_ind != -1 and tempT2_ind != -1:
                    self.hists_pipico['pipico'][tempT1_ind, tempT2_ind] += 1

                tempEng_ind = next(
                    (tEng_ind for tEng_ind, tEng_ele in enumerate(
                        self.parent.vars_axis['eng']) if tEng_ele > tempEng),
                    0) - 1
                tempEng_a_ind = next(
                    (tEng_ind for tEng_ind, tEng_ele in enumerate(
                        self.parent.vars_axis['eng_a']) if tEng_ele > tempEng),
                    0) - 1
                tempPx_ind = next((tPx_ind for tPx_ind, tPx_ele in enumerate(
                    self.parent.vars_axis['px']) if tPx_ele > tempPx), 0) - 1
                tempPy_ind = next((tPy_ind for tPy_ind, tPy_ele in enumerate(
                    self.parent.vars_axis['py']) if tPy_ele > tempPy), 0) - 1
                tempPz_ind = next((tPz_ind for tPz_ind, tPz_ele in enumerate(
                    self.parent.vars_axis['pz']) if tPz_ele > tempPz), 0) - 1

                # tempPx1_ind = next((tPx1_ind for tPx1_ind, tPx1_ele in enumerate(self.parent.PXaxis) if tPx1_ele > tempPx1[i1]),0)
                # tempPy1_ind = next((tPy1_ind for tPy1_ind, tPy1_ele in enumerate(self.parent.PYaxis) if tPy1_ele > tempPy1[i1]),0)
                # tempPz1_ind = next((tPz1_ind for tPz1_ind, tPz1_ele in enumerate(self.parent.PZaxis) if tPz1_ele > tempPz1[i1]),0)

                if tempEng_ind != -1 and tempPx_ind != -1 and tempPy_ind != -1 and tempPz_ind != -1:

                    self.hists_pipico['eng_'][tempEng_ind] += 1

                    self.hists_pipico['eng_a_'][tempEng_a_ind] += 1
                    self.hists_pipico['eng_a_pho_'][tempEng_a_ind] += pho_eng
                    self.hists_pipico['eng_a_pls_'][tempEng_a_ind] += pls_eng
                    self.hists_pipico['eng_a_er'][tempEng_a_ind,
                                                  self.tempEr] += 1
                    # self.Momen[tempPx_ind-1, tempPy_ind-1, tempPz_ind-1] += 1

                    self.hists_pipico['pxsum_'][tempPx_ind] += 1
                    self.hists_pipico['pysum_'][tempPy_ind] += 1
                    self.hists_pipico['pzsum_'][tempPz_ind] += 1

                    #  self.Momenf1[self.tempPx1ind_arr[i1], self.tempPy1ind_arr[i1], self.tempPz1ind_arr[i1]] += 1
                    #  self.Momenf2[self.tempPx2ind_arr[i2], self.tempPy2ind_arr[i2], self.tempPz2ind_arr[i2]] += 1

                    #   self.X1Y1[self.tempX1ind_arr[i1],self.tempY1ind_arr[i1]] += 1
                    #   self.X2Y2[self.tempX2ind_arr[i2],self.tempY2ind_arr[i2]] += 1

                    cos_theta = tempPx / np.sqrt(tempPx**2 + tempPy**2 +
                                                 tempPz**2)

                    cos_theta_orth = tempPy / np.sqrt(tempPx**2 + tempPy**2 +
                                                      tempPz**2)

                    if cos_theta >= self.cos_theta_f1 or cos_theta <= self.cos_theta_f4:
                        self.hists_pipico['eng_para_'][tempEng_ind] += 1

                        #    self.Eng1_para[self.tempEng1ind_arr[i1]] += 1
                        #    self.Eng2_para[self.tempEng2ind_arr[i2]] += 1
                        #  self.Momens1[self.tempPx1ind_arr[i1], self.tempPy1ind_arr[i1], self.tempPz1ind_arr[i1]] += 1
                        #  self.Momens2[self.tempPx2ind_arr[i2], self.tempPy2ind_arr[i2], self.tempPz2ind_arr[i2]] += 1

                        self.P_para += 1

                #  elif cos_theta >= self.cos_theta_f3 and cos_theta <= self.cos_theta_f2:
                #      self.Eng_orth[tempEng_ind] += 1
                    elif cos_theta_orth >= self.cos_theta_f1 or cos_theta_orth <= self.cos_theta_f4:
                        self.hists_pipico['eng_orth_'][tempEng_ind] += 1

                        #    self.Eng1_orth[self.tempEng1ind_arr[i1]] += 1
                        #   self.Eng2_orth[self.tempEng2ind_arr[i2]] += 1
                        #  self.Momenl1[self.tempPx1ind_arr[i1], self.tempPy1ind_arr[i1], self.tempPz1ind_arr[i1]] += 1
                        #  self.Momenl2[self.tempPx2ind_arr[i2], self.tempPy2ind_arr[i2], self.tempPz2ind_arr[i2]] += 1

                        #  self.Momenl[tempPx_ind, tempPy_ind, tempPz_ind] += 1
                        self.P_orth += 1

                    if tempEng < self.thresh1:
                        self.hists_pipico['eng_s_'][tempEng_ind] += 1

                        #   self.Engs1[self.tempEng1ind_arr[i1]-1] += 1
                        #  self.Engs2[self.tempEng2ind_arr[i2]-1] += 1
                        #  self.Momens1[self.tempPx1ind_arr[i1]-1, self.tempPy1ind_arr[i1]-1, self.tempPz1ind_arr[i1]-1] += 1
                        #  self.Momens2[self.tempPx2ind_arr[i2]-1, self.tempPy2ind_arr[i2]-1, self.tempPz2ind_arr[i2]-1] += 1

                        self.Ps += 1

                    elif tempEng >= self.thresh1 and tempEng < self.thresh2:
                        self.hists_pipico['eng_m_'][tempEng_ind] += 1

                        #  self.Engm1[self.tempEng1ind_arr[i1]-1] += 1
                        #  self.Engm2[self.tempEng2ind_arr[i2]-1] += 1
                        #  self.Momenm1[self.tempPx1ind_arr[i1]-1, self.tempPy1ind_arr[i1]-1, self.tempPz1ind_arr[i1]-1] += 1
                        #  self.Momenm2[self.tempPx2ind_arr[i2]-1, self.tempPy2ind_arr[i2]-1, self.tempPz2ind_arr[i2]-1] += 1

                        #  self.Momenl[tempPx_ind-1, tempPy_ind-1, tempPz_ind-1] += 1
                        self.Pm += 1

                    elif tempEng >= self.thresh2:
                        self.hists_pipico['eng_l_'][tempEng_ind] += 1

                        #  self.Engl1[self.tempEng1ind_arr[i1]-1] += 1
                        #  self.Engl2[self.tempEng2ind_arr[i2]-1] += 1
                        #  self.Momenl1[self.tempPx1ind_arr[i1]-1, self.tempPy1ind_arr[i1]-1, self.tempPz1ind_arr[i1]-1] += 1
                        #  self.Momenl2[self.tempPx2ind_arr[i2]-1, self.tempPy2ind_arr[i2]-1, self.tempPz2ind_arr[i2]-1] += 1

                        #  self.Momenl[tempPx_ind-1, tempPy_ind-1, tempPz_ind-1] += 1
                        self.Pl += 1

        self.tempXef1, self.tempYef1, self.tempErf1, self.pho_ind_f1, self.pls_ind_f1 = self.processDataE(
            self.parent.irun, self.parent.ievt - 1)
        self.tempXef2, self.tempYef2, self.tempErf2, self.pho_ind_f2, self.pls_ind_f2 = self.processDataE(
            self.parent.irun, self.parent.ievt + 1)

        if self.Ps > 0:

            self.fill_ele(self.tempXe, self.tempYe, self.tempEr, pho_ind,
                          pls_ind, self.hists_pipico['ex_ey_s'],
                          self.hists_pipico['er_er_s'],
                          self.hists_pipico['pho_pls_eng_s'], self.num_eventss)

            self.fill_ele_f(self.tempXef1, self.tempYef1, self.tempErf1,
                            self.pho_ind_f1, self.pls_ind_f1,
                            self.hists_pipico['ex_ey_s_fls1'],
                            self.hists_pipico['er_er_s_fls1'],
                            self.hists_pipico['pho_pls_eng_s_fls1'],
                            self.num_eventss_f)

            self.fill_ele_f(self.tempXef2, self.tempYef2, self.tempErf2,
                            self.pho_ind_f2, self.pls_ind_f2,
                            self.hists_pipico['ex_ey_s_fls2'],
                            self.hists_pipico['er_er_s_fls2'],
                            self.hists_pipico['pho_pls_eng_s_fls2'],
                            self.num_eventss_f)

        if self.Pm > 0:

            self.fill_ele(self.tempXe, self.tempYe, self.tempEr, pho_ind,
                          pls_ind, self.hists_pipico['ex_ey_m'],
                          self.hists_pipico['er_er_m'],
                          self.hists_pipico['pho_pls_eng_m'], self.num_eventsm)

            self.fill_ele_f(self.tempXef1, self.tempYef1, self.tempErf1,
                            self.pho_ind_f1, self.pls_ind_f1,
                            self.hists_pipico['ex_ey_m_fls1'],
                            self.hists_pipico['er_er_m_fls1'],
                            self.hists_pipico['pho_pls_eng_m_fls1'],
                            self.num_eventsm_f)

            self.fill_ele_f(self.tempXef2, self.tempYef2, self.tempErf2,
                            self.pho_ind_f2, self.pls_ind_f2,
                            self.hists_pipico['ex_ey_m_fls2'],
                            self.hists_pipico['er_er_m_fls2'],
                            self.hists_pipico['pho_pls_eng_m_fls2'],
                            self.num_eventsm_f)

        if self.Pl > 0:

            self.fill_ele(self.tempXe, self.tempYe, self.tempEr, pho_ind,
                          pls_ind, self.hists_pipico['ex_ey_l'],
                          self.hists_pipico['er_er_l'],
                          self.hists_pipico['pho_pls_eng_l'], self.num_eventsl)

            self.fill_ele_f(self.tempXef1, self.tempYef1, self.tempErf1,
                            self.pho_ind_f1, self.pls_ind_f1,
                            self.hists_pipico['ex_ey_l_fls1'],
                            self.hists_pipico['er_er_l_fls1'],
                            self.hists_pipico['pho_pls_eng_l_fls1'],
                            self.num_eventsl_f)

            self.fill_ele_f(self.tempXef2, self.tempYef2, self.tempErf2,
                            self.pho_ind_f2, self.pls_ind_f2,
                            self.hists_pipico['ex_ey_l_fls2'],
                            self.hists_pipico['er_er_l_fls2'],
                            self.hists_pipico['pho_pls_eng_l_fls2'],
                            self.num_eventsl_f)

        if self.P_para > 0:

            self.fill_ele(self.tempXe, self.tempYe, self.tempEr, pho_ind,
                          pls_ind, self.hists_pipico['ex_ey_para'],
                          self.hists_pipico['er_er_para'],
                          self.hists_pipico['pho_pls_eng_para'],
                          self.num_events_para)

            self.fill_ele_f(self.tempXef1, self.tempYef1, self.tempErf1,
                            self.pho_ind_f1, self.pls_ind_f1,
                            self.hists_pipico['ex_ey_para_fls1'],
                            self.hists_pipico['er_er_para_fls1'],
                            self.hists_pipico['pho_pls_eng_para_fls1'],
                            self.num_events_para_f)

            self.fill_ele_f(self.tempXef2, self.tempYef2, self.tempErf2,
                            self.pho_ind_f2, self.pls_ind_f2,
                            self.hists_pipico['ex_ey_para_fls2'],
                            self.hists_pipico['er_er_para_fls2'],
                            self.hists_pipico['pho_pls_eng_para_fls2'],
                            self.num_events_para_f)

        if self.P_orth > 0:

            self.fill_ele(self.tempXe, self.tempYe, self.tempEr, pho_ind,
                          pls_ind, self.hists_pipico['ex_ey_orth'],
                          self.hists_pipico['er_er_orth'],
                          self.hists_pipico['pho_pls_eng_orth'],
                          self.num_events_orth)

            self.fill_ele_f(self.tempXef1, self.tempYef1, self.tempErf1,
                            self.pho_ind_f1, self.pls_ind_f1,
                            self.hists_pipico['ex_ey_orth_fls1'],
                            self.hists_pipico['er_er_orth_fls1'],
                            self.hists_pipico['pho_pls_eng_orth_fls1'],
                            self.num_events_orth_f)

            self.fill_ele_f(self.tempXef2, self.tempYef2, self.tempErf2,
                            self.pho_ind_f2, self.pls_ind_f2,
                            self.hists_pipico['ex_ey_orth_fls2'],
                            self.hists_pipico['er_er_orth_fls2'],
                            self.hists_pipico['pho_pls_eng_orth_fls2'],
                            self.num_events_orth_f)

        if self.Ps > 0 or self.Pl > 0 or self.Pm > 0:

            self.fill_ele(self.tempXe, self.tempYe, self.tempEr, pho_ind,
                          pls_ind, self.hists_pipico['ex_ey_pg'],
                          self.hists_pipico['er_er_pg'],
                          self.hists_pipico['pho_pls_eng_pg'], self.num_events)

            self.fill_ele_f(self.tempXef1, self.tempYef1, self.tempErf1,
                            self.pho_ind_f1, self.pls_ind_f1,
                            self.hists_pipico['ex_ey_fls1'],
                            self.hists_pipico['er_er_pg_fls1'],
                            self.hists_pipico['pho_pls_eng_fls1'],
                            self.num_events_f)

            self.fill_ele_f(self.tempXef2, self.tempYef2, self.tempErf2,
                            self.pho_ind_f2, self.pls_ind_f2,
                            self.hists_pipico['ex_ey_fls2'],
                            self.hists_pipico['er_er_pg_fls2'],
                            self.hists_pipico['pho_pls_eng_fls2'],
                            self.num_events_f)

    def fill_ele(self, tempXe0, tempYe0, tempEr0, pho_ind0, pls_ind0, eXY0,
                 eReR0, pho_pls_eng0, num_events0):
        for itemp in range(len(tempXe0)):
            eXY0[tempXe0[itemp], tempYe0[itemp]] += 1

        for itemp in range(len(tempEr0)):
            eReR0[tempEr0[itemp], tempEr0] += 1

        pho_pls_eng0[pho_ind0, pls_ind0] += 1
        num_events0 += 1

    def fill_ele_f(self, tempXe0, tempYe0, tempEr0, pho_ind0, pls_ind0, eXY0,
                   eReR0, pho_pls_eng0, num_events0):
        if len(tempXe0) > 0:
            self.fill_ele(tempXe0, tempYe0, tempEr0, pho_ind0, pls_ind0, eXY0,
                          eReR0, pho_pls_eng0, num_events0)

    def reset_coin_var(self):

        self.P1 = 0
        self.P2 = 0
        self.P12 = 0

        self.tempX1ind = []
        self.tempY1ind = []

        self.tempX2ind = []
        self.tempY2ind = []

        self.tempX1 = []
        self.tempY1 = []
        self.tempT1 = []
        self.tempT1_f = []

        self.tempX2 = []
        self.tempY2 = []
        self.tempT2 = []
        self.tempT2_f = []

        self.tempXe = []
        self.tempYe = []

        self.tempXe_f1 = []
        self.tempYe_f1 = []
        self.tempXe_f2 = []
        self.tempYe_f2 = []

        self.tempEr = []

        self.tempErf1 = []

        self.tempErf2 = []

        self.tempEng1_arr = []
        self.tempPx1_arr = []
        self.tempPy1_arr = []
        self.tempPz1_arr = []

        self.tempEng2_arr = []
        self.tempPx2_arr = []
        self.tempPy2_arr = []
        self.tempPz2_arr = []

        self.tempEng1ind_arr = []
        self.tempPx1ind_arr = []
        self.tempPy1ind_arr = []
        self.tempPz1ind_arr = []

        self.tempEng2ind_arr = []
        self.tempPx2ind_arr = []
        self.tempPy2ind_arr = []
        self.tempPz2ind_arr = []

        self.tempX1ind_arr = []
        self.tempY1ind_arr = []

        self.tempX2ind_arr = []
        self.tempY2ind_arr = []

        #       self.num_eventss = 0
        #       self.num_eventsl = 0

        self.Ps = 0
        self.Pl = 0

        self.Pm = 0
        self.P_orth = 0
        self.P_para = 0

    def save_var(self, h5f):
        grp = h5f.create_group('PiPiCoGate_' + self.gateName)
        #      grp.create_dataset('XY',data = self.XY)
        #      grp.create_dataset('XT',data = self.XT)
        #      grp.create_dataset('YT',data = self.YT)

        grp.create_dataset(
            'gateInfo_tof1s_tof1l_tof2s_tof2l_pipixbin_pipiybin',
            data=np.array([
                self.tof1s, self.tof1l, self.tof2s, self.tof2l,
                self.pipico_xbin, self.pipico_ybin
            ]))

        for histname in self.parent.hist_names_pipico:
            try:
                grp.create_dataset(histname,
                                   data=self.hists_pipico_all[histname])
            except Exception as e:
                print(histname + ' failed to be saved.')
                print(e)

    def reduce(self):
        for histname in self.parent.hist_names_pipico:
            try:
                self.time_a = time.time()
                MPI.COMM_WORLD.Reduce(self.hists_pipico[histname],
                                      self.hists_pipico_all[histname])
                self.time_b = time.time()
                print(histname + ' reduced by ' +
                      'Rank {0} in {1:.2f} seconds'.format(
                          self.parent.mpi_rank, self.time_b - self.time_a))
            except Exception as e:
                print(histname + ' failed to be redueced by ' +
                      str(self.parent.mpi_rank))
                print(e)

    def processDataE(self, irun, ievt):

        if self.temp_irun != irun:
            self.psana_source = psana.DataSource(self.parent.source)
            for ii, rr in enumerate(self.psana_source.runs()):

                if ii == irun:
                    self.temp_irun = irun
                    self.temprun = rr
                    break

            self.temptimes = self.temprun.times()
            self.temp_len_run = len(self.temptimes)

        if ievt < 0 or ievt >= self.temp_len_run:
            return [], [], [], None, None

        event = {'evt': self.temprun.event(self.temptimes[ievt])}
        if event['evt'] is None:
            return [], [], [], None, None

        self.extractE(event, self)
        if self.eImage_f is None or self.pulse_eng_f is None or self.photon_eng_f is None:
            return [], [], [], None, None

        photon_eng_ind = next((pho_eng_ind for pho_eng_ind, pho_eng_ele in
                               enumerate(self.parent.vars_axis['phoeng'])
                               if pho_eng_ele > self.photon_eng_f), 0) - 1

        pulse_eng_ind = next((pls_eng_ind for pls_eng_ind, pls_eng_ele in
                              enumerate(self.parent.vars_axis['plseng'])
                              if pls_eng_ele > self.pulse_eng_f), 0) - 1

        if photon_eng_ind == -1 or pulse_eng_ind == -1:
            return [], [], [], None, None

        eXinds = []
        eYinds = []
        eRinds = []
        e_peaks = self.alg.peak_finder_v4r2(self.eImage_f,
                                            thr_low=self.parent.thr_low,
                                            thr_high=self.parent.thr_high,
                                            rank=self.parent.rank,
                                            r0=self.parent.r0,
                                            dr=self.parent.dr)

        eXs = e_peaks[:, 1].astype(int)
        eYs = e_peaks[:, 2].astype(int)

        eRadius, eAngle = self.parent.cart2polar(eXs, eYs)

        for e_ind in range(len(eXs)):
            tempRind = next(
                (eR_ind
                 for eR_ind, eR_ele in enumerate(self.parent.vars_axis['er'])
                 if eR_ele > eRadius[e_ind]), 0) - 1
            #   tempAind = next((eA_ind for eA_ind, eA_ele in enumerate(self.eAaxis) if eA_ele > eAngle[e_ind]),0)
            tempXind = next(
                (eX_ind
                 for eX_ind, eX_ele in enumerate(self.parent.vars_axis['ex'])
                 if eX_ele > eXs[e_ind]), 0) - 1
            tempYind = next(
                (eY_ind
                 for eY_ind, eY_ele in enumerate(self.parent.vars_axis['ey'])
                 if eY_ele > eYs[e_ind]), 0) - 1
            # if tempRind != 0 and tempAind != 0 and tempXind != 0 and tempYind != 0:
            if tempXind != -1 and tempYind != -1:
                eXinds.append(tempXind)
                eYinds.append(tempYind)
                eRinds.append(tempRind)
        if len(eXinds) > 0:
            return eXinds, eYinds, eRinds, photon_eng_ind, pulse_eng_ind

        else:
            return [], [], [], None, None
示例#8
0
winds_bkgd = [(s, 10, 100, 270, 370) for s in (4,12,20,28)] # use part of segments 4 and 20 to subtr bkgd

winds_arc = [(s, 0, 185, 0, 388) for s in (0,7,8,15)]
winds_equ = [(s, 0, 185, 0, 388) for s in (0,1,9,15,16,17,25,31)]
winds_tot = [(s, 0, 185, 0, 388) for s in (0,1,7,8,9,15,16,17,23,24,25,31)]

mask_winds_tot = np.zeros(shape_cspad, dtype=np.int16)
mask_winds_tot[(0,1,7,8,9,15,16,17,23,24,25,31),:,:] = seg1
#mask_winds_equ[(0,1,9,15,16,17,25,31),:,:] = seg1
#mask_winds_arc[(0,7,8,15),:,:] = seg1

print_arr(winds_arc, 'winds_arc')
print_arr_attr(winds_arc, 'winds_arc')

alg_arc = PyAlgos(windows=winds_arc, mask=mask_arc, pbits=2)
alg_arc.set_peak_selection_pars(npix_min=0, npix_max=1e6, amax_thr=0, atot_thr=0, son_min=10)
#alg_arc.set_peak_selection_pars(npix_min=0, npix_max=1e6, amax_thr=0, atot_thr=500, son_min=6) # for v2r1

alg_equ = PyAlgos(windows=winds_equ, mask=mask_equ, pbits=0)
alg_equ.set_peak_selection_pars(npix_min=0, npix_max=1e6, amax_thr=0, atot_thr=0, son_min=10)
#alg_equ.set_peak_selection_pars(npix_min=0, npix_max=1e6, amax_thr=0, atot_thr=500, son_min=6) # for v2r1

#alg_equ.print_attributes()
#alg_equ.print_input_pars()

##-----------------------------

xoffset, yoffset = 300, 300
xsize,   ysize   = 1150, 1150

# Pixel image indexes
class Onda(MasterWorker):

    def __init__(self, source, monitor_params):

        super(Onda, self).__init__(map_func=self.process_data,
                                   reduce_func=self.collect_data,
                                   source=source, monitor_params=monitor_params)
        

        import psana


        self.npix_min, self.npix_max= monitor_params['Opal']['npix_min'],monitor_params['Opal']['npix_max']
        self.amax_thr, self.atot_thr, self.son_min = monitor_params['Opal']['amax_thr'], monitor_params['Opal']['atot_thr'], monitor_params['Opal']['son_min']
        self.thr_low, self.thr_high  = monitor_params['Opal']['thr_low'], monitor_params['Opal']['thr_high']
        self.rank, self.r0, self.dr = monitor_params['Opal']['rank'], monitor_params['Opal']['r0'], monitor_params['Opal']['dr']
        
        self.e_center_x, self.e_center_y = monitor_params['Opal']['e_center_x'],monitor_params['Opal']['e_center_y']        
        
        print 'coin_point1'
        self.params_gen = monitor_params['General']
        self.params_peakfinder_t, self.params_peakfinder_x, self.params_peakfinder_y = monitor_params['PeakFinderMcp'], monitor_params['PeakFinderX'], monitor_params['PeakFinderY']
        self.params_hitfinder = monitor_params['HitFinder']
        
        self.output_params = monitor_params['OutputLayer']
        
        self.offset_acq = [0.01310443,0.02252858,0.02097541,0.01934959,-0.0001188]   

        self.t_channel = monitor_params['DetectorLayer']['mcp_channel']
        self.x1_channel = monitor_params['DetectorLayer']['x1_channel']
        self.x2_channel = monitor_params['DetectorLayer']['x2_channel']
        self.y1_channel = monitor_params['DetectorLayer']['y1_channel']
        self.y2_channel = monitor_params['DetectorLayer']['y2_channel']
        
  #################################################################              
        self.Xmin, self.Ymin, self.Tmin = monitor_params['OutputLayer']['xmin'],monitor_params['OutputLayer']['ymin'],monitor_params['OutputLayer']['tmin']
        self.Xmax, self.Ymax, self.Tmax = monitor_params['OutputLayer']['xmax'],monitor_params['OutputLayer']['ymax'],monitor_params['OutputLayer']['tmax']
        self.Xbin, self.Ybin, self.Tbin = monitor_params['OutputLayer']['xbin'],monitor_params['OutputLayer']['ybin'],monitor_params['OutputLayer']['tbin']
        
        self.Xbinnum = int((self.Xmax - self.Xmin)/self.Xbin)
        self.Ybinnum = int((self.Ymax - self.Ymin)/self.Ybin)
        self.Tbinnum = int((self.Tmax - self.Tmin)/self.Tbin)
        
        self.Xaxis  = np.linspace(self.Xmin, self.Xmax, self.Xbinnum)
        self.Yaxis = np.linspace(self.Ymin, self.Ymax, self.Ybinnum)
        self.Taxis = np.linspace(self.Tmin, self.Tmax, self.Tbinnum)
        
        self.Xaxis_r  = self.Xaxis[::-1]
        self.Yaxis_r = self.Yaxis[::-1]
        self.Taxis_r = self.Taxis[::-1]
 
        self.XaxisM = (self.Xaxis[:-1] + self.Xaxis[1:])/2
        self.YaxisM = (self.Yaxis[:-1] + self.Yaxis[1:])/2
        self.TaxisM = (self.Taxis[:-1] + self.Taxis[1:])/2
        
        
        
        self.eXmin, self.eYmin, self.eRmin, self.eAmin = monitor_params['OutputLayer']['exmin'],monitor_params['OutputLayer']['eymin'],monitor_params['OutputLayer']['ermin'],monitor_params['OutputLayer']['eamin']
        self.eXmax, self.eYmax, self.eRmax, self.eAmax = monitor_params['OutputLayer']['exmax'],monitor_params['OutputLayer']['eymax'],monitor_params['OutputLayer']['ermax'],monitor_params['OutputLayer']['eamax']
        self.eXbin, self.eYbin, self.eRbin, self.eAbin = monitor_params['OutputLayer']['exbin'],monitor_params['OutputLayer']['eybin'],monitor_params['OutputLayer']['erbin'],monitor_params['OutputLayer']['eabin']
        
        
        self.photon_eng_bin, self.pulse_eng_bin = monitor_params['OutputLayer']['photon_eng_bin'],monitor_params['OutputLayer']['pulse_eng_bin']
        self.photon_eng_min, self.pulse_eng_min = monitor_params['OutputLayer']['photon_eng_min'],monitor_params['OutputLayer']['pulse_eng_min']
        self.photon_eng_max, self.pulse_eng_max = monitor_params['OutputLayer']['photon_eng_max'],monitor_params['OutputLayer']['pulse_eng_max']        
        
        self.photon_eng_binnum = int((self.photon_eng_max - self.photon_eng_min)/self.photon_eng_bin)
        self.pulse_eng_binnum = int((self.pulse_eng_max - self.pulse_eng_min)/self.pulse_eng_bin) 
        
        self.photon_eng_axis  = np.linspace(self.photon_eng_min, self.photon_eng_max, self.photon_eng_binnum)
        self.pulse_eng_axis = np.linspace(self.pulse_eng_min, self.pulse_eng_max, self.pulse_eng_binnum)               
        
        self.eXbinnum = int((self.eXmax - self.eXmin)/self.eXbin)
        self.eYbinnum = int((self.eYmax - self.eYmin)/self.eYbin)
        self.eAbinnum = int((self.eAmax - self.eAmin)/self.eAbin)
        self.eRbinnum = int((self.eRmax - self.eRmin)/self.eRbin)    
        print 'binnum:', self.eXbinnum, self.eYbinnum
        
        self.eXaxis  = np.linspace(self.eXmin, self.eXmax, self.eXbinnum)
        self.eYaxis = np.linspace(self.eYmin, self.eYmax, self.eYbinnum)
        self.eAaxis = np.linspace(self.eAmin, self.eAmax, self.eAbinnum)
        self.eRaxis = np.linspace(self.eRmin, self.eRmax, self.eRbinnum)        
        
        self.eXaxis_r  = self.eXaxis[::-1]
        self.eYaxis_r = self.eYaxis[::-1]
        self.eAaxis_r = self.eAaxis[::-1]
        self.eRaxis_r = self.eRaxis[::-1]        
 
        self.eXaxisM = (self.eXaxis[:-1] + self.eXaxis[1:])/2
        self.eYaxisM = (self.eYaxis[:-1] + self.eYaxis[1:])/2
        self.eAaxisM = (self.eAaxis[:-1] + self.eAaxis[1:])/2        
        self.eRaxisM = (self.eRaxis[:-1] + self.eRaxis[1:])/2               

        self.pho_pls_eng = np.zeros([self.photon_eng_binnum-1 , self.pulse_eng_binnum-1])
     
        
        self.eXY = np.zeros([self.photon_eng_binnum-1 , self.pulse_eng_binnum-1, self.eXbinnum-1, self.eYbinnum-1])
        self.eAR = np.zeros([self.photon_eng_binnum-1 , self.pulse_eng_binnum-1, self.eAbinnum-1, self.eRbinnum-1])
        self.eA = np.zeros([self.photon_eng_binnum-1 , self.pulse_eng_binnum-1, self.eAbinnum-1])                     
        self.eR = np.zeros([self.photon_eng_binnum-1 , self.pulse_eng_binnum-1, self.eRbinnum-1])                                   


        self.PeakFinderT = AcqirisPeakFinder(self.params_peakfinder_t)
        self.PeakFinderX = AcqirisPeakFinder(self.params_peakfinder_x)
        self.PeakFinderY = AcqirisPeakFinder(self.params_peakfinder_y)



        self.hit_list = []

        self.HitFinder = BasicHitFinder(self.params_hitfinder)
        
        self.num_events_all = 0
        self.mask = np.ones([1024,1024])
        self.mask[350:650, 350:650] = 0
        self.mask[:, :350] = 0        

        self.alg = PyAlgos()        
        self.alg.set_peak_selection_pars(npix_min=self.npix_min, npix_max=self.npix_max, amax_thr=self.amax_thr, atot_thr=self.atot_thr, son_min=self.son_min)        


        if self.role == 'master':
            
            self.collected_data = {}
            self.publish_ip = self.params_gen['publish_ip']
            self.publish_port = self.params_gen['publish_port']
            self.speed_rep_int = self.params_gen['speed_report_interval']

            self.accumulated_shots = self.params_gen['accumulated_shots']
            self.peaks_to_send_string = self.params_gen['peaks_to_send'].split(',')
            self.peaks_to_send = (int(self.peaks_to_send_string[0]),
                                  int(self.peaks_to_send_string[1]))

            print('Starting the monitor...')
            sys.stdout.flush()


            zmq_mon.init_zmq_to_gui(self, self.publish_ip, self.publish_port)
            
            self.num_events = 0
            self.old_time = time.time()

            self.time = None

            self.data_accumulator = []


        if self.role == 'worker':
        
            self.XYw = np.zeros([self.Xbinnum-1, self.Ybinnum-1])
            self.eXYw = np.zeros([self.eXbinnum-1, self.eYbinnum-1])        
            self.eARw = np.zeros([self.eAbinnum-1, self.eRbinnum-1])            
            self.eRw = np.zeros([1, self.eRbinnum-1])            
            self.eAw = np.zeros([1, self.eAbinnum-1])                                                    
            self.Tofw = np.zeros([1, self.Tbinnum-1])                
            self.XTw = np.zeros([self.Tbinnum-1, self.Xbinnum-1])
            self.YTw = np.zeros([self.Tbinnum-1, self.Ybinnum-1])
            self.TSumXw = np.zeros([self.Tbinnum-1,1])
            self.TSumYw = np.zeros([self.Tbinnum-1,1])
        
            self.PiPiCow = np.zeros([self.Tbinnum-2,self.Tbinnum-2])        
                
            
            self.results_dict = {}

            print('Starting worker: {0}.'.format(self.mpi_rank))
            sys.stdout.flush()
        
        return


    def cart2polar_img(self, x, y, intensity):
    
        x1 = x-self.e_center_x
        y1 = y-self.e_center_y
        r = np.sqrt(x1**2 + y1**2)

        angle = np.arctan2(y1, x1)
        return r, angle, intensity*r    
        
    def cart2polar(self, x, y):
    
        x1 = x-self.e_center_x
        y1 = y-self.e_center_y
        r = np.sqrt(x1**2 + y1**2)

        angle = np.arctan2(y1, x1)
        return r, angle         

    def process_data(self):
    
        self.results_dict = {} 
        MCPinds = [] 
        Tofinds = []
        Xinds = []
        Yinds =[]
        eXinds = []
        eYinds = []
        eAinds = []
        eRinds = []
        eXinds_f = []
        eYinds_f = []
        eAinds_f = []
        eRinds_f = []        
        
        pulse_eng_ind = 0
        photon_eng_ind = 0
 

        self.acqiris_data_wf[2:7] = self.acqiris_data_wf[2:7] - np.mean(self.acqiris_data_wf[2:7,self.acqiris_data_wt[6,:]>10000], axis=1)[:,np.newaxis]
        self.acqiris_data_wf[self.t_channel] = -self.acqiris_data_wf[self.t_channel]
        t_peaks = np.array(self.PeakFinderT.cfd(self.acqiris_data_wf[self.t_channel],self.acqiris_data_wt[self.t_channel]))
        x1_peaks = np.array(self.PeakFinderX.cfd(self.acqiris_data_wf[self.x1_channel],self.acqiris_data_wt[self.x1_channel]))
        x2_peaks = np.array(self.PeakFinderX.cfd(self.acqiris_data_wf[self.x2_channel],self.acqiris_data_wt[self.x2_channel]))
        y1_peaks = np.array(self.PeakFinderY.cfd(self.acqiris_data_wf[self.y1_channel],self.acqiris_data_wt[self.y1_channel]))
        y2_peaks = np.array(self.PeakFinderY.cfd(self.acqiris_data_wf[self.y2_channel],self.acqiris_data_wt[self.y2_channel]))
        
        
        e_peaks = self.alg.peak_finder_v4r2(self.eImage, thr_low=self.thr_low, thr_high=self.thr_high, rank=self.rank, r0=self.r0, dr=self.dr)
        
        self.num_events_all += 1
        
        if (0==1) and self.num_events_all == 60:
            self.results_dict['acq'] = (self.acqiris_data_wt, self.acqiris_data_wf)
            self.results_dict['t_peaks'] = t_peaks
            self.results_dict['x1_peaks'] = x1_peaks
            self.results_dict['x2_peaks'] = x2_peaks
            self.results_dict['y1_peaks'] = y1_peaks
            self.results_dict['y2_peaks'] = y2_peaks
        else:
            self.results_dict['acq'] = None



        
        for t_peak in t_peaks:
            MCPinds.append(next((MCP_ind for MCP_ind, MCP_ele in enumerate(self.Taxis) if MCP_ele > t_peak),0))
     
        ion_hits = self.HitFinder.FindHits(t_peaks, x1_peaks, x2_peaks, y1_peaks, y2_peaks)
        
        if (0==1):
            self.results_dict['ion_hits'] = ion_hits
        
        eXs = e_peaks[:,1].astype(int)
        eYs = e_peaks[:,2].astype(int)
        eRadius, eAngle =self.cart2polar(eXs, eYs)
        
        
        
        
        
        for ion_hit in ion_hits:
            Tofinds.append(next((Tof_ind for Tof_ind, Tof_ele in enumerate(self.Taxis) if Tof_ele > ion_hit[0]),0))
            Xinds.append(next((X_ind for X_ind, X_ele in enumerate(self.Xaxis) if X_ele > ion_hit[1]),0))
            Yinds.append(next((Y_ind for Y_ind, Y_ele in enumerate(self.Yaxis) if Y_ele > ion_hit[2]),0))
            
            
        for e_ind in range(len(eXs)):

            tempRind = next((eR_ind for eR_ind, eR_ele in enumerate(self.eRaxis) if eR_ele > eRadius[e_ind]),0)
            tempAind = next((eA_ind for eA_ind, eA_ele in enumerate(self.eAaxis) if eA_ele > eAngle[e_ind]),0)
            tempXind = next((eX_ind for eX_ind, eX_ele in enumerate(self.eXaxis) if eX_ele > eXs[e_ind]),0)
            tempYind = next((eY_ind for eY_ind, eY_ele in enumerate(self.eYaxis) if eY_ele > eYs[e_ind]),0)
            eRinds.append(tempRind)
            eAinds.append(tempAind)
            eXinds.append(tempXind)
            eYinds.append(tempYind)            
            
            if not (eRadius[e_ind] > 172.2 and eRadius[e_ind] < 361 and eAngle[e_ind] > -2.5 and eAngle[e_ind] < -0.8):         
                if eRadius[e_ind] > 100:
                    eRinds_f.append(tempRind)
                    eAinds_f.append(tempAind)
                    eXinds_f.append(tempXind)
                    eYinds_f.append(tempYind)    
                      
            

        pulse_eng_ind = next((pls_eng_ind for pls_eng_ind, pls_eng_ele in enumerate(self.pulse_eng_axis) if pls_eng_ele > self.pulse_eng),0)
        photon_eng_ind = next((pho_eng_ind for pho_eng_ind, pho_eng_ele in enumerate(self.photon_eng_axis) if pho_eng_ele > self.photon_eng),0)        
        self.results_dict['t_peaks'] = MCPinds
        self.results_dict['ion'] = {'Xinds': Xinds, 'Yinds': Yinds, 'Tofinds': Tofinds}
        self.results_dict['e'] = {'eXinds': eXinds, 'eYinds': eYinds, 'eRinds': eRinds, 'eAinds': eAinds, 'eXinds_f': eXinds_f, 'eYinds_f': eYinds_f, 'eRinds_f': eRinds_f, 'eAinds_f': eAinds_f}
        
        self.results_dict['beam'] = {'pulse_eng_ind': pulse_eng_ind, 'photon_eng_ind': photon_eng_ind}
        
   
        
        
        return self.results_dict, self.mpi_rank

    def collect_data_offline(self, new):
    
                                                                                                                                                                       

        self.collected_data = {}

        self.collected_data, _ = new         
                
        if len(self.collected_data['ion']['Xinds']) > 0 and len(self.collected_data['e']['Xinds']) > 0 and len(self.collected_data['beam']['pulse_eng_ind']) > 0 and len(self.collected_data['beam']['photon_eng_ind']) > 0:
            




        self.num_events += 1

        if self.num_events % self.speed_rep_int == 0:
            self.time = time.time()
            print('Processed: {0} in {1:.2f} seconds ({2:.2f} Hz)'.format(
                self.num_events,
                self.time - self.old_time,
                float(self.speed_rep_int)/float(self.time-self.old_time)))
            sys.stdout.flush()
            self.old_time = self.time

        if self.num_events == self.output_params['max_events'] :

            
            self.shutdown(msg='maximum number of events reached.')

        return
        
        

    def collect_data(self, new):
    
                                                                                                                                                                       

        self.collected_data = {}

        self.collected_data, _ = new
        
 
        
        
        if len(self.collected_data['ion']['Xinds']) > 0 and len(self.collected_data['e']['Xinds']) > 0 and len(self.collected_data['beam']['pulse_eng_ind']) > 0 and len(self.collected_data['beam']['photon_eng_ind']) > 0:
            
            self.zmq_publish.send(b'coin_data', zmq.SNDMORE)
            self.zmq_publish.send_pyobj(self.collected_data)


        self.num_events += 1

        if self.num_events % self.speed_rep_int == 0:
            self.time = time.time()
            print('Processed: {0} in {1:.2f} seconds ({2:.2f} Hz)'.format(
                self.num_events,
                self.time - self.old_time,
                float(self.speed_rep_int)/float(self.time-self.old_time)))
            sys.stdout.flush()
            self.old_time = self.time

        if self.num_events == self.output_params['max_events'] :


            
            self.shutdown(msg='maximum number of events reached.')

        return
示例#10
0
import psana

ds = psana.DataSource('exp=xpptut15:run=54:smd')
det = psana.Detector('cspad')

from ImgAlgos.PyAlgos import PyAlgos
alg = PyAlgos()
alg.set_peak_selection_pars(npix_min=2, npix_max=50, amax_thr=10, atot_thr=20, son_min=5)
 
hdr = '\nSeg  Row  Col  Npix    Amptot'
fmt = '%3d %4d %4d  %4d  %8.1f'
 
for nevent,evt in enumerate(ds.events()):
    if nevent>=2 : break
    nda = det.calib(evt)
    if nda is None: continue

    peaks = alg.peak_finder_v1(nda, thr_low=5, thr_high=21, radius=5, dr=0.05)

    print hdr
    for peak in peaks :
        seg,row,col,npix,amax,atot = peak[0:6]
        print fmt % (seg, row, col, npix, atot)
示例#11
0
class PeakFinder:
    def __init__(self,exp,run,detname,evt,detector,algorithm,hitParam_alg_npix_min,hitParam_alg_npix_max,
                 hitParam_alg_amax_thr,hitParam_alg_atot_thr,hitParam_alg_son_min,
                 streakMask_on,streakMask_sigma,streakMask_width,userMask_path,psanaMask_on,psanaMask_calib,
                 psanaMask_status,psanaMask_edges,psanaMask_central,psanaMask_unbond,psanaMask_unbondnrs,
                 medianFilterOn=0, medianRank=5, radialFilterOn=0, distance=0.0, windows=None, **kwargs):
        self.exp = exp
        self.run = run
        self.detname = detname
        self.det = detector
        self.algorithm = algorithm
        self.maxRes = 0

        self.npix_min=hitParam_alg_npix_min
        self.npix_max=hitParam_alg_npix_max
        self.amax_thr=hitParam_alg_amax_thr
        self.atot_thr=hitParam_alg_atot_thr
        self.son_min=hitParam_alg_son_min

        self.streakMask_on = str2bool(streakMask_on)
        self.streakMask_sigma = streakMask_sigma
        self.streakMask_width = streakMask_width
        self.userMask_path = userMask_path
        self.psanaMask_on = str2bool(psanaMask_on)
        self.psanaMask_calib = str2bool(psanaMask_calib)
        self.psanaMask_status = str2bool(psanaMask_status)
        self.psanaMask_edges = str2bool(psanaMask_edges)
        self.psanaMask_central = str2bool(psanaMask_central)
        self.psanaMask_unbond = str2bool(psanaMask_unbond)
        self.psanaMask_unbondnrs = str2bool(psanaMask_unbondnrs)

        self.medianFilterOn = medianFilterOn
        self.medianRank = medianRank
        self.radialFilterOn = radialFilterOn
        self.distance = distance

        self.windows = windows

        self.userMask = None
        self.psanaMask = None
        self.streakMask = None
        self.userPsanaMask = None
        self.combinedMask = None

        # Make user mask
        if self.userMask_path is not None:
            self.userMask = np.load(self.userMask_path)

        # Make psana mask
        if self.psanaMask_on:
            self.psanaMask = detector.mask(evt, calib=self.psanaMask_calib, status=self.psanaMask_status,
                                           edges=self.psanaMask_edges, central=self.psanaMask_central,
                                           unbond=self.psanaMask_unbond, unbondnbrs=self.psanaMask_unbondnrs)

        # Combine userMask and psanaMask
        self.userPsanaMask = np.ones_like(self.det.calib(evt))
        if self.userMask is not None:
            self.userPsanaMask *= self.userMask
        if self.psanaMask is not None:
            self.userPsanaMask *= self.psanaMask

        # Powder of hits and misses
        self.powderHits = np.zeros_like(self.userPsanaMask)
        self.powderMisses = np.zeros_like(self.userPsanaMask)

        self.alg = PyAlgos(windows=self.windows, mask=self.userPsanaMask, pbits=0)
        # set peak-selector parameters:
        self.alg.set_peak_selection_pars(npix_min=self.npix_min, npix_max=self.npix_max, \
                                        amax_thr=self.amax_thr, atot_thr=self.atot_thr, \
                                        son_min=self.son_min)
        # set algorithm specific parameters
        if algorithm == 1:
            self.hitParam_alg1_thr_low = kwargs["alg1_thr_low"]
            self.hitParam_alg1_thr_high = kwargs["alg1_thr_high"]
            self.hitParam_alg1_rank = int(kwargs["alg1_rank"])
            self.hitParam_alg1_radius = int(kwargs["alg1_radius"])
            self.hitParam_alg1_dr = kwargs["alg1_dr"]
        elif algorithm == 3:
            self.hitParam_alg3_rank = kwargs["alg3_rank"]
            self.hitParam_alg3_r0 = int(kwargs["alg3_r0"])
            self.hitParam_alg3_dr = kwargs["alg3_dr"]
        elif algorithm == 4:
            self.hitParam_alg4_thr_low = kwargs["alg4_thr_low"]
            self.hitParam_alg4_thr_high = kwargs["alg4_thr_high"]
            self.hitParam_alg4_rank = int(kwargs["alg4_rank"])
            self.hitParam_alg4_r0 = int(kwargs["alg4_r0"])
            self.hitParam_alg4_dr = kwargs["alg4_dr"]

        self.maxNumPeaks = 2048
        self.StreakMask = myskbeam.StreakMask(self.det, evt, width=self.streakMask_width, sigma=self.streakMask_sigma)
        self.cx, self.cy = self.det.point_indexes(evt, pxy_um=(0, 0))
        self.iX = np.array(self.det.indexes_x(evt), dtype=np.int64)
        self.iY = np.array(self.det.indexes_y(evt), dtype=np.int64)
        if len(self.iX.shape) == 2:
            self.iX = np.expand_dims(self.iX, axis=0)
            self.iY = np.expand_dims(self.iY, axis=0)

        # Initialize radial background subtraction
        self.setupExperiment()
        if self.radialFilterOn:
            self.setupRadialBackground()
            self.updatePolarizationFactor()

    def setupExperiment(self):
        self.ds = psana.DataSource('exp=' + str(self.exp) + ':run=' + str(self.run) + ':idx')
        self.run = self.ds.runs().next()
        self.times = self.run.times()
        self.eventTotal = len(self.times)
        self.env = self.ds.env()
        self.evt = self.run.event(self.times[0])
        self.det = psana.Detector(str(self.detname), self.env)
        self.det.do_reshape_2d_to_3d(flag=True)

    def setupRadialBackground(self):
        self.geo = self.det.geometry(self.run)  # self.geo = GeometryAccess(self.parent.geom.calibPath+'/'+self.parent.geom.calibFile)
        self.xarr, self.yarr, self.zarr = self.geo.get_pixel_coords()
        self.ix = self.det.indexes_x(self.evt)
        self.iy = self.det.indexes_y(self.evt)
        if self.ix is None:
            self.iy = np.tile(np.arange(self.userMask.shape[1]), [self.userMask.shape[2], 1])
            self.ix = np.transpose(self.iy)
        self.iX = np.array(self.ix, dtype=np.int64)
        self.iY = np.array(self.iy, dtype=np.int64)
        if len(self.iX.shape) == 2:
            self.iX = np.expand_dims(self.iX, axis=0)
            self.iY = np.expand_dims(self.iY, axis=0)
        self.mask = self.geo.get_pixel_mask( mbits=0377)  # mask for 2x1 edges, two central columns, and unbound pixels with their neighbours
        self.rb = RadialBkgd(self.xarr, self.yarr, mask=self.mask, radedges=None, nradbins=100,
                             phiedges=(0, 360), nphibins=1)

    def updatePolarizationFactor(self):
        self.pf = polarization_factor(self.rb.pixel_rad(), self.rb.pixel_phi(), self.distance * 1e6)  # convert to um

    def findPeaks(self, calib, evt):

        if self.streakMask_on: # make new streak mask
            self.streakMask = self.StreakMask.getStreakMaskCalib(evt)

        # Apply background correction
        if self.medianFilterOn:
            calib -= median_filter_ndarr(calib, self.medianRank)

        if self.radialFilterOn:
            self.pf.shape = calib.shape  # FIXME: shape is 1d
            calib = self.rb.subtract_bkgd(calib * self.pf)
            calib.shape = self.userPsanaMask.shape  # FIXME: shape is 1d

        if self.streakMask is not None:
            self.combinedMask = self.userPsanaMask * self.streakMask
        else:
            self.combinedMask = self.userPsanaMask
        # set new mask
        #self.alg = PyAlgos(windows=self.windows, mask=self.combinedMask, pbits=0)
        # set peak-selector parameters:
        #self.alg.set_peak_selection_pars(npix_min=self.npix_min, npix_max=self.npix_max, \
        #                                amax_thr=self.amax_thr, atot_thr=self.atot_thr, \
        #                                son_min=self.son_min)
        self.alg.set_mask(self.combinedMask) # This doesn't work reliably
        # set algorithm specific parameters
        if self.algorithm == 1:
            # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region
            #                           around pixel with maximal intensity.
            self.peaks = self.alg.peak_finder_v4r2(calib,
                                                   thr_low=self.hitParam_alg1_thr_low,
                                                   thr_high=self.hitParam_alg1_thr_high,
                                                   rank=self.hitParam_alg1_rank,
                                                   r0=self.hitParam_alg1_radius,
                                                   dr=self.hitParam_alg1_dr)
        elif self.algorithm == 3:
            self.peaks = self.alg.peak_finder_v3(calib, rank=self.hitParam_alg3_rank, r0=self.hitParam_alg3_r0, dr=self.hitParam_alg3_dr)
        elif self.algorithm == 4:
            # v4 - aka iDroplet Finder - two-threshold peak-finding algorithm in restricted region
            #                            around pixel with maximal intensity.
            self.peaks = self.alg.peak_finder_v4(calib, thr_low=self.hitParam_alg4_thr_low, thr_high=self.hitParam_alg4_thr_high, \
                                   rank=self.hitParam_alg4_rank, r0=self.hitParam_alg4_r0, dr=self.hitParam_alg4_dr)
        self.numPeaksFound = self.peaks.shape[0]

        if self.numPeaksFound > 0:
            cenX = self.iX[np.array(self.peaks[:, 0], dtype=np.int64), np.array(self.peaks[:, 1], dtype=np.int64), np.array(
                self.peaks[:, 2], dtype=np.int64)] + 0.5
            cenY = self.iY[np.array(self.peaks[:, 0], dtype=np.int64), np.array(self.peaks[:, 1], dtype=np.int64), np.array(
                self.peaks[:, 2], dtype=np.int64)] + 0.5
            self.maxRes = getMaxRes(cenX, cenY, self.cx, self.cy)
        else:
            self.maxRes = 0

        if self.numPeaksFound >= 15:
            self.powderHits = np.maximum(self.powderHits, calib)
        else:
            self.powderMisses = np.maximum(self.powderMisses, calib)
from psana import *
import numpy as np
from ImgAlgos.PyAlgos import PyAlgos
from skbeam.core.accumulators.histogram import Histogram

dsource = MPIDataSource('exp=sxr07416:run=28:smd')
det = Detector('OPAL1')

alg = PyAlgos()
alg.set_peak_selection_pars(npix_min=9,
                            npix_max=100,
                            amax_thr=40,
                            atot_thr=300,
                            son_min=0)

hist_row = Histogram((1024, 0., 1024.))
hist_col = Histogram((1024, 0., 1024.))
hist_amp = Histogram((1024, 0., 3000.))

smldata = dsource.small_data('run28.h5', gather_interval=100)

peakrow = np.zeros((10), dtype=int)
peakcol = np.zeros((10), dtype=int)
peakamp = np.zeros((10), dtype=float)
for nevt, evt in enumerate(dsource.events()):

    calib = det.calib(evt)
    if calib is None: continue
    peaks = alg.peak_finder_v1(calib,
                               thr_low=40,
                               thr_high=40,