Skip to content

Latest commit

 

History

History
247 lines (166 loc) · 11.4 KB

File metadata and controls

247 lines (166 loc) · 11.4 KB

Developer Instructions - EVE software

Contents

Introduction

EVE is a software platform developed for the analysis of single-molecule imaging data captured by event-based sensors. This document is for developers who want to add functionality to EVE. EVE is a highly open framework and can easily be expanded upon. Expandability of EVE is possible in the following routines (with more detailed information following):

  • Candidate Finding

    Routines involved in finding which events belong to a single molecule localization/PSF

    Input: All events (possibly filtered by polarity), settings, function arguments

    Output: Found candidates, metadata

  • Candidate Fitting

    Routines involved in fitting the events of each candidate cluster to determine the x-, y- (,z-) and t-coordinates of each single molecule. Some fitting methods rely on using ‘Event distributions’ (below)

    Input: All found candidates, settings, function arguments

    Output: Localizations (x,y(,z),t-coordinates), metadata

  • Event distributions

    Classes to create varying distributions from events

    Input: Events, settings, function arguments

    Output: Histogram classes with certain arguments

  • Post-processing

    Routines involved in post-processing the localization data, either for further filtering or data quantification or for calculating quantitative metrics

    Input: Localizations, candidates, settings, function arguments

    Output: (Possibly changed) localizations, metadata; or None

  • Visualization

    Routines that visualize the current localization list

    Input: Localizations, settings, function arguments

    Output: 2D array containing image data, scale of the image

  • Candidate preview

    Routines that visualize individual candidates for user inspection

    Input: Candidates, localizations, all events, settings, function arguments

    Output: None (updated figure)

Expandability of EVE

All routines, with the exception of the Event distributions, follow the same method of expandability. One or multiple routines should be written in a .py file, and placed within a sub-folder in the main EVE GUI folder, or alternatively in the AppData/Local/UniBonn/Eve folder. EVE will automatically find and add all suitable routines into the GUI. The .py files should start with the following defined structure:

def __function_metadata__():
 return {
  "FunctionTitle": {
   "required_kwargs": [
    {"name": "kwarg1", "description": "Some Description", "default": 5.0, " type": float, "display_text": "Keyword Argument 1"},
    {"name": "kwarg2", "description": "Some other Description", "default":"string", "type": str, "display_text": "Keyword Argument 2"}
   ],
   "optional_kwargs": [
    {"name": "oarg", "description": "An optional argument", "default":1, "type":int, "display_text":"Optional Argument"},
   ],
   "help_string": "This is an exemplary routine.",
    "display_name": "Exemplary Routine"
  }
 }

This function would be displayed as such by the EVE GUI (exemplary for candidate finding on positive events):

The function_metadata function describes important metadata for the function(s) that should be displayed and callable:

  • One or multiple functions can be defined with this structure

  • The same .py file requires a function called the same as “FunctionTitle”

    The following parameters should be created:

    display_name (optional) provides the function name which is visible for the user

    help_string (optional) provides a description of the function for the user

    required_kwargs (required)** defines required keyword arguments that your function expects.

    optional_kwargs (required)** defines optional keyword arguments that your function could use.

  • For each keyword argument, the following should be provided:

    name (required): the internal name of the keyword argument

    display_text (optional): the name visible to the user 

    description (optional): a description of the argument that users can see in the EVE GUI default (optional): the default value of this argument

    type (optional): the expected type of the input, options are [float, int, str, “fileLoc”]

    The “fileLoc” value indicates a file which can be found by the user

Detailed information on input/output data of EVE

All data has these two input variables:

settings: named dictionary with (advanced) settings.
kwargs: dictionary with named entries of the function (as defined in __function_metadata__())

Candidate Finding

Function definition

def function(npy_array, settings,**kwargs): return candidates, performance_metadata

Input

npy_array: numpy.ndarray with one entry for each event. Each entry has dtype([('x', '<u2'), ('y', '<u2'), ('p', '<i2'), ('t', '<i8')]) structure, with x/y in pixels, p either 0 or 1 (negative or positive), and t in microseconds

Output

candidates: dictionary where each entry is a candidate. Each entry should have three named sub-entries:

events: pandas DataFrame with N-by-4 array, array names x,y,t,p (same units as input, N being the number of events in this cluster).



N_events: Number of events



cluster_size: [size_x, size_y, size_t] of the cluster (in [pixel, pixel, microsecond] units)

performance_metadata: string with details on the performance. Will be stored in the metadata.txt output.

Pseudo-code explaining the structure of candidates finding output

