Ejemplo n.º 1
0
 def setUp(self):
     self.timeseries = NamedTimeseries(csvPath=TEST_DATA_PATH)
     self.model = te.loada(ANTIMONY_MODEL)
Ejemplo n.º 2
0
 def testMissingData(self):
     if IGNORE_TEST:
         return
     with self.assertRaises(ValueError):
         timeseries = NamedTimeseries(csvPath=TEST_BAD_DATA_PATH)
Ejemplo n.º 3
0
class TestNamedTimeseries(unittest.TestCase):
    def setUp(self):
        self.timeseries = NamedTimeseries(csvPath=TEST_DATA_PATH)
        self.model = te.loada(ANTIMONY_MODEL)

    def tearDown(self):
        if os.path.isfile(TEMP_FILE):
            os.remove(TEMP_FILE)

    def testConstructor1(self):
        if IGNORE_TEST:
            return
        self.assertGreater(len(self.timeseries.values), 0)
        # colnames doesn't include TIME
        self.assertEqual(len(self.timeseries.colnames),
                         np.shape(self.timeseries.values)[1] - 1)
        #
        newTS = self.timeseries.copy(isInitialize=True)
        self.assertEqual(np.sum(newTS[self.timeseries.colnames[0]]), 0)

    def testConstructor2(self):
        if IGNORE_TEST:
            return
        COLNAMES = [TIME, "S1", "S2"]

        def test(timeseries, colnames=COLNAMES):
            for name in colnames:
                self.assertTrue(
                    np.isclose(sum(timeseries[name] - self.timeseries[name]),
                               0))

        #
        newTS = NamedTimeseries(colnames=COLNAMES,
                                array=self.timeseries[COLNAMES])
        test(newTS)
        # Check can use different cases for TIME
        newTS = NamedTimeseries(colnames=["Time", "S1", "S2"],
                                array=self.timeseries[COLNAMES])
        test(newTS)

    def testConstructorNamedArray(self):
        if IGNORE_TEST:
            return
        namedArray = self.model.simulate(0, 100, 30)
        ts = NamedTimeseries(namedArray=namedArray)
        self.assertTrue(
            namedTimeseries.arrayEquals(namedArray.flatten(),
                                        ts.values.flatten()))

    def testSizeof(self):
        if IGNORE_TEST:
            return
        self.assertEqual(len(self.timeseries), LENGTH)

    def testGetitem(self):
        if IGNORE_TEST:
            return
        times = self.timeseries[TIME]
        # Access time column with different case
        refs = ["TiMe", "S1"]
        self.assertTrue(
            namedTimeseries.arrayEquals(self.timeseries[refs],
                                        self.timeseries[refs]))
        self.assertTrue(
            namedTimeseries.arrayEquals(self.timeseries[TIME],
                                        self.timeseries["TimE"]))
        self.assertTrue(
            namedTimeseries.arrayEquals(self.timeseries[TIME],
                                        self.timeseries["TimE"]))
        self.assertEqual(len(times), len(self.timeseries))
        self.assertEqual(min(times), self.timeseries.start)
        self.assertEqual(max(times), self.timeseries.end)
        # Get multiple values at once
        values = self.timeseries[self.timeseries.colnames]
        trues = np.array([
            v1 == v2 for v1, v2 in zip(values, self.timeseries.values[:, 1:])
        ])
        self.assertTrue(all(trues.flatten()))

    def testMissingData(self):
        if IGNORE_TEST:
            return
        with self.assertRaises(ValueError):
            timeseries = NamedTimeseries(csvPath=TEST_BAD_DATA_PATH)

    def testCopyExisting(self):
        if IGNORE_TEST:
            return
        timeseries = NamedTimeseries(timeseries=self.timeseries)

        #
        def checkVector(attribute):
            length = len(self.timeseries.__getattribute__(attribute))
            trues = [
                timeseries.__getattribute__(attribute)[k] ==
                self.timeseries.__getattribute__(attribute)[k]
                for k in range(length)
            ]
            self.assertTrue(all(trues))

        def checkMatrix(attribute):
            trues = []
            for rowIdx, row in enumerate(
                    timeseries.__getattribute__(attribute)):
                for colIdx, val in enumerate(row):
                    trues.append(val == self.timeseries.__getattribute__(
                        attribute)[rowIdx, colIdx])
            self.assertTrue(all(trues))

        #
        for variable in ["start", "end"]:
            self.assertEqual(timeseries.__getattribute__(variable),
                             self.timeseries.__getattribute__(variable))
        for variable in ["colnames"]:
            checkVector(variable)
        for variable in ["values"]:
            checkMatrix(variable)

    def testFlattenValues(self):
        if IGNORE_TEST:
            return
        values = self.timeseries.flatten()
        self.assertTrue(
            np.isclose(sum(values - self.timeseries.values[:, 1:].flatten()),
                       0))

    def testSelectTimes(self):
        if IGNORE_TEST:
            return
        selectorFunction = lambda t: t > 2
        array = self.timeseries.selectTimes(selectorFunction)
        self.assertLess(len(array), len(self.timeseries))

    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 testToPandas(self):
        if IGNORE_TEST:
            return
        df = self.timeseries.to_dataframe()
        timeseries = NamedTimeseries(dataframe=df)
        diff = set(df.columns).symmetric_difference(timeseries.colnames)
        self.assertEqual(len(diff), 0)
        total = sum(timeseries.values.flatten() -
                    self.timeseries.values.flatten())
        self.assertTrue(np.isclose(total, 0))

    def testArrayEquals(self):
        if IGNORE_TEST:
            return
        arr1 = np.array([1, 2, 3, 4])
        arr1 = np.reshape(arr1, (2, 2))
        self.assertTrue(namedTimeseries.arrayEquals(arr1, arr1))
        arr2 = 1.0001 * arr1
        self.assertFalse(namedTimeseries.arrayEquals(arr1, arr2))

    def testEquals(self):
        if IGNORE_TEST:
            return
        self.assertTrue(self.timeseries.equals(self.timeseries))
        newTS = self.timeseries.copy()
        newTS["S1"] = -1
        self.assertFalse(self.timeseries.equals(newTS))

    def testCopy(self):
        if IGNORE_TEST:
            return
        ts2 = self.timeseries.copy()
        self.assertTrue(self.timeseries.equals(ts2))

    def testSetitem(self):
        if IGNORE_TEST:
            return
        self.timeseries["S1"] = self.timeseries["S2"]
        self.assertTrue(
            namedTimeseries.arrayEquals(self.timeseries["S1"],
                                        self.timeseries["S2"]))
        value = -20
        self.timeseries["S19"] = value
        self.assertEqual(self.timeseries["S19"].sum(),
                         len(self.timeseries) * value)

    def testGetitemRows(self):
        if IGNORE_TEST:
            return
        start = 1
        stop = 3
        ts1 = self.timeseries[start:stop]
        self.assertTrue(isinstance(ts1, NamedTimeseries))
        self.assertEqual(len(ts1), stop - start)
        #
        ts2 = self.timeseries[[1, 2]]
        self.assertTrue(ts1.equals(ts2))
        #
        ts3 = self.timeseries[1]
        self.assertEqual(np.shape(ts3.values), (1, len(ts2.allColnames)))

    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 testDelitem(self):
        if IGNORE_TEST:
            return
        ts1 = self.timeseries.copy()
        del ts1["S1"]
        stg = str(ts1)
        self.assertEqual(len(ts1), len(self.timeseries))
        self.assertEqual(len(ts1.colnames) + 1, len(self.timeseries.colnames))

    def testToCsv(self):
        if IGNORE_TEST:
            return
        self.timeseries.to_csv(TEMP_FILE)
        self.assertTrue(os.path.isfile(TEMP_FILE))

    def testConcatenateColumns(self):
        if IGNORE_TEST:
            return
        ts = self.timeseries.concatenateColumns(self.timeseries)
        newNames = ["%s_" % c for c in self.timeseries.colnames]
        self.assertTrue(
            namedTimeseries.arrayEquals(
                ts[newNames], self.timeseries[self.timeseries.colnames]))
        self.assertEqual(len(ts), len(self.timeseries))
        self.assertTrue(
            namedTimeseries.arrayEquals(ts[TIME], self.timeseries[TIME]))
        #
        ts = self.timeseries.concatenateColumns(
            [self.timeseries, self.timeseries])
        self.assertEqual(3 * len(self.timeseries.colnames), len(ts.colnames))

    def testConcatenateRows(self):
        if IGNORE_TEST:
            return
        ts = self.timeseries.concatenateRows(self.timeseries)
        diff = set(ts.colnames).symmetric_difference(self.timeseries.colnames)
        self.assertEqual(len(diff), 0)
        length = len(self.timeseries)
        ts1 = ts[length:]
        self.assertTrue(self.timeseries.equals(ts1))
        #
        ts = self.timeseries.concatenateRows(
            [self.timeseries, self.timeseries])
        self.assertEqual(3 * len(self.timeseries), len(ts))

    def testSubsetColumns(self):
        if IGNORE_TEST:
            return
        ts = self.timeseries.concatenateColumns(self.timeseries)
        ts1 = ts.subsetColumns(self.timeseries.colnames)
        self.assertTrue(self.timeseries.equals(ts1))

    def testGetTimes(self):
        if IGNORE_TEST:
            return
        SIZE = 10
        VALUE = "values"
        TIMES = np.array(range(SIZE))

        def test(values, reference):
            df = pd.DataFrame({TIME: TIMES, VALUE: values})
            ts = NamedTimeseries(dataframe=df)
            results = ts.getTimesForValue(VALUE, reference)
            for time in results:
                idx1 = int(time)
                idx2 = idx1 + 1
                small = min(ts[VALUE][idx1], ts[VALUE][idx2])
                large = max(ts[VALUE][idx1], ts[VALUE][idx2])
                self.assertLessEqual(small, reference)
                self.assertGreaterEqual(large, reference)

        #
        values = (TIMES - 5)**2
        test(values, 10)  # 2 times
        test(-values, 5)  # Single maxk

    def testRpickleInterface(self):
        if IGNORE_TEST:
            return
        serialization = rpickle.Serialization(self.timeseries)
        timeseries = serialization.deserialize()
        self.assertTrue(timeseries.equals(self.timeseries))

    def testRename(self):
        if IGNORE_TEST:
            return
        NEW_NAME = "T1"
        OLD_NAME = "S1"
        newTimeseries = self.timeseries.rename(OLD_NAME, NEW_NAME)
        self.assertTrue(NEW_NAME in newTimeseries.colnames)
        self.assertFalse(OLD_NAME in newTimeseries.colnames)
        del newTimeseries[NEW_NAME]
        del self.timeseries[OLD_NAME]
        self.assertTrue(newTimeseries.equals(self.timeseries))
