Beispiel #1
0
        /// <summary>
        /// Compile the expression and return the compiled function.
        /// </summary>
        public void CompileExpression()
        {
            // From a list of visible models in scope, create [Link] lines e.g.
            //    [Link] Clock Clock;
            //    [Link] Weather Weather;
            // and namespace lines e.g.
            //    using Models.Clock;
            //    using Models;
            var models = Apsim.FindAll(Parent).Where(model => !model.IsHidden &&
                                                     model.GetType() != typeof(Graph) &&
                                                     model.GetType() != typeof(Series) &&
                                                     model.GetType().Name != "StorageViaSockets");
            var links         = new StringBuilder();
            var namespaceList = new SortedSet <string>();

            foreach (var model in models)
            {
                links.Append("[Link(ByName=true)] ");
                links.Append(model.GetType().FullName);
                links.Append(' ');
                links.Append(model.Name);
                links.AppendLine(";");

                namespaceList.Add("using " + model.GetType().Namespace + ";");
            }
            var namespaces = StringUtilities.BuildString(namespaceList, Environment.NewLine);

            // Get template c# script.
            var template = ReflectionUtilities.GetResourceAsString("Models.Resources.Scripts.CSharpExpressionTemplate.cs");

            // Replace the "using Models;" namespace place holder with the namesspaces above.
            //template = template.Replace("using Models;", namespaces);

            // Replace the link place holder in the template with links created above.
            template = template.Replace("[Link] Clock Clock;", links.ToString());

            // Replace the expression place holder in the template with the real expression.
            template = template.Replace("return 123456;", "return " + Expression + ";");

            // Create a new manager that will compile the expression.
            var manager = new Manager();

            manager.Code   = template;
            manager.Parent = Parent;
            try
            {
                manager.OnCreated();   // This will compile the expression.
            }
            catch (Exception err)
            {
                var st = "Cannot compile expression: " + Expression + Environment.NewLine;
                st += err.ToString() + Environment.NewLine;
                st += "Generated code: " + Environment.NewLine + template;
                throw new Exception(st);
            }

            expressionFunction = manager.Children[0] as IFunction;

            // Resolve links
            var linkResolver = new Links();

            linkResolver.Resolve(expressionFunction as IModel, true);
        }
Beispiel #2
0
        /// <summary>
        /// Event handler for checkbox for 'Include in documentation' menu item.
        /// </summary>
        public bool IncludeInDocumentationChecked()
        {
            IModel model = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as IModel;

            return((model != null) ? model.IncludeInDocumentation : false);
        }
Beispiel #3
0
        /// <summary>
        /// Event handler for checkbox for 'Enabled' menu item.
        /// </summary>
        public bool EnabledChecked()
        {
            IModel model = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as IModel;

            return(model.Enabled);
        }
Beispiel #4
0
        /// <summary>Main run method for performing our calculations and storing data.</summary>
        /// <param name="dataStore">The data store.</param>
        /// <exception cref="ApsimXException">
        /// Could not find model data table:  + PredictedTableName
        /// or
        /// Could not find observed data table:  + ObservedTableName
        /// </exception>
        public void Run(IStorageReader dataStore)
        {
            if (PredictedTableName != null && ObservedTableName != null)
            {
                dataStore.DeleteDataInTable(this.Name);

                List <string> predictedDataNames = dataStore.GetTableColumns(PredictedTableName);
                List <string> observedDataNames  = dataStore.GetTableColumns(ObservedTableName);

                if (predictedDataNames == null)
                {
                    throw new ApsimXException(this, "Could not find model data table: " + PredictedTableName);
                }

                if (observedDataNames == null)
                {
                    throw new ApsimXException(this, "Could not find observed data table: " + ObservedTableName);
                }

                // get the common columns between these lists of columns
                IEnumerable <string> commonCols = predictedDataNames.Intersect(observedDataNames);

                StringBuilder query = new StringBuilder("SELECT ");
                foreach (string s in commonCols)
                {
                    if (s == FieldNameUsedForMatch || s == FieldName2UsedForMatch || s == FieldName3UsedForMatch)
                    {
                        query.Append("I.'@field', ");
                    }
                    else
                    {
                        query.Append("I.'@field' AS 'Observed.@field', R.'@field' AS 'Predicted.@field', ");
                    }

                    query.Replace("@field", s);
                }

                query.Append("FROM " + ObservedTableName + " I INNER JOIN " + PredictedTableName + " R USING (SimulationID) WHERE I.'@match1' = R.'@match1'");
                if (FieldName2UsedForMatch != null && FieldName2UsedForMatch != string.Empty)
                {
                    query.Append(" AND I.'@match2' = R.'@match2'");
                }
                if (FieldName3UsedForMatch != null && FieldName3UsedForMatch != string.Empty)
                {
                    query.Append(" AND I.'@match3' = R.'@match3'");
                }

                int checkpointID = dataStore.GetCheckpointID("Current");
                query.Append(" AND R.CheckpointID = " + checkpointID);

                query.Replace(", FROM", " FROM"); // get rid of the last comma
                query.Replace("I.'SimulationID' AS 'Observed.SimulationID', R.'SimulationID' AS 'Predicted.SimulationID'", "I.'SimulationID' AS 'SimulationID'");

                query = query.Replace("@match1", FieldNameUsedForMatch);
                query = query.Replace("@match2", FieldName2UsedForMatch);
                query = query.Replace("@match3", FieldName3UsedForMatch);

                if (Parent is Folder)
                {
                    // Limit it to particular simulations in scope.
                    List <string> simulationNames = new List <string>();
                    foreach (Experiment experiment in Apsim.FindAll(this, typeof(Experiment)))
                    {
                        simulationNames.AddRange(experiment.GetSimulationNames());
                    }
                    foreach (Simulation simulation in Apsim.FindAll(this, typeof(Simulation)))
                    {
                        if (!(simulation.Parent is Experiment))
                        {
                            simulationNames.Add(simulation.Name);
                        }
                    }

                    query.Append(" AND I.SimulationID in (");
                    foreach (string simulationName in simulationNames)
                    {
                        if (simulationName != simulationNames[0])
                        {
                            query.Append(',');
                        }
                        query.Append(dataStore.GetSimulationID(simulationName));
                    }
                    query.Append(")");
                }

                DataTable predictedObservedData = dataStore.RunQuery(query.ToString());

                if (predictedObservedData != null)
                {
                    predictedObservedData.TableName = this.Name;
                    dataStore.WriteTable(predictedObservedData);

                    List <string> unitFieldNames = new List <string>();
                    List <string> unitNames      = new List <string>();

                    // write units to table.
                    foreach (string fieldName in commonCols)
                    {
                        string units = dataStore.GetUnits(PredictedTableName, fieldName);
                        if (units != null && units != "()")
                        {
                            string unitsMinusBrackets = units.Replace("(", "").Replace(")", "");
                            unitFieldNames.Add("Predicted." + fieldName);
                            unitNames.Add(unitsMinusBrackets);
                            unitFieldNames.Add("Observed." + fieldName);
                            unitNames.Add(unitsMinusBrackets);
                        }
                    }
                    if (unitNames.Count > 0)
                    {
                        dataStore.AddUnitsForTable(Name, unitFieldNames, unitNames);
                    }
                }

                else
                {
                    // Determine what went wrong.
                    DataTable predictedData = dataStore.RunQuery("SELECT * FROM " + PredictedTableName);
                    DataTable observedData  = dataStore.RunQuery("SELECT * FROM " + ObservedTableName);
                    if (predictedData == null || predictedData.Rows.Count == 0)
                    {
                        throw new Exception(Name + ": Cannot find any predicted data.");
                    }
                    else if (observedData == null || observedData.Rows.Count == 0)
                    {
                        throw new Exception(Name + ": Cannot find any observed data in node: " + ObservedTableName + ". Check for missing observed file or move " + ObservedTableName + " to top of child list under DataStore (order is important!)");
                    }
                    else
                    {
                        throw new Exception(Name + ": Observed data was found but didn't match the predicted values. Make sure the values in the SimulationName column match the simulation names in the user interface. Also ensure column names in the observed file match the APSIM report column names.");
                    }
                }
            }
        }
Beispiel #5
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>
        public void GetSeriesToPutOnGraph(List <SeriesDefinition> definitions)
        {
            List <SeriesDefinition> ourDefinitions = 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)
            {
                ourDefinitions.Add(CreateDefinition(Name, null, Colour, Marker, Line, null));
            }
            else
            {
                // Find a parent that heads the scope that we're going to graph
                IModel parent = FindParent();

                List <SimulationZone> simulationZones = null;
                do
                {
                    // Create a list of all simulation/zone objects that we're going to graph.
                    simulationZones = BuildListFromModel(parent);
                    parent          = parent.Parent;
                }while (simulationZones.Count == 0 && parent != null);

                // Get rid of factors that don't vary across objects.
                RemoveFactorsThatDontVary(simulationZones);
                FactorNamesForVarying = GetFactorList(simulationZones);

                // Check for old .apsimx that doesn't vary colours, lines or markers but has experiments. In this
                // new code, we want to make this situation explicit and say we'll vary colours and markers by
                // experiment.
                if (FactorIndexToVaryColours == -1 && FactorIndexToVaryLines == -1 && FactorIndexToVaryMarkers == -1 &&
                    FactorNamesForVarying.Contains("Experiment") && !ColourUtilities.Colours.Contains(Colour))
                {
                    FactorIndexToVaryColours = FactorNamesForVarying.IndexOf("Experiment");
                    FactorIndexToVaryMarkers = FactorIndexToVaryColours;
                }
                else if (!ColourUtilities.Colours.Contains(Colour))
                {
                    Colour = ColourUtilities.Colours[0];
                }

                // If a factor isn't being used to vary a colour/marker/line, then remove the factor. i.e. we
                // don't care about it.
                simulationZones = RemoveFactorsNotBeingUsed(simulationZones);

                // Get data for each simulation / zone object
                DataStore dataStore = new DataStore(this);
                DataTable baseData  = GetBaseData(dataStore, simulationZones);
                dataStore.Disconnect();
                simulationZones.ForEach(simulationZone => simulationZone.CreateDataView(baseData, this));

                // Setup all colour, marker, line types etc in all simulation / zone objects.
                PaintAllSimulationZones(simulationZones);

                // Convert all simulation / zone objects to seriesdefinitions.
                simulationZones.ForEach(simZone => ourDefinitions.Add(ConvertToSeriesDefinition(simZone)));
            }

            // Get all data.
            //StoreDataInSeriesDefinitions(ourDefinitions);

            // 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(ourDefinitions);
            }

            // Remove series that have no data.
            ourDefinitions.RemoveAll(d => !MathUtilities.ValuesInArray(d.x) || !MathUtilities.ValuesInArray(d.y));

            definitions.AddRange(ourDefinitions);
        }
