The script below are example scripts that users can use as reference to implement their own script for many different algorithms.
Algorithm Name
|
Script |
---|---|
My rookie script |
In this example script a new parameter is created via Python. The value for this parameter is set to be the same for all input events.
In this script, four options are defined, allowing the user to: •Name the new parameter (option of type string). A default name is also defined. •Define a integer value to assign to all input events (option of type integer). A default integer is also defined. •Define whether or not to add a constant decimal to the integer value defined above (option of type boolean). A default boolean value is also defined. •Define which decimal to add (option of type floating), if any. A default value, together with minimum/maximum allowed values are defined.
# Add Constant Parameter from FcsExpress import *
def RegisterOptions(params): RegisterStringOption("Constant Name", "MyConstParam") RegisterIntegerOption("Constant Value", 3) RegisterFloatOption("Constant Decimal", 0.5, 0, 1) RegisterBooleanOption("Add decimal?", True)
def RegisterParameters(opts, params): RegisterParameter(opts["Constant Name"])
def Execute(opts, data, res): valToSet = opts["Constant Value"] if opts["Add decimal?"]: valToSet += opts["Constant Decimal"]
res[opts["Constant Name"]][:] = [valToSet] * NumberDataPoints return res
|
Using a Classification Identifier |
This script shows how a Classification Identifier parameter can be used. Specifically, in this example the distance from the mean is calculated for each data point. This is done independently for each Classification Identifier label.
The parameter used for this calculation is defined by the user through the Parameter to Calculate Statistic on option. If ANY is entered, the first non-Classification parameter of the selected parameter list will be used.
This script require the user to select a Classification Identifier parameter and at least an additional parameter which is not a Classification identifier parameter.
# Classification parameter input example from FcsExpress import * from pprint import pprint
# swap print command for pretty version print = pprint
available_options = ["mean"] stat_option = "Statistic to Calculate ({})".format(available_options) param_option = "Parameter to Calculate Statistic on" default_param = "ANY"
# Could also support median without too much extra work def RegisterOptions(ParameterNames): RegisterStringOption(stat_option, available_options[0]) RegisterStringOption(param_option, default_param)
def RegisterParameters(Options, ParameterNames): RegisterParameter("Distance from {}".format(Options[stat_option]))
def Execute(Options, Parameters, Result): # Make sure that the stat passes in is valid if not Options[stat_option] in available_options: print(Options[stat_option]) print("Could not calculate {0} of each classification as {0} is an " \ "unrecognized statistic. Please choose a statistic from available " \ "options: {1}".format(Options[stat_option], available_options)) # We have a valid stat so now proceed in calculating for each classification elif ( Options[param_option] != default_param and len(Parameters.keys()) < 2 and not Options[param_option] in Parameters.keys() ): print("Could not find {} in list of passed in parameters. Please " \ "choose a parameter selected for this step, or use {} to " \ "select any parameter passed in".format(Options[param_option], default_param)) else: output_param_name = "Distance from {}".format(Options[stat_option]) # Get reference to the classification parameter we care about classification_name = "Classification Identifier" classification_values = Parameters[classification_name] classification_labels = InputClassificationLabels[classification_name] # Classification values are 0-based number_of_classification = max(classification_values) + 1
# Get reference to the parameter we care about if Options[param_option] == default_param: for param in Parameters.keys(): if param != classification_name: parameter_name = param break else: parameter_name = Options[param_option]
parameter_values = Parameters[parameter_name] # If mean was chosen then compute the mean of each classification in parameter if Options[stat_option] == "mean": # Initialize sums with a value of 0 for each label classification_sums = {label: 0 for label in classification_labels} classification_counts = classification_sums.copy() # Now populate all the sums for index, cell in enumerate(parameter_values): cur_classification_value = classification_values[index] cur_label = classification_labels[cur_classification_value]
classification_sums[cur_label] += cell classification_counts[cur_label] += 1
# Now divide the sums by the number of each classification stat_of_interest = {label: (classification_sums[label] / classification_counts[label]) for label in classification_labels}
# Now that stat_of_interest is populated, we need to compute the difference # from this statistic to the value of each cell in chosen parameter print("The {} of each classification in {}:".format(Options[stat_option], parameter_name)) print(stat_of_interest, sort_dicts=False) for index, cell in enumerate(parameter_values): cur_classification_value = classification_values[index] cur_label = classification_labels[cur_classification_value]
Result[output_param_name][index] = abs(stat_of_interest[cur_label] - cell)
return Result
|
Using a Spectral parameter |
Spectral parameters (either from actual spectral data or created using the Merge To Spectra pipeline step) can be used as input parameters in the Python Transformation pipeline step. Parameter selected in the Parameter Option panel of Python Transformation step are imported into Python as a dictionary object. Keys are derived from the names of the selected parametrs. The length of the dictionary matches the number of selected input parameters. The value for each key is a a list containing the values for that parameter. The length of each list of the dictionary matches the number of input data points for the Python Transformation step. Spectral parameters (and KNN parameters) are also allowed (their value in the dictionary object, is a list of list).
The script below shows how a Spectral parameter can be used. Specifically, a user-selected statistic (e.g. sum, mean, median or max) is calculated for each data point of each selected spectral parameter.
For each input parameter, a new parameter is created with the result of the calculation for each data point.
This script require that only spectral parameters are selected as input.
# Spectral parameter input example from FcsExpress import * import statistics
available_options = ["sum", "mean", "median", "max"] stat_option = "Statistic to Calculate ({})".format(available_options)
stat_functions = { "sum": sum, "mean": statistics.mean, "median": statistics.median, "max": max } # Could also support median without too much extra work def RegisterOptions(ParameterNames): RegisterStringOption(stat_option, available_options[0])
def RegisterParameters(Options, ParameterNames): for param in ParameterNames: RegisterParameter("{} {}s".format(param, Options[stat_option].capitalize()))
def Execute(Options, Parameters, Result): # Make sure that the stat passes in is valid if not Options[stat_option] in available_options: raise RuntimeError("Could not calculate {0} of each spectrum as {0} is an " \ "unrecognized statistic. Please choose a statistic from available " \ "options: {1}".format(Options[stat_option], available_options)) else: # Make sure that the parameters selected are spectral Parameters for parameter_name, parameter_values in Parameters.items(): # If each cell value is not a list of values this is not a spectrum if not isinstance(parameter_values[0], list): raise RuntimeError("{} is not a spectral parameter. Calculating {} on non-spectral " \ "parameters does not make sense. Change input parameter selection." .format(parameter_name, Options[stat_option]))
print("Processing {} which contains {} detector values".format(parameter_name, len(parameter_values[0]))) output_param_name = "{} {}s".format(parameter_name, Options[stat_option].capitalize())
# Now iterate over cells and calculate stat for index, cell_values in enumerate(parameter_values): # Python < 3.10 doesn't have case statements otherwise this would be a use case cell_values_stat = stat_functions[Options[stat_option]](cell_values) Result[output_param_name][index] = cell_values_stat
return Result
|
Using a KNN parameter |
KNN parameters can be used as input parameters in the Python Transformation pipeline step. Parameter selected in the Parameter Option panel of Python Transformation step are imported into Python as a dictionary object. Keys are derived from the names of the selected parametrs. The length of the dictionary matches the number of selected input parameters. The value for each key is a a list containing the values for that parameter. The length of each list of the dictionary matches the number of input data points for the Python Transformation step. KNN parameters (and Spectral parameters) are also allowed (their value in the dictionary object, is a list of list).
The script below shows how a KNN parameter can be used. Specifically, the script below counts how many neighborhoods a cell (i.e. a data point) participate in. The output of this script is a new parameter reporting, for each cell, the difference between the number of neighborhoods that cell participate in, and the average number of neighborhoods cells participate in. The script also generate a textual output in the Layout Messages dialog, reporting the Minimum, the Maximum and the Average number of neighborhoods cell participate in.
The script below require a KNN parameter as input parameter.
# KNN parameter input example from FcsExpress import * from statistics import mean
def RegisterOptions(ParameterNames): pass
def RegisterParameters(Options, ParameterNames): RegisterParameter('Number of Neighborhoods')
def Execute(Options, Parameters, Result): # Make sure that the parameters selected are knn Parameters for parameter_name, parameter_values in Parameters.items(): # If each cell value is not a list of values this is not a knn if not isinstance(parameter_values[0], list): raise RuntimeError("{} is not a knn parameter. Using non-knn " \ "parameters with this does not make sense. Change input parameter selection." .format(parameter_name))
print("Processing {} which contains {} neighborhoods per cell.".format(parameter_name, len(parameter_values[0]))) output_param_name = 'Number of Neighborhoods'
# iterate over each cells neighorhood and build up neighbor stats into a dict num_neighborhoods_participating = {neighbor: 0 for neighbor in range(NumberDataPoints)}
for neighborhood in parameter_values: for neighbor in neighborhood: num_neighborhoods_participating[neighbor] += 1
neighborhood_counts = num_neighborhoods_participating.values() # need to return relative differences based on the average average_num_neighborhoods = mean(neighborhood_counts) print("Average number of Neighborhoods Cells Participate in (Should be K of KNN):", average_num_neighborhoods) print("Max number of Neighborhoods: ", max(neighborhood_counts)) print("Min number of Neighborhoods: ", min(neighborhood_counts)) Result[output_param_name] = [num_neighborhoods - average_num_neighborhoods for num_neighborhoods in neighborhood_counts]
return Result
|
|