Ejemplo n.º 4
0
 def setUp(self):
     self.timeseries = NamedTimeseries(csvPath=TEST_DATA_PATH)
     self.plotter = TimeseriesPlotter(isPlot=IS_PLOT)
Ejemplo n.º 5
0
 def getTS(data):
     if isinstance(data, pd.DataFrame):
         return NamedTimeseries(dataframe=data)
     return data
Ejemplo n.º 6
0
    def plotTimeSingle(self, timeseries1:NamedTimeseries,
           meanTS:NamedTimeseries=None, stdTS:NamedTimeseries=None,
           bandLowTS:NamedTimeseries=None, bandHighTS:NamedTimeseries=None,
           ax_spec=None,
           position=None,  **kwargs):
        """
        Constructs plots of single columns, possibly with a second
        timeseries.

        Parameters
        ---------
        timeseries1: timeseries to plot
        meanTS: mean values of timeseries to plot
        stdTS: standard deviations of meanTS (same times)
        bandLowTS: timeseries that describes the lower band for timeseries1
        bandhighTS: timeseries that describes the higher band for timeseries1
        ax_spec: Optionally specified axis for all lines
        position: (int, int) - position of ax_spec
        #@expand
               
        Example
        -------
        plotter = TimeseriesPlotter()
        plotter.plotTimeSingle(timeseries)
        """
        options = self._mkPlotOptionsMatrix(timeseries1, **kwargs)
        # Adjust rows and columns
        numPlot = len(options.columns)  # Number of plots
        if po.NUM_COL in kwargs.keys():
            options.numRow = int(np.ceil(numPlot/options.numCol))
        else:
            options.numCol = int(np.ceil(numPlot/options.numRow))
        options.set(po.XLABEL, TIME)
        # Create the LayoutManager
        if ax_spec is None:
            layout = self._mkManager(options, numPlot)
        else:
            layout = None
        #
        def mkStatement(ax, statement:StatementManager,
            timeseries:NamedTimeseries, variable:str):
            """
            Creates a plotting statement.
   
            Parameters
            ----------
            ax: plotting axes
            initialStatement: statement if initialized
            timeseries: what to plot
            variable: variable to plot
            
            Returns
            -------
            StatementManager
            """
            times, values = self._adjustSeriesForNan(
                  timeseries[TIME], timeseries[variable])
            statement.addPosarg(times)
            statement.addPosarg(values)
            return statement
        #
        def isFirstColumn(plotIdx):
            if layout is not None:
                return layout.isFirstColumn(plotIdx)
            else:
                if position is not None:
                    return position[1]  == 0
                else:
                    return True
        #
        def isLastRow(plotIdx):
            if layout is not None:
                return layout.isLastRow(plotIdx)
            else:
                if po.NUM_ROW in kwargs.keys():
                    numRow = kwargs[po.NUM_ROW]
                else:
                    return True
                if position is None:
                    return True
                return position[0] + 1 == numRow
        #
        def mkBand(ts, variable, plotIdx, lineIdx):
            initialStatement = StatementManager(ax.fill_between)
            statement = mkStatement(ax, initialStatement, timeseries1, variable)
            statement.addPosarg(ts[variable])
            statement.addKwargs(alpha=0.2)
            options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
        #
        # Construct the plots
        baseOptions = copy.deepcopy(options)
        for plotIdx, variable in enumerate(options.columns):
            if ax_spec is None:
                ax = layout.getAxis(plotIdx)
            else:
                ax = ax_spec
            options = copy.deepcopy(baseOptions)
            #ax = axes[row, col]
            options.set(po.YLABEL, "concentration")
            options.set(po.TITLE, variable)
            if not isFirstColumn(plotIdx):
                options.ylabel =  NULL_STR
                options.set(po.YLABEL, "", isOverride=True)
            if not isLastRow(plotIdx):
                options.set(po.XLABEL, "", isOverride=True)
            # Construct the plot
            lineIdx = 0
            initialStatement = StatementManager(ax.plot)
            statement = mkStatement(ax, initialStatement, timeseries1, variable)
            options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
            legends = []
            if options.timeseries2 is not None:
                lineIdx = 1
                initialStatement = StatementManager(ax.plot)
                if options.marker is not None:
                    if len(options.marker) > 1:
                        if options.marker[lineIdx] is not None:
                            initialStatement = StatementManager(ax.scatter)
                    elif options.marker is not None:
                        initialStatement = StatementManager(ax.scatter)
                statement = mkStatement(ax, initialStatement,
                      options.timeseries2, variable)
                legends = [LABEL1, LABEL2]
                options.lengends = legends
                options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
            if  meanTS is not None:
                if stdTS is None:
                    stdTS = meanTS.copy(isInitialize=True)
                lineIdx = 2
                initialStatement = StatementManager(ax.scatter)
                statement = mkStatement(ax, initialStatement, meanTS, variable)
                options.marker = "^"
                statement.addKwargs(facecolors="none")
                options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
                #
                initialStatement = StatementManager(ax.errorbar)
                statement = mkStatement(ax, initialStatement, meanTS, variable)
                statement.addKwargs(yerr=stdTS[variable])
                statement.addKwargs(linestyle="none")
                legends.append("Bootstrap mean")
                options.lengends = legends
                options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
            if  bandLowTS is not None:
                lineIdx = 0
                mkBand(bandLowTS, variable, plotIdx, lineIdx)
            if  bandHighTS is not None:
                lineIdx = 0
                mkBand(bandHighTS, variable, plotIdx, lineIdx)
        if self.isPlot:
            plt.show()