Beispiel #6
0
 private void OnEndOfDay(object sender, EventArgs e)
 {
     DltTT = (double)Apsim.Get(this, "[Phenology].DltTT.Value()");
 }
Beispiel #7
0
        /// <summary>
        /// Calculate the potential N uptake for today. Should return null if crop is not in the ground (this is not true for old sorghum).
        /// </summary>
        public override List <Soils.Arbitrator.ZoneWaterAndN> GetNitrogenUptakeEstimates(SoilState soilstate)
        {
            if (Plant.IsEmerged)
            {
                var nSupply = 0.0;//NOTE: This is in kg, not kg/ha, to arbitrate N demands for spatial simulations.

                //this function is called 4 times as part of estimates
                //shouldn't set public variables in here

                var grainIndex = 0;
                var rootIndex  = 1;
                var leafIndex  = 2;
                var stemIndex  = 4;

                var rootDemand  = N.StructuralDemand[rootIndex] + N.MetabolicDemand[rootIndex];
                var stemDemand  = /*N.StructuralDemand[stemIndex] + */ N.MetabolicDemand[stemIndex];
                var leafDemand  = N.MetabolicDemand[leafIndex];
                var grainDemand = N.StructuralDemand[grainIndex] + N.MetabolicDemand[grainIndex];
                //have to correct the leaf demand calculation
                var leaf           = Organs[leafIndex] as SorghumLeaf;
                var leafAdjustment = leaf.calculateClassicDemandDelta();

                //double NDemand = (N.TotalPlantDemand - N.TotalReallocation) / kgha2gsm * Plant.Zone.Area; //NOTE: This is in kg, not kg/ha, to arbitrate N demands for spatial simulations.
                //old sorghum uses g/m^2 - need to convert after it is used to calculate actual diffusion
                // leaf adjustment is not needed here because it is an adjustment for structural demand - we only look at metabolic here.

                // dh - In old sorghum, root only has one type of NDemand - it doesn't have a structural/metabolic division.
                // In new apsim, root only uses structural, metabolic is always 0. Therefore, we have to include root's structural
                // NDemand in this calculation.

                // dh - In old sorghum, totalDemand is metabolic demand for all organs. However in new apsim, grain has no metabolic
                // demand, so we must include its structural demand in this calculation.
                double totalDemand         = N.TotalMetabolicDemand + N.StructuralDemand[rootIndex] + N.StructuralDemand[grainIndex];
                double nDemand             = Math.Max(0, totalDemand - grainDemand); // to replicate calcNDemand in old sorghum
                List <ZoneWaterAndN> zones = new List <ZoneWaterAndN>();

                foreach (ZoneWaterAndN zone in soilstate.Zones)
                {
                    ZoneWaterAndN UptakeDemands = new ZoneWaterAndN(zone.Zone);

                    UptakeDemands.NO3N = new double[zone.NO3N.Length];
                    UptakeDemands.NH4N = new double[zone.NH4N.Length];
                    UptakeDemands.PlantAvailableNO3N = new double[zone.NO3N.Length];
                    UptakeDemands.PlantAvailableNH4N = new double[zone.NO3N.Length];
                    UptakeDemands.Water = new double[UptakeDemands.NO3N.Length];

                    //only using Root to get Nitrogen from - temporary code for sorghum
                    var root = Organs[rootIndex] as Root;

                    //Get Nuptake supply from each organ and set the PotentialUptake parameters that are passed to the soil arbitrator

                    //at present these 2arrays arenot being used within the CalculateNitrogenSupply function
                    //sorghum uses Diffusion & Massflow variables currently
                    double[] organNO3Supply = new double[zone.NO3N.Length]; //kg/ha - dltNo3 in old apsim
                    double[] organNH4Supply = new double[zone.NH4N.Length];

                    ZoneState myZone = root.Zones.Find(z => z.Name == zone.Zone.Name);
                    if (myZone != null)
                    {
                        CalculateNitrogenSupply(myZone, zone);

                        //new code
                        double[] diffnAvailable = new double[myZone.Diffusion.Length];
                        for (var i = 0; i < myZone.Diffusion.Length; ++i)
                        {
                            diffnAvailable[i] = myZone.Diffusion[i] - myZone.MassFlow[i];
                        }
                        var totalMassFlow  = MathUtilities.Sum(myZone.MassFlow); //g/m^2
                        var totalDiffusion = MathUtilities.Sum(diffnAvailable);  //g/m^2

                        var potentialSupply   = totalMassFlow + totalDiffusion;
                        var actualDiffusion   = 0.0;
                        var actualMassFlow    = DltTT > 0 ? totalMassFlow : 0.0;
                        var maxDiffusionConst = root.MaxDiffusion.Value();

                        double NUptakeCease = (Apsim.Find(this, "NUptakeCease") as Functions.IFunction).Value();
                        if (TTFMFromFlowering > NUptakeCease)
                        {
                            totalMassFlow = 0;
                        }
                        actualMassFlow = totalMassFlow;

                        if (totalMassFlow < nDemand && TTFMFromFlowering < NUptakeCease) // fixme && ttElapsed < nUptakeCease
                        {
                            actualDiffusion = MathUtilities.Bound(nDemand - totalMassFlow, 0.0, totalDiffusion);
                            actualDiffusion = MathUtilities.Divide(actualDiffusion, maxDiffusionConst, 0.0);

                            var nsupplyFraction = root.NSupplyFraction.Value();
                            var maxRate         = root.MaxNUptakeRate.Value();

                            var maxUptakeRateFrac = Math.Min(1.0, (potentialSupply / root.NSupplyFraction.Value())) * root.MaxNUptakeRate.Value();
                            var maxUptake         = Math.Max(0, maxUptakeRateFrac * DltTT - actualMassFlow);
                            actualDiffusion = Math.Min(actualDiffusion, maxUptake);
                        }

                        //adjust diffusion values proportionally
                        //make sure organNO3Supply is in kg/ha
                        for (int layer = 0; layer < organNO3Supply.Length; layer++)
                        {
                            var massFlowLayerFraction  = MathUtilities.Divide(myZone.MassFlow[layer], totalMassFlow, 0.0);
                            var diffusionLayerFraction = MathUtilities.Divide(diffnAvailable[layer], totalDiffusion, 0.0);
                            //organNH4Supply[layer] = massFlowLayerFraction * root.MassFlow[layer];
                            organNO3Supply[layer] = (massFlowLayerFraction * actualMassFlow +
                                                     diffusionLayerFraction * actualDiffusion) / kgha2gsm; //convert to kg/ha
                        }
                    }
                    //originalcode
                    UptakeDemands.NO3N = MathUtilities.Add(UptakeDemands.NO3N, organNO3Supply); //Add uptake supply from each organ to the plants total to tell the Soil arbitrator
                    if (UptakeDemands.NO3N.Any(n => MathUtilities.IsNegative(n)))
                    {
                        throw new Exception("-ve no3 uptake demand");
                    }
                    UptakeDemands.NH4N = MathUtilities.Add(UptakeDemands.NH4N, organNH4Supply);

                    N.UptakeSupply[rootIndex] += MathUtilities.Sum(organNO3Supply) * kgha2gsm * zone.Zone.Area / Plant.Zone.Area;  //g/m2
                    if (MathUtilities.IsNegative(N.UptakeSupply[rootIndex]))
                    {
                        throw new Exception($"-ve uptake supply for organ {(Organs[rootIndex] as IModel).Name}");
                    }
                    nSupply += MathUtilities.Sum(organNO3Supply) * zone.Zone.Area;
                    zones.Add(UptakeDemands);
                }

                return(zones);
            }
            return(null);
        }
