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 setupRadialBackground(self): self.findPsanaGeometry() if self.calibFile is not None: self.geo = GeometryAccess(self.calibPath+'/'+self.calibFile) self.xarr, self.yarr, self.zarr = self.geo.get_pixel_coords() self.iX, self.iY = self.geo.get_pixel_coord_indexes() 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) else: self.rb = None
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)
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)
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, generousMask=0, 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.generousMaskOn = generousMask 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 self.generousMask = None # Make user mask if self.userMask_path is not None: self.userMask = np.load(self.userMask_path) if facility == 'LCLS': # 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) if self.generousMaskOn: self.psanaMask = self.generousBadPixel(self.psanaMask) # Combine userMask and psanaMask self.userPsanaMask = np.ones_like(self.det.calib(evt), dtype=np.int16) if self.userMask is not None: self.userPsanaMask *= self.userMask if self.psanaMask is not None: self.userPsanaMask *= self.psanaMask elif facility == 'PAL': self.userPsanaMask = self.userMask # Powder of hits and misses self.powderHits = None self.powderMisses = None # 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 == 2: 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"] if facility == 'LCLS': self.access = kwargs["access"] if self.algorithm == 1: self.alg = PyAlgos(mask=None, pbits=0) self.peakRadius = int(self.hitParam_alg1_radius) 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 = myskbeam.DropletA(self.peakRadius, self.peakRadius+self.hitParam_alg1_dr) #PyAlgos(windows=self.windows, mask=None, pbits=0) elif self.algorithm == 2: # set peak-selector parameters: self.alg = PyAlgos(mask=None, pbits=0) self.peakRadius = int(self.hitParam_alg1_radius) 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) elif facility == 'PAL': self.peakRadius = int(self.hitParam_alg1_radius) self.alg = myskbeam.DropletA(self.peakRadius, self.hitParam_alg1_dr) if facility == 'LCLS': 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() elif facility == 'PAL': self.geom = kwargs["geom"] with open(self.geom, 'r') as f: lines = f.readlines() for i, line in enumerate(lines): if 'p0/max_ss' in line: dim0 = int(line.split('=')[-1]) + 1 elif 'p0/max_fs' in line: dim1 = int(line.split('=')[-1]) + 1 elif 'p0/corner_x' in line: self.cy = -1 * float(line.split('=')[-1]) elif 'p0/corner_y' in line: self.cx = float(line.split('=')[-1]) 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) def generousBadPixel(self, unassemMask, n=10): generousBadPixelMask = unassemMask (numAsic, numFs, numSs) = unassemMask.shape for i in range(numAsic): for a in range(numSs): numBadPixels = len(np.where(unassemMask[i, :, a] == 0)[0]) if numBadPixels >= n: generousBadPixelMask[i, :, a] = 0 return generousBadPixelMask def setupExperiment(self): access = 'exp=' + str(self.exp) + ':run=' + str(self.run) + ':idx' if 'ffb' in self.access.lower(): access += ':dir=/reg/d/ffb/' + self.exp[:3] + '/' + self.exp + '/xtc' self.ds = psana.DataSource(access) 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, thr_high=None, thr_low=None): if facility == 'LCLS': 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.set_mask(self.combinedMask) # This doesn't work reliably elif facility == 'PAL': self.combinedMask = self.userMask # set algorithm specific parameters if self.algorithm == 1: if facility == 'LCLS': #print "param: ", self.npix_min, self.npix_max, self.atot_thr, self.son_min, thr_low, thr_high, np.sum(self.combinedMask) # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region # around pixel with maximal intensity. if thr_high is None: # use gui input self.peakRadius = int(self.hitParam_alg1_radius) self.peaks = self.alg.peak_finder_v4r3( 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, mask=self.combinedMask.astype(np.uint16)) # 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) else: self.peaks = self.alg.findPeaks(calib, npix_min=self.npix_min, npix_max=self.npix_max, atot_thr=self.atot_thr, son_min=self.son_min, thr_low=thr_low, thr_high=thr_high, mask=self.combinedMask) # self.peaks = self.alg.peak_finder_v4r2(calib, # thr_low=thr_low, # thr_high=thr_high, # rank=self.hitParam_alg1_rank, # r0=self.hitParam_alg1_radius, # dr=self.hitParam_alg1_dr) elif facility == 'PAL': self.peakRadius = int(self.hitParam_alg1_radius) _calib = np.zeros((1, calib.shape[0], calib.shape[1])) _calib[0, :, :] = calib if self.combinedMask is None: _mask = None else: _mask = self.combinedMask.astype(np.uint16) self.peaks = self.alg.findPeaks( _calib, npix_min=self.npix_min, npix_max=self.npix_max, son_min=self.son_min, thr_low=self.hitParam_alg1_thr_low, thr_high=self.hitParam_alg1_thr_high, atot_thr=self.atot_thr, r0=self.peakRadius, dr=int(self.hitParam_alg1_dr), mask=_mask) elif self.algorithm == 2: if facility == 'LCLS': #print "param: ", self.npix_min, self.npix_max, self.atot_thr, self.son_min, thr_low, thr_high, np.sum(self.combinedMask) # 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_v3r3( calib, rank=int(self.hitParam_alg1_rank), r0=self.peakRadius, dr=self.hitParam_alg1_dr, nsigm=self.son_min, mask=self.combinedMask.astype(np.uint16)) 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: if facility == 'LCLS': 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 elif facility == 'PAL': cenX = self.iX[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[:, 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: if self.powderHits is None: self.powderHits = calib else: self.powderHits = np.maximum(self.powderHits, calib) else: if self.powderMisses is None: self.powderMisses = calib else: self.powderMisses = np.maximum(self.powderMisses, calib) if self.powderHits is None: self.powderHits = np.zeros_like(calib) if self.powderMisses is None: self.powderMisses = np.zeros_like(calib)
class ImageViewer(object): def __init__(self, parent=None): self.parent = parent self.maxPercentile = 0 self.minPercentile = 0 self.displayMaxPercentile = 99.0 self.displayMinPercentile = 1.0 self.rb = None ## Dock 1: Image Panel self.d1 = Dock("Image Panel", size=(500, 400)) self.w1 = pg.ImageView(view=pg.PlotItem()) self.w1.getView().invertY(False) self.img_feature = pg.ImageItem() self.w1.getView().addItem(self.img_feature) self.ring_feature = pg.ScatterPlotItem() self.centre_feature = pg.ScatterPlotItem() self.peak_feature = pg.ScatterPlotItem() self.indexedPeak_feature = pg.ScatterPlotItem() self.z_direction = pg.ScatterPlotItem() self.z_direction1 = pg.ScatterPlotItem() self.w1.getView().addItem(self.ring_feature) self.w1.getView().addItem(self.centre_feature) self.w1.getView().addItem(self.peak_feature) self.w1.getView().addItem(self.indexedPeak_feature) self.w1.getView().addItem(self.z_direction) self.w1.getView().addItem(self.z_direction1) self.abc_text = pg.TextItem(html='', anchor=(0, 0)) # unit cell display self.w1.getView().addItem(self.abc_text) self.peak_text = pg.TextItem(html='', anchor=(0, 0)) # peak display self.w1.getView().addItem(self.peak_text) # # Isocurve drawing # self.iso = pg.IsocurveItem(level=0.8, pen='r') # self.iso.setParentItem(self.img_feature) # self.iso.setZValue(2) # # Contrast/color control # self.hist = pg.HistogramLUTItem() # self.hist.setImageItem(self.img_feature) # self.w1.getView().addItem(self.hist) # # Draggable line for setting isocurve level # self.isoLine = pg.InfiniteLine(angle=0, movable=True, pen='g') # self.hist.vb.addItem(self.isoLine) # self.hist.vb.setMouseEnabled(y=False) # makes user interaction a little easier # self.isoLine.setValue(1.8) # self.isoLine.setZValue(1000) # bring iso line above contrast controls self.d1.addWidget(self.w1) self.drawLabCoordinates( ) # FIXME: This does not match the lab coordinates yet! def clearPeakMessage(self): self.w1.getView().removeItem(self.peak_text) self.peak_feature.setData([], [], pxMode=False) if self.parent.args.v >= 1: print "Done clearPeakMessage" def drawLabCoordinates(self): (cenX, cenY) = (-20, -20) # no offset # Draw xy arrows symbolSize = 40 cutoff = symbolSize / 2 headLen = 30 tailLen = 30 - cutoff xArrow = pg.ArrowItem(angle=180, tipAngle=30, baseAngle=20, headLen=headLen, tailLen=tailLen, tailWidth=8, pen=None, brush='b', pxMode=False) xArrow.setPos(2 * headLen + cenX, 0 + cenY) self.w1.getView().addItem(xArrow) yArrow = pg.ArrowItem(angle=-90, tipAngle=30, baseAngle=20, headLen=headLen, tailLen=tailLen, tailWidth=8, pen=None, brush='r', pxMode=False) yArrow.setPos(0 + cenX, 2 * headLen + cenY) self.w1.getView().addItem(yArrow) # Lab coordinates: Add z-direction self.z_direction.setData([0+cenX], [0+cenY], symbol='o', \ size=symbolSize, brush='w', \ pen={'color': 'k', 'width': 4}, pxMode=False) self.z_direction1.setData([0+cenX], [0+cenY], symbol='o', \ size=symbolSize/6, brush='k', \ pen={'color': 'k', 'width': 4}, pxMode=False) # Lab coordinates: Add xyz text self.x_text = pg.TextItem( html= '<div style="text-align: center"><span style="color: #0000FF; font-size: 16pt;">x</span></div>', anchor=(0, 0)) self.w1.getView().addItem(self.x_text) self.x_text.setPos(2 * headLen + cenX, 0 + cenY) self.y_text = pg.TextItem( html= '<div style="text-align: center"><span style="color: #FF0000; font-size: 16pt;">y</span></div>', anchor=(1, 1)) self.w1.getView().addItem(self.y_text) self.y_text.setPos(0 + cenX, 2 * headLen + cenY) self.z_text = pg.TextItem( html= '<div style="text-align: center"><span style="color: #FFFFFF; font-size: 16pt;">z</span></div>', anchor=(1, 0)) self.w1.getView().addItem(self.z_text) self.z_text.setPos(-headLen + cenX, 0 + cenY) # Label xy axes self.x_axis = self.w1.getView().getAxis('bottom') self.x_axis.setLabel('X-axis (pixels)') self.y_axis = self.w1.getView().getAxis('left') self.y_axis.setLabel('Y-axis (pixels)') def updateImage(self, calib=None): if self.parent.hasExperimentName and self.parent.hasRunNumber and self.parent.hasDetInfo: if calib is None: self.parent.calib, self.parent.data = self.getDetImage( self.parent.eventNumber) else: _, self.parent.data = self.getDetImage(self.parent.eventNumber, calib=calib) if self.parent.firstUpdate: if self.parent.exp.logscaleOn: self.w1.setImage( np.log10(abs(self.parent.data) + self.parent.eps)) self.parent.firstUpdate = False else: self.minPercentile = np.percentile( self.parent.data, self.displayMinPercentile) if self.minPercentile < 0: self.minPercentile = 0 self.maxPercentile = np.percentile( self.parent.data, self.displayMaxPercentile) self.w1.setImage(self.parent.data, levels=(self.minPercentile, self.maxPercentile)) self.parent.firstUpdate = False else: if self.parent.exp.logscaleOn: self.w1.setImage( np.log10(abs(self.parent.data) + self.parent.eps), autoRange=False, autoLevels=False, autoHistogramRange=False) else: if self.minPercentile == 0 and self.maxPercentile == 0: self.minPercentile = np.percentile( self.parent.data, self.displayMinPercentile) if self.minPercentile < 0: self.minPercentile = 0 self.maxPercentile = np.percentile( self.parent.data, self.displayMaxPercentile) self.w1.setImage(self.parent.data, levels=(self.minPercentile, self.maxPercentile)) else: self.w1.setImage(self.parent.data, autoRange=False, autoLevels=False, autoHistogramRange=False) try: fname = "/reg/d/psdm/cxi/cxitut13/res/psocake/log/" + \ self.parent.exp.username + "_" + self.parent.experimentName + "_" \ + str(self.parent.runNumber) + "_" + self.parent.detInfo + ".txt" with open(fname, "a") as myfile: date = datetime.datetime.today().strftime( '%Y-%m-%d-%H-%M-%S') myStr = date + ": " + str(self.parent.eventNumber) + '\n' myfile.write(myStr) except: pass # Load peak parameters if exists if 'sfx' in self.parent.args.mode and self.parent.pk.userUpdate is None: self.parent.pk.updateParam() if self.parent.args.v >= 1: print "Done updateImage" def getCalib(self, evtNumber): if self.parent.exp.run is not None: self.parent.evt = self.parent.exp.getEvt(evtNumber) if self.parent.exp.applyCommonMode: # play with different common mode if self.parent.exp.commonMode[0] == 5: # Algorithm 5 calib = self.parent.det.calib( self.parent.evt, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1])) else: # Algorithms 1 to 4 print "### Overriding common mode: ", self.parent.exp.commonMode calib = self.parent.det.calib( self.parent.evt, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1], self.parent.exp.commonMode[2], self.parent.exp.commonMode[3])) else: calib = self.parent.det.calib(self.parent.evt) return calib else: return None def getCommonModeCorrected(self, evtNumber): if self.parent.exp.run is not None: try: self.parent.evt = self.parent.exp.getEvt(evtNumber) pedestalCorrected = self.parent.det.raw( self.parent.evt) - self.parent.det.pedestals( self.parent.evt) if self.parent.exp.applyCommonMode: # play with different common mode if self.parent.exp.commonMode[0] == 5: # Algorithm 5 commonMode = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1])) commonModeCorrected = pedestalCorrected - commonMode else: # Algorithms 1 to 4 print "### Overriding common mode: ", self.parent.exp.commonMode commonMode = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1], self.parent.exp.commonMode[2], self.parent.exp.commonMode[3])) commonModeCorrected = pedestalCorrected - commonMode else: commonMode = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected) commonModeCorrected = pedestalCorrected + commonMode # WHAT! You need to ADD common mode?!! return commonModeCorrected except: return None else: return None def getCommonMode(self, evtNumber): if self.parent.exp.run is not None: self.parent.evt = self.parent.exp.getEvt(evtNumber) pedestalCorrected = self.parent.det.raw( self.parent.evt) - self.parent.det.pedestals(self.parent.evt) if self.parent.exp.applyCommonMode: # play with different common mode print "### Overriding common mode: ", self.parent.exp.commonMode if self.parent.exp.commonMode[0] == 5: # Algorithm 5 cm = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1])) else: # Algorithms 1 to 4 cm = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1], self.parent.exp.commonMode[2], self.parent.exp.commonMode[3])) else: cm = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected) return cm else: return None def getAssembledImage(self, arg, calib): if arg == 'lcls': _calib = calib.copy() # this is important tic = time.time() if self.parent.exp.applyFriedel: # Apply Friedel symmetry print "Apply Friedel symmetry" centre = self.parent.det.point_indexes(self.parent.evt, pxy_um=(0, 0)) self.fs = FriedelSym(self.parent.exp.detGuaranteedData.shape, centre) data = self.parent.det.image(self.parent.evt, _calib) if self.parent.mk.combinedMask is not None: data = self.fs.applyFriedel( data, mask=self.parent.det.image( self.parent.evt, self.parent.mk.combinedMask), mode='same') else: data = self.fs.applyFriedel(data, mask=None, mode='same') else: data = self.parent.det.image(self.parent.evt, _calib) if data is None: data = _calib toc = time.time() if self.parent.args.v >= 1: print "time assemble: ", toc - tic return data def setupRadialBackground(self): self.parent.geom.findPsanaGeometry() if self.parent.geom.calibFile is not None: if self.parent.args.v >= 1: print "calibFile: ", self.parent.geom.calibPath + '/' + self.parent.geom.calibFile self.geo = self.parent.det.geometry( self.parent.runNumber ) #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.iY = self.geo.get_pixel_coord_indexes() 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) if self.parent.args.v >= 1: print "Done setupRadialBackground" else: self.rb = None def updatePolarizationFactor(self): if self.rb is not None: self.pf = polarization_factor(self.rb.pixel_rad(), self.rb.pixel_phi(), self.parent.detectorDistance * 1e6) # convert to um if self.parent.args.v >= 1: print "Done updatePolarizationFactor" def updateDetectorCentre(self, arg): if arg == 'lcls': self.parent.cx, self.parent.cy = self.parent.det.point_indexes( self.parent.evt, pxy_um=(0, 0)) if self.parent.cx is None: data = self.parent.det.image(self.parent.evt, self.parent.exp.detGuaranteed) self.parent.cx, self.parent.cy = self.getCentre(data.shape) if self.parent.args.v >= 1: print "cx, cy: ", self.parent.cx, self.parent.cy def getDetImage(self, evtNumber, calib=None): if calib is None: if self.parent.exp.image_property == self.parent.exp.disp_medianCorrection: # median subtraction calib = self.getCalib(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') calib -= median_filter_ndarr(calib, self.parent.exp.medianFilterRank) elif self.parent.exp.image_property == self.parent.exp.disp_radialCorrection: # radial subtraction + polarization corrected calib = self.getCalib(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') self.pf.shape = calib.shape # FIXME: shape is 1d calib = self.rb.subtract_bkgd(calib * self.pf) calib.shape = self.parent.calib.shape # FIXME: shape is 1d elif self.parent.exp.image_property == self.parent.exp.disp_adu: # gain and hybrid gain corrected calib = self.getCalib(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') elif self.parent.exp.image_property == self.parent.exp.disp_commonModeCorrected: # common mode corrected calib = self.getCommonModeCorrected(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') elif self.parent.exp.image_property == self.parent.exp.disp_pedestalCorrected: # pedestal corrected calib = self.parent.det.raw(self.parent.evt).astype('float32') if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') else: calib -= self.parent.det.pedestals(self.parent.evt) elif self.parent.exp.image_property == self.parent.exp.disp_raw: # raw calib = self.parent.det.raw(self.parent.evt) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_photons: # photon counts calib = self.parent.det.photons( self.parent.evt, mask=self.parent.mk.userMask, adu_per_photon=self.parent.exp.aduPerPhoton) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='int32') self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_pedestal: # pedestal calib = self.parent.det.pedestals(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_status: # status calib = self.parent.det.status(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_rms: # rms calib = self.parent.det.rms(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_commonMode: # common mode calib = self.getCommonMode(evtNumber) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_gain: # gain calib = self.parent.det.gain(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_gainMask: # gain_mask calib = self.parent.det.gain_mask(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_coordx: # coords_x calib = self.parent.det.coords_x(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_coordy: # coords_y calib = self.parent.det.coords_y(self.parent.evt) self.parent.firstUpdate = True shape = self.parent.det.shape(self.parent.evt) if len(shape) == 3: if self.parent.exp.image_property == self.parent.exp.disp_quad: # quad ind calib = np.zeros(shape) for i in range(shape[0]): # TODO: handle detectors properly if shape[0] == 32: # cspad calib[i, :, :] = int(i) % 8 elif shape[0] == 2: # cspad2x2 calib[i, :, :] = int(i) % 2 elif shape[0] == 4: # pnccd calib[i, :, :] = int(i) % 4 self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_seg: # seg ind calib = np.zeros(shape) if shape[0] == 32: # cspad for i in range(32): calib[i, :, :] = int(i) / 8 elif shape[0] == 2: # cspad2x2 for i in range(2): calib[i, :, :] = int(i) elif shape[0] == 4: # pnccd for i in range(4): calib[i, :, :] = int(i) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_row: # row ind calib = np.zeros(shape) if shape[0] == 32: # cspad for i in range(185): calib[:, i, :] = i elif shape[0] == 2: # cspad2x2 for i in range(185): calib[:, i, :] = i elif shape[0] == 4: # pnccd for i in range(512): calib[:, i, :] = i self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_col: # col ind calib = np.zeros(shape) if shape[0] == 32: # cspad for i in range(388): calib[:, :, i] = i elif shape[0] == 2: # cspad2x2 for i in range(388): calib[:, :, i] = i elif shape[0] == 4: # pnccd for i in range(512): calib[:, :, i] = i self.parent.firstUpdate = True # Update photon energy self.parent.exp.updatePhotonEnergy('lcls') # Update clen self.parent.geom.updateClen('lcls') # Write a temporary geom file self.parent.geom.deployCrystfelGeometry('lcls') self.parent.geom.writeCrystfelGeom('lcls') # Hack to override coffset # Get assembled image if calib is not None: data = self.getAssembledImage('lcls', calib) else: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') data = self.getAssembledImage('lcls', calib) # Update detector centre self.updateDetectorCentre('lcls') # Update ROI histogram if self.parent.roi.roiCurrent == 'rect': self.parent.roi.updateRoi(self.parent.roi.roi) elif self.parent.roi.roiCurrent == 'poly': self.parent.roi.updateRoi(self.parent.roi.roiPoly) elif self.parent.roi.roiCurrent == 'circ': self.parent.roi.updateRoi(self.parent.roi.roiCircle) return calib, data def getCentre(self, shape): cx = shape[1] / 2 cy = shape[0] / 2 return cx, cy
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) if facility == 'LCLS': # Make psana mask self.psanaMask = detector.mask(run, 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.psanaMask, dtype=np.int16) if self.userMask is not None: self.userPsanaMask *= self.userMask if self.psanaMask_on: self.userPsanaMask *= self.psanaMask # Powder of hits and misses self.powderHits = None self.powderMisses = None # 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 >= 2: 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"] if facility == 'LCLS': self.access = kwargs["access"] if self.algorithm == 1: self.alg = PyAlgos(mask=None, pbits=0) self.peakRadius = int(self.hitParam_alg1_radius) 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) elif self.algorithm >= 2: self.alg = PyAlgos(mask=None, pbits=0) self.peakRadius = int(self.hitParam_alg1_radius) 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 facility == 'LCLS': 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)) try: self.cy, self.cx = self.det.point_indexes( evt, pxy_um=(0, 0), pix_scale_size_um=None, xy0_off_pix=None, cframe=gu.CFRAME_PSANA, fract=True) except AttributeError: 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): access = 'exp=' + str(self.exp) + ':run=' + str(self.run) + ':idx' if 'ffb' in self.access.lower(): access += ':dir=/reg/d/ffb/' + self.exp[:3] + '/' + self.exp + '/xtc' self.ds = psana.DataSource(access) self.run = next(self.ds.runs()) 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=0o0377 ) # 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): # FIXME: handle vertical/horizontal polarization properly self.pf = polarization_factor(self.rb.pixel_rad(), self.rb.pixel_phi() + 90, self.distance * 1e6) # convert to um def findPeaks(self, calib, evt, minPeaks=15, thr_high=None, thr_low=None): #t0 = time.time() if facility == 'LCLS': 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 self.calib = calib # save background subtracted calib as an attribute if self.streakMask is not None: self.combinedMask = self.userPsanaMask * self.streakMask else: self.combinedMask = self.userPsanaMask #t1 = time.time() # set algorithm specific parameters if self.algorithm == 1: if facility == 'LCLS': # v1 - aka Droplet Finder - two-threshold peak-finding algorithm in restricted region # around pixel with maximal intensity. if thr_high is None: # use gui input self.peakRadius = int(self.hitParam_alg1_radius) self.peaks = self.alg.peak_finder_v4r3( 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, mask=self.combinedMask.astype(np.uint16)) else: self.peaks = self.alg.findPeaks(calib, npix_min=self.npix_min, npix_max=self.npix_max, atot_thr=self.atot_thr, son_min=self.son_min, thr_low=thr_low, thr_high=thr_high, mask=self.combinedMask) elif self.algorithm == 2: if facility == 'LCLS': # Adaptive peak finder v3r3 self.peakRadius = int(self.hitParam_alg1_radius) self.peaks = self.alg.peak_finder_v3r3( calib, rank=int(self.hitParam_alg1_rank), r0=self.peakRadius, dr=self.hitParam_alg1_dr, nsigm=self.son_min, mask=self.combinedMask.astype(np.uint16)) elif self.algorithm == 3: if facility == 'LCLS': # perform binning here binr = 2 binc = 2 downCalib = sm.block_reduce(calib, block_size=(1, binr, binc), func=np.sum) downWeight = sm.block_reduce(self.combinedMask, block_size=(1, binr, binc), func=np.sum) warr = np.zeros_like(downCalib, dtype='float32') ind = np.where(downWeight > 0) warr[ind] = downCalib[ind] / downWeight[ind] upCalib = utils.upsample(warr, calib.shape, binr, binc) self.peakRadius = int(self.hitParam_alg1_radius) self.peaks = self.alg.peak_finder_v3r3( upCalib, rank=int(self.hitParam_alg1_rank), r0=self.peakRadius, dr=self.hitParam_alg1_dr, nsigm=self.son_min, mask=self.combinedMask.astype(np.uint16)) #t2 = time.time() self.numPeaksFound = self.peaks.shape[0] if self.numPeaksFound >= minPeaks: if facility == 'LCLS': 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 #t3 = time.time() if self.numPeaksFound >= minPeaks: if self.powderHits is None: self.powderHits = calib else: self.powderHits = np.maximum(self.powderHits, calib) else: if self.powderMisses is None: self.powderMisses = calib else: self.powderMisses = np.maximum(self.powderMisses, calib) if self.powderHits is None: self.powderHits = np.zeros_like(calib) if self.powderMisses is None: self.powderMisses = np.zeros_like(calib)
class psanaWhisperer(): def __init__(self, experimentName, runNumber, detInfo, clen='', aduPerPhoton=1, localCalib=False): self.experimentName = experimentName self.runNumber = runNumber self.detInfo = detInfo self.clenStr = clen self.aduPerPhoton = aduPerPhoton self.localCalib = localCalib def setupExperiment(self): self.ds = psana.DataSource('exp=' + str(self.experimentName) + ':run=' + str(self.runNumber) + ':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.detInfo), self.env) self.det.do_reshape_2d_to_3d(flag=True) self.getDetInfoList() self.detAlias = self.getDetectorAlias(str(self.detInfo)) self.updateClen() # Get epics variable, clen def updateClen(self): if 'cspad' in self.detInfo.lower() and 'cxi' in self.experimentName: self.epics = self.ds.env().epicsStore() self.clen = self.epics.value(self.clenStr) elif 'rayonix' in self.detInfo.lower( ) and 'mfx' in self.experimentName: self.epics = self.ds.env().epicsStore() self.clen = self.epics.value(self.clenStr) elif 'rayonix' in self.detInfo.lower( ) and 'xpp' in self.experimentName: self.epics = self.ds.env().epicsStore() self.clen = self.epics.value(self.clenStr) def getDetectorAlias(self, srcOrAlias): for i in self.detInfoList: src, alias, _ = i if srcOrAlias.lower() == src.lower() or srcOrAlias.lower( ) == alias.lower(): return alias def getDetInfoList(self): myAreaDetectors = [] self.detnames = psana.DetNames() for k in self.detnames: try: if Detector.PyDetector.dettype(str( k[0]), self.env) == Detector.AreaDetector.AreaDetector: myAreaDetectors.append(k) except ValueError: continue self.detInfoList = list(set(myAreaDetectors)) def getEvent(self, number): self.evt = self.run.event(self.times[number]) def getImg(self, number): self.getEvent(number) img = self.det.image(self.evt, self.det.calib(self.evt)) return img def getImg(self): if self.evt is not None: img = self.det.image(self.evt, self.det.calib(self.evt)) return img return None def getCheetahImg(self, calib=None): """Converts seg, row, col assuming (32,185,388) to cheetah 2-d table row and col (8*185, 4*388) """ if 'cspad2x2' in self.detInfo.lower(): print "Not implemented yet: cspad2x2" elif 'cspad' in self.detInfo.lower(): if calib is None: calib = self.det.calib(self.evt) # (32,185,388) img = np.zeros((8 * 185, 4 * 388)) counter = 0 for quad in range(4): for seg in range(8): img[seg * 185:(seg + 1) * 185, quad * 388:(quad + 1) * 388] = calib[counter, :, :] counter += 1 elif 'rayonix' in self.detInfo.lower(): if calib is None: img = np.squeeze(self.det.calib(self.evt)) # (1920,1920) else: img = np.squeeze(calib) return img def getCleanAssembledImg(self, backgroundEvent): """Returns psana assembled image """ backgroundEvt = self.run.event(self.times[backgroundEvent]) backgroundCalib = self.det.calib(backgroundEvt) calib = self.det.calib(self.evt) cleanCalib = calib - backgroundCalib img = self.det.image(self.evt, cleanCalib) return img def getAssembledImg(self): """Returns psana assembled image """ img = self.det.image(self.evt) return img def getCalibImg(self): """Returns psana assembled image """ img = self.det.calib(self.evt) return img def getCleanAssembledPhotons(self, backgroundEvent): """Returns psana assembled image in photon counts """ backgroundEvt = self.run.event(self.times[backgroundEvent]) backgroundCalib = self.det.calib(backgroundEvt) calib = self.det.calib(self.evt) cleanCalib = calib - backgroundCalib img = self.det.photons(self.evt, nda_calib=cleanCalib, adu_per_photon=self.aduPerPhoton) phot = self.det.image(self.evt, img) return phot def getAssembledPhotons(self): """Returns psana assembled image in photon counts """ img = self.det.photons(self.evt, adu_per_photon=self.aduPerPhoton) phot = self.det.image(self.evt, img) return phot def getPsanaEvent(self, cheetahFilename): # Gets psana event given cheetahFilename, e.g. LCLS_2015_Jul26_r0014_035035_e820.h5 hrsMinSec = cheetahFilename.split('_')[-2] fid = int(cheetahFilename.split('_')[-1].split('.')[0], 16) for t in self.times: if t.fiducial() == fid: localtime = time.strftime('%H:%M:%S', time.localtime(t.seconds())) localtime = localtime.replace(':', '') if localtime[0:3] == hrsMinSec[0:3]: self.evt = self.run.event(t) else: self.evt = None def getStartTime(self): self.evt = self.run.event(self.times[0]) evtId = self.evt.get(psana.EventId) sec = evtId.time()[0] nsec = evtId.time()[1] fid = evtId.fiducials() return time.strftime('%FT%H:%M:%S-0800', time.localtime(sec)) # Hard-coded pacific time ##################################################################### # TODO: Functions below are not being used yet ##################################################################### def findPsanaGeometry(self): try: self.source = psana.Detector.PyDetector.map_alias_to_source( self.detInfo, self.ds.env()) # 'DetInfo(CxiDs2.0:Cspad.0)' self.calibSource = self.source.split('(')[-1].split(')')[ 0] # 'CxiDs2.0:Cspad.0' self.detectorType = gu.det_type_from_source(self.source) # 1 self.calibGroup = gu.dic_det_type_to_calib_group[ self.detectorType] # 'CsPad::CalibV1' self.detectorName = gu.dic_det_type_to_name[ self.detectorType].upper() # 'CSPAD' if self.localCalib: self.calibPath = "./calib/" + self.calibGroup + "/" + self.calibSource + "/geometry" else: self.calibPath = "/reg/d/psdm/" + self.parent.experimentName[0:3] + \ "/" + self.parent.experimentName + "/calib/" + \ self.calibGroup + "/" + self.calibSource + "/geometry" # Determine which calib file to use geometryFiles = os.listdir(self.calibPath) self.calibFile = None minDiff = -1e6 for fname in geometryFiles: if fname.endswith('.data'): endValid = False startNum = int(fname.split('-')[0]) endNum = fname.split('-')[-1].split('.data')[0] diff = startNum - self.parent.runNumber # Make sure it's end number is valid too if 'end' in endNum: endValid = True else: try: if self.parent.runNumber <= int(endNum): endValid = True except: continue if diff <= 0 and diff > minDiff and endValid is True: minDiff = diff self.calibFile = fname except: if self.parent.args.v >= 1: print "Couldn't find psana geometry" self.calibFile = None def setupRadialBackground(self): self.findPsanaGeometry() if self.calibFile is not None: self.geo = GeometryAccess(self.calibPath + '/' + self.calibFile) self.xarr, self.yarr, self.zarr = self.geo.get_pixel_coords() self.iX, self.iY = self.geo.get_pixel_coord_indexes() 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) else: self.rb = None def updatePolarizationFactor(self, detectorDistance_in_m): if self.rb is not None: self.pf = polarization_factor(self.rb.pixel_rad(), self.rb.pixel_phi(), detectorDistance_in_m * 1e6) # convert to um def getCalib(self, evtNumber): if self.run is not None: self.evt = self.getEvent(evtNumber) if self.applyCommonMode: # play with different common mode if self.commonMode[0] == 5: # Algorithm 5 calib = self.det.calib(self.evt, cmpars=(self.commonMode[0], self.commonMode[1])) else: # Algorithms 1 to 4 print "### Overriding common mode: ", self.commonMode calib = self.det.calib( self.evt, cmpars=(self.commonMode[0], self.commonMode[1], self.commonMode[2], self.commonMode[3])) else: calib = self.det.calib(self.evt) return calib else: return None def getPreprocessedImage(self, evtNumber, image_property): disp_medianCorrection = 19 disp_radialCorrection = 18 disp_gainMask = 17 disp_coordy = 16 disp_coordx = 15 disp_col = 14 disp_row = 13 disp_seg = 12 disp_quad = 11 disp_gain = 10 disp_commonMode = 9 disp_rms = 8 disp_status = 7 disp_pedestal = 6 disp_photons = 5 disp_raw = 4 disp_pedestalCorrected = 3 disp_commonModeCorrected = 2 disp_adu = 1 if image_property == disp_medianCorrection: # median subtraction print "Sorry, this feature isn't available yet" elif image_property == disp_radialCorrection: # radial subtraction + polarization corrected self.getEvent(evtNumber) calib = self.getCalib(evtNumber) if calib: self.pf.shape = self.parent.calib.shape calib = self.rb.subtract_bkgd(calib * self.pf) elif image_property == disp_adu: # gain and hybrid gain corrected calib = self.getCalib(evtNumber) elif image_property == disp_commonModeCorrected: # common mode corrected calib = self.getCommonModeCorrected(evtNumber) elif image_property == disp_pedestalCorrected: # pedestal corrected calib = self.det.raw(self.evt).astype('float32') if calib: calib -= self.det.pedestals(self.evt) elif image_property == disp_raw: # raw calib = self.det.raw(self.evt) elif image_property == disp_photons: # photon counts calib = self.det.photons( self.evt, mask=self.parent.mk.userMask, adu_per_photon=self.parent.exp.aduPerPhoton) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='int32') elif image_property == disp_pedestal: # pedestal calib = self.parent.det.pedestals(self.parent.evt) elif image_property == disp_status: # status calib = self.parent.det.status(self.parent.evt) elif image_property == disp_rms: # rms calib = self.parent.det.rms(self.parent.evt) elif image_property == disp_commonMode: # common mode calib = self.getCommonMode(evtNumber) elif image_property == disp_gain: # gain calib = self.parent.det.gain(self.parent.evt) elif image_property == disp_gainMask: # gain_mask calib = self.parent.det.gain_mask(self.parent.evt) elif image_property == disp_coordx: # coords_x calib = self.parent.det.coords_x(self.parent.evt) elif image_property == disp_coordy: # coords_y calib = self.parent.det.coords_y(self.parent.evt) shape = self.parent.det.shape(self.parent.evt) if len(shape) == 3: if image_property == disp_quad: # quad ind calib = np.zeros(shape) for i in range(shape[0]): # FIXME: handle detectors properly if shape[0] == 32: # cspad calib[i, :, :] = int(i) % 8 elif shape[0] == 2: # cspad2x2 calib[i, :, :] = int(i) % 2 elif shape[0] == 4: # pnccd calib[i, :, :] = int(i) % 4 elif image_property == disp_seg: # seg ind calib = np.zeros(shape) if shape[0] == 32: # cspad for i in range(32): calib[i, :, :] = int(i) / 8 elif shape[0] == 2: # cspad2x2 for i in range(2): calib[i, :, :] = int(i) elif shape[0] == 4: # pnccd for i in range(4): calib[i, :, :] = int(i) elif image_property == disp_row: # row ind calib = np.zeros(shape) if shape[0] == 32: # cspad for i in range(185): calib[:, i, :] = i elif shape[0] == 2: # cspad2x2 for i in range(185): calib[:, i, :] = i elif shape[0] == 4: # pnccd for i in range(512): calib[:, i, :] = i elif image_property == disp_col: # col ind calib = np.zeros(shape) if shape[0] == 32: # cspad for i in range(388): calib[:, :, i] = i elif shape[0] == 2: # cspad2x2 for i in range(388): calib[:, :, i] = i elif shape[0] == 4: # pnccd for i in range(512): calib[:, :, i] = i
class ImageViewer(object): def __init__(self, parent=None): self.parent = parent self.maxPercentile = 0 self.minPercentile = 0 self.displayMaxPercentile = 99.8 self.displayMinPercentile = 1.0 self.rb = None pg.setConfigOptions(imageAxisOrder="row-major") ## Dock 2: Image Panel self.dock = Dock("Image Panel", size=(500, 400)) self.win = pg.ImageView(view=pg.PlotItem()) self.win.getView().invertY(True) self.img_feature = pg.ImageItem() # Set color map white -> black #colors = [ # (255, 255, 255), # (0, 0, 0) #] #self.cmap = pg.ColorMap(pos=np.linspace(0.0, 1.0, len(colors)), color=colors) #self.win.setColorMap(self.cmap) self.win.getView().addItem(self.img_feature) self.ring_feature = pg.ScatterPlotItem() self.centre_feature = pg.ScatterPlotItem() self.peak_feature = pg.ScatterPlotItem() self.indexedPeak_feature = pg.ScatterPlotItem() self.filePeak_feature = pg.ScatterPlotItem() self.z_direction = pg.ScatterPlotItem() self.z_direction1 = pg.ScatterPlotItem() self.win.getView().addItem(self.ring_feature) self.win.getView().addItem(self.centre_feature) self.win.getView().addItem(self.peak_feature) self.win.getView().addItem(self.indexedPeak_feature) self.win.getView().addItem(self.filePeak_feature) self.win.getView().addItem(self.z_direction) self.win.getView().addItem(self.z_direction1) self.abc_text = pg.TextItem(html='', anchor=(0, 0)) # unit cell display self.win.getView().addItem(self.abc_text) self.peak_text = pg.TextItem(html='', anchor=(0, 0)) # peak display self.win.getView().addItem(self.peak_text) self.dock.addWidget(self.win) self.drawLabCoordinates() def clearPeakMessage(self): self.win.getView().removeItem(self.peak_text) self.peak_feature.setData([], [], pxMode=False) if self.parent.args.v >= 1: print("Done clearPeakMessage") def clearIndexingMessage(self): self.win.getView().removeItem(self.abc_text) self.indexedPeak_feature.setData([], [], pxMode=False) if self.parent.args.v >= 1: print("Done clearIndexingMessage") def updateIndexingMessage(self, abc_text): self.win.getView().addItem(abc_text) def drawLabCoordinates(self): (cenX, cenY) = (-20, -20) # no offset # Draw xy arrows symbolSize = 40 cutoff = symbolSize / 2 headLen = -30 tailLen = -30 + cutoff xArrow = pg.ArrowItem(angle=180, tipAngle=30, baseAngle=20, headLen=headLen, tailLen=tailLen, tailWidth=8, pen=None, brush='b', pxMode=False) xArrow.setPos(2 * headLen + cenY, 0 + cenX) self.win.getView().addItem(xArrow) yArrow = pg.ArrowItem(angle=-90, tipAngle=30, baseAngle=20, headLen=headLen, tailLen=tailLen, tailWidth=8, pen=None, brush='r', pxMode=False) yArrow.setPos(0 + cenY, 2 * headLen + cenX) self.win.getView().addItem(yArrow) # Lab coordinates: Add z-direction self.z_direction.setData([0+cenY], [0+cenX], symbol='o', \ size=symbolSize, brush='w', \ pen={'color': 'k', 'width': 4}, pxMode=False) self.z_direction1.setData([0+cenY], [0+cenX], symbol='x', \ size=symbolSize, brush='k', \ pen={'color': 'k', 'width': 4}, pxMode=False) # Lab coordinates: Add xyz text self.x_text = pg.TextItem( html= '<div style="text-align: left"><span style="color: #0000FF; font-size: 16pt;">x</span></div>', anchor=(0, 0)) self.win.getView().addItem(self.x_text) self.x_text.setPos(2 * headLen + cenY, 0 + cenX) self.y_text = pg.TextItem( html= '<div style="text-align: left"><span style="color: #FF0000; font-size: 16pt;">y</span></div>', anchor=(1, 1)) self.win.getView().addItem(self.y_text) self.y_text.setPos(0 + cenY, 2 * headLen + cenX) self.z_text = pg.TextItem( html= '<div style="text-align: left"><span style="color: #000000; font-size: 16pt;">z</span></div>', anchor=(1, 0)) self.win.getView().addItem(self.z_text) self.z_text.setPos(-headLen + cenY, 0 + cenX) # Label xy axes self.x_axis = self.win.getView().getAxis('bottom') self.x_axis.setLabel('X-axis (pixels)') self.y_axis = self.win.getView().getAxis('left') self.y_axis.setLabel('Y-axis (pixels)') def updateImage(self, calib=None): if self.parent.hasExperimentName and self.parent.hasRunNumber and self.parent.hasDetInfo: if calib is None: self.parent.calib, self.parent.data = self.getDetImage( self.parent.eventNumber) else: _, self.parent.data = self.getDetImage(self.parent.eventNumber, calib=calib) if self.parent.firstUpdate: if self.parent.exp.logscaleOn: self.win.setImage( np.log10(abs(self.parent.data) + self.parent.eps)) self.win.view.setRange( xRange=[0, self.parent.data.shape[0]], yRange=[0, self.parent.data.shape[1]], padding=0) self.parent.firstUpdate = False else: self.minPercentile = np.percentile( self.parent.data, self.displayMinPercentile) if self.minPercentile < 0: self.minPercentile = 0 self.maxPercentile = np.percentile( self.parent.data, self.displayMaxPercentile) self.win.setImage(self.parent.data, levels=(self.minPercentile, self.maxPercentile)) # properly resize the image to fit on screen self.win.view.setRange( xRange=[0, self.parent.data.shape[0]], yRange=[0, self.parent.data.shape[1]], padding=0) self.parent.firstUpdate = False else: if self.parent.exp.logscaleOn: self.win.setImage( np.log10(abs(self.parent.data) + self.parent.eps), autoRange=False, autoLevels=False, autoHistogramRange=False) else: if self.minPercentile == 0 and self.maxPercentile == 0: self.minPercentile = np.percentile( self.parent.data, self.displayMinPercentile) if self.minPercentile < 0: self.minPercentile = 0 self.maxPercentile = np.percentile( self.parent.data, self.displayMaxPercentile) self.win.setImage(self.parent.data, levels=(self.minPercentile, self.maxPercentile)) else: self.win.setImage(self.parent.data, autoRange=False, autoLevels=False, autoHistogramRange=False) # Load peak parameters if exists if 'sfx' in self.parent.args.mode and self.parent.pk.userUpdate is None: self.parent.pk.updateParam() else: self.parent.mk.displayMask() if 'label' in self.parent.args.mode: self.parent.labeling.updateText() if self.parent.args.v >= 1: print("Done updateImage") def getCalib(self, evtNumber): if self.parent.exp.run is not None: self.parent.evt = self.parent.exp.getEvt(evtNumber) if self.parent.exp.applyCommonMode: # play with different common mode if self.parent.exp.commonMode[0] == 5: # Algorithm 5 calib = self.parent.det.calib( self.parent.evt, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1])) else: # Algorithms 1 to 4 print("### Overriding common mode: ", self.parent.exp.commonMode) calib = self.parent.det.calib( self.parent.evt, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1], self.parent.exp.commonMode[2], self.parent.exp.commonMode[3])) else: if not self.parent.inputImages: calib = self.parent.det.calib(self.parent.evt) else: f = h5py.File(self.parent.inputImages) ind = np.where(f['eventNumber'][()] == evtNumber)[0][0] if len(f['/data/data'].shape) == 3: calib = ipct(self.parent.detInfo, f['data/data'][ind, :, :]) else: calib = f['data/data'][ind, :, :, :] f.close() return calib else: return None def getCommonModeCorrected(self, evtNumber): if self.parent.exp.run is not None: try: self.parent.evt = self.parent.exp.getEvt(evtNumber) pedestalCorrected = self.parent.det.raw( self.parent.evt) - self.parent.det.pedestals( self.parent.evt) if self.parent.exp.applyCommonMode: # play with different common mode if self.parent.exp.commonMode[0] == 5: # Algorithm 5 commonMode = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1])) commonModeCorrected = pedestalCorrected - commonMode else: # Algorithms 1 to 4 print("### Overriding common mode: ", self.parent.exp.commonMode) commonMode = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1], self.parent.exp.commonMode[2], self.parent.exp.commonMode[3])) commonModeCorrected = pedestalCorrected - commonMode else: commonMode = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected) commonModeCorrected = pedestalCorrected + commonMode # WHAT! You need to ADD common mode?!! return commonModeCorrected except: return None else: return None def getCommonMode(self, evtNumber): if self.parent.exp.run is not None: self.parent.evt = self.parent.exp.getEvt(evtNumber) pedestalCorrected = self.parent.det.raw( self.parent.evt) - self.parent.det.pedestals(self.parent.evt) if self.parent.exp.applyCommonMode: # play with different common mode print("### Overriding common mode: ", self.parent.exp.commonMode) if self.parent.exp.commonMode[0] == 5: # Algorithm 5 cm = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1])) else: # Algorithms 1 to 4 cm = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected, cmpars=(self.parent.exp.commonMode[0], self.parent.exp.commonMode[1], self.parent.exp.commonMode[2], self.parent.exp.commonMode[3])) else: cm = self.parent.det.common_mode_correction( self.parent.evt, pedestalCorrected) return cm else: return None def getAssembledImage(self, arg, calib): _calib = calib.copy() # this is important tic = time.time() if self.parent.exp.applyFriedel: # Apply Friedel symmetry print("Apply Friedel symmetry") try: centre = self.parent.det.point_indexes(self.parent.evt, pxy_um=(0, 0), pix_scale_size_um=None, xy0_off_pix=None, cframe=gu.CFRAME_PSANA, fract=True) except AttributeError: centre = self.parent.det.point_indexes(self.parent.evt) self.fs = FriedelSym(self.parent.exp.detGuaranteedData.shape, centre) data = self.parent.det.image(self.parent.evt, _calib) if self.parent.mk.combinedMask is not None: data = self.fs.applyFriedel(data, mask=self.parent.det.image( self.parent.evt, self.parent.mk.combinedMask), mode='same') else: data = self.fs.applyFriedel(data, mask=None, mode='same') else: data = self.parent.det.image(self.parent.evt, _calib) if data is None: data = _calib toc = time.time() if self.parent.args.v >= 1: print("time assemble: ", toc - tic) return data def setupRadialBackground(self): self.parent.geom.findPsanaGeometry() if self.parent.geom.calibFile is not None: if self.parent.args.v >= 1: print( "calibFile: ", self.parent.geom.calibPath + '/' + self.parent.geom.calibFile) self.geo = self.parent.det.geometry( self.parent.runNumber ) #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.iY = self.geo.get_pixel_coord_indexes() self.mask = self.geo.get_pixel_mask(mbits=0o0377) # 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) if self.parent.args.v >= 1: print("Done setupRadialBackground") else: self.rb = None def updatePolarizationFactor( self): # FIXME: change to vertical polarization after July 2020 if self.rb is not None: self.pf = polarization_factor(self.rb.pixel_rad(), self.rb.pixel_phi() + 90, self.parent.detectorDistance * 1e6) # convert to um if self.parent.args.v >= 1: print("Done updatePolarizationFactor") def updateDetectorCentre(self): try: self.parent.cy, self.parent.cx = self.parent.det.point_indexes( self.parent.evt, pxy_um=(0, 0), pix_scale_size_um=None, xy0_off_pix=None, cframe=gu.CFRAME_PSANA, fract=True) except AttributeError: self.parent.cy, self.parent.cx = self.parent.det.point_indexes( self.parent.evt, pxy_um=(0, 0)) if self.parent.cx is None: print("#######################################") print( "WARNING: Unable to get detector center position. Check detector geometry is deployed." ) print("#######################################") data = self.parent.det.image(self.parent.evt, self.parent.exp.detGuaranteed) self.parent.cx, self.parent.cy = self.getCentre(data.shape) if self.parent.args.v >= 1: print("cx, cy: ", self.parent.cx, self.parent.cy) def getDetImage(self, evtNumber, calib=None): if calib is None: if self.parent.exp.image_property == self.parent.exp.disp_medianCorrection: # median subtraction calib = self.getCalib(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') calib -= median_filter_ndarr(calib, self.parent.exp.medianFilterRank) elif self.parent.exp.image_property == self.parent.exp.disp_radialCorrection: # radial subtraction + polarization corrected calib = self.getCalib(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') self.pf.shape = calib.shape # FIXME: shape is 1d calib = self.rb.subtract_bkgd(calib * self.pf) calib.shape = self.parent.calib.shape # FIXME: shape is 1d elif self.parent.exp.image_property == self.parent.exp.disp_adu: # gain and hybrid gain corrected calib = self.getCalib(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') elif self.parent.exp.image_property == self.parent.exp.disp_commonModeCorrected: # common mode corrected calib = self.getCommonModeCorrected(evtNumber) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') elif self.parent.exp.image_property == self.parent.exp.disp_pedestalCorrected: # pedestal corrected calib = self.parent.det.raw(self.parent.evt).astype('float32') if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') else: calib -= self.parent.det.pedestals(self.parent.evt) elif self.parent.exp.image_property == self.parent.exp.disp_raw: # raw calib = self.parent.det.raw(self.parent.evt) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_photons: # photon counts calib = self.parent.det.photons( self.parent.evt, mask=self.parent.mk.userMask, adu_per_photon=self.parent.exp.aduPerPhoton) if calib is None: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='int32') self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_pedestal: # pedestal calib = self.parent.det.pedestals(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_status: # status calib = self.parent.det.status(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_rms: # rms calib = self.parent.det.rms(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_commonMode: # common mode calib = self.getCommonMode(evtNumber) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_gain: # gain calib = self.parent.det.gain(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_gainMask: # gain_mask calib = self.parent.det.gain_mask(self.parent.evt) self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_coordx: # coords_x try: calib = self.parent.det.coords_x(self.parent.evt, cframe=1) # lab coords except: calib = self.parent.det.coords_x( self.parent.evt) # matrix coords self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_coordy: # coords_y try: calib = self.parent.det.coords_y(self.parent.evt, cframe=1) # lab coords except: calib = self.parent.det.coords_y( self.parent.evt) # matrix coords self.parent.firstUpdate = True shape = self.parent.det.shape(self.parent.evt) if len(shape) == 3: if self.parent.exp.image_property == self.parent.exp.disp_seg: # seg ind calib = np.zeros(shape) for i in range(shape[0]): calib[i, :, :] = i self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_row: # row ind calib = np.zeros(shape) for i in range(shape[1]): calib[:, i, :] = i self.parent.firstUpdate = True elif self.parent.exp.image_property == self.parent.exp.disp_col: # col ind calib = np.zeros(shape) for i in range(shape[2]): calib[:, :, i] = i self.parent.firstUpdate = True # Update photon energy self.parent.exp.updatePhotonEnergy(self.parent.facility) # Update clen self.parent.geom.updateClen(self.parent.facility) # Write a temporary geom file #self.parent.geom.deployCrystfelGeometry(self.parent.facility) #self.parent.geom.writeCrystfelGeom(self.parent.facility) # Hack to override coffset # Get assembled image if calib is not None: data = self.getAssembledImage(self.parent.facility, calib) else: calib = np.zeros_like(self.parent.exp.detGuaranteed, dtype='float32') data = self.getAssembledImage(self.parent.facility, calib) # Update ROI histogram if self.parent.roi.roiCurrent == 'rect': self.parent.roi.updateRoi(self.parent.roi.roi) elif self.parent.roi.roiCurrent == 'poly': self.parent.roi.updateRoi(self.parent.roi.roiPoly) elif self.parent.roi.roiCurrent == 'circ': self.parent.roi.updateRoi(self.parent.roi.roiCircle) return calib, data def getCentre(self, shape): cx = shape[1] / 2 cy = shape[0] / 2 return cx, cy