Ejemplo n.º 7
0
class TestTimeseriesPlotter(unittest.TestCase):
    def setUp(self):
        self.timeseries = NamedTimeseries(csvPath=TEST_DATA_PATH)
        self.plotter = TimeseriesPlotter(isPlot=IS_PLOT)

    def testConstructor1(self):
        if IGNORE_TEST:
            return
        self.assertTrue(isinstance(self.plotter.isPlot, bool))

    def testInitializeRowColumn(self):
        if IGNORE_TEST:
            return

        def test(maxCol, **kwargs):
            options = self.plotter._mkPlotOptionsMatrix(self.timeseries,
                                                        maxCol=maxCol,
                                                        **kwargs)
            if po.NUM_ROW in kwargs:
                self.assertGreaterEqual(options.numRow, kwargs[po.NUM_ROW])
            if po.NUM_COL in kwargs:
                self.assertEqual(options.numCol, kwargs[po.NUM_COL])

        #
        test(3, **{})
        test(3, **{po.NUM_COL: 3})
        test(4, **{po.NUM_ROW: 2})
        test(5, **{po.NUM_ROW: 2})

    def testPlotSingle1(self):
        if IGNORE_TEST:
            return
        self.plotter.plotTimeSingle(self.timeseries,
                                    timeseries2=self.timeseries,
                                    numCol=4,
                                    marker=[None, '*'],
                                    alpha=[0.1, 0.8],
                                    color=["red", "g"],
                                    titlePosition=[0.8, 0.5],
                                    titleFontsize=10)
        self.plotter.plotTimeSingle(self.timeseries,
                                    numCol=4,
                                    marker=[None, '*'])
        self.plotter.plotTimeSingle(self.timeseries,
                                    numCol=4,
                                    subplotWidthSpace=0.2,
                                    yticklabels=[])
        self.plotter.plotTimeSingle(self.timeseries,
                                    columns=["S1", "S2", "S3"],
                                    numRow=2)
        self.plotter.plotTimeSingle(self.timeseries, numCol=4)
        self.plotter.plotTimeSingle(self.timeseries, numCol=2)
        self.plotter.plotTimeSingle(self.timeseries,
                                    numRow=2,
                                    numCol=3,
                                    ylabel="xxx")
        self.plotter.plotTimeSingle(self.timeseries, columns=["S1", "S2"])

    def testPlotSingle5(self):
        if IGNORE_TEST:
            return
        timeseries = self.timeseries.subsetColumns(["S1"])
        dct = {}
        indices = [i for i in range(len(timeseries)) if i % 4 == 0]
        for col in timeseries.allColnames:
            dct[col] = timeseries[col][indices]
        df = pd.DataFrame(dct)
        meanTS = NamedTimeseries(dataframe=df)
        meanTS[meanTS.colnames] = 1.1 * meanTS[meanTS.colnames]
        stdTS = meanTS.copy()
        for col in meanTS.colnames:
            stdTS[col] = 1
        #
        self.plotter.plotTimeSingle(timeseries,
                                    timeseries2=self.timeseries,
                                    meanTS=meanTS,
                                    stdTS=stdTS,
                                    marker=[None, 'o', "^"],
                                    color=["b", "r", "g"])
        #
        self.plotter.plotTimeSingle(timeseries, meanTS=meanTS, stdTS=stdTS)
        #
        self.plotter.plotTimeSingle(timeseries,
                                    timeseries2=self.timeseries,
                                    marker='*')

    def testPlotSingle6(self):
        if IGNORE_TEST:
            return
        numCol = 3
        numRow = 2
        fig, axes = plt.subplots(numRow, numCol)
        self.plotter.isPlot = False
        for idx in range(numCol * numRow):
            if idx < numCol:
                row = 0
                col = idx
            else:
                row = 1
                col = idx - numCol
            position = [row, col]
            ax = axes[row, col]
            ts = self.timeseries.subsetColumns(self.timeseries.colnames[idx])
            self.plotter.plotTimeSingle(ts,
                                        ax_spec=ax,
                                        position=position,
                                        numRow=2)
        if IS_PLOT:
            plt.show()

    def testPlotSingle7(self):
        if IGNORE_TEST:
            return

        def setTS(ts, frac):
            ts = self.timeseries.copy()
            for col in ts.colnames:
                ts[col] = frac * ts[col]
            return ts

        #
        numCol = 3
        numRow = 2
        fig, axes = plt.subplots(numRow, numCol)
        self.plotter.isPlot = False
        tsLower = setTS(self.timeseries, 0.7)
        tsUpper = setTS(self.timeseries, 1.5)
        for idx in range(numCol * numRow):
            if idx < numCol:
                row = 0
                col = idx
            else:
                row = 1
                col = idx - numCol
            position = [row, col]
            ax = axes[row, col]
            ts = self.timeseries.subsetColumns(self.timeseries.colnames[idx])
            self.plotter.plotTimeSingle(ts,
                                        ax_spec=ax,
                                        position=position,
                                        bandLowTS=tsLower,
                                        bandHighTS=tsUpper,
                                        numRow=2)
        if IS_PLOT:
            plt.show()

    def testPlotSingle8(self):
        # Plot with nan values
        if IGNORE_TEST:
            return

        def setTS(ts, mult, numNan):
            ts = self.timeseries.copy()
            for col in ts.colnames:
                ts[col] = mult * ts[col]
                ts[col][:numNan] = np.nan
            return ts

        #
        numCol = 3
        numRow = 2
        timeseries2 = setTS(self.timeseries, 2, 3)
        self.plotter.plotTimeSingle(self.timeseries,
                                    timeseries2=timeseries2,
                                    columns=["S1"],
                                    numRow=numRow,
                                    numCol=numCol)
        if IS_PLOT:
            plt.show()

    def mkTimeseries(self):
        ts2 = self.timeseries.copy()
        ts2[ts2.colnames] = ts2[ts2.colnames] + np.multiply(
            ts2[ts2.colnames], ts2[ts2.colnames])
        return ts2

    def testPlotSingle2(self):
        if IGNORE_TEST:
            return
        ts2 = self.mkTimeseries()
        self.plotter.plotTimeSingle(self.timeseries,
                                    timeseries2=ts2,
                                    columns=["S1", "S2"])
        self.plotter.plotTimeSingle(self.timeseries, timeseries2=ts2)
        self.plotter.plotTimeSingle(self.timeseries,
                                    timeseries2=ts2,
                                    numRow=2,
                                    numCol=3)

    def testPlotSingle3(self):
        if IGNORE_TEST:
            return
        self.plotter.plotTimeSingle(self.timeseries, ylabel="MISSING")

    def testPlotSingle4(self):
        if IGNORE_TEST:
            return
        ts2 = self.mkTimeseries()
        self.plotter.plotTimeSingle(self.timeseries,
                                    markersize=[2, 5],
                                    timeseries2=ts2,
                                    numRow=2,
                                    numCol=3,
                                    marker=[None, "o"])
        self.plotter.plotTimeSingle(self.timeseries,
                                    timeseries2=ts2,
                                    numRow=2,
                                    numCol=3,
                                    marker=[None, "o"],
                                    alpha=0.1)

    def testPlotMultiple1(self):
        if IGNORE_TEST:
            return
        ts2 = self.mkTimeseries()
        self.plotter.plotTimeMultiple(
            self.timeseries,
            timeseries2=ts2,
            suptitle="Testing",
            marker=[None, 'o', None, None, None, None],
            color=['r', 'g', 'b', 'brown', 'g', 'pink'],
            alpha=0.3)
        self.plotter.plotTimeMultiple(self.timeseries,
                                      timeseries2=ts2,
                                      suptitle="Testing",
                                      numRow=1,
                                      numCol=1,
                                      marker="o")
        self.plotter.plotTimeMultiple(self.timeseries,
                                      timeseries2=ts2,
                                      suptitle="Testing",
                                      numRow=2,
                                      marker="o")
        self.plotter.plotTimeMultiple(self.timeseries, suptitle="Testing")

    def testValuePairs(self):
        if IGNORE_TEST:
            return
        ts2 = self.mkTimeseries()
        self.plotter.plotValuePairs(self.timeseries,
                                    [("S1", "S2"), ("S2", "S3"), ("S4", "S5")],
                                    numCol=2,
                                    numRow=2,
                                    alpha=0.3)
        self.plotter.plotValuePairs(self.timeseries, [("S1", "S2"),
                                                      ("S2", "S3")],
                                    numRow=2)
        self.plotter.plotValuePairs(self.timeseries, [("S1", "S2")])

    def testPlotHistograms(self):
        if IGNORE_TEST:
            return
        self.plotter.plotHistograms(self.timeseries, numCol=2, alpha=0.3)
        self.plotter.plotHistograms(self.timeseries,
                                    numCol=2,
                                    alpha=0.3,
                                    bins=100)

    def testPlotValuePairsBug(self):
        if IGNORE_TEST:
            return
        self.plotter.plotValuePairs(self.timeseries,
                                    pairs=[("S1", "S2"), ("S1", "S6"),
                                           ("S2", "S3")],
                                    numCol=3)

    def testPlotCompare(self):
        if IGNORE_TEST:
            return
        self.plotter.plotCompare(self.timeseries, self.timeseries, numCol=3)

    def testPlotAutoCorrelations(self):
        if IGNORE_TEST:
            return
        self.plotter.plotAutoCorrelations(self.timeseries,
                                          numCol=3,
                                          color=["black", "grey", "grey"],
                                          linestyle=[None, "dashed", "dashed"],
                                          alpha=[None, 0.5, 0.5])

    def testPlotCrossCorrelations(self):
        if IGNORE_TEST:
            return
        self.plotter.plotCrossCorrelations(self.timeseries,
                                           titleFontsize=8,
                                           titlePosition=(0.8, 0.8),
                                           suptitle="Cross Correlations",
                                           color=["black", "g", "g"],
                                           figsize=(12, 10))