Beispiel #8
0
        /// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary>
        public void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent)
        {
            if (IncludeInDocumentation)
            {
                // add a heading.
                tags.Add(new AutoDocumentation.Heading(Name, headingLevel));

                // write description of this class.
                AutoDocumentation.DocumentModelSummary(this, tags, headingLevel, indent, false);

                // write children.
                foreach (IModel child in Apsim.Children(this, typeof(Memo)))
                {
                    AutoDocumentation.DocumentModel(child, tags, headingLevel + 1, indent);
                }

                // Write Phase Table
                tags.Add(new AutoDocumentation.Paragraph(" **List of stages and phases used in the simulation of crop phenological development**", indent));

                DataTable tableData = new DataTable();
                tableData.Columns.Add("Phase Number", typeof(int));
                tableData.Columns.Add("Phase Name", typeof(string));
                tableData.Columns.Add("Initial Stage", typeof(string));
                tableData.Columns.Add("Final Stage", typeof(string));

                int N = 1;
                foreach (IModel child in Apsim.Children(this, typeof(IPhase)))
                {
                    DataRow row;
                    row    = tableData.NewRow();
                    row[0] = N;
                    row[1] = child.Name;
                    row[2] = (child as IPhase).Start;
                    row[3] = (child as IPhase).End;
                    if (child is GotoPhase)
                    {
                        row[3] = (child as GotoPhase).PhaseNameToGoto;
                    }
                    tableData.Rows.Add(row);
                    N++;
                }
                tags.Add(new AutoDocumentation.Table(tableData, indent));
                tags.Add(new AutoDocumentation.Paragraph(System.Environment.NewLine, indent));


                // add a heading.
                tags.Add(new AutoDocumentation.Heading("Phenological Phases", headingLevel + 1));
                foreach (IModel child in Apsim.Children(this, typeof(IPhase)))
                {
                    AutoDocumentation.DocumentModel(child, tags, headingLevel + 2, indent);
                }

                // write children.
                foreach (IModel child in Apsim.Children(this, typeof(IModel)))
                {
                    if (child.GetType() != typeof(Memo) && !typeof(IPhase).IsAssignableFrom(child.GetType()))
                    {
                        AutoDocumentation.DocumentModel(child, tags, headingLevel + 1, indent);
                    }
                }
            }
        }
        /// <summary>
        /// Finds a shared marketplace
        /// </summary>
        /// <returns>Market</returns>
        public Market FindMarket()
        {
            IModel parentSim = Apsim.Parent(this, typeof(Simulation));

            return(Apsim.Children(parentSim, typeof(Market)).Where(a => a.Enabled).FirstOrDefault() as Market);
        }
Beispiel #10
0
        /// <summary>
        /// Returns soil water uptake from each zone by the static tree model
        /// </summary>
        /// <param name="soilstate"></param>
        /// <returns></returns>
        public List <Soils.Arbitrator.ZoneWaterAndN> GetSWUptakes(Soils.Arbitrator.SoilState soilstate)
        {
            double SWDemand    = 0; // Tree water demand (L)
            double PotSWSupply = 0; // Total water supply (L)

            foreach (ZoneInfo ZI in ZoneInfoList)
            {
                Soils.SoilWater S = Apsim.Find(ZI.zone, typeof(Soils.SoilWater)) as Soils.SoilWater;
                SWDemand += S.Eo * (1 / (1 - ZI.Shade / 100) - 1) * ZI.zone.Area * 10000;
            }

            List <ZoneWaterAndN> Uptakes = new List <ZoneWaterAndN>();

            foreach (ZoneWaterAndN Z in soilstate.Zones)
            {
                foreach (ZoneInfo ZI in ZoneInfoList)
                {
                    if (Z.Name == ZI.zone.Name)
                    {
                        ZoneWaterAndN Uptake = new ZoneWaterAndN();
                        //Find the soil for this zone
                        Zone       ThisZone = new Zone();
                        Soils.Soil ThisSoil = new Soils.Soil();

                        foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone)))
                        {
                            if (SearchZ.Name == Z.Name)
                            {
                                ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil;
                            }
                        }

                        Uptake.Name = Z.Name;
                        double[] SW = Z.Water;
                        Uptake.NO3N  = new double[SW.Length];
                        Uptake.NH4N  = new double[SW.Length];
                        Uptake.Water = new double[SW.Length];
                        for (int i = 0; i <= SW.Length - 1; i++)
                        {
                            double[] LL15mm = MathUtilities.Multiply(ThisSoil.LL15, ThisSoil.Thickness);
                            Uptake.Water[i] = (SW[i] - LL15mm[i]) * ZI.RLD[i];
                            PotSWSupply    += Uptake.Water[i] * ZI.zone.Area * 10000;
                        }
                        Uptakes.Add(Uptake);
                    }
                }
            }
            // Now scale back uptakes if supply > demand
            double F = 0;  // Uptake scaling factor

            if (PotSWSupply > 0)
            {
                F = SWDemand / PotSWSupply;
                if (F > 1)
                {
                    F = 1;
                }
            }
            else
            {
                F = 1;
            }


            foreach (ZoneWaterAndN Z in Uptakes)
            {
                Z.Water = MathUtilities.Multiply_Value(Z.Water, F);
            }
            return(Uptakes);
        }
