class FiducialApplyFromFiducials(ModuleBase): inputData = Input('filtered') inputFiducials = Input('Fiducials') outputName = Output('fiducialApplied') outputFiducials = Output('corrected_fiducials') def execute(self, namespace): inp = namespace[self.inputData] fiducial = namespace[self.inputFiducials] mapped = tabular.mappingFilter(inp) out_f = tabular.mappingFilter(fiducial) for dim in ['x', 'y', 'z']: fiducial_dim = finterpDS(inp, fiducial, 'fiducial_%s' % dim) mapped.addColumn('fiducial_%s' % dim, fiducial_dim) mapped.addColumn(dim, inp[dim] - fiducial_dim) out_f.setMapping(dim, '{0} - fiducial_{0}'.format(dim)) # propogate metadata, if present try: mapped.mdh = inp.mdh out_f.mdh = fiducial.mdh except AttributeError: pass namespace[self.outputName] = mapped namespace[self.outputFiducials] = out_f
class InterpolateDrift(ModuleBase): """ Creates a spline interpolator from drift data. (``scipy.interpolate.UnivariateSpline``) Inputs ------ input_drift_raw : Tuple of arrays Drift measured from localization or image dataset. Outputs ------- output_drift_interpolator : Drift interpolator. Returns drift when called with frame number / time. output_drift_plot : Plot Plot of the original and interpolated drift. Parameters ---------- degree_of_spline : int Degree of the smoothing spline. smoothing_factor : float Smoothing factor. """ # input_dummy = Input('input') # breaks GUI without this??? # load_path = File() degree_of_spline = Int(3) # 1 for linear, 3 for cubic smoothing_factor = Float( -1) # 0 for no smoothing. set to negative for UnivariateSpline defulat input_drift_raw = Input('drift_raw') output_drift_interpolator = Output('drift_interpolator') output_drift_plot = Output('drift_plot') def execute(self, namespace): # data = np.load(self.load_path) # tIndex = data['tIndex'] # drift = data['drift'] # namespace[self.output_drift_raw] = (tIndex, drift) tIndex, drift = namespace[self.input_drift_raw] spl = interpolate_drift(tIndex, drift, self.degree_of_spline, self.smoothing_factor) namespace[self.output_drift_interpolator] = spl # # non essential, only for plotting out drift data namespace[self.output_drift_plot] = Plot( partial(generate_drift_plot, tIndex, drift, spl)) namespace[self.output_drift_plot].plot()
class ClusterTimeRange(ModuleBase): inputName = Input('dbscanClustered') IDkey = CStr('dbscanClumpID') outputName = Output('withTrange') def execute(self, namespace): from scipy.stats import binned_statistic inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) ids = inp[self.IDkey] t = inp['t'] maxid = int(ids.max()) edges = -0.5 + np.arange(maxid + 2) resmin = binned_statistic(ids, t, statistic='min', bins=edges) resmax = binned_statistic(ids, t, statistic='max', bins=edges) trange = resmax[0][ids] - resmin[0][ids] + 1 mapped.addColumn('trange', trange) # propogate metadata, if present try: mapped.mdh = inp.mdh except AttributeError: pass namespace[self.outputName] = mapped
class DriftOutput(ModuleBase): """ Save drift data to a file. Inputs ------ input_name : Drift measured from localization or image dataset. Outputs ------- output_dummy : None Blank output. Required to run correctly. Parameters ---------- save_path : File Filepath to save drift data. """ input_name = Input('drift') save_path = File('drift') output_dummy = Output('dummy') # will not run execute without this def execute(self, namespace, context={}): # out_filename = self.filePattern.format(**context) out_filename = self.save_path tIndex, drift = namespace[self.input_name] np.savez_compressed(out_filename, tIndex=tIndex, drift=drift) print('saved')
class SnrCalculation(ModuleBase): inputName = Input('filtered') outputName = Output('snr') def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) if 'mdh' not in dir(inp): raise RuntimeError('SnrCalculation needs metadata') else: mdh = inp.mdh nph = inp['nPhotons'] bgraw = inp['fitResults_background'] bgph = np.clip((bgraw) * mdh['Camera.ElectronsPerCount'] / mdh.getEntry('Camera.TrueEMGain'), 1, None) npixroi = (2 * mdh.getOrDefault('Analysis.ROISize', 5) + 1)**2 snr = 1.0 / npixroi * np.clip(nph, 0, None) / np.sqrt(bgph) mapped.addColumn('SNR', snr) mapped.addColumn('backgroundPhotons', bgph) mapped.mdh = inp.mdh namespace[self.outputName] = mapped
class Cleanup(ModuleBase): """ Currently includes some steps for data collected from Leica SMS (Kevin). * Removed hot pixel * Subtract AD offset """ inputName = Input('input') outputName = Output('cleaned_image') def execute(self, namespace): ims = namespace[self.inputName] mdh = ims.mdh img = ims.data[:,:,:,:] img[img==2**16-1] = 0 np.clip(img, mdh.Camera.ADOffset, None, img) img -= mdh.Camera.ADOffset new_mdh = None try: new_mdh = MetaDataHandler.NestedClassMDHandler(mdh) print "here" if not 'voxelsize.z' in new_mdh.keys() or np.allclose(new_mdh['voxelsize.z'], 0): print 'there' new_mdh['voxelsize.z'] = new_mdh['StackSettings.StepSize'] if not "PSFExtraction.SourceFilenames" in new_mdh.keys(): new_mdh["PSFExtraction.SourceFilenames"] = ims.filename except Exception as e: print(e) namespace[self.outputName] = ImageStack(img, new_mdh)
class ExtractChannel(ModuleBase): """Extract one channel from an image""" inputName = Input('input') outputName = Output('filtered_image') channelToExtract = Int(0) def _pickChannel(self, image): chan = image.data[:, :, :, self.channelToExtract] im = ImageStack(chan, titleStub='Filtered Image') im.mdh.copyEntriesFrom(image.mdh) try: im.mdh['ChannelNames'] = [ image.names[self.channelToExtract], ] except (KeyError, AttributeError): logger.warn("Error setting channel name") im.mdh['Parent'] = image.filename return im def execute(self, namespace): namespace[self.outputName] = self._pickChannel( namespace[self.inputName])
class ValidClumps(ModuleBase): inputName = Input('with_clumps') inputValid = Input('valid_clumps') IDkey = CStr('clumpIndex') outputName = Output('with_validClumps') def execute(self, namespace): inp = namespace[self.inputName] valid = namespace[self.inputValid] mapped = tabular.mappingFilter(inp) # note: in coalesced data the clumpIndices are float! # this creates issues in comparisons unless these are converted to int before comparisons are made!! # that is the reason for the rint and astype conversions below ids = np.rint(inp[self.IDkey]).astype('i') validIDs = np.in1d(ids, np.unique(np.rint(valid[self.IDkey]).astype('i'))) mapped.addColumn('validID', validIDs.astype('f')) # should be float or int? # propogate metadata, if present try: mapped.mdh = inp.mdh except AttributeError: pass namespace[self.outputName] = mapped
class CopyMapped(ModuleBase): inputName = Input('filtered') outputName = Output('filtered-copy') def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) namespace[self.outputName] = mapped
class ClusterStats(ModuleBase): inputName = Input('with_clumps') IDkey = CStr('clumpIndex') StatMethod = Enum(['std', 'min', 'max', 'mean', 'median', 'count', 'sum']) StatKey = CStr('x') outputName = Output('withClumpStats') def execute(self, namespace): from scipy.stats import binned_statistic inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) ids = inp[self.IDkey] # I imagine this needs to be an int type key prop = inp[self.StatKey] maxid = int(ids.max()) edges = -0.5 + np.arange(maxid + 2) resstat = binned_statistic(ids, prop, statistic=self.StatMethod, bins=edges) mapped.addColumn(self.StatKey + "_" + self.StatMethod, resstat[0][ids]) # propogate metadata, if present try: mapped.mdh = inp.mdh except AttributeError: pass namespace[self.outputName] = mapped @property def _key_choices(self): #try and find the available column names try: return sorted(self._parent.namespace[self.inputName].keys()) except: return [] @property def default_view(self): from traitsui.api import View, Group, Item from PYME.ui.custom_traits_editors import CBEditor return View(Item('inputName', editor=CBEditor(choices=self._namespace_keys)), Item('_'), Item('IDkey', editor=CBEditor(choices=self._key_choices)), Item('StatKey', editor=CBEditor(choices=self._key_choices)), Item('StatMethod'), Item('_'), Item('outputName'), buttons=['OK'])
class TimedSpecies(ModuleBase): inputName = Input('filtered') outputName = Output('timedSpecies') Species_1_Name = CStr('Species1') Species_1_Start = Float(0) Species_1_Stop = Float(1e6) Species_2_Name = CStr('') Species_2_Start = Float(0) Species_2_Stop = Float(0) Species_3_Name = CStr('') Species_3_Start = Float(0) Species_3_Stop = Float(0) def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) timedSpecies = self.populateTimedSpecies() mapped.addColumn('ColourNorm', np.ones_like(mapped['t'], 'float')) for species in timedSpecies: mapped.addColumn('p_%s' % species['name'], (mapped['t'] >= species['t_start']) * (mapped['t'] < species['t_end'])) if 'mdh' in dir(inp): mapped.mdh = inp.mdh mapped.mdh['TimedSpecies'] = timedSpecies namespace[self.outputName] = mapped def populateTimedSpecies(self): ts = [] if self.Species_1_Name: ts.append({ 'name': self.Species_1_Name, 't_start': self.Species_1_Start, 't_end': self.Species_1_Stop }) if self.Species_2_Name: ts.append({ 'name': self.Species_2_Name, 't_start': self.Species_2_Start, 't_end': self.Species_2_Stop }) if self.Species_3_Name: ts.append({ 'name': self.Species_3_Name, 't_start': self.Species_3_Start, 't_end': self.Species_3_Stop }) return ts
class BiplanePhotons(ModuleBase): inputName = Input('filtered') outputName = Output('withPhotons') def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) fdialog = wx.FileDialog( None, 'Please select PSF to use ...', #defaultDir=os.path.split(self.image.filename)[0], wildcard='PSF Files|*.psf|TIFF files|*.tif', style=wx.FD_OPEN) succ = fdialog.ShowModal() if (succ == wx.ID_OK): psfn = filename = fdialog.GetPath() mdh = inp.mdh if mdh.getEntry('Analysis.FitModule') not in [ 'SplitterFitInterpBNR' ]: Warn('Plugin works only for Biplane analysis') return fitMod = __import__( 'PYME.localization.FitFactories.' + mdh.getEntry('Analysis.FitModule'), fromlist=['PYME', 'localization', 'FitFactories']) fr = populate_fresults(fitMod, inp) progress = wx.ProgressDialog("calculating photon numbers", "calculating...", maximum=100, parent=None, style=wx.PD_SMOOTH | wx.PD_AUTO_HIDE) nph = nPhotons(fitMod, fr, mdh, psfname=psfn, nmax=1e6, progressBar=progress, updateStep=100) progress.Destroy() mapped.addColumn('nPhotons', nph) mapped.addColumn('fitResults_background', inp['fitResults_bg'] + inp['fitResults_br']) #mapped.addColumn('sig',float(137.0)+np.zeros_like(inp['x'])) # this one is a straight kludge for mortensenError # propogate metadata, if present try: mapped.mdh = inp.mdh except AttributeError: pass namespace[self.outputName] = mapped
class FitProfiles(ModuleBase): inputName = Input('profiles') fit_type = CStr(list(profile_fitters.non_ensemble_fitters.keys())[0]) outputName = Output('fit_results') def execute(self, namespace): inp = namespace[self.inputName] # generate LineProfileHandler from tables handler = LineProfileHandler() handler._load_profiles_from_list(inp) fit_class = profile_fitters.non_ensemble_fitters[self.fit_type] self.fitter = fit_class(handler) self.fitter.fit_profiles() res = tabular.RecArraySource(self.fitter.results) # propagate metadata, if present res.mdh = MetaDataHandler.NestedClassMDHandler( getattr(inp, 'mdh', None)) res.mdh['FitProfiles.FitType'] = self.fit_type namespace[self.outputName] = res @property def _fitter_choices(self): return list(profile_fitters.non_ensemble_fitters.keys()) @property def default_view(self): from traitsui.api import View, Item from PYME.ui.custom_traits_editors import CBEditor return View(Item('inputName', editor=CBEditor(choices=self._namespace_keys)), Item('_'), Item('fit_type', editor=CBEditor(choices=self._fitter_choices)), Item('_'), Item('outputName'), buttons=['OK']) @property def pipeline_view(self): from traitsui.api import View, Item from PYME.ui.custom_traits_editors import CBEditor return View( Item('fit_type', editor=CBEditor(choices=self._fitter_choices)), )
class HistByID(ModuleBase): """Plot histogram of a column by ID""" inputName = Input('measurements') IDkey = CStr('objectID') histkey = CStr('qIndex') outputName = Output('outGraph') nbins = Int(50) minval = Float(float('nan')) maxval = Float(float('nan')) def execute(self, namespace): import math meas = namespace[self.inputName] ids = meas[self.IDkey] uid, valsu = uniqueByID(ids, meas[self.histkey]) if math.isnan(self.minval): minv = valsu.min() else: minv = self.minval if math.isnan(self.maxval): maxv = valsu.max() else: maxv = self.maxval import matplotlib.pyplot as plt plt.figure() plt.hist(valsu, self.nbins, range=(minv, maxv)) plt.xlabel(self.histkey) @property def _key_choices(self): #try and find the available column names try: return sorted(self._parent.namespace[self.inputName].keys()) except: return [] @property def default_view(self): from traitsui.api import View, Group, Item from PYME.ui.custom_traits_editors import CBEditor return View(Item('inputName', editor=CBEditor(choices=self._namespace_keys)), Item('_'), Item('IDkey', editor=CBEditor(choices=self._key_choices)), Item('histkey', editor=CBEditor(choices=self._key_choices)), Item('nbins'), Item('minval'), Item('maxval'), Item('_'), Item('outputName'), buttons=['OK'])
class SlidingWindowMAD(ModuleBase): """ Using a rolling window along the time (/ z) dimension, calculate the median-absolute deviation (MAD) Parameters ---------- series: PYME.IO.image.ImageStack time_window_size: int Size of window to use in rolling-median and standard deviation calculations Returns ------- output: PYME.IO.image.ImageStack MAD calculated within the rolling window. Note that the window size is kept constant, so output will be a shorter series than the input. Notes ----- Currently only set up for single-color data """ input = Input('input') time_window_size = Int(10) process_frames_individually = False output = Output('MAD') def execute(self, namespace): from scipy.stats import median_absolute_deviation series = namespace[self.input] steps = range(series.data.shape[2] - self.time_window_size) output = np.empty( (series.data.shape[0], series.data.shape[1], len(steps)), dtype=series.data[:, :, 0, 0].dtype) # only 1 color for now for ti in steps: output[:, :, ti] = median_absolute_deviation( series.data[:, :, ti:ti + self.time_window_size], scale=1, axis=2) out = image.ImageStack(data=output) out.mdh = MetaDataHandler.NestedClassMDHandler() try: out.mdh.copyEntriesFrom(series.mdh) except AttributeError: pass out.mdh['Analysis.FilterSpikes.TimeWindowSize'] = self.time_window_size namespace[self.output] = out
class ArithmaticFilter(ModuleBase): """ Module with two image inputs and one image output Parameters ---------- inputName0: PYME.IO.image.ImageStack inputName1: PYME.IO.image.ImageStack outputName: PYME.IO.image.ImageStack """ inputName0 = Input('input') inputName1 = Input('input') outputName = Output('filtered_image') processFramesIndividually = Bool(False) def filter(self, image0, image1): if self.processFramesIndividually: filt_ims = [] for chanNum in range(image0.data.shape[3]): out = [] for i in range(image0.data.shape[2]): d0 = image0.data[:, :, i, chanNum].squeeze().astype('f') d1 = image1.data[:, :, i, chanNum].squeeze().astype('f') out.append( np.atleast_3d( self.applyFilter(d0, d1, chanNum, i, image0))) filt_ims.append(np.concatenate(out, 2)) else: filt_ims = [] for chanNum in range(image0.data.shape[3]): d0 = image0.data[:, :, :, chanNum].squeeze().astype('f') d1 = image1.data[:, :, :, chanNum].squeeze().astype('f') filt_ims.append( np.atleast_3d(self.applyFilter(d0, d1, chanNum, 0, image0))) im = ImageStack(filt_ims, titleStub=self.outputName) im.mdh.copyEntriesFrom(image0.mdh) im.mdh['Parents'] = '%s, %s' % (image0.filename, image1.filename) self.completeMetadata(im) return im def execute(self, namespace): namespace[self.outputName] = self.filter(namespace[self.inputName0], namespace[self.inputName1]) def completeMetadata(self, im): pass
class SwapColorAndSlice(ModuleBase): """swap slice (z/t) with color""" input_name = Input('input') output_name = Output('swapped') def execute(self, namespace): from quant_condensate.SwapColorAndSliceDataSource import DataSource from PYME.IO.MetaDataHandler import DictMDHandler from PYME.IO.image import ImageStack im = namespace[self.input_name] mdh = DictMDHandler() mdh.copyEntriesFrom(im.mdh) mdh['SwapColorAndSlice'] = True namespace[self.output_name] = ImageStack(DataSource(im.data), mdh=mdh)
class ObjectVolume(ModuleBase): inputName = Input('objectID') outputName = Output('volumes') def execute(self, namespace): from PYMEcs.Analysis.objectVolumes import objectVolumes inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) volumes = objectVolumes( np.vstack([inp[k] for k in ('x', 'y')]).T, inp['objectID']) mapped.addColumn('volumes', volumes) namespace[self.outputName] = mapped
class CombineBeadStacks(ModuleBase): """ Combine multiply bead stacks in the 4th dimension. X, Y, Z must be identical. """ inputName = Input('dummy') files = List(File, ['', ''], 2) cache = File() outputName = Output('bead_images') def execute(self, namespace): ims = ImageStack(filename=self.files[0]) dims = np.asarray(ims.data.shape, dtype=np.long) dims[3] = 0 dtype_ = ims.data[:,0,0,0].dtype mdh = ims.mdh del ims for fil in self.files: ims = ImageStack(filename=fil) dims[3] += ims.data.shape[3] del ims if self.cache != '': raw_data = np.memmap(self.cache, dtype=dtype_, mode='w+', shape=tuple(dims)) else: raw_data = np.zeros(shape=tuple(dims), dtype=dtype_) counter = 0 for fil in self.files: ims = ImageStack(filename=fil) c_len = ims.data.shape[3] data = ims.data[:,:,:,:] data.shape += (1,) * (4 - data.ndim) raw_data[:,:,:,counter:counter+c_len] = data counter += c_len del ims new_mdh = None try: new_mdh = MetaDataHandler.NestedClassMDHandler(mdh) new_mdh["PSFExtraction.SourceFilenames"] = self.files except Exception as e: print(e) namespace[self.outputName] = ImageStack(data=raw_data, mdh=new_mdh)
class ExtractChannelByName(ModuleBase): """Extract one channel from an image using regular expression matching to image channel names - by default this is case insensitive""" inputName = Input('input') outputName = Output('filtered_image') channelNamePattern = CStr('channel0') caseInsensitive = Bool(True) def _matchChannels(self, channelNames): # we put this into its own function so that we can call it externally for testing import re flags = 0 if self.caseInsensitive: flags |= re.I idxs = [ i for i, c in enumerate(channelNames) if re.search(self.channelNamePattern, c, flags) ] return idxs def _pickChannel(self, image): channelNames = image.mdh['ChannelNames'] idxs = self._matchChannels(channelNames) if len(idxs) < 1: raise RuntimeError( "Expression '%s' did not match any channel names" % self.channelNamePattern) if len(idxs) > 1: raise RuntimeError( ("Expression '%s' did match more than one channel name: " % self.channelNamePattern) + ', '.join([channelNames[i] for i in idxs])) idx = idxs[0] chan = image.data[:, :, :, idx] im = ImageStack(chan, titleStub='Filtered Image') im.mdh.copyEntriesFrom(image.mdh) im.mdh['ChannelNames'] = [channelNames[idx]] im.mdh['Parent'] = image.filename return im def execute(self, namespace): namespace[self.outputName] = self._pickChannel( namespace[self.inputName])
class ScatterbyID(ModuleBase): """Take just certain columns of a variable""" inputName = Input('measurements') IDkey = CStr('objectID') xkey = CStr('qIndex') ykey = CStr('objArea') outputName = Output('outGraph') def execute(self, namespace): meas = namespace[self.inputName] ids = meas[self.IDkey] uid, x = uniqueByID(ids, meas[self.xkey]) uid, y = uniqueByID(ids, meas[self.ykey]) import pylab pylab.figure() pylab.scatter(x, y) pylab.grid() pylab.xlabel(self.xkey) pylab.ylabel(self.ykey) #namespace[self.outputName] = out @property def _key_choices(self): #try and find the available column names try: return sorted(self._parent.namespace[self.inputName].keys()) except: return [] @property def default_view(self): from traitsui.api import View, Group, Item from PYME.ui.custom_traits_editors import CBEditor return View(Item('inputName', editor=CBEditor(choices=self._namespace_keys)), Item('_'), Item('IDkey', editor=CBEditor(choices=self._key_choices)), Item('xkey', editor=CBEditor(choices=self._key_choices)), Item('ykey', editor=CBEditor(choices=self._key_choices)), Item('_'), Item('outputName'), buttons=['OK'])
class QindexRatio(ModuleBase): inputName = Input('qindex') outputName = Output('qindex-calibrated') qIndexDenom = CStr('qIndex1') qIndexNumer = CStr('qIndex2') qIndexRatio = CStr('qRatio') def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) qkey1 = self.qIndexDenom qkey2 = self.qIndexNumer v2 = inp[qkey2] ratio = np.zeros_like(v2, dtype='float64') qigood = v2 > 0 ratio[qigood] = inp[qkey1][qigood] / v2[qigood] mapped.addColumn(self.qIndexRatio, ratio) namespace[self.outputName] = mapped @property def _key_choices(self): #try and find the available column names try: return sorted(self._parent.namespace[self.inputName].keys()) except: return [] @property def default_view(self): from traitsui.api import View, Group, Item from PYME.ui.custom_traits_editors import CBEditor return View(Item('inputName', editor=CBEditor(choices=self._namespace_keys)), Item('_'), Item('qIndexDenom', editor=CBEditor(choices=self._key_choices)), Item('qIndexNumer', editor=CBEditor(choices=self._key_choices)), Item('qIndexRatio'), Item('_'), Item('outputName'), buttons=['OK'])
class MeanNormalizeToFirstFrame(ModuleBase): """ Mean-normalize all frames to the first frame. Any (analog-digital) offset should therefore be subtracted first, meaning this should wrap a dark-corrected datasource. """ input_image = Input('input') output_name = Output('mean_normalized') def execute(self, namespace): from PYME.IO.image import ImageStack from quant_condensate import MeanNormalizedDataSource image = namespace[self.input_image] mnd = MeanNormalizedDataSource.DataSource(image.data, image.mdh) im = ImageStack(mnd, titleStub=self.output_name) im.mdh.copyEntriesFrom(image.mdh) im.mdh['Parent'] = image.filename namespace[self.output_name] = im
class QindexScale(ModuleBase): inputName = Input('qindex') outputName = Output('qindex-calibrated') qIndexkey = CStr('qIndex') qindexValue = Float(1.0) NEquivalent = Float(1.0) def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) qkey = self.qIndexkey scaled = inp[qkey] qigood = inp[qkey] > 0 scaled[ qigood] = inp[qkey][qigood] * self.NEquivalent / self.qindexValue self.newKey = '%sCal' % qkey mapped.addColumn(self.newKey, scaled) namespace[self.outputName] = mapped @property def _key_choices(self): #try and find the available column names try: return sorted(self._parent.namespace[self.inputName].keys()) except: return [] @property def default_view(self): from traitsui.api import View, Group, Item from PYME.ui.custom_traits_editors import CBEditor return View(Item('inputName', editor=CBEditor(choices=self._namespace_keys)), Item('_'), Item('qIndexkey', editor=CBEditor(choices=self._key_choices)), Item('qindexValue'), Item('NEquivalent'), Item('_'), Item('outputName'), buttons=['OK'])
class LoadDrift(ModuleBase): """ *Deprecated.* Use ``LoadDriftandInterp`` instead. Load drift from a file. """ input_dummy = Input('input') # breaks GUI without this??? load_path = File() output_drift_raw = Input('drift_raw') output_drift_plot = Output('drift_plot') def execute(self, namespace): data = np.load(self.load_path) tIndex = data['tIndex'] drift = data['drift'] namespace[self.output_drift_raw] = (tIndex, drift) # non essential, only for plotting out drift data namespace[self.output_drift_plot] = Plot( partial(generate_drift_plot, tIndex, drift))
class FiducialApply(ModuleBase): inputName = Input('filtered') outputName = Output('fiducialApplied') def execute(self, namespace): inp = namespace[self.inputName] mapped = tabular.mappingFilter(inp) for dim in ['x', 'y', 'z']: try: mapped.addColumn(dim, inp[dim] - inp['fiducial_%s' % dim]) except: logger.warn('Could not set dim %s' % dim) # propogate metadata, if present try: mapped.mdh = inp.mdh except AttributeError: pass namespace[self.outputName] = mapped
class JoinChannels(ModuleBase): """Join multiple channels to form a composite image""" inputChan0 = Input('input0') inputChan1 = Input('') inputChan2 = Input('') inputChan3 = Input('') outputName = Output('output') #channelToExtract = Int(0) def _joinChannels(self, namespace): chans = [] image = namespace[self.inputChan0] chans.append(np.atleast_3d(image.data[:, :, :, 0])) channel_names = [ self.inputChan0, ] if not self.inputChan1 == '': chans.append(namespace[self.inputChan1].data[:, :, :, 0]) channel_names.append(self.inputChan1) if not self.inputChan2 == '': chans.append(namespace[self.inputChan2].data[:, :, :, 0]) channel_names.append(self.inputChan2) if not self.inputChan3 == '': chans.append(namespace[self.inputChan3].data[:, :, :, 0]) channel_names.append(self.inputChan3) im = ImageStack(chans, titleStub='Composite Image') im.mdh.copyEntriesFrom(image.mdh) im.names = channel_names im.mdh['Parent'] = image.filename return im def execute(self, namespace): namespace[self.outputName] = self._joinChannels(namespace)
class MergeClumpsTperiod(ModuleBase): """ Create a new mapping object which derives mapped keys from original ones. Also adds the time period of bursts by adding tmin and tmax columns for each clump. """ inputName = Input('clumped') outputName = Output('merged') labelKey = CStr('clumpIndex') def execute(self, namespace): from PYME.Analysis.points.DeClump import pyDeClump from PYME.Analysis.points.DeClump import deClump as deClumpC inp = namespace[self.inputName] grouped = pyDeClump.mergeClumps(inp, labelKey=self.labelKey) # work out tmin and tmax I = np.argsort(inp[self.labelKey]) sorted_src = {k: inp[k][I] for k in [self.labelKey, 't']} # tmin and tmax - tentative addition NClumps = int(np.max(sorted_src[self.labelKey]) + 1) tmin = deClumpC.aggregateMin(NClumps, sorted_src[self.labelKey].astype('i'), sorted_src['t'].astype('f')) tmax = -deClumpC.aggregateMin(NClumps, sorted_src[self.labelKey].astype('i'), -1.0 * sorted_src['t'].astype('f')) grouped.addColumn('tmin', tmin) grouped.addColumn('tmax', tmax) try: grouped.mdh = inp.mdh except AttributeError: pass namespace[self.outputName] = grouped
class AddMetaData(ModuleBase): """ Hack to inject missing metadata into an image / point dataset Parameters ---------- input_name : Input PYME.IO.ImageStack or PYME.IO.Tabular Returns ------- output_name : Output Notes ----- """ input_name = Input('input') metadata_to_add = DictStrAny() output_name = Output('with_metadata') def execute(self, namespace): from PYME.IO.MetaDataHandler import CachingMDHandler inp = namespace[self.input_name] # md_dict = namespace[] mdh = CachingMDHandler(self.metadata_to_add) try: # add to the existing handler if there is one inp.mdh.copyEntriesFrom(mdh) except: # move on with our new handler inp.mdh = mdh namespace[self.output_name] = inp
class PointFeaturesPairwiseDist(PointFeatureBase): """ Create a feature vector for each point in a point-cloud using a histogram of it's distances to all other points """ inputLocalisations = Input('localisations') outputName = Output('features') binWidth = Float(100.) # width of the bins in nm numBins = Int(20) #number of bins (starting at 0) threeD = Bool(True) normaliseRelativeDensity = Bool( False ) # divide by the sum of all radial bins. If not performed, the first principle component will likely be average density def execute(self, namespace): from PYME.Analysis.points import DistHist points = namespace[self.inputLocalisations] if self.threeD: x, y, z = points['x'], points['y'], points['z'] f = np.array([ DistHist.distanceHistogram3D(x[i], y[i], z[i], x, y, z, self.numBins, self.binWidth) for i in xrange(len(x)) ]) else: x, y = points['x'], points['y'] f = np.array([ DistHist.distanceHistogram(x[i], y[i], x, y, self.numBins, self.binWidth) for i in xrange(len(x)) ]) namespace[self.outputName] = self._process_features(points, f)