Ejemplo n.º 8
0
 def _mkParameterDF(self, parameters=None):
     df = pd.DataFrame(self.bootstrapResult.parameterDct)
     if parameters is not None:
         df = df[parameters]
     df.index.name = TIME
     return NamedTimeseries(dataframe=df)
Ejemplo n.º 9
0
 def mkTimeSeries(self, values, name):
     numPoint = len(values)
     arr = np.array([range(numPoint), values])
     arr = np.resize(arr, (2, numPoint))
     arr = arr.transpose()
     return NamedTimeseries(array=arr, colnames=["time", name])
Ejemplo n.º 10
0
    def copy(self, isKeepLogger=False, isKeepOptimizer=False, **kwargs):
        """
        Creates a copy of the model fitter, overridding any argument
        that is not None.
        Preserves the user-specified settings and the results
        of bootstrapping.
        
        Parameters
        ----------
        isKeepLogger: bool
        isKeepOptimizer: bool
        kwargs: dict
            arguments to override in copy
        
        Returns
        -------
        ModelFitter
        """
        def setValues(names):
            """
            Sets the value for a list of names.
   
            Parameters
            ----------
            names: list-str
           
            Returns
            -------
            list-object
            """
            results = []
            for name in names:
                altName = "_%s" % name
                if name in kwargs.keys():
                    results.append(kwargs[name])
                elif name in self.__dict__.keys():
                    results.append(self.__dict__[name])
                elif altName in self.__dict__.keys():
                    results.append(self.__dict__[altName])
                else:
                    raise RuntimeError("%s: not found" % name)
            return results

        #
        # Get the positional and keyword arguments
        inspectResult = inspect.getfullargspec(ModelFitterCore.__init__)
        allArgNames = inspectResult.args[1:]  # Ignore 'self'
        if inspectResult.defaults is None:
            numKwarg = 0
        else:
            numKwarg = len(inspectResult.defaults)
        numParg = len(allArgNames) - numKwarg  # positional arguments
        pargNames = allArgNames[:numParg]
        kwargNames = allArgNames[numParg:]
        # Construct the arguments
        callPargs = setValues(pargNames)
        callKwargValues = setValues(kwargNames)
        callKwargs = {n: v for n, v in zip(kwargNames, callKwargValues)}
        if numKwarg > 0:
            # Adjust model specification
            modelSpecificationIdx = pargNames.index("modelSpecification")
            observedDataIdx = pargNames.index("observedData")
            modelSpecification = callPargs[modelSpecificationIdx]
            observedTS = NamedTimeseries(callPargs[observedDataIdx])
            selectedColumns = callKwargs["selectedColumns"]
            if not isinstance(modelSpecification, str):
                try:
                    modelSpecification = self.modelSpecification.getAntimony()
                    callPargs[modelSpecificationIdx] = modelSpecification
                    observedTS, selectedColumns = self._adjustNames(
                        modelSpecification, observedTS)
                    callPargs[observedDataIdx] = observedTS
                    callKwargs["selectedColumns"] = selectedColumns
                except Exception as err:
                    self.logger.error(
                        "Problem wth conversion to Antimony. Details:", err)
                    raise ValueError("Cannot proceed.")
            #
            if isKeepLogger:
                callKwargs["logger"] = self.logger
        if numParg < 2:
            callPargs = [None, None]
        newModelFitter = self.__class__(*callPargs, **callKwargs)
        if self.optimizer is not None:
            if isKeepOptimizer:
                newModelFitter.optimizer = self.optimizer.copyResults()
        if self.bootstrapResult is not None:
            newModelFitter.bootstrapResult = self.bootstrapResult.copy()
        return newModelFitter
