Features are derived from multiple analytes within a single trial. For example, product yield is a function of the substrate consumed, and product produced. Features are registered to the SingleTrial
class and are composed of two components: the feature, and the feature manager.
The feature manager ensures that the feature is created as soon as all the required analytes are available. Here we build the OD normalization feature as an example
First we import the base features:
In [1]:
from impact.core.features import BaseAnalyteFeature, BaseAnalyteFeatureFactory
Then, we can build our features
In [2]:
class ODNormalizedData(BaseAnalyteFeature):
# The constructor should accept all required analytes as parameters
def __init__(self, biomass, reporter):
self.biomass = biomass
self.reporter = reporter
self.normalized_data = None
# This data property assures that the data is returned, or calculated as needed
@property
def data(self):
if self.normalized_data is None: self.calculate()
return self.normalized_data
# This is where the property is actually calculated and set
def calculate(self):
self.normalized_data = self.reporter.data_vector/self.biomass.data_vector
# The feature factory watches for those analytes
class ODNormalizedDataFactory(BaseAnalyteFeatureFactory):
# define what the feature
requires = ['biomass','reporter']
name = 'od_normalized_data'
# constructor should initialize variables until all required analytes are present,
# this will ensure that despite the order analytes are added, feature will be calculated appropriately
def __init__(self):
self.biomass = None
self.reporter = None
# define how to handle new analytes
def add_analyte_data(self, analyte_data):
if analyte_data.trial_identifier.analyte_type == 'reporter':
self.reporter = analyte_data
elif analyte_data.trial_identifier.analyte_type == 'biomass':
self.biomass = analyte_data
if self.reporter is not None and self.biomass is not None:
setattr(analyte_data,self.name,ODNormalizedData(biomass,reporter))
Finally, we register the feature
In [3]:
import impact.core.SingleTrial as SingleTrial
SingleTrial.register_feature(ODNormalizedDataFactory)
and test it
In [4]:
from impact.core.AnalyteData import Biomass, Reporter
from impact.core.TrialIdentifier import ReplicateTrialIdentifier as TI
t = [0,1,2,3,4]
biomass_data = [0.1,0.2,0.4,0.8,0.8]
reporter_data = [1000,2000,3000,4000,5000]
biomass = Biomass()
biomass.time_vector = t
biomass.data_vector = biomass_data
ti = TI()
ti.analyte_name = 'OD'
ti.analyte_type = 'biomass'
biomass.trial_identifier = ti
reporter = Reporter()
reporter.time_vector = t
reporter.data_vector = reporter_data
ti = TI()
ti.analyte_name = 'gfp'
ti.analyte_type = 'reporter'
reporter.trial_identifier = ti
trial = SingleTrial()
trial.add_analyte_data(biomass)
trial.add_analyte_data(reporter)
In [5]:
import numpy as np
calculated_data = trial.analyte_dict['gfp'].od_normalized_data.data
expected_data = np.array(reporter_data)/biomass_data
print(calculated_data)
print(expected_data)
print(all(calculated_data==expected_data))