def testMkNamedTimeseries(self): if IGNORE_TEST: return # Create a new time series that subsets the old one colnames = ["time", "S1", "S2"] newTS = namedTimeseries.mkNamedTimeseries(colnames, self.timeseries[colnames]) self.assertEqual(len(self.timeseries), len(newTS)) # Create a new timeseries with a subset of times array = self.timeseries.selectTimes(lambda t: t > 2) newTS = namedTimeseries.mkNamedTimeseries(self.timeseries.allColnames, array) self.assertGreater(len(self.timeseries), len(newTS)) # ts = mkNamedTimeseries(self.timeseries) self.assertTrue(self.timeseries.equals(ts)) # ts = mkNamedTimeseries(TEST_DATA_PATH) self.assertTrue(self.timeseries.equals(ts)) # with self.assertRaises(ValueError): ts = mkNamedTimeseries(3)
def testExamples(self): if IGNORE_TEST: return # Create from file timeseries = NamedTimeseries(csvPath=TEST_DATA_PATH) # NamedTimeseries can use len function length = len(timeseries) # number of rows # Extract the numpy array values using indexing timeValues = timeseries["time"] s1Values = timeseries["S1"] # Get the start and end times startTime = timeseries.start endTime = timeseries.end # Create a new time series that subsets the variables of the old one colnames = ["time", "S1", "S2"] newTS = mkNamedTimeseries(colnames, timeseries[colnames]) # Create a new timeseries that excludes time 0 ts2 = timeseries[1:] # Create a new column variable timeseries["S8"] = timeseries["time"]**2 + 3 * timeseries["S1"] timeseries["S9"] = 10 # Assign a constant to all rows
def __init__( self, modelSpecification, observedData, # The following must be kept in sync with ModelFitterBootstrap.bootstrap parametersToFit=None, # Must be first kw for backwards compatibility bootstrapMethods=None, endTime=None, fitterMethods=None, isPlot=True, logger=Logger(), _loggerPrefix="", maxProcess: int = None, numFitRepeat=1, numIteration: int = 10, numPoint=None, numRestart=0, parameterLowerBound=cn.PARAMETER_LOWER_BOUND, parameterUpperBound=cn.PARAMETER_UPPER_BOUND, selectedColumns=None, serializePath: str = None, isParallel=True, isProgressBar=True, ): """ Constructs estimates of parameter values. Parameters ---------- endTime: float end time for the simulation modelSpecification: ExtendedRoadRunner/str roadrunner model or antimony model observedData: NamedTimeseries/str str: path to CSV file parametersToFit: list-str/SBstoat.Parameter/None parameters in the model that you want to fit if None, no parameters are fit selectedColumns: list-str species names you wish use to fit the model default: all columns in observedData parameterLowerBound: float lower bound for the fitting parameters parameterUpperBound: float upper bound for the fitting parameters logger: Logger fitterMethods: str/list-str/list-OptimizerMethod method used for minimization in fitModel numFitRepeat: int number of times fitting is repeated for a method bootstrapMethods: str/list-str/list-OptimizerMethod method used for minimization in bootstrap numIteration: number of bootstrap iterations numPoint: int number of time points in the simulation maxProcess: Maximum number of processes to use. Default: numCPU serializePath: Where to serialize the fitter after bootstrap numRestart: int number of times the minimization is restarted with random initial values for parameters to fit. isParallel: bool run in parallel where possible isProgressBar: bool display the progress bar Usage ----- parametersToFit = [SBstoat.Parameter("k1", lower=1, upper=10, value=5), SBstoat.Parameter("k2", lower=2, upper=6, value=3), ] ftter = ModelFitter(roadrunnerModel, "observed.csv", parametersToFit=parametersToFit) fitter.fitModel() # Do the fit fitter.bootstrap() # Estimate parameter variance with bootstrap """ if modelSpecification is not None: # Not the default constructor self._numIteration = numIteration # Save for copy constructor self._serializePath = serializePath # Save for copy constructor self._loggerPrefix = _loggerPrefix self.modelSpecification = modelSpecification self.observedData = observedData self.parametersToFit = parametersToFit self.parameterLowerBound = parameterLowerBound self.parameterUpperBound = parameterUpperBound self._maxProcess = maxProcess self.bootstrapKwargs = dict( numIteration=numIteration, serializePath=serializePath, ) self._numFitRepeat = numFitRepeat self.selectedColumns = selectedColumns self.observedTS, self.selectedColumns = self._updateObservedTS( mkNamedTimeseries(self.observedData)) # Check for nan in observedTS self._isObservedNan = np.isnan(np.sum(self.observedTS.flatten())) # self.selectedColumns = [c.strip() for c in self.selectedColumns] self.numPoint = numPoint if self.numPoint is None: self.numPoint = len(self.observedTS) self.endTime = endTime if self.endTime is None: self.endTime = self.observedTS.end # Other internal state self._fitterMethods = ModelFitterCore.makeMethods( fitterMethods, cn.METHOD_FITTER_DEFAULTS) self._bootstrapMethods = ModelFitterCore.makeMethods( bootstrapMethods, cn.METHOD_BOOTSTRAP_DEFAULTS) if isinstance(self._bootstrapMethods, str): self._bootstrapMethods = [self._bootstrapMethods] self._isPlot = isPlot self._plotter = tp.TimeseriesPlotter(isPlot=self._isPlot) self.logger = logger self._numRestart = numRestart self._isParallel = isParallel self._isProgressBar = isProgressBar self._selectedIdxs = None self._params = self.mkParams() # The following are calculated during fitting self.roadrunnerModel = None self.minimizerResult = None # Results of minimization self.fittedTS = self.observedTS.copy( isInitialize=True) # Initialize self.residualsTS = None # Residuals for selectedColumns self.bootstrapResult = None # Result from bootstrapping self.optimizer = None self.suiteFitterParams = None # Result from a suite fitter # else: pass
def __init__( self, modelSpecification, observedData, parametersToFit=None, selectedColumns=None, fitterMethods=METHOD_FITTER_DEFAULTS, numFitRepeat=1, bootstrapMethods=METHOD_BOOTSTRAP_DEFAULTS, parameterLowerBound=PARAMETER_LOWER_BOUND, parameterUpperBound=PARAMETER_UPPER_BOUND, parameterDct={}, fittedDataTransformDct={}, logger=Logger(), isPlot=True, _loggerPrefix="", # The following must be kept in sync with ModelFitterBootstrap.bootstrap numIteration: int = 10, reportInterval: int = 1000, synthesizerClass=ObservationSynthesizerRandomizedResiduals, maxProcess: int = None, serializePath: str = None, ): """ Constructs estimates of parameter values. Parameters ---------- modelSpecification: ExtendedRoadRunner/str roadrunner model or antimony model observedData: NamedTimeseries/str str: path to CSV file parametersToFit: list-str/None parameters in the model that you want to fit if None, no parameters are fit selectedColumns: list-str species names you wish use to fit the model default: all columns in observedData parameterLowerBound: float lower bound for the fitting parameters parameterUpperBound: float upper bound for the fitting parameters parameterDct: dict key: parameter name value: triple - (lowerVange, startingValue, upperRange) fittedDataTransformDct: dict key: column in selectedColumns value: function of the data in selectedColumns; input: NamedTimeseries output: array for the values of the column logger: Logger fitterMethods: str/list-str method used for minimization in fitModel numFitRepeat: int number of times fitting is repeated for a method bootstrapMethods: str/list-str method used for minimization in bootstrap numIteration: number of bootstrap iterations reportInterval: number of iterations between progress reports synthesizerClass: object that synthesizes new observations Must subclass ObservationSynthesizer maxProcess: Maximum number of processes to use. Default: numCPU serializePath: Where to serialize the fitter after bootstrap Usage ----- parameterDct = { "k1": (1, 5, 10), # name of parameter: low value, initial, high "k2": (2, 3, 6)} ftter = ModelFitter(roadrunnerModel, "observed.csv", parameterDct=parameterDct) fitter.fitModel() # Do the fit fitter.bootstrap() # Estimate parameter variance with bootstrap """ if modelSpecification is not None: # Not the default constructor self._loggerPrefix = _loggerPrefix self.modelSpecification = modelSpecification self.parametersToFit = parametersToFit self.lowerBound = parameterLowerBound self.upperBound = parameterUpperBound self.bootstrapKwargs = dict( numIteration=numIteration, reportInterval=reportInterval, maxProcess=maxProcess, serializePath=serializePath, ) self.parameterDct = self._updateParameterDct(parameterDct) self._numFitRepeat = numFitRepeat if self.parametersToFit is None: self.parametersToFit = [p for p in self.parameterDct.keys()] self.observedTS = observedData if self.observedTS is not None: self.observedTS = mkNamedTimeseries(observedData) # self.fittedDataTransformDct = fittedDataTransformDct # if (selectedColumns is None) and (self.observedTS is not None): selectedColumns = self.observedTS.colnames self.selectedColumns = selectedColumns # Construct array of non-nan observed values self._observedArr = self.observedTS[self.selectedColumns].flatten() # Other internal state self._fitterMethods = fitterMethods if isinstance(self._fitterMethods, str): if self._fitterMethods == METHOD_BOTH: self._fitterMethods = METHOD_FITTER_DEFAULTS else: self._fitterMethods = [self._fitterMethods] self._bootstrapMethods = bootstrapMethods if isinstance(self._bootstrapMethods, str): self._bootstrapMethods = [self._bootstrapMethods] self._isPlot = isPlot self._plotter = tp.TimeseriesPlotter(isPlot=self._isPlot) self._plotFittedTS = None # Timeseries that is plotted self.logger = logger # The following are calculated during fitting self.roadrunnerModel = None self.minimizer = None # lmfit.minimizer self.minimizerResult = None # Results of minimization self.params = None # params property in lmfit.minimizer self.fittedTS = self.observedTS.copy( isInitialize=True) # Initialize self.residualsTS = None # Residuals for selectedColumns self.bootstrapResult = None # Result from bootstrapping # Validation checks self._validateFittedDataTransformDct() else: pass