Ejemplo n.º 11
0
    def simulate(self,
                 params=None,
                 startTime=None,
                 endTime=None,
                 numPoint=None):
        """
        Runs a simulation. Defaults to parameter values in the simulation.

        Parameters
       ----------
        params: lmfit.Parameters
        startTime: float
        endTime: float
        numPoint: int

        Return
        ------
        NamedTimeseries
        """
        def set(default, parameter):
            # Sets to default if parameter unspecified
            if parameter is None:
                return default
            else:
                return parameter

        ##V
        block = Logger.join(self._loggerPrefix, "fitModel.simulate")
        guid = self.logger.startBlock(block)
        ## V
        sub1Block = Logger.join(block, "sub1")
        sub1Guid = self.logger.startBlock(sub1Block)
        startTime = set(self.observedTS.start, startTime)
        endTime = set(self.observedTS.end, endTime)
        numPoint = set(len(self.observedTS), numPoint)
        ##  V
        sub1aBlock = Logger.join(sub1Block, "sub1a")
        sub1aGuid = self.logger.startBlock(sub1aBlock)
        if self.roadrunnerModel is None:
            self._initializeRoadrunnerModel()
        self.roadrunnerModel.reset()
        ##  ^
        self.logger.endBlock(sub1aGuid)
        ##  V
        sub1bBlock = Logger.join(sub1Block, "sub1b")
        sub1bGuid = self.logger.startBlock(sub1bBlock)
        if params is not None:
            # Parameters have been specified
            self._setupModel(params)
        ##  ^
        self.logger.endBlock(sub1bGuid)
        # Do the simulation
        selectedColumns = list(self.selectedColumns)
        if not TIME in selectedColumns:
            selectedColumns.insert(0, TIME)
        ## ^
        self.logger.endBlock(sub1Guid)
        ## V
        roadrunnerBlock = Logger.join(block, "roadrunner")
        roadrunnerGuid = self.logger.startBlock(roadrunnerBlock)
        data = self.roadrunnerModel.simulate(startTime, endTime, numPoint,
                                             selectedColumns)
        self.logger.endBlock(roadrunnerGuid)
        ## ^
        # Select the required columns
        ## V
        sub2Block = Logger.join(block, "sub2")
        sub2Guid = self.logger.startBlock(sub2Block)
        fittedTS = NamedTimeseries(namedArray=data)
        self.logger.endBlock(sub2Guid)
        ## ^
        self.logger.endBlock(guid)
        ##^
        return fittedTS