candidates = {}
for cluster in all_clusters:
    clusterEvents = all_cluster_events(cluster_id==cluster)
    candidates[cluster] = {}
    candidates[cluster]['events'] = clusterEvents
    candidates[cluster]['N_events'] = len(clusterEvents)
    candidates[cluster]['cluster_size'] =...
    [np.max(clusterEvents['y'])-np.min(clusterEvents['y'])+1,...
    np.max(clusterEvents['x'])-np.min(clusterEvents['x'])+1,...
    np.max(clusterEvents['t'])-np.min(clusterEvents['t'])]

metadata = 'The file ran as expected!'

Candidate Fitting

For the candidate fitting, the __function_metadata__() needs to be expanded to provide information about the dist_kwarg and time_kwarg. These structures contain information about which XY distribution and Time distribution can be selected by the user. If these are not defined, an XYT-combined fitting is ran (which should result in XY ánd time fitting results). In an XY+Time distribution, the candidate fitting routine should only provide the XY fitting result, since the Time distribution is handled independently. Please look at the following examples for implementation details:

Example for XY+Time: GaussianFitting

Example for XYT: Radial_Symmetry – RadialSym3D.

Function definition
*def function(candidate_dic, settings,**kwargs): return localizations, fit_info

Input
*candidate_dic: see output from candidate finding

Output
localizations: Pandas Dataframe of localizations corresponding to input clusters.
fit_info: string with info of metadata. Will be stored in the metadata.txt output. Should at least have columns with names ‘candidate_id’, ‘x’, ‘y’, ‘p’, [‘t’], in units integer, pixel, pixel, 0/1, microseconds, respectively. t is not required if an independent Time distribution fitting is used (see above). Can also have more columns as wanted, with nomenclature normally following ‘del_x’ for uncertainty in x. Commonly also ‘fit_info’ column can be used to report on incomplete/wrong fits. Each candidate should have one entry.
performance_metadata: string with details on the performance. Will be stored in the metadata.txt output.

Pseudo-code explaining the structure of candidate fitting output

localizations = {}
for i in np.unique(list(candidate_dic)):
    localizations[i]={}
    localizations[i]['x'] = np.mean(candidate_dic[i]['events']['x'])*float(settings['PixelSize_nm']['value']) #X position in nm
    localizations[i]['y'] = np.mean(candidate_dic[i]['events']['y'])*float(settings['PixelSize_nm']['value']) #Y position in nm
    localizations[i]['p'] = 1 #Polarisation: 0 or 1
    localizations[i]['t'] = np.mean(candidate_dic[i]['events']['t'])/1000 #time in ms

#Make a pd dataframe out of it - needs to be transposed
localizations = pd.DataFrame(localizations).T

metadata = 'The file ran as expected!'

Post-processing

Function definition
def function(localizations, findingResult, settings,**kwargs): return localizations, metadata

Input
localizations: See Candidate Fitting ‘localizations’ output.
findingResult: See Candidate Finding ‘candidates’ output.

Output
localizations: See Candidate Fitting ‘localizations’ output. Practically, should be a filtered/amended list of the original localizations.
metadata: string with info of metadata. Will be shown in the Run info GUI tab.

Visualization

Function definition
def function(resultArray, settings,**kwargs): return image, scale

Input
resultArray: See Candidate Fitting ‘localizations’ output. Uses the currently found results as in Eve (i.e. could be adapted via Post-processing).

Output
image: numpy.ndarray of pixel-values of the resulted image. Will be displayed in the ‘Visualization’ tab
scale: float value of pixel-to-micrometer size (e.g. value of 0.01 means 0.01 micrometer per pixel, or 10 nm per pixel). Used to set the scale bar in the ‘Visualization’ tab.

Candidate preview

Function definition
def function(findingResult, fittingResult, previewEvents, figure, settings,**kwargs): return None

Input
findingResult: See Candidate Finding ‘candidates’ output. The information of a single candidate is provided.
fittingResult: See Candidate Fitting ‘localizations’ output. The information of a single localization is provided.
previewEvents: Unused
figure: Matplotlib Figure object. Should be addressed by e.g. performing ax = figure.add_subplot(111); ax.bar(…). figure.show() does not have to be called.

Output
None. Expected that figure is updated properly.

Event distributions

These Event distributions follow a different expandability method, and cannot be adapted from the AppData folder, but only from changing the EventDistributions/eventDistributions.py file in the EVE installation folder.

Each Event distribution is defined by a class (e.g. class Hist1d_t() ). These classes should have a __call__(self, events, **kwargs) function, which should return the wanted distribution and bin edge positions.

Please use the existing classes in eventDistributions.py for detailed info.

Temporal Fitting

Same structure as Event distributions, only for fitting time distributions.