Example #1
0
        /// <summary>
        /// Create series definitions assuming the vary by fields are text fields in the table.
        /// </summary>
        /// <param name="reader">The reader to read from.</param>
        /// <param name="varyByFieldNames">The vary by fields.</param>
        /// <param name="whereClauseForInScopeData">An SQL WHERE clause for rows that are in scope.</param>
        private List <SeriesDefinition> CreateDefinitionsFromFieldInTable(IStorageReader reader, List <string> varyByFieldNames, string whereClauseForInScopeData)
        {
            List <SeriesDefinition> definitions = new List <SeriesDefinition>();

            var fieldsThatExist        = reader.ColumnNames(TableName);
            var varyByThatExistInTable = varyByFieldNames.Where(v => fieldsThatExist.Contains(v)).ToList();

            var validValuesForEachVaryByField = new List <List <string> >();

            foreach (var varyByFieldName in varyByThatExistInTable)
            {
                var data = reader.GetData(TableName,
                                          fieldNames: new string[] { varyByFieldName },
                                          filter: whereClauseForInScopeData,
                                          distinct: true);
                var values = DataTableUtilities.GetColumnAsStrings(data, varyByFieldName).Distinct().ToList();
                validValuesForEachVaryByField.Add(values);
            }

            foreach (var combination in MathUtilities.AllCombinationsOf(validValuesForEachVaryByField.ToArray(), reverse:true))
            {
                var descriptors = new List <SimulationDescription.Descriptor>();
                for (int i = 0; i < combination.Count; i++)
                {
                    descriptors.Add(new SimulationDescription.Descriptor(varyByThatExistInTable[i],
                                                                         combination[i]));
                }
                definitions.Add(new SeriesDefinition(this, whereClauseForInScopeData, Filter, descriptors));
            }

            return(definitions);
        }
Example #2
0
        /// <summary>
        /// If a simulation description has the same descriptor more than once,
        /// split it into multiple descriptions.
        /// </summary>
        /// <remarks>
        /// A simulation description can have multiple zones
        /// e.g.
        ///    Sim1 Descriptors: SimulationName=abc, Zone=field1, Zone=field2, x=1, x=2
        /// Need to split this into 4 separate simulation descriptions:
        ///    Sim1 Descriptors: SimulationName=abc, Zone=field1, x=1
        ///    Sim2 Descriptors: SimulationName=abc, Zone=field1, x=2
        ///    Sim3 Descriptors: SimulationName=abc, Zone=field2, x=1
        ///    Sim4 Descriptors: SimulationName=abc, Zone=field2f, x=2
        /// </remarks>
        /// <param name="simulationDescriptions">Simulation descriptions.</param>
        private void SplitDescriptionsWithSameDescriptors(List <SimulationDescription> simulationDescriptions)
        {
            var newList = new List <SimulationDescription>();

            foreach (var simulationDescription in simulationDescriptions)
            {
                var descriptors      = new List <List <SimulationDescription.Descriptor> >();
                var descriptorGroups = simulationDescription.Descriptors.GroupBy(d => d.Name);
                foreach (var group in descriptorGroups)
                {
                    descriptors.Add(group.ToList());
                }

                var allCombinations = MathUtilities.AllCombinationsOf(descriptors.ToArray());
                foreach (var combination in allCombinations)
                {
                    newList.Add(new SimulationDescription(null, simulationDescription.Name)
                    {
                        Descriptors = combination
                    });
                }
            }
            simulationDescriptions.Clear();
            simulationDescriptions.AddRange(newList);
        }