Ejemplo n.º 12
0
    def evaluate(self,
                 stdResiduals: float = 0.1,
                 relError: float = 0.1,
                 endTime: float = 10.0,
                 numPoint: int = 30,
                 fractionParameterDeviation: float = 0.5,
                 numIteration=NUM_BOOTSTRAP_ITERATION):
        """
        Evaluates model fitting accuracy and bootstrapping for model

        Parameters
        ----------
        stdResiduals: Standard deviations of variable used in constructing reiduals
        relError: relative error of parameter used in evaluation
        endTime: ending time of the simulation
        numPoint: number of points in the simulatin
        fractionParameterDeviation: fractional amount that the parameter can vary
        """
        # Construct synthetic observations
        if self.selectedColumns is None:
            data = self.roadRunner.simulate(0, endTime, numPoint)
        else:
            allColumns = list(self.selectedColumns)
            if TIME not in allColumns:
                allColumns.append(TIME)
            data = self.roadRunner.simulate(0, endTime, numPoint, allColumns)
        bracketTime = "[%s]" % TIME
        if bracketTime in data.colnames:
            # Exclude any column named '[time]'
            idx = data.colnames.index(bracketTime)
            dataArr = np.delete(data, idx, axis=1)
            colnames = list(data.colnames)
            colnames.remove(bracketTime)
            colnames = [s[1:-1] if s != TIME else s for s in colnames]
            simTS = NamedTimeseries(array=dataArr, colnames=colnames)
        else:
            simTS = NamedTimeseries(namedArray=data)
        synthesizer = ObservationSynthesizerRandomErrors(fittedTS=simTS,
                                                         std=stdResiduals)
        observedTS = synthesizer.calculate()
        # Construct the parameter ranges
        parametersToFit = []
        for name in self.parameterValueDct.keys():
            lower = self.parameterValueDct[name] * (1 -
                                                    fractionParameterDeviation)
            upper = self.parameterValueDct[name] * (1 +
                                                    fractionParameterDeviation)
            value = np.random.uniform(lower, upper)
            parametersToFit.append(
                SBstoat.Parameter(name, lower=lower, upper=upper, value=value))
        # Create the fitter
        fitter = ModelFitter(self.roadRunner,
                             observedTS,
                             selectedColumns=self.selectedColumns,
                             parametersToFit=parametersToFit,
                             **self.kwargs)
        msg = "Fitting the parameters %s" % str(self.parameterValueDct.keys())
        self.logger.result(msg)
        # Evaluate the fit
        fitter.fitModel()
        self._recordResult(fitter.params, relError, self.fitModelResult)
        # Evaluate bootstrap
        fitter.bootstrap(numIteration=numIteration)
        if fitter.bootstrapResult is not None:
            if fitter.bootstrapResult.numSimulation > 0:
                self._recordResult(fitter.bootstrapResult.params, relError,
                                   self.bootstrapResult)
