Beispiel #1
0
        /// <summary>Called by the graph presenter to get a list of all actual series to put on the graph.</summary>
        /// <param name="reader">A storage reader.</param>
        /// <param name="simulationDescriptions">A list of simulation descriptions that are in scope.</param>
        /// <param name="simulationFilter"></param>
        public IEnumerable <SeriesDefinition> CreateSeriesDefinitions(IStorageReader reader,
                                                                      List <SimulationDescription> simulationDescriptions,
                                                                      List <string> simulationFilter = null)
        {
            var seriesDefinitions = new List <SeriesDefinition>();

            // If this series doesn't have a table name then it must be getting its data from other models.
            if (TableName == null)
            {
                seriesDefinitions.Add(new SeriesDefinition(this, "Current", colModifier: 0, markerModifier: 0));
            }
            else
            {
                int checkpointNumber = 0;
                foreach (var checkpointName in reader.CheckpointNames)
                {
                    if (checkpointName == "Current" || reader.GetCheckpointShowOnGraphs(checkpointName))
                    {
                        // Colour modifier can be in range [-1, 1] but we will
                        // use only 0..1 so that we start with the normal colour
                        // and gradually get brighter.
                        double colourModifier = (double)checkpointNumber / reader.CheckpointNames.Count;
                        double markerModifier = 1 + 1.0 * checkpointNumber / reader.CheckpointNames.Count;

                        // TableName exists so get the vary by fields and the simulation descriptions.
                        var varyByFieldNames = GetVaryByFieldNames();
                        if (simulationFilter == null)
                        {
                            simulationFilter = simulationDescriptions.Select(d => d.Name).Distinct().ToList();
                        }

                        var inScopeSimulationNames = CreateInScopeWhereClause(reader, simulationFilter);

                        if (varyByFieldNames.Count == 0 || varyByFieldNames.Contains("Graph series"))
                        {
                            // No vary by fields. Just plot the whole table in a single
                            // series with data that is in scope.
                            seriesDefinitions.Add(new SeriesDefinition(this, checkpointName, colourModifier, markerModifier, inScopeSimulationNames, Filter));
                        }
                        else
                        {
                            // There are one or more vary by fields. Create series definitions
                            // for each combination of vary by fields.
                            seriesDefinitions.AddRange(CreateDefinitionsUsingVaryBy(varyByFieldNames, checkpointName, colourModifier, markerModifier, simulationDescriptions, inScopeSimulationNames));
                        }

                        // If we don't have any definitions then see if the vary by fields
                        // refer to string fields in the database table.
                        if (seriesDefinitions.Count == 0)
                        {
                            seriesDefinitions = CreateDefinitionsFromFieldInTable(reader, checkpointName, colourModifier, markerModifier, varyByFieldNames, inScopeSimulationNames);
                        }

                        // Paint all definitions.
                        var painter = GetSeriesPainter();
                        foreach (var seriesDefinition in seriesDefinitions)
                        {
                            painter.Paint(seriesDefinition);
                        }

                        checkpointNumber++;
                    }
                }
            }
            return(seriesDefinitions);
        }
Beispiel #2
0
        /// <summary>Called by the graph presenter to get a list of all actual series to put on the graph.</summary>
        /// <param name="definitions">A list of definitions to add to.</param>
        /// <param name="reader">A storage reader.</param>
        /// <param name="simulationFilter"></param>
        public void GetSeriesToPutOnGraph(IStorageReader reader, List <SeriesDefinition> definitions, List <string> simulationFilter = null)
        {
            List <SeriesDefinition> seriesDefinitions = new List <SeriesDefinition>();

            // If this series doesn't have a table name then it must be getting its data from other models.
            if (TableName == null)
            {
                seriesDefinitions.Add(new SeriesDefinition(this, "Current", colModifier: 0, markerModifier: 0));
                seriesDefinitions[0].ReadData(reader, simulationDescriptions);
            }
            else
            {
                int checkpointNumber = 0;
                foreach (var checkpointName in reader.CheckpointNames)
                {
                    if (checkpointName == "Current" || reader.GetCheckpointShowOnGraphs(checkpointName))
                    {
                        // Colour modifier can be in range [-1, 1] but we will
                        // use only 0..1 so that we start with the normal colour
                        // and gradually get brighter.
                        double colourModifier = (double)checkpointNumber / reader.CheckpointNames.Count;
                        double markerModifier = 1 + 1.0 * checkpointNumber / reader.CheckpointNames.Count;

                        // TableName exists so get the vary by fields and the simulation descriptions.
                        var varyByFieldNames = GetVaryByFieldNames();
                        simulationDescriptions = FindSimulationDescriptions();
                        if (simulationFilter == null)
                        {
                            simulationFilter = simulationDescriptions.Select(d => d.Name).Distinct().ToList();
                        }

                        var whereClauseForInScopeData = CreateInScopeWhereClause(reader, simulationFilter);

                        if (varyByFieldNames.Count == 0 || varyByFieldNames.Contains("Graph series"))
                        {
                            // No vary by fields. Just plot the whole table in a single
                            // series with data that is in scope.
                            seriesDefinitions.Add(new SeriesDefinition(this, checkpointName, colourModifier, markerModifier, whereClauseForInScopeData, Filter));
                        }
                        else
                        {
                            // There are one or more vary by fields. Create series definitions
                            // for each combination of vary by fields.
                            seriesDefinitions.AddRange(CreateDefinitionsUsingVaryBy(varyByFieldNames, checkpointName, colourModifier, markerModifier, simulationDescriptions, whereClauseForInScopeData));
                        }

                        // If we don't have any definitions then see if the vary by fields
                        // refer to string fields in the database table.
                        if (seriesDefinitions.Count == 0)
                        {
                            seriesDefinitions = CreateDefinitionsFromFieldInTable(reader, checkpointName, colourModifier, markerModifier, varyByFieldNames, whereClauseForInScopeData);
                        }

                        // Paint all definitions.
                        var painter = GetSeriesPainter();
                        foreach (var seriesDefinition in seriesDefinitions)
                        {
                            painter.Paint(seriesDefinition);
                        }

                        // Tell each series definition to read its data.
                        foreach (var seriesDefinition in seriesDefinitions)
                        {
                            seriesDefinition.ReadData(reader, simulationDescriptions);
                        }

                        // Remove series that have no data.
                        seriesDefinitions.RemoveAll(d => !MathUtilities.ValuesInArray(d.X) || !MathUtilities.ValuesInArray(d.Y));

                        checkpointNumber++;
                    }
                }
            }

            definitions.AddRange(seriesDefinitions);

            // We might have child models that want to add to our series definitions e.g. regression.
            foreach (IGraphable series in Apsim.Children(this, typeof(IGraphable)))
            {
                series.GetSeriesToPutOnGraph(reader, definitions);
            }
        }