Example #3
0
        /// <summary>
        /// Calculate a list of fall combinations of factors.
        /// </summary>
        private List <List <CompositeFactor> > CalculateAllCombinations()
        {
            Factors Factors = Apsim.Child(this, typeof(Factors)) as Factors;

            // Create a list of list of factorValues so that we can do permutations of them.
            List <List <CompositeFactor> > allValues = new List <List <CompositeFactor> >();

            if (Factors != null)
            {
                foreach (Factor factor in Factors.factors)
                {
                    if (factor.Enabled)
                    {
                        allValues.Add(factor.GetCompositeFactors());
                    }
                }
                var allCombinations = MathUtilities.AllCombinationsOf <CompositeFactor>(allValues.ToArray());

                // Remove disabled simulations.
                if (DisabledSimNames != null)
                {
                    allCombinations.RemoveAll(comb => DisabledSimNames.Contains(GetName(comb)));
                }

                return(allCombinations);
            }
            else
            {
                return(null);
            }
        }
Example #4
0
        /// <summary>
        /// Return a list of list of factorvalue objects for all permutations.
        /// </summary>
        public List <List <FactorValue> > AllCombinations()
        {
            Factors Factors = Apsim.Child(this, typeof(Factors)) as Factors;

            // Create a list of list of factorValues so that we can do permutations of them.
            List <List <FactorValue> > allValues = new List <List <FactorValue> >();

            if (Factors != null)
            {
                bool doFullFactorial = false;
                foreach (Factor factor in Factors.factors)
                {
                    List <FactorValue> factorValues = factor.CreateValues();
                    allValues.Add(factorValues);
                    doFullFactorial = doFullFactorial || factorValues.Count > 1;
                }
                if (doFullFactorial)
                {
                    return(MathUtilities.AllCombinationsOf <FactorValue>(allValues.ToArray()));
                }
                else
                {
                    return(allValues);
                }
            }
            return(null);
        }