Beispiel #11
0
        /// <summary>Harvest the crop.</summary>
        public void RemoveBiomass(string biomassRemoveType, RemovalFractions removalData = null)
        {
            // Set up the default BiomassRemovalData values
            RemovingBiomassArgs allData = new RemovingBiomassArgs();

            allData.biomassRemoveType = biomassRemoveType;
            foreach (IOrgan organ in Organs)
            {
                OrganBiomassRemovalType biomassRemoved = Apsim.Get(organ as IModel, "BiomassRemovalDefaults." + biomassRemoveType) as OrganBiomassRemovalType;
                if (biomassRemoved == null)
                {
                    throw new Exception("Cannot find biomass removal defaults: " + organ.Name + ".BiomassRemovalDefaults.Harvest");
                }

                // Override the defaults if values were supplied as arguments.
                if (removalData != null)
                {
                    OrganBiomassRemovalType userFractions = removalData.GetFractionsForOrgan(organ.Name);
                    if (userFractions != null)
                    {
                        if (userFractions.FractionRemoved >= 0)
                        {
                            biomassRemoved.FractionRemoved = userFractions.FractionRemoved;
                        }
                        if (userFractions.FractionToResidue >= 0)
                        {
                            biomassRemoved.FractionToResidue = userFractions.FractionToResidue;
                        }
                    }
                }
                allData.removalData.Add(organ.Name, biomassRemoved);
            }

            Summary.WriteMessage(this, string.Format("Biomass removed from crop " + Name + " by " + biomassRemoveType + "ing"));

            // Invoke an event.
            if (biomassRemoveType == "Harvest" && Harvesting != null)
            {
                Harvesting.Invoke(this, new EventArgs());
            }
            else if (RemovingBiomass != null)
            {
                RemovingBiomass.Invoke(this, allData);
            }

            // Remove the biomass
            foreach (IOrgan organ in Organs)
            {
                organ.DoRemoveBiomass(allData.removalData[organ.Name]);
            }

            // Reset the phenology if SetPhenologyStage specified.
            if (removalData != null && removalData.SetPhenologyStage != 0)
            {
                Phenology.ReSetToStage(removalData.SetPhenologyStage);
            }

            // Reduce plant and stem population if thinning proportion specified
            if (removalData != null && removalData.SetThinningProportion != 0)
            {
                Structure.doThin(removalData.SetThinningProportion);
            }
        }
        private void OnCLEMAnimalSell(object sender, EventArgs e)
        {
            // Sell excess above store reserve level calculated from AE and daily target of first feed target
            // Performed here so all activities have access to human food stores before being sold.

            if (SellExcess && TimingOK)
            {
                // only uses the first target metric as measure
                double[] stored      = new double[MonthsStorage + 1];
                double[] target      = new double[MonthsStorage + 1];
                int[]    daysInMonth = new int[MonthsStorage + 1];

                // determine AEs to be fed - NOTE does not account ofr aging in reserve calcualtion
                double aE = people.Items.Where(a => IncludeHiredLabour || a.Hired == false).Sum(a => a.AdultEquivalent);

                LabourActivityFeedTarget feedTarget = Apsim.Children(this, typeof(LabourActivityFeedTarget)).FirstOrDefault() as LabourActivityFeedTarget;

                for (int i = 1; i <= MonthsStorage; i++)
                {
                    DateTime month = Clock.Today.AddMonths(i);
                    daysInMonth[i] = DateTime.DaysInMonth(month.Year, month.Month);
                    target[i]      = daysInMonth[i] * aE * feedTarget.TargetValue;
                }

                foreach (HumanFoodStoreType foodStore in Apsim.Children(food, typeof(HumanFoodStoreType)).Cast <HumanFoodStoreType>().ToList())
                {
                    double amountStored    = 0;
                    double amountAvailable = foodStore.Pools.Sum(a => a.Amount);

                    if (amountAvailable > 0)
                    {
                        foreach (HumanFoodStorePool pool in foodStore.Pools.OrderBy(a => ((foodStore.UseByAge == 0) ? MonthsStorage : a.Age)))
                        {
                            if (foodStore.UseByAge != 0 && pool.Age == foodStore.UseByAge)
                            {
                                // don't sell food expiring this month as spoiled
                                amountStored += pool.Amount;
                            }
                            else
                            {
                                int    currentMonth  = ((foodStore.UseByAge == 0) ? MonthsStorage : foodStore.UseByAge - pool.Age + 1);
                                double poolRemaining = pool.Amount;
                                while (currentMonth > 0)
                                {
                                    if (stored[currentMonth] < target[currentMonth])
                                    {
                                        // place amount in store
                                        double amountNeeded       = target[currentMonth] - stored[currentMonth];
                                        double towardTarget       = pool.Amount * foodStore.EdibleProportion * foodStore.ConversionFactor(feedTarget.Metric);
                                        double amountSupplied     = Math.Min(towardTarget, amountNeeded);
                                        double proportionProvided = amountSupplied / towardTarget;

                                        amountStored         += pool.Amount * proportionProvided;
                                        poolRemaining        -= pool.Amount * proportionProvided;
                                        stored[currentMonth] += amountSupplied;

                                        if (poolRemaining <= 0)
                                        {
                                            break;
                                        }
                                    }
                                    currentMonth--;
                                }
                            }
                        }

                        double amountSold = amountAvailable - amountStored;
                        if (amountSold > 0)
                        {
                            price = foodStore.Price;
                            double units = amountSold / price.PacketSize;
                            if (price.UseWholePackets)
                            {
                                units = Math.Truncate(units);
                            }

                            // remove resource
                            ResourceRequest purchaseRequest = new ResourceRequest
                            {
                                ActivityModel      = this,
                                Required           = units * price.PacketSize,
                                AllowTransmutation = false,
                                Reason             = "Sell excess"
                            };
                            foodStore.Remove(purchaseRequest);

                            // transfer money earned
                            if (bankAccount != null)
                            {
                                bankAccount.Add(units * price.PricePerPacket, this, $"Sales {foodStore.Name}");
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Method to determine resources required for this activity in the current month
        /// </summary>
        /// <returns>List of required resource requests</returns>
        public override List <ResourceRequest> GetResourcesNeededForActivity()
        {
            if (people is null | food is null)
            {
                return(null);
            }

            List <LabourType> peopleList = people.Items.Where(a => IncludeHiredLabour || a.Hired == false).ToList();

            peopleList.Select(a => a.FeedToTargetIntake == 0);

            // determine AEs to be fed
            double aE = peopleList.Sum(a => a.AdultEquivalent);

            if (aE <= 0)
            {
                return(null);
            }

            int daysInMonth = DateTime.DaysInMonth(Clock.Today.Year, Clock.Today.Month);

            // determine feed limits (max kg per AE per day * AEs * days)
            double intakeLimit = DailyIntakeLimit * aE * daysInMonth;

            // remove previous consumption
            double otherIntake = this.DailyIntakeOtherSources * aE * daysInMonth;

            otherIntake += peopleList.Sum(a => a.GetAmountConsumed());

            List <LabourActivityFeedTarget> labourActivityFeedTargets = Apsim.Children(this, typeof(LabourActivityFeedTarget)).Cast <LabourActivityFeedTarget>().ToList();

            // determine targets
            foreach (LabourActivityFeedTarget target in labourActivityFeedTargets)
            {
                // calculate target
                target.Target = target.TargetValue * aE * daysInMonth;

                // set initial level based on off store inputs
                target.CurrentAchieved = target.OtherSourcesValue * aE * daysInMonth;

                // calculate current level from previous intake this month (LabourActivityFeed)
                target.CurrentAchieved += people.GetDietaryValue(target.Metric, IncludeHiredLabour) * aE * daysInMonth;
            }

            // get max months before spoiling of all food stored (will be zero for non perishable food)
            int maxFoodAge = Apsim.Children(food, typeof(HumanFoodStoreType)).Cast <HumanFoodStoreType>().Max(a => a.Pools.Select(b => a.UseByAge - b.Age).DefaultIfEmpty(0).Max());

            // create list of all food parcels
            List <HumanFoodParcel> foodParcels = new List <HumanFoodParcel>();

            foreach (HumanFoodStoreType foodStore in Apsim.Children(food, typeof(HumanFoodStoreType)).Cast <HumanFoodStoreType>().ToList())
            {
                foreach (HumanFoodStorePool pool in foodStore.Pools)
                {
                    foodParcels.Add(new HumanFoodParcel()
                    {
                        FoodStore = foodStore,
                        Pool      = pool,
                        Expires   = ((foodStore.UseByAge == 0) ? maxFoodAge + 1: foodStore.UseByAge - pool.Age)
                    });
                }
            }

            //foodParcels = foodParcels.OrderBy(a => a.Expires).ThenByDescending(a => a.FoodStore.ConversionFactor(labourActivityFeedTargets.FirstOrDefault().Metric)).ThenBy(a => a.FoodStore.ConversionFactor("$")).ToList();
            foodParcels = foodParcels.OrderBy(a => a.Expires).ToList();
            int    parcelIndex = 0;
            double intake      = otherIntake;

            // start eating food from list from that about to expire first
            while (parcelIndex < foodParcels.Count)
            {
                foodParcels[parcelIndex].Proportion = 0;
                if (intake < intakeLimit && (labourActivityFeedTargets.Where(a => !a.TargetMet).Count() > 0 | foodParcels[parcelIndex].Expires == 0))
                {
                    // still able to eat and target not met or food about to expire this timestep
                    //reduce by amout theat can be eaten
                    double reduceAmount = Math.Min(1, (intakeLimit - intake) / (foodParcels[parcelIndex].FoodStore.EdibleProportion * foodParcels[parcelIndex].Pool.Amount));
                    // reduce to target limits
                    double reduceTarget = 1;
                    if (foodParcels[parcelIndex].Expires != 0)
                    {
                        LabourActivityFeedTarget targetUnfilled = labourActivityFeedTargets.Where(a => !a.TargetMet).FirstOrDefault();
                        if (targetUnfilled != null)
                        {
                            // calculate reduction to metric target
                            double metricneeded       = Math.Max(0, targetUnfilled.Target - targetUnfilled.CurrentAchieved);
                            double amountneeded       = metricneeded / foodParcels[parcelIndex].FoodStore.ConversionFactor(targetUnfilled.Metric);
                            double reduceAmountMetric = Math.Min(1, (amountneeded) / (foodParcels[parcelIndex].FoodStore.EdibleProportion * foodParcels[parcelIndex].Pool.Amount));
                            reduceTarget = (reduceAmountMetric < 1) ? reduceAmountMetric : 1;
                        }
                    }
                    foodParcels[parcelIndex].Proportion = Math.Min(reduceAmount, reduceTarget);
                    // update intake
                    double newIntake = (foodParcels[parcelIndex].FoodStore.EdibleProportion * foodParcels[parcelIndex].Pool.Amount * foodParcels[parcelIndex].Proportion);
                    intake += newIntake;
                    // update metrics
                    foreach (LabourActivityFeedTarget target in labourActivityFeedTargets)
                    {
                        target.CurrentAchieved += newIntake * foodParcels[parcelIndex].FoodStore.ConversionFactor(target.Metric);
                    }
                }
                else if (intake >= intakeLimit && labourActivityFeedTargets.Where(a => !a.TargetMet).Count() > 1)
                {
                    // full but could still reach target with some substitution
                    // but can substitute to remove a previous target

                    // does the current parcel have better target values than any previous non age 0 pool of a different food type
                }
                else
                {
                    break;
                }
                parcelIndex++;
            }

            // fill resource requests
            List <ResourceRequest> requests = new List <ResourceRequest>();

            foreach (var item in foodParcels.GroupBy(a => a.FoodStore))
            {
                if (item.Sum(a => a.Pool.Amount * a.Proportion) > 0)
                {
                    requests.Add(new ResourceRequest()
                    {
                        Resource           = item.Key,
                        ResourceType       = typeof(HumanFoodStore),
                        AllowTransmutation = false,
                        Required           = item.Sum(a => a.Pool.Amount * a.Proportion),
                        ResourceTypeName   = item.Key.Name,
                        ActivityModel      = this,
                        Reason             = "Consumption"
                    });
                }
            }

            // use market stores
            // buy extra into market store and use market stores
            // if no market buy from unknown source

            // if still intake available and targets not met

            //

            // add more to stores from purchases, either from money or market and money

            // these purchases need to be instant

            // then go and add to the resource requests to take any extra just purchased if needed



            // now we need to add a heap of purchase requests for the shortfall in intake
            // finances will limit the
            // one at a time going through the food types we will try and buy the shortfall up to intake and targets
            // This will take money only if the food is available to buy (limited if market is present)
            // This process will stop as soon as sufficient food has been purchased.
            // The relavent resource request will need to be updated or a new request added

            return(requests);
        }
Beispiel #14
0
        /// <summary>
        /// Convert the simulation decription to a simulation.
        /// path.
        /// </summary>
        public Simulation ToSimulation()
        {
            try
            {
                AddReplacements();

                Simulation newSimulation;
                if (doClone)
                {
                    newSimulation = Apsim.Clone(baseSimulation) as Simulation;

                    // After a binary clone, we need to force all managers to
                    // recompile their scripts. This is to work around an issue
                    // where scripts will change during deserialization. See issue
                    // #4463 and the TestMultipleChildren test inside ReportTests.
                    foreach (Manager script in newSimulation.FindAllDescendants <Manager>())
                    {
                        script.OnCreated();
                    }
                }
                else
                {
                    newSimulation = baseSimulation;
                }

                if (string.IsNullOrWhiteSpace(Name))
                {
                    newSimulation.Name = baseSimulation.Name;
                }
                else
                {
                    newSimulation.Name = Name;
                }

                newSimulation.Parent = null;
                newSimulation.ParentAllDescendants();
                replacementsToApply.ForEach(r => r.Replace(newSimulation));

                // Give the simulation the descriptors.
                if (newSimulation.Descriptors == null || Descriptors.Count > 0)
                {
                    newSimulation.Descriptors = Descriptors;
                }
                newSimulation.Services = GetServices();

                // Standardise the soil.
                var soils = newSimulation.FindAllDescendants <Soils.Soil>();
                foreach (Soils.Soil soil in soils)
                {
                    SoilStandardiser.Standardise(soil);
                }

                newSimulation.ClearCaches();
                return(newSimulation);
            }
            catch (Exception err)
            {
                var message = "Error in file: " + baseSimulation.FileName + " Simulation: " + Name;
                throw new Exception(message, err);
            }
        }
Beispiel #15
0
        /// <summary>Add user documentation, based on the example.</summary>
        /// <param name="tags">The tags to add to.</param>
        /// <param name="modelName">Name of model to document.</param>
        private void AddUserDocumentation(List <AutoDocumentation.ITag> tags, string modelName)
        {
            // Look for some instructions on which models in the example file we should write.
            // Instructions will be in a memo in the validation .apsimx file

            IModel userDocumentation = Apsim.Get(ExplorerPresenter.ApsimXFile, ".Simulations.UserDocumentation") as IModel;
            string exampleFileName   = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..", "Examples", modelName + ".apsimx");

            if (userDocumentation != null && userDocumentation.Children.Count > 0 && File.Exists(exampleFileName))
            {
                // Write heading.
                tags.Add(new AutoDocumentation.Heading("User documentation", 1));

                // Open the related example .apsimx file and get its presenter.
                ExplorerPresenter examplePresenter = ExplorerPresenter.MainPresenter.OpenApsimXFileInTab(exampleFileName, onLeftTabControl: true);

                try
                {
                    Memo     instructionsMemo = userDocumentation.Children[0] as Memo;
                    string[] instructions     = instructionsMemo.MemoText.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    foreach (string instruction in instructions)
                    {
                        IModel model = Apsim.Find(examplePresenter.ApsimXFile, instruction);
                        if (model != null)
                        {
                            examplePresenter.SelectNode(Apsim.FullPath(model));
                            Application.DoEvents();
                            if (model is Memo)
                            {
                                model.Document(tags, 1, 0);
                            }
                            else
                            {
                                System.Drawing.Image image;

                                if (model is Manager)
                                {
                                    image = (examplePresenter.CurrentPresenter as ManagerPresenter).GetScreenshot();
                                }
                                else
                                {
                                    image = examplePresenter.GetScreenhotOfRightHandPanel();
                                }

                                if (image != null)
                                {
                                    string name = "Example" + instruction;
                                    tags.Add(new AutoDocumentation.Image()
                                    {
                                        name = name, image = image
                                    });
                                }
                            }
                        }
                    }
                }
                finally
                {
                    // Close the tab
                    examplePresenter.MainPresenter.CloseTabContaining(examplePresenter.GetView());
                }
            }
        }
Beispiel #16
0
 /// <summary>
 /// Move a node to a new parent node.
 /// </summary>
 public void Move(string originalPath, IModel toParent, TreeViewNode nodeDescription)
 {
     view.Tree.Delete(originalPath);
     view.Tree.AddChild(Apsim.FullPath(toParent), nodeDescription);
 }
Beispiel #17
0
 /// <summary>Get the names of all fields.</summary>
 public IEnumerable <string> GetFieldNames()
 {
     return(Apsim.FindAll(this, typeof(Zone)).Select(zone => zone.Name));
 }
Beispiel #18
0
        /// <summary>
        /// The view wants us to return a list of menu descriptions for the
        /// currently selected Node.
        /// </summary>
        /// <param name="nodePath">The path to the node</param>
        public void PopulateContextMenu(string nodePath)
        {
            if (view.Tree.ContextMenu == null)
            {
                view.Tree.ContextMenu = new MenuView();
            }

            List <MenuDescriptionArgs> descriptions = new List <MenuDescriptionArgs>();

            // Get the selected model.
            object selectedModel = Apsim.Get(this.ApsimXFile, nodePath);

            // Go look for all [UserInterfaceAction]
            foreach (MethodInfo method in typeof(ContextMenu).GetMethods())
            {
                ContextMenuAttribute contextMenuAttr = ReflectionUtilities.GetAttribute(method, typeof(ContextMenuAttribute), false) as ContextMenuAttribute;
                if (contextMenuAttr != null)
                {
                    bool ok = true;
                    if (contextMenuAttr.AppliesTo != null && selectedModel != null)
                    {
                        ok = false;
                        foreach (Type t in contextMenuAttr.AppliesTo)
                        {
                            if (t.IsAssignableFrom(selectedModel.GetType()))
                            {
                                ok = true;
                            }
                        }
                    }

                    if (ok)
                    {
                        MenuDescriptionArgs desc = new MenuDescriptionArgs();
                        desc.Name = contextMenuAttr.MenuName;
                        desc.ResourceNameForImage = "ApsimNG.Resources.MenuImages." + desc.Name + ".png";
                        desc.ShortcutKey          = contextMenuAttr.ShortcutKey;
                        desc.ShowCheckbox         = contextMenuAttr.IsToggle;
                        desc.FollowsSeparator     = contextMenuAttr.FollowsSeparator;

                        // Check for an enable method
                        MethodInfo enableMethod = typeof(ContextMenu).GetMethod(method.Name + "Enabled");
                        if (enableMethod != null)
                        {
                            desc.Enabled = (bool)enableMethod.Invoke(this.contextMenu, null);
                        }
                        else
                        {
                            desc.Enabled = true;
                        }

                        // Check for an checked method
                        MethodInfo checkMethod = typeof(ContextMenu).GetMethod(method.Name + "Checked");
                        if (checkMethod != null)
                        {
                            desc.Checked = (bool)checkMethod.Invoke(this.contextMenu, null);
                        }
                        else
                        {
                            desc.Checked = false;
                        }

                        EventHandler handler = (EventHandler)Delegate.CreateDelegate(typeof(EventHandler), this.contextMenu, method);
                        desc.OnClick = handler;

                        descriptions.Add(desc);
                    }
                }
            }

            view.Tree.ContextMenu.Populate(descriptions);
        }
Beispiel #19
0
        /// <summary>
        /// This is basically one giant hack to calculate the equivalent
        /// of phenology's daysTotal variable in the old sorghum model.
        ///
        /// This should be refactored out at some point.
        /// </summary>
        /// <param name="calcNewStage"></param>
        private void IncrementDaysTotal(bool calcNewStage)
        {
            if (doIncrement)
            {
                double newStage = phenology.Stage;
                if (calcNewStage)
                {
                    newStage = Math.Floor(newStage) + 1; // 😭
                }
                int phaseIndex = Convert.ToInt32(Math.Floor(newStage));
                while (DaysTotal.Count <= phaseIndex)
                {
                    DaysTotal.Add(0);
                }

                if (phaseIndex == Convert.ToInt32(Math.Floor(stage)))
                {
                    DaysTotal[phaseIndex]++;
                }
                else if (previousPhase is GenericPhase phase)
                {
                    double dltTT    = phase.ProgressionForTimeStep;
                    double potDltTT = DltTT;

                    // TT proportions should be based on dlt in prev phase / total daily dlTT.
                    // If after flowering, use dltTTFM instead. If on day of flowering, we want
                    // to mimic a bug in old apsim where the proportion is still based on dltTT.
                    if (phenology.Between("Flowering", "Maturity") && phaseIndex != 7)
                    {
                        potDltTT = (double)Apsim.Get(this, "[Phenology].DltTTFM.Value()");
                    }

                    // Amount of TT which goes to next phase = total TT - amount allocated to previous phase.
                    double portionInNew = Math.Max(0, potDltTT - dltTT);

                    double propInNew = MathUtilities.Divide(portionInNew, potDltTT, 0);
                    double propInOld = 1 - propInNew;

                    DaysTotal[phaseIndex] += propInNew;
                    if (phaseIndex > 0)
                    {
                        DaysTotal[phaseIndex - 1] += propInOld;
                    }
                }
                else if (previousPhase is EmergingPhase emerg)
                {
                    double dltTT    = emerg.TTForTimeStep;
                    double potDltTT = DltTT;

                    // Amount of TT which goes to next phase = total TT - amount allocated to previous phase.
                    double portionInNew = Math.Max(0, potDltTT - dltTT);
                    double propInNew    = MathUtilities.Divide(portionInNew, potDltTT, 0);
                    double propInOld    = 1 - propInNew;

                    DaysTotal[phaseIndex] += propInNew;
                    if (phaseIndex > 0)
                    {
                        DaysTotal[phaseIndex - 1] += propInOld;
                    }
                }
                else
                {
                    double propInOld = phaseIndex - stage;
                    double propInNew = 1 - propInOld;
                    DaysTotal[phaseIndex]     += propInNew;
                    DaysTotal[phaseIndex - 1] += propInOld;
                }

                stage         = newStage;
                previousPhase = phenology.CurrentPhase;
                doIncrement   = false;
            }
        }
Beispiel #20
0
        /// <summary>
        /// Generates .apsimx files for each child model under a given model.
        /// Returns false if errors were encountered, or true otherwise.
        /// </summary>
        /// <param name="model">Model to generate .apsimx files for.</param>
        /// <param name="path">
        /// Path which the files will be saved to.
        /// If null, the user will be prompted to choose a directory.
        /// </param>
        public bool GenerateApsimXFiles(IModel model, string path = null)
        {
            List <IModel> children;

            if (model is ISimulationGenerator)
            {
                children = new List <IModel> {
                    model
                };
            }
            else
            {
                children = Apsim.ChildrenRecursively(model, typeof(ISimulationGenerator));
            }

            if (string.IsNullOrEmpty(path))
            {
                IFileDialog fileChooser = new FileDialog()
                {
                    Prompt = "Select a directory to save model files to.",
                    Action = FileDialog.FileActionType.SelectFolder
                };
                path = fileChooser.GetFile();
                if (string.IsNullOrEmpty(path))
                {
                    return(false);
                }
            }

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            List <Exception> errors = new List <Exception>();
            int i = 0;

            foreach (IModel sim in children)
            {
                MainPresenter.ShowMessage("Generating simulation files: ", Simulation.MessageType.Information);
                MainPresenter.ShowProgress(100 * i / children.Count, false);
                while (GLib.MainContext.Iteration())
                {
                    ;
                }
                try
                {
                    (sim as ISimulationGenerator).GenerateApsimXFile(path);
                }
                catch (Exception err)
                {
                    errors.Add(err);
                }

                i++;
            }
            if (errors.Count < 1)
            {
                MainPresenter.ShowMessage("Successfully generated .apsimx files under " + path + ".", Simulation.MessageType.Information);
                return(true);
            }
            else
            {
                MainPresenter.ShowError(errors);
                return(false);
            }
        }
Beispiel #21
0
        /// <summary>Loop through each cohort in this LifeCyclePhase to calculate development, mortality, graduation and reproduciton</summary>
        public void Process()
        {
            if (Cohorts?.Count > 500)  //Check cohort number are not becomming silly
            {
                throw new Exception(Apsim.FullPath(this) + " has over 500 cohorts which is to many really.  This is why your simulation is slow and the data store is about to chuck it in.  Check your " + this.Parent.Name.ToString() + " model to ensure development and mortality are sufficient.");
            }

            ZeorDeltas(); //Zero reporting properties for daily summing

            foreach (ProgenyDestinationPhase pdest in ProgenyDestinations)
            {
                pdest.ProgenyToDestination = 0;
            }

            if (Cohorts != null)
            {
                // Calculate daily deltas
                foreach (Cohort c in Cohorts)
                {
                    CurrentCohort       = c;
                    c.ChronologicalAge += 1;
                    //Do development for each cohort
                    c.PhysiologicalAge = Math.Min(1.0, c.PhysiologicalAge + development.Value());
                    //Do mortality for each cohort
                    c.Mortalities = mortality.Value();
                    Mortalities  += c.Mortalities;
                    c.Population  = Math.Max(0.0, c.Population - c.Mortalities);
                    //Do reproduction for each cohort
                    Progeny += reproduction.Value();
                    foreach (ProgenyDestinationPhase dest in ProgenyDestinations)
                    {
                        dest.ProgenyToDestination += reproduction.Value() * dest.ProportionOfProgeny;
                    }
                    //Do migration for each cohort
                    Migrants += migration.Value();
                    if (Migrants > 0)
                    {
                        if (MigrantDestinations.Count == 0)
                        {
                            throw new Exception(Apsim.FullPath(this) + " is predicting values for migration but has no MigrationDestinationPhase specified");
                        }
                        double MtotalProportion = 0;
                        foreach (MigrantDestinationPhase mdest in MigrantDestinations)
                        {
                            double cohortMigrants = migration.Value() * mdest.ProportionOfMigrants;
                            if ((MigrantDestinations.Count == 0) && (cohortMigrants > 0))
                            {
                                throw new Exception(Apsim.FullPath(this) + " is predicting values for migration but has not MigrantDestinationPhase specified");
                            }
                            if (cohortMigrants > 0)
                            {
                                IModel    zone = Apsim.Parent(this.Parent, typeof(Zone));
                                LifeCycle mDestinationCycle = Apsim.Find(zone, mdest.NameOfLifeCycleForMigrants) as LifeCycle;
                                if (mDestinationCycle == null)
                                {
                                    throw new Exception(Apsim.FullPath(this) + " could not find a destination LifeCycle for migrants called " + mdest.NameOfLifeCycleForMigrants);
                                }
                                LifeCyclePhase mDestinationPhase = Apsim.Child(mDestinationCycle, mdest.NameOfPhaseForMigrants) as LifeCyclePhase;
                                if (mDestinationPhase == null)
                                {
                                    throw new Exception(Apsim.FullPath(this) + " could not find a destination LifeCyclePhase for migrants called " + mdest.NameOfPhaseForMigrants);
                                }
                                mDestinationPhase.NewCohort(cohortMigrants, c.ChronologicalAge, c.PhysiologicalAge);
                                MtotalProportion += mdest.ProportionOfMigrants;
                            }
                        }
                        if ((MtotalProportion > 1.001) && (Migrants > 0))
                        {
                            throw new Exception("The sum of ProportionOfMigrants values in " + Apsim.FullPath(this) + " ProgenyDestinationPhases is greater than 1.0");
                        }
                    }
                }

                // Add progeny into destination phase
                if ((ProgenyDestinations.Count == 0) && (Progeny > 0))
                {
                    throw new Exception(Apsim.FullPath(this) + " is predicting values for reproduction but has no ProgenyDestinationPhase specified");
                }
                double PtotalProportion = 0;
                foreach (ProgenyDestinationPhase pdest in ProgenyDestinations)
                {
                    if (pdest.ProgenyToDestination > 0)
                    {
                        IModel    zone = Apsim.Parent(this.Parent, typeof(Zone));
                        LifeCycle pDestinationCylce = Apsim.Find(zone, pdest.NameOfLifeCycleForProgeny) as LifeCycle;
                        if (pDestinationCylce == null)
                        {
                            throw new Exception(Apsim.FullPath(this) + " could not find a destination LifeCycle for progeny called " + pdest.NameOfLifeCycleForProgeny);
                        }
                        LifeCyclePhase pDestinationPhase = Apsim.Child(pDestinationCylce, pdest.NameOfPhaseForProgeny) as LifeCyclePhase;
                        if (pDestinationPhase == null)
                        {
                            throw new Exception(Apsim.FullPath(this) + " could not find a destination LifeCyclePhase for progeny called " + pdest.NameOfPhaseForProgeny);
                        }
                        pDestinationPhase.NewCohort(pdest.ProgenyToDestination, 0, 0);
                        PtotalProportion += pdest.ProportionOfProgeny;
                    }
                }
                if (((PtotalProportion < 0.999) || (PtotalProportion > 1.001)) && (Progeny > 0))
                {
                    throw new Exception("The sum of ProportionOfProgeny values in " + Apsim.FullPath(this) + " ProgenyDestinationPhases does not equal 1.0");
                }


                // Move garduates to destination phase
                foreach (Cohort c in Cohorts.ToArray())
                {
                    if (c.PhysiologicalAge >= 1.0) //Members ready to graduate or die
                    {
                        if (LifeCyclePhaseForGraduates != null)
                        {
                            Graduates += c.Population; //Members graduate
                        }
                        else
                        {
                            Mortalities += c.Population; //Members die
                        }
                        Cohorts.Remove(c);               //Remove mature cohort
                    }

                    if (c.Population < 0.001)  //Remove cohort if all members dead
                    {
                        Cohorts.Remove(c);
                    }
                }

                if (Graduates > 0)  //Promote graduates to cohort in next LifeCyclePhase
                {
                    LifeCyclePhaseForGraduates?.NewCohort(Graduates, 0.0, 0.0);
                }
            }
        }
Beispiel #22
0
 /// <summary>Undoes the command.</summary>
 /// <param name="CommandHistory">The command history.</param>
 public void Undo(CommandHistory CommandHistory)
 {
     explorerView.Tree.Rename(Apsim.FullPath(modelToRename), originalName);
     modelToRename.Name = originalName;
 }
Beispiel #23
0
 private void OnSimulationCommencing(object sender, EventArgs e)
 {
     RebuildScriptModel();
     SetParametersInObject(Apsim.Child(this, "Script") as Model);
 }
Beispiel #24
0
        /// <summary>
        /// Format the grid.
        /// </summary>
        private void FormatGrid()
        {
            for (int i = 0; i < this.properties.Count; i++)
            {
                IGridCell cell = this.grid.GetCell(1, i);

                if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.TableName)
                {
                    cell.EditorType      = EditorTypeEnum.DropDown;
                    cell.DropDownStrings = this.storage.TableNames.ToArray();
                }
                else if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.CultivarName)
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    ICrop crop = this.GetCrop(this.properties);
                    if (crop != null)
                    {
                        cell.DropDownStrings = this.GetCultivarNames(crop);
                    }
                }
                else if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.FileName)
                {
                    cell.EditorType = EditorTypeEnum.Button;
                }
                else if (this.properties[i].DisplayType == DisplayAttribute.DisplayTypeEnum.FieldName)
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    string[] fieldNames = this.GetFieldNames();
                    if (fieldNames != null)
                    {
                        cell.DropDownStrings = fieldNames;
                    }
                }
                else
                {
                    object cellValue = this.properties[i].ValueWithArrayHandling;
                    if (cellValue is DateTime)
                    {
                        cell.EditorType = EditorTypeEnum.DateTime;
                    }
                    else if (cellValue is bool)
                    {
                        cell.EditorType = EditorTypeEnum.Boolean;
                    }
                    else if (cellValue.GetType().IsEnum)
                    {
                        cell.EditorType      = EditorTypeEnum.DropDown;
                        cell.DropDownStrings = StringUtilities.EnumToStrings(cellValue);
                    }
                    else if (cellValue.GetType() == typeof(ICrop))
                    {
                        cell.EditorType = EditorTypeEnum.DropDown;
                        List <string> cropNames = new List <string>();
                        foreach (Model crop in Apsim.FindAll(this.model, typeof(ICrop)))
                        {
                            cropNames.Add(crop.Name);
                        }

                        cell.DropDownStrings = cropNames.ToArray();
                    }
                    else if (this.properties[i].DataType == typeof(ICrop))
                    {
                        List <string> plantNames = Apsim.FindAll(this.model, typeof(ICrop)).Select(m => m.Name).ToList();
                        cell.EditorType      = EditorTypeEnum.DropDown;
                        cell.DropDownStrings = plantNames.ToArray();
                    }
                    else
                    {
                        cell.EditorType = EditorTypeEnum.TextBox;
                    }
                }
            }

            IGridColumn descriptionColumn = this.grid.GetColumn(0);

            descriptionColumn.Width    = -1;
            descriptionColumn.ReadOnly = true;

            IGridColumn valueColumn = this.grid.GetColumn(1);

            valueColumn.Width = -1;
        }
Beispiel #25
0
 public void OnGenerateApsimXFiles(object sender, EventArgs e)
 {
     explorerPresenter.GenerateApsimXFiles(Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as IModel);;
 }
Beispiel #26
0
        /// <summary>
        /// Format the grid.
        /// </summary>
        protected virtual void FormatGrid()
        {
            for (int i = 0; i < properties.Count; i++)
            {
                IGridCell cell = grid.GetCell(1, i);

                if (properties[i] is VariableObject)
                {
                    cell.EditorType = EditorTypeEnum.TextBox;

                    grid.SetRowAsSeparator(i, true);
                }
                else if (properties[i].Display != null &&
                         properties[i].Display.Type == DisplayType.TableName)
                {
                    cell.EditorType      = EditorTypeEnum.DropDown;
                    cell.DropDownStrings = storage.Reader.TableNames.ToArray();
                }
                else if (properties[i].Display != null &&
                         properties[i].Display.Type == DisplayType.CultivarName)
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    IPlant crop = GetCrop(properties);
                    if (crop != null)
                    {
                        cell.DropDownStrings = GetCultivarNames(crop);
                    }
                }
                else if (properties[i].Display != null &&
                         properties[i].Display.Type == DisplayType.FileName)
                {
                    cell.EditorType = EditorTypeEnum.Button;
                }
                else if (properties[i].Display != null &&
                         properties[i].Display.Type == DisplayType.FieldName)
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    List <string> fieldNames = GetFieldNames();
                    if (fieldNames != null)
                    {
                        fieldNames.Insert(0, string.Empty);
                        cell.DropDownStrings = fieldNames.ToArray();
                    }
                }
                else if (properties[i].Display != null &&
                         properties[i].Display.Type == DisplayType.ResidueName &&
                         model is SurfaceOrganicMatter)
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    string[] fieldNames = GetResidueNames();
                    if (fieldNames != null)
                    {
                        cell.DropDownStrings = fieldNames;
                    }
                }
                else if (properties[i].Display != null &&
                         (properties[i].Display.Type == DisplayType.CLEMResourceName))
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    List <string> fieldNames = new List <string>();
                    fieldNames.AddRange(this.GetCLEMResourceNames(this.properties[i].Display.CLEMResourceNameResourceGroups));

                    // add any extras elements provided to the list.
                    if (this.properties[i].Display.CLEMExtraEntries != null)
                    {
                        fieldNames.AddRange(this.properties[i].Display.CLEMExtraEntries);
                    }

                    if (fieldNames.Count != 0)
                    {
                        cell.DropDownStrings = fieldNames.ToArray();
                    }
                }
                else if (properties[i].Display != null &&
                         (properties[i].Display.Type == DisplayType.CLEMCropFileName))
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    List <string> fieldNames = new List <string>();
                    Simulation    clemParent = Apsim.Parent(this.model, typeof(Simulation)) as Simulation;
                    // get crop file names
                    fieldNames.AddRange(Apsim.ChildrenRecursively(clemParent, typeof(FileCrop)).Select(a => a.Name).ToList());
                    fieldNames.AddRange(Apsim.ChildrenRecursively(clemParent, typeof(FileSQLiteCrop)).Select(a => a.Name).ToList());
                    if (fieldNames.Count != 0)
                    {
                        cell.DropDownStrings = fieldNames.ToArray();
                    }
                }
                else if (properties[i].Display != null &&
                         (properties[i].Display.Type == DisplayType.CLEMGraspFileName))
                {
                    cell.EditorType = EditorTypeEnum.DropDown;
                    List <string> fieldNames = new List <string>();
                    Simulation    clemParent = Apsim.Parent(this.model, typeof(Simulation)) as Simulation;
                    // get GRASP file names
                    fieldNames.AddRange(Apsim.ChildrenRecursively(clemParent, typeof(FileGRASP)).Select(a => a.Name).ToList());
                    fieldNames.AddRange(Apsim.ChildrenRecursively(clemParent, typeof(FileSQLiteGRASP)).Select(a => a.Name).ToList());
                    if (fieldNames.Count != 0)
                    {
                        cell.DropDownStrings = fieldNames.ToArray();
                    }
                }
                else if (properties[i].Display != null &&
                         properties[i].Display.Type == DisplayType.Model)
                {
                    cell.EditorType = EditorTypeEnum.DropDown;

                    string[] modelNames = GetModelNames(properties[i].Display.ModelType);
                    if (modelNames != null)
                    {
                        cell.DropDownStrings = modelNames;
                    }
                }
                else
                {
                    object cellValue = properties[i].ValueWithArrayHandling;
                    if (cellValue is DateTime)
                    {
                        cell.EditorType = EditorTypeEnum.DateTime;
                    }
                    else if (cellValue is bool)
                    {
                        cell.EditorType = EditorTypeEnum.Boolean;
                    }
                    else if (cellValue.GetType().IsEnum)
                    {
                        cell.EditorType      = EditorTypeEnum.DropDown;
                        cell.DropDownStrings = VariableProperty.EnumToStrings(cellValue);
                        Enum cellValueAsEnum = cellValue as Enum;
                        if (cellValueAsEnum != null)
                        {
                            cell.Value = VariableProperty.GetEnumDescription(cellValueAsEnum);
                        }
                    }
                    else if (cellValue.GetType() == typeof(IPlant))
                    {
                        cell.EditorType = EditorTypeEnum.DropDown;
                        List <string> cropNames = new List <string>();
                        foreach (Model crop in Apsim.FindAll(model, typeof(IPlant)))
                        {
                            cropNames.Add(crop.Name);
                        }

                        cell.DropDownStrings = cropNames.ToArray();
                    }
                    else if (properties[i].DataType == typeof(IPlant))
                    {
                        List <string> plantNames = Apsim.FindAll(model, typeof(IPlant)).Select(m => m.Name).ToList();
                        cell.EditorType      = EditorTypeEnum.DropDown;
                        cell.DropDownStrings = plantNames.ToArray();
                    }
                    else if (!string.IsNullOrWhiteSpace(properties[i].Display?.Values))
                    {
                        MethodInfo method = model.GetType().GetMethod(properties[i].Display.Values);
                        string[]   values = ((IEnumerable <object>)method.Invoke(model, null))?.Select(v => v?.ToString())?.ToArray();
                        cell.EditorType      = EditorTypeEnum.DropDown;
                        cell.DropDownStrings = values;
                    }
                    else
                    {
                        cell.EditorType = EditorTypeEnum.TextBox;
                    }
                }
                cell.IsRowReadonly = !IsPropertyEnabled(i);
            }

            IGridColumn descriptionColumn = grid.GetColumn(0);

            descriptionColumn.Width    = -1;
            descriptionColumn.ReadOnly = true;

            IGridColumn valueColumn = grid.GetColumn(1);

            valueColumn.Width = -1;
        }