Ejemplo n.º 13
0
    def runSimulation(
            cls,
            parameters=None,
            roadrunner=None,
            startTime=0,
            endTime=5,
            numPoint=30,
            selectedColumns=None,
            returnDataFrame=True,
            _logger=Logger(),
            _loggerPrefix="",
    ):
        """
        Runs a simulation. Defaults to parameter values in the simulation.

        Parameters
       ----------
        roadrunner: ExtendedRoadRunner/str
            Roadrunner model
        parameters: lmfit.Parameters
            lmfit parameters
        startTime: float
            start time for the simulation
        endTime: float
            end time for the simulation
        numPoint: int
            number of points in the simulation
        selectedColumns: list-str
            output columns in simulation
        returnDataFrame: bool
            return a DataFrame
        _logger: Logger
        _loggerPrefix: str


        Return
        ------
        NamedTimeseries (or None if fail to converge)
        """
        if isinstance(roadrunner, str):
            roadrunner = cls.initializeRoadrunnerModel(roadrunner)
        else:
            roadrunner.reset()
        if parameters is not None:
            # Parameters have been specified
            cls.setupModel(roadrunner, parameters, logger=_logger)
        # Do the simulation
        if selectedColumns is not None:
            newSelectedColumns = list(selectedColumns)
            if TIME not in newSelectedColumns:
                newSelectedColumns.insert(0, TIME)
            try:
                data = roadrunner.simulate(startTime, endTime, numPoint,
                                           newSelectedColumns)
            except Exception as err:
                _logger.error("Roadrunner exception: ", err)
                data = None
        else:
            try:
                data = roadrunner.simulate(startTime, endTime, numPoint)
            except Exception as err:
                _logger.exception("Roadrunner exception: %s", err)
                data = None
        if data is None:
            return data
        fittedTS = NamedTimeseries(namedArray=data)
        if returnDataFrame:
            result = fittedTS.to_dataframe()
        else:
            result = fittedTS
        return result
Ejemplo n.º 14
0
def getTimeseries():
    return NamedTimeseries(csvPath=TEST_DATA_PATH)