Example #5
0
        /// <summary>
        /// Return a list of list of factorvalue objects for all permutations.
        /// </summary>
        public List <List <FactorValue> > AllCombinations()
        {
            Factors Factors = Apsim.Child(this, typeof(Factors)) as Factors;

            // Create a list of list of factorValues so that we can do permutations of them.
            List <List <FactorValue> > allValues = new List <List <FactorValue> >();

            if (Factors != null)
            {
                bool doFullFactorial = true;
                foreach (Factor factor in Factors.factors)
                {
                    if (factor.Enabled)
                    {
                        List <FactorValue> factorValues = factor.CreateValues();

                        // Iff any of the factors modify the same model (e.g. have a duplicate path), then we do not want to do a full factorial.
                        // This code should check if there are any such duplicates by checking each path in each factor value in the list of factor
                        // values for the current factor against each path in each list of factor values in the list of all factors which we have
                        // already added to the global list of list of factor values.
                        foreach (FactorValue currentFactorValue in factorValues)
                        {
                            foreach (string currentFactorPath in currentFactorValue.Paths)
                            {
                                foreach (List <FactorValue> allFactorValues in allValues)
                                {
                                    foreach (FactorValue globalValue in allFactorValues)
                                    {
                                        foreach (string globalPath in globalValue.Paths)
                                        {
                                            if (string.Equals(globalPath, currentFactorPath, StringComparison.CurrentCulture))
                                            {
                                                doFullFactorial = false;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        allValues.Add(factorValues);
                    }
                }
                if (doFullFactorial)
                {
                    return(MathUtilities.AllCombinationsOf <FactorValue>(allValues.ToArray()));
                }
                else
                {
                    return(allValues);
                }
            }
            return(null);
        }
        /// <summary>Return a enumerable collection of groups where a group is
        /// defined by the current index.</summary>
        public IEnumerable <IndexedDataTableGroupEnumerator> Groups()
        {
            SetIndex(null);

            List <List <object> > allValues = new List <List <object> >();

            foreach (string indexColumnName in indexColumnNames)
            {
                allValues.Add(Get <object>(indexColumnName).Distinct().ToList());
            }
            List <List <object> > allPermutations = MathUtilities.AllCombinationsOf <object>(allValues.ToArray());

            foreach (var permutation in allPermutations)
            {
                SetIndex(permutation.ToArray());
                if (view.Count > 0)
                {
                    yield return(new IndexedDataTableGroupEnumerator(this, permutation.ToArray()));
                }
            }
        }
Example #7
0
        /// <summary>
        /// Get a list of row filters that define the blocks of data that we have
        /// to calculate stats for.
        /// </summary>
        /// <returns></returns>
        private List <string> GetRowFilters(DataTable data)
        {
            var rowFilters = new List <string>();

            List <List <string> > fieldValues = new List <List <string> >();

            foreach (var fieldName in FieldNamesToSplitOn)
            {
                if (!data.Columns.Contains(fieldName))
                {
                    throw new Exception($"Cannot find field {fieldName} in table {data.TableName}");
                }
                fieldValues.Add(DataTableUtilities.GetColumnAsStrings(data, fieldName).Distinct().ToList());
            }

            var permutations = MathUtilities.AllCombinationsOf <string>(fieldValues.ToArray());

            foreach (var permutation in permutations)
            {
                rowFilters.Add(CreateRowFilter(permutation, data));
            }

            return(rowFilters);
        }
Example #8
0
        /// <summary>
        /// Get a list of all permutations of child factors and compositefactors.
        /// </summary>
        internal List <List <CompositeFactor> > GetPermutations()
        {
            var factors = new List <List <CompositeFactor> >();

            foreach (Factor factor in Apsim.Children(this, typeof(Factor)))
            {
                if (factor.Enabled)
                {
                    factors.Add(factor.GetCompositeFactors());
                }
            }

            var compositeFactors = Apsim.Children(this, typeof(CompositeFactor)).Where(cf => cf.Enabled);

            var permutations = new List <List <CompositeFactor> >();

            if (compositeFactors.Count() > 0)
            {
                // Loop through each composite factor and permute with the factor children.
                foreach (CompositeFactor compositeFactor in compositeFactors)
                {
                    var valuesToPermutate = new List <List <CompositeFactor> >(factors);
                    valuesToPermutate.Add(new List <CompositeFactor>()
                    {
                        compositeFactor
                    });
                    permutations.AddRange(MathUtilities.AllCombinationsOf <CompositeFactor>(valuesToPermutate.ToArray()));
                }
            }
            else
            {
                permutations = MathUtilities.AllCombinationsOf <CompositeFactor>(factors.ToArray());
            }

            return(permutations);
        }
Example #9
0
        /// <summary>Get a .db filter for the specified combination.</summary>
        /// <param name="experiment">The experiment</param>
        /// <param name="combination">The combination</param>
        /// <returns>The filter</returns>
        private string GetFilter(Experiment experiment, List <FactorAndIndex> combination)
        {
            // Need to determine all the simulation names that match the specified combination.
            // If the combination is just a single factor value then the simulation names will be
            // a permutation of that factor value and all other factor values in other factors
            // For example:
            //   IF combination is CVGibe
            //   THEN filter = SimulationName = 'VanDeldenCvGibePP1' or SimulationName = 'VanDeldenCvGibePP2' or SimulationName = 'VanDeldenCvGibePP3' ...
            // If the combintation of 2 factor values for 2 different factors then the filter will
            // be a permutation of those 2 factor values and all OTHER factor values in OTHER factors.
            // For example:
            //   IF combintation is CVGibePP1
            //   THEN filter = SimulationName = 'SimulationName = 'VanDeldenCvGibePP1'
            //   (This is because the example has no other factors other than CV and PP.
            Factors factors = Apsim.Child(experiment as IModel, typeof(Factors)) as Factors;

            List <List <KeyValuePair <string, string> > > simulationBits = new List <List <KeyValuePair <string, string> > >();

            foreach (Factor factor in factors.factors)
            {
                List <KeyValuePair <string, string> > names = new List <KeyValuePair <string, string> >();
                FactorAndIndex factorAndIndex = combination.Find(f => factor.Name == f.factorName);
                if (factorAndIndex == null)
                {
                    if (factor.Children.Count > 0)
                    {
                        foreach (IModel child in factor.Children)
                        {
                            names.Add(new KeyValuePair <string, string>(factor.Name, child.Name));
                        }
                    }
                    else
                    {
                        foreach (FactorValue factorValue in factor.CreateValues())
                        {
                            if (factorValue.Values.Count >= 1)
                            {
                                names.Add(new KeyValuePair <string, string>(factor.Name, factorValue.Values[0].ToString()));
                            }
                        }
                    }
                }
                else
                {
                    names.Add(new KeyValuePair <string, string>(factor.Name, factorAndIndex.factorValue));
                }
                simulationBits.Add(names);
            }

            List <List <KeyValuePair <string, string> > > combinations = MathUtilities.AllCombinationsOf <KeyValuePair <string, string> >(simulationBits.ToArray());

            string filter = string.Empty;

            foreach (List <KeyValuePair <string, string> > c in combinations)
            {
                if (filter != string.Empty)
                {
                    filter += " or ";
                }
                filter += "SimulationName = '" + experiment.Name;
                foreach (KeyValuePair <string, string> pair in c)
                {
                    filter += pair.Key + pair.Value;
                }
                filter += "'";
            }

            return(filter);
        }
Example #10
0
        /// <summary>
        /// Graph the specified experiment.
        /// </summary>
        /// <param name="parentExperiment"></param>
        /// <param name="ourDefinitions"></param>
        private void GraphExperiment(Experiment parentExperiment, List <SeriesDefinition> ourDefinitions)
        {
            Factors factors = Apsim.Child(parentExperiment as IModel, typeof(Factors)) as Factors;

            if (factors != null)
            {
                // Given this example (from Teff.apsimx).
                //    Factors
                //       CV   - Gibe, Ziquala, Ayana, 04T19   (4 factor values)
                //       PP   - 1, 2, 3, 4, 5, 6              (6 factor values)
                // -----------------------------------------------------------
                //    If FactorIndexToVaryColours = 0  (index of CV factor)
                //       FactorIndexToVaryLines   = 1  (index of PP factor)
                //       FactorIndexToVaryMarkers = -1 (doesn't point to a factor)
                //    Then permutations will be:
                //       CVGibe & PP1
                //       CVZiquala & PP2
                //       CVAyana & PP3
                //       ... (24 in total - 4 x 6)
                // -----------------------------------------------------------
                //    If FactorIndexToVaryColours = 0  (index of CV factor)
                //       FactorIndexToVaryLines   = -1 (doesn't point to a factor)
                //       FactorIndexToVaryMarkers = -1 (doesn't point to a factor)
                //    Then permutations will be:
                //       CVGibe
                //       CVZiquala
                //       CVAyana
                //       CV04T19  (4 in total - 4)
                // -----------------------------------------------------------
                // The FactorIndexToVary... variables denote which factors should be
                // separate series.

                List <List <FactorAndIndex> > factorIndexes = new List <List <FactorAndIndex> >();
                for (int f = 0; f != factors.Children.Count; f++)
                {
                    if (FactorIndexToVaryColours == f)
                    {
                        CreateFactorAndIndex(factors.Children[FactorIndexToVaryColours] as Factor, factorIndexes,
                                             FactorAndIndex.TypeToVary.Colour);
                    }

                    if (FactorIndexToVaryLines == f)
                    {
                        CreateFactorAndIndex(factors.Children[FactorIndexToVaryLines] as Factor, factorIndexes,
                                             FactorAndIndex.TypeToVary.Line);
                    }

                    if (FactorIndexToVaryMarkers == f)
                    {
                        CreateFactorAndIndex(factors.Children[FactorIndexToVaryMarkers] as Factor, factorIndexes,
                                             FactorAndIndex.TypeToVary.Marker);
                    }
                }

                List <List <FactorAndIndex> > permutations = MathUtilities.AllCombinationsOf(factorIndexes.ToArray());

                // If no 'vary by' were specified then create a dummy one. All data will be on one series.
                if (permutations == null || permutations.Count == 0)
                {
                    permutations = new List <List <FactorAndIndex> >();
                    permutations.Add(new List <FactorAndIndex>());
                }

                // Loop through all permutations and create a graph series definition for each.
                foreach (List <FactorAndIndex> combination in permutations)
                {
                    // Determine the marker, line and colour for this combination.
                    MarkerType marker      = Marker;
                    LineType   line        = Line;
                    int        colourIndex = Array.IndexOf(ColourUtilities.Colours, Colour);
                    if (colourIndex == -1)
                    {
                        colourIndex = 0;
                    }
                    string seriesName = string.Empty;
                    for (int i = 0; i < combination.Count; i++)
                    {
                        if (combination[i].typeToVary == FactorAndIndex.TypeToVary.Colour)
                        {
                            colourIndex = combination[i].factorValueIndex;
                        }
                        if (combination[i].typeToVary == FactorAndIndex.TypeToVary.Marker)
                        {
                            marker = GetEnumValue <MarkerType>(combination[i].factorValueIndex);
                        }
                        if (combination[i].typeToVary == FactorAndIndex.TypeToVary.Line)
                        {
                            line = GetEnumValue <LineType>(combination[i].factorValueIndex);
                        }
                        seriesName += combination[i].factorName + combination[i].factorValue;
                    }

                    string filter = GetFilter(parentExperiment, combination);

                    CreateDefinitions(parentExperiment.BaseSimulation, seriesName, filter, ref colourIndex,
                                      ref marker, line, ourDefinitions, parentExperiment.Names());
                }
            }
        }
Example #11
0
        /// <summary>
        /// Return all possible factor values for this factor.
        /// </summary>
        public List <FactorValue> CreateValues()
        {
            List <FactorValue> factorValues = new List <FactorValue>();

            // Example specifications:
            //    simple specification:
            //      [SowingRule].Script.SowingDate = 2003-11-01
            //      [SowingRule].Script.SowingDate = 2003-11-01, 2003-12-20
            //    range specification:
            //      [FertiliserRule].Script.ApplicationAmount = 0 to 100 step 20
            //    model replacement specification:
            //      [FertiliserRule]
            //    compound specification has multiple other specifications that
            //    result in a single factor value being returned.


            List <List <PathValuesPair> > allValues   = new List <List <PathValuesPair> >();
            List <PathValuesPair>         fixedValues = new List <PathValuesPair>();

            foreach (string specification in Specifications)
            {
                if (specification.Contains(" to ") &&
                    specification.Contains(" step "))
                {
                    allValues.Add(ParseRangeSpecification(specification));
                }
                else
                {
                    List <PathValuesPair> localValues;
                    if (specification.Contains('='))
                    {
                        localValues = ParseSimpleSpecification(specification);
                    }
                    else
                    {
                        localValues = ParseModelReplacementSpecification(specification);
                    }

                    if (localValues.Count == 1)
                    {
                        fixedValues.Add(localValues[0]);
                    }
                    else if (localValues.Count > 1)
                    {
                        allValues.Add(localValues);
                    }
                }
            }

            // Look for child Factor models.
            foreach (Factor childFactor in Apsim.Children(this, typeof(Factor)))
            {
                foreach (FactorValue childFactorValue in childFactor.CreateValues())
                {
                    childFactorValue.Name = Name + childFactorValue.Name;
                    factorValues.Add(childFactorValue);
                }
            }


            if (allValues.Count == 0)
            {
                PathValuesPairToFactorValue(factorValues, fixedValues, null);
            }

            List <List <PathValuesPair> > allCombinations = MathUtilities.AllCombinationsOf <PathValuesPair>(allValues.ToArray());

            if (allCombinations != null)
            {
                foreach (List <PathValuesPair> combination in allCombinations)
                {
                    PathValuesPairToFactorValue(factorValues, fixedValues, combination);
                }
            }

            return(factorValues);
        }