Beispiel #27
0
        /// <summary>
        /// Event handler for checkbox for 'Include in documentation' menu item.
        /// </summary>
        public bool ShowPageOfGraphsChecked()
        {
            Folder folder = Apsim.Get(explorerPresenter.ApsimXFile, explorerPresenter.CurrentNodePath) as Folder;

            return((folder != null) ? folder.ShowPageOfGraphs : false);
        }
Beispiel #28
0
        /// <summary>
        /// Export to PDF
        /// </summary>
        public void DoExportPDF(string modelNameToExport)
        {
            // Create a temporary working directory.
            string workingDirectory = Path.Combine(Path.GetTempPath(), "autodoc");

            if (Directory.Exists(workingDirectory))
            {
                Directory.Delete(workingDirectory, true);
            }
            Directory.CreateDirectory(workingDirectory);

            Document document = new Document();

            CreatePDFSyles(document);
            document.DefaultPageSetup.LeftMargin   = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(1);
            document.DefaultPageSetup.TopMargin    = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(1);
            document.DefaultPageSetup.BottomMargin = MigraDoc.DocumentObjectModel.Unit.FromCentimeter(1);
            Section section = document.AddSection();

            // write image files
            string png1 = Path.Combine(workingDirectory, "AIBanner.png");

            using (FileStream file = new FileStream(png1, FileMode.Create, FileAccess.Write))
            {
                Assembly.GetExecutingAssembly().GetManifestResourceStream("UserInterface.Resources.AIBanner.png").CopyTo(file);
            }
            section.AddImage(png1);

            List <AutoDocumentation.ITag> tags = new List <AutoDocumentation.ITag>();

            IModel titlePage = Apsim.Child(ExplorerPresenter.ApsimXFile, "TitlePage");

            if (titlePage != null)
            {
                titlePage.Document(tags, 1, 0);
            }
            else
            {
                // See if there is a title page. If so do it first.
                foreach (IModel memo in Apsim.FindAll(ExplorerPresenter.ApsimXFile, typeof(Memo)))
                {
                    if (memo.Name == "TitlePage" && memo.Parent.Name == modelNameToExport)
                    {
                        memo.Document(tags, 1, 0);
                        break;
                    }
                }
            }
            AddBackground(tags);

            // See if there is a title page. If so do it first.
            IModel introductionPage = Apsim.Find(ExplorerPresenter.ApsimXFile, "Introduction");

            if (introductionPage != null)
            {
                tags.Add(new AutoDocumentation.Heading("Introduction", 1));
                introductionPage.Document(tags, 1, 0);
            }

            AddUserDocumentation(tags, modelNameToExport);

            // Document model description.
            int modelDescriptionIndex = tags.Count;

            tags.Add(new AutoDocumentation.Heading("Model description", 1));
            ExplorerPresenter.ApsimXFile.DocumentModel(modelNameToExport, tags, 1);

            // If no model was documented then remove the 'Model description' tag.
            if (modelDescriptionIndex == tags.Count - 1)
            {
                tags.RemoveAt(modelDescriptionIndex);
            }

            // If 'Model description tag is imediately followed by a another heading at the same level.
            // then the model must have writen its own name as a heading. We don't want that.
            if (modelDescriptionIndex + 1 < tags.Count &&
                tags[modelDescriptionIndex + 1] is AutoDocumentation.Heading &&
                (tags[modelDescriptionIndex + 1] as AutoDocumentation.Heading).headingLevel == 1)
            {
                tags.RemoveAt(modelDescriptionIndex + 1);
            }

            // Document model validation.
            AddValidationTags(tags, ExplorerPresenter.ApsimXFile, 1, workingDirectory);

            // Add statistics
            AddStatistics(tags);

            // Move cultivars to end.
            MoveCultivarsToEnd(tags);

            // Strip all blank sections i.e. two headings with nothing between them.
            StripEmptySections(tags);

            // Scan for citations.
            ScanForCitations(tags);

            // Create a bibliography.
            CreateBibliography(tags);

            // numebr all headings.
            NumberHeadings(tags);

            // Populate the PDF section.
            TagsToMigraDoc(section, tags, workingDirectory);

            // Write the PDF file.
            FileNameWritten = Path.Combine(Path.GetDirectoryName(ExplorerPresenter.ApsimXFile.FileName), modelNameToExport + ".pdf");
            PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(false, PdfSharp.Pdf.PdfFontEmbedding.Always);

            pdfRenderer.Document = document;
            pdfRenderer.RenderDocument();
            pdfRenderer.PdfDocument.Save(FileNameWritten);

            // Remove temporary working directory.
            Directory.Delete(workingDirectory, true);
        }