Beispiel #3
0
        /// <summary>Get a list of all actual series to put on the graph.</summary>
        /// <param name="storage">Storage service (required for access to checkpoint names).</param>
        /// <param name="definitions">Series definitions to be used (allows for caching of data).</param>
        /// <param name="simulationsFilter">Unused simulation names filter.</param>
        public IEnumerable <SeriesDefinition> GetSeriesToPutOnGraph(IStorageReader storage, IEnumerable <SeriesDefinition> definitions, List <string> simulationsFilter = null)
        {
            stats.Clear();
            equationColours.Clear();

            int checkpointNumber = 0;
            List <SeriesDefinition> regressionLines = new List <SeriesDefinition>();

            foreach (var checkpointName in storage.CheckpointNames)
            {
                if (checkpointName != "Current" && !storage.GetCheckpointShowOnGraphs(checkpointName)) // smh
                // If "Show on graphs" is disabled on this checkpoint, skip it.
                {
                    continue;
                }

                // Get all x/y data
                List <double> x = new List <double>();
                List <double> y = new List <double>();
                foreach (SeriesDefinition definition in definitions)
                {
                    if (definition.CheckpointName == checkpointName)
                    {
                        if (definition.X != null && definition.Y != null)
                        {
                            if (ReflectionUtilities.IsNumericType(definition.X.GetType().GetElementType()) && ReflectionUtilities.IsNumericType(definition.Y.GetType().GetElementType()))
                            {
                                x.AddRange(definition.X.Cast <object>().Select(xi => Convert.ToDouble(xi, CultureInfo.InvariantCulture)).ToArray());
                                y.AddRange(definition.Y.Cast <object>().Select(yi => Convert.ToDouble(yi, CultureInfo.InvariantCulture)).ToArray());
                            }
                        }
                    }
                }
                try
                {
                    if (ForEachSeries)
                    {
                        // Display a regression line for each series.
                        // todo - should this also filter on checkpoint name?
                        foreach (SeriesDefinition definition in definitions)
                        {
                            if (definition.X is double[] && definition.Y is double[])
                            {
                                SeriesDefinition regressionSeries = PutRegressionLineOnGraph(definition.X, definition.Y, definition.Colour, null);
                                if (regressionSeries != null)
                                {
                                    regressionLines.Add(regressionSeries);
                                    equationColours.Add(definition.Colour);
                                }
                            }
                        }
                    }
                    else
                    {
                        var regresionLineName = "Regression line";
                        if (checkpointName != "Current")
                        {
                            regresionLineName = "Regression line (" + checkpointName + ")";
                        }

                        // Display a single regression line for all data.
                        if (x.Count > 0 && y.Count == x.Count)
                        {
                            SeriesDefinition regressionSeries = PutRegressionLineOnGraph(x, y, ColourUtilities.ChooseColour(checkpointNumber), regresionLineName);
                            if (regressionSeries != null)
                            {
                                regressionLines.Add(regressionSeries);
                                equationColours.Add(ColourUtilities.ChooseColour(checkpointNumber));
                            }
                        }
                    }

                    if (showOneToOne)
                    {
                        if (x.Count > 0 && y.Count == x.Count)
                        {
                            regressionLines.Add(Put1To1LineOnGraph(x, y));
                        }
                    }
                }
                catch (Exception err)
                {
                    IEnumerable <string> xs = definitions.Select(d => d.XFieldName).Distinct();
                    IEnumerable <string> ys = definitions.Select(d => d.YFieldName).Distinct();
                    string xFields          = string.Join(", ", xs);
                    string yFields          = string.Join(", ", ys);
                    throw new InvalidOperationException($"Unable to create regression line for checkpoint {checkpointName}. (x variables = [{xFields}], y variables = [{yFields}])", err);
                }
                checkpointNumber++;
            }

            return(regressionLines);
        }