Beispiel #29
0
        public void OnFindReferences(object sender, EventArgs e)
        {
            try
            {
                IModel model = Apsim.Get(this.explorerPresenter.ApsimXFile, this.explorerPresenter.CurrentNodePath) as IModel;
                if (model != null)
                {
                    string           modelPath  = Apsim.FullPath(model);
                    StringBuilder    message    = new StringBuilder($"Searching for references to model {Apsim.FullPath(model)}...");
                    List <Reference> references = new List <Reference>();
                    message.AppendLine();
                    message.AppendLine();
                    Stopwatch    timer = Stopwatch.StartNew();
                    BindingFlags flags;

                    foreach (IModel child in Apsim.FindAll(model))
                    {
                        if (Apsim.FullPath(child) == Apsim.FullPath(model))
                        {
                            continue;
                        }

                        // Resolve links (this doesn't seem to work properly).
                        explorerPresenter.ApsimXFile.Links.Resolve(child);
                        MemberInfo[] members   = null;
                        Type         childType = child.GetType();

                        // First, find all links to the model.
                        // First, try the cache.
                        if (!links.TryGetValue(childType, out members))
                        {
                            // We haven't looked for members of this type before.
                            List <MemberInfo> localMembers = new List <MemberInfo>();

                            // Links may be static or non-static (instance), and can have any accessibility.
                            flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

                            // Find all properties which are links.
                            localMembers.AddRange(child.GetType().GetProperties(flags).Where(p => ReflectionUtilities.GetAttribute(p, typeof(LinkAttribute), true) != null));

                            // Find all fields which are links.
                            localMembers.AddRange(child.GetType().GetFields(flags).Where(f => ReflectionUtilities.GetAttribute(f, typeof(LinkAttribute), true) != null));

                            members = localMembers.ToArray();

                            // Add members to cache.
                            links.Add(childType, members);
                        }

                        // Now iterate over all members of this type which are links.
                        foreach (MemberInfo member in members)
                        {
                            IModel linkValue = ReflectionUtilities.GetValueOfFieldOrProperty(member.Name, child) as IModel;
                            if (linkValue == null)
                            {
                                continue; // Silently ignore this member.
                            }
                            bool isCorrectType  = model.GetType().IsAssignableFrom(linkValue.GetType());
                            bool hasCorrectPath = string.Equals(Apsim.FullPath(linkValue), modelPath, StringComparison.InvariantCulture);
                            if (isCorrectType && hasCorrectPath)
                            {
                                message.AppendLine($"Found member {member.Name} of node {Apsim.FullPath(child)}.");
                                references.Add(new Reference()
                                {
                                    Member = member, Target = model, Model = child
                                });
                            }
                        }

                        //if (model is IFunction && child is IFunction)
                        {
                            // Next, search all public string properties for the path to this model.
                            PropertyInfo[] properties;
                            if (!stringProperties.TryGetValue(childType, out properties))
                            {
                                flags      = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
                                properties = childType.GetProperties(flags).Where(p => p.PropertyType == typeof(string) && p.CanRead).ToArray();
                                stringProperties.Add(childType, properties);
                            }
                            foreach (PropertyInfo property in properties)
                            {
                                string value;
                                try
                                {
                                    // An exception could be thrown here from inside the property's getter.
                                    value = property.GetValue(child) as string;
                                }
                                catch
                                {
                                    continue;
                                }
                                if (value == null)
                                {
                                    continue;
                                }

                                value = value.Replace(".Value()", "").Replace(".Value", "");
                                IModel result = null;
                                try
                                {
                                    result = Apsim.Get(child, value) as IModel;
                                }
                                catch
                                {
                                    continue;
                                }
                                if (result == null)
                                {
                                    continue;
                                }
                                bool correctType = model.GetType().IsAssignableFrom(result.GetType());
                                bool correctPath = string.Equals(Apsim.FullPath(result), modelPath, StringComparison.InvariantCulture);
                                if (correctType && correctPath)
                                {
                                    message.AppendLine($"Found reference in string property {property.Name} of node {Apsim.FullPath(child)}.");
                                    references.Add(new Reference()
                                    {
                                        Member = property, Target = model, Model = child
                                    });
                                }
                            }
                        }
                    }
                    timer.Stop();
                    message.AppendLine();
                    message.AppendLine($"Finished. Elapsed time: {timer.Elapsed.TotalSeconds.ToString("#.00")} seconds");
                    explorerPresenter.MainPresenter.ShowMessage(message.ToString(), Simulation.MessageType.Information);
                    var dialog = new Utility.FindAllReferencesDialog(model, references, explorerPresenter);
                }
            }
            catch (Exception err)
            {
                explorerPresenter.MainPresenter.ShowError(err);
            }
        }
Beispiel #30
0
        /// <summary>
        /// Attach the model to the view.
        /// </summary>
        /// <param name="model">The underlying model we are to use</param>
        /// <param name="view">The underlying view we are to attach to</param>
        /// <param name="explorerPresenter">Our parent explorerPresenter</param>
        public void Attach(object model, object view, ExplorerPresenter explorerPresenter)
        {
            this.model = model as Model;
            this.view  = view as IProfileView;
            profileGrid.Attach(model, this.view.ProfileGrid, explorerPresenter);
            this.explorerPresenter = explorerPresenter;

            this.view.ShowView(false);

            // Setup the property presenter and view. Hide the view if there are no properties to show.
            this.propertyPresenter = new PropertyPresenter();
            this.propertyPresenter.Attach(this.model, this.view.PropertyGrid, this.explorerPresenter);
            propertyPresenter.ScalarsOnly = true;
            // Populate the grid
            this.PopulateGrid();

            // Populate the graph.
            this.graph = Utility.Graph.CreateGraphFromResource("WaterGraph");
            graph.Name = "";
            if (this.graph == null)
            {
                this.view.ShowGraph(false);
            }
            else
            {
                // The graph's series contain many variables such as [Soil].LL. We now replace
                // these relative paths with absolute paths.
                foreach (Series series in Apsim.Children(graph, typeof(Series)))
                {
                    series.XFieldName  = series.XFieldName?.Replace("[Soil]", Apsim.FullPath(this.model.Parent));
                    series.X2FieldName = series.X2FieldName?.Replace("[Soil]", Apsim.FullPath(this.model.Parent));
                    series.YFieldName  = series.YFieldName?.Replace("[Soil]", Apsim.FullPath(this.model.Parent));
                    series.Y2FieldName = series.Y2FieldName?.Replace("[Soil]", Apsim.FullPath(this.model.Parent));
                }

                this.parentForGraph = this.model.Parent as IModel;
                if (this.parentForGraph != null)
                {
                    this.parentForGraph.Children.Add(this.graph);
                    this.graph.Parent = this.parentForGraph;
                    this.view.ShowGraph(true);
                    int padding = (this.view as ProfileView).MainWidget.Allocation.Width / 2 / 2;
                    this.view.Graph.LeftRightPadding = padding;
                    this.graphPresenter = new GraphPresenter();
                    for (int i = 0; i < this.profileGrid.Properties.Length; i++)
                    {
                        string columnName = profileGrid.Properties[i].Name;

                        if (columnName.Contains("\r\n"))
                        {
                            StringUtilities.SplitOffAfterDelimiter(ref columnName, "\r\n");
                        }

                        // crop colours
                        if (columnName.Contains("LL"))
                        {
                            if (profileGrid.Properties[i].Object is SoilCrop)
                            {
                                string soilCropName = (profileGrid.Properties[i].Object as SoilCrop).Name;
                                string cropName     = soilCropName.Replace("Soil", "");
                                columnName = cropName + " " + columnName;
                            }

                            Series cropLLSeries = new Series();
                            cropLLSeries.Name         = columnName;
                            cropLLSeries.Colour       = ColourUtilities.ChooseColour(this.graph.Children.Count);
                            cropLLSeries.Line         = LineType.Solid;
                            cropLLSeries.Marker       = MarkerType.None;
                            cropLLSeries.Type         = SeriesType.Scatter;
                            cropLLSeries.ShowInLegend = true;
                            cropLLSeries.XAxis        = Axis.AxisType.Top;
                            cropLLSeries.YAxis        = Axis.AxisType.Left;
                            cropLLSeries.YFieldName   = (parentForGraph is Soil ? Apsim.FullPath(parentForGraph) : "[Soil]") + ".DepthMidPoints";
                            cropLLSeries.XFieldName   = Apsim.FullPath((profileGrid.Properties[i].Object as IModel)) + "." + profileGrid.Properties[i].Name;
                            //cropLLSeries.XFieldName = Apsim.FullPath(property.Object as Model) + "." + property.Name;
                            cropLLSeries.Parent = this.graph;

                            this.graph.Children.Add(cropLLSeries);
                        }
                    }

                    explorerPresenter.ApsimXFile.Links.Resolve(graphPresenter);
                    this.graphPresenter.Attach(this.graph, this.view.Graph, this.explorerPresenter);
                    graphPresenter.LegendInsideGraph = false;
                }
            }

            // Trap the model changed event so that we can handle undo.
            this.explorerPresenter.CommandHistory.ModelChanged += this.OnModelChanged;

            this.view.ShowView(true);
        }