Skip to content

Commit

Permalink
Merge pull request #3250 from hut104/SoilNutrientIncrementalMerge
Browse files Browse the repository at this point in the history
First batch of files to merge for Soil Nutrient
  • Loading branch information
hol353 authored Nov 6, 2018
2 parents d31872c + 6370e8a commit 5f0843a
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 21 deletions.
99 changes: 99 additions & 0 deletions APSIM.bib
Original file line number Diff line number Diff line change
Expand Up @@ -16856,3 +16856,102 @@ @article{rubilar2018advances
year={2018},
publisher={Springer}
}

@article{Young2009_HudsonCarbon,
Author = {Young, R. R. and Wilson, B. and Harden, S. and Bernardi, A.},
Title = {{Accumulation of soil carbon under zero tillage cropping and perennial
vegetation on the Liverpool Plains, eastern Australia}},
Journal = {{AUSTRALIAN JOURNAL OF SOIL RESEARCH}},
Year = {{2009}},
Volume = {{47}},
Number = {{3}},
Pages = {{273-285}},
Publisher = {{CSIRO PUBLISHING}},
Address = {{150 OXFORD ST, PO BOX 1139, COLLINGWOOD, VICTORIA 3066, AUSTRALIA}},
Type = {{Article}},
Language = {{English}},
Affiliation = {{Young, RR (Reprint Author), Tamworth Agr Inst, NSW Dept Primary Ind, 4 Marsden Pk Rd, Calala, NSW 2340, Australia.
Young, R. R.; Harden, S.; Bernardi, A., Tamworth Agr Inst, NSW Dept Primary Ind, Calala, NSW 2340, Australia.
Wilson, B., Univ New England, NSW Dept Environm \& Climate Change, Armidale, NSW 2351, Australia.
Wilson, B., Univ New England, Sch Environm \& Rural Sci, Armidale, NSW 2351, Australia.}},
DOI = {{10.1071/SR08104}},
ISSN = {{0004-9573}},
Keywords-Plus = {{NEW-SOUTH-WALES; ORGANIC-CARBON; NO-TILL; CONSERVATION TILLAGE;
SUBTROPICAL ACRISOL; STUBBLE MANAGEMENT; SEQUESTRATION; NITROGEN;
SYSTEMS; MATTER}},
Research-Areas = {{Agriculture}},
Web-of-Science-Categories = {{Soil Science}},
Author-Email = {{[email protected]}},
ResearcherID-Numbers = {{Wilson, Brian/G-4996-2011
Management, Ecosystem/C-2259-2011
}},
Journal-ISO = {{Aust. J. Soil Res.}},
}

@article{Rolston1984,
author = {Rolston, D.E.; Rao, P.S.C.; Davidson, J.M.; Jessup, R.E.},
title = {Simulation of denitrification losses of Nitrate fertiliser applied to uncropped, cropped, and manure-amended field plots},
journal = {Soil Science},
volume = {137},
number = {270-278},
year = {1984},
type = {Journal Article}
}
@article{Reddy1980,
author = {Reddy, K.R.; Khaleel, R.; Overcash, M.R.},
title = {Carbon transformations in land areas receiving organic wastes in relation to nonpoint source pollution: A conceptual model},
journal = {Journal of Environmental Quality},
volume = {9},
number = {434-442},
year = {1980},
type = {Journal Article}
}

@article{Schultz1995,
author = {Schultz, J.E.},
title = {Crop production in a rotation trial at Tarlee, South Australia},
journal = {Australian Journal of Experimental Agriculture},
volume = {35},
number = {865-876},
year = {1995},
type = {Journal Article}
}

@article{Skjemstad2004,
author = {Skjemstad, J.O., Spouncer, L.R., Cowie, B., Swift, R.S.},
title = {Calibration of the Rothamsted organic carbon turnover model (RothC ver.26.3), using measurable soil organic carbon pools},
journal = {Australian Journal of Soil Research},
volume = {42},
number = {79-88},
year = {2004},
type = {Journal Article}
}

@article{PARTON1998,
title = "DAYCENT and its land surface submodel: description and testing",
journal = "Global and Planetary Change",
volume = "19",
number = "1",
pages = "35 - 48",
year = "1998",
issn = "0921-8181",
doi = "https://doi.org/10.1016/S0921-8181(98)00040-X",
url = "http://www.sciencedirect.com/science/article/pii/S092181819800040X",
author = "William J. Parton and Melannie Hartman and Dennis Ojima and David Schimel",
keywords = "soil water, ecological models, soil temperature, latent heat flux, DAYCENT, water flow, trace gas flux"
}

@article{THORBURN2010,
title = "Using the APSIM model to estimate nitrous oxide emissions from diverse Australian sugarcane production systems",
journal = "Agriculture, Ecosystems & Environment",
volume = "136",
number = "3",
pages = "343 - 350",
year = "2010",
note = "Estimation of nitrous oxide emission from ecosystems and its mitigation technologies",
issn = "0167-8809",
doi = "https://doi.org/10.1016/j.agee.2009.12.014",
url = "http://www.sciencedirect.com/science/article/pii/S0167880909003740",
author = "P.J. Thorburn and J.S. Biggs and K. Collins and M.E. Probert",
keywords = "Crop residues, Denitrification, Nitrification, Greenhouse gas, Nitrogen fertiliser, Irrigation"
}
104 changes: 83 additions & 21 deletions ApsimNG/Views/DirectedGraphView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,70 @@ namespace UserInterface.Views
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;

/// <summary>
/// A view that contains a graph and click zones for the user to allow
/// editing various parts of the graph.
/// </summary>
public class DirectedGraphView : ViewBase
{
/// <summary>
/// The currently selected node/object.
/// </summary>
private DGObject selectedObject;

/// <summary>
/// Keeps track of whether the mouse button is currently down.
/// </summary>
private bool mouseDown = false;

/// <summary>
/// Drawing area upon which the graph is rendered.
/// </summary>
private DrawingArea drawable;

/// <summary>
/// Position of the last moved node.
/// </summary>
private PointD lastPos;
private List<DGNode> Nodes = new List<DGNode>();
private List<DGArc> Arcs = new List<DGArc>();

/// <summary>
/// List of nodes. These are currently circles with text in them.
/// </summary>
private List<DGNode> nodes = new List<DGNode>();

/// <summary>
/// List of arcs which connect the nodes.
/// </summary>
private List<DGArc> arcs = new List<DGArc>();

/// <summary>Initializes a new instance of the <see cref="DirectedGraphView" /> class.</summary>
public DirectedGraphView(ViewBase owner = null) : base(owner)
{
DrawingArea drawingArea = new DrawingArea();

drawingArea.AddEvents(
drawable = new DrawingArea();
drawable.AddEvents(
(int)Gdk.EventMask.PointerMotionMask
| (int)Gdk.EventMask.ButtonPressMask
| (int)Gdk.EventMask.ButtonReleaseMask);

drawingArea.ExposeEvent += OnDrawingAreaExpose;
drawingArea.ButtonPressEvent += OnMouseButtonPress;
drawingArea.ButtonReleaseEvent += OnMouseButtonRelease; ;
drawingArea.MotionNotifyEvent += OnMouseMove; ;
_mainWidget = drawingArea;
drawingArea.ModifyBg(StateType.Normal, new Gdk.Color(255, 255, 255));
drawable.ExposeEvent += OnDrawingAreaExpose;
drawable.ButtonPressEvent += OnMouseButtonPress;
drawable.ButtonReleaseEvent += OnMouseButtonRelease;
drawable.MotionNotifyEvent += OnMouseMove;

ScrolledWindow scroller = new ScrolledWindow(new Adjustment(0, 0, 100, 1, 1, 1), new Adjustment(0, 0, 100, 1, 1, 1))
{
HscrollbarPolicy = PolicyType.Always,
VscrollbarPolicy = PolicyType.Always
};

scroller.AddWithViewport(drawable);

_mainWidget = scroller;
drawable.ModifyBg(StateType.Normal, new Gdk.Color(255, 255, 255));
drawable.Realized += OnRealized;
}

/// <summary>The description (nodes & arcs) of the directed graph.</summary>
Expand All @@ -50,14 +85,14 @@ public DirectedGraph DirectedGraph
get
{
DirectedGraph graph = new DirectedGraph();
Nodes.ForEach(node => graph.Nodes.Add(node.ToNode()));
Arcs.ForEach(arc => graph.Arcs.Add(arc.ToArc()));
nodes.ForEach(node => graph.Nodes.Add(node.ToNode()));
arcs.ForEach(arc => graph.Arcs.Add(arc.ToArc()));
return graph;
}
set
{
value.Nodes.ForEach(node => Nodes.Add(new DGNode(node)));
value.Arcs.ForEach(arc => Arcs.Add(new DGArc(arc, Nodes)));
value.Nodes.ForEach(node => nodes.Add(new DGNode(node)));
value.Arcs.ForEach(arc => arcs.Add(new DGArc(arc, nodes)));
}
}

Expand All @@ -67,7 +102,7 @@ public System.Drawing.Image Export()
int width;
int height;
MainWidget.GdkWindow.GetSize(out width, out height);
Gdk.Pixbuf screenshot = Gdk.Pixbuf.FromDrawable(MainWidget.GdkWindow, MainWidget.Colormap, 0, 0, 0, 0, width, height);
Gdk.Pixbuf screenshot = Gdk.Pixbuf.FromDrawable(drawable.GdkWindow, drawable.Colormap, 0, 0, 0, 0, width - 20, height - 20);
byte[] buffer = screenshot.SaveToBuffer("png");
MemoryStream stream = new MemoryStream(buffer);
System.Drawing.Bitmap bitmap = new Bitmap(stream);
Expand All @@ -81,9 +116,9 @@ private void OnDrawingAreaExpose(object sender, ExposeEventArgs args)

Cairo.Context context = Gdk.CairoHelper.Create(area.GdkWindow);

foreach (DGArc tmpArc in Arcs)
foreach (DGArc tmpArc in arcs)
tmpArc.Paint(context);
foreach (DGNode tmpNode in Nodes)
foreach (DGNode tmpNode in nodes)
tmpNode.Paint(context);

((IDisposable)context.Target).Dispose();
Expand All @@ -101,11 +136,11 @@ private void OnMouseButtonPress(object o, ButtonPressEventArgs args)
selectedObject.Selected = false;

// Look through nodes for the click point
selectedObject = Nodes.FindLast(node => node.HitTest(clickPoint));
selectedObject = nodes.FindLast(node => node.HitTest(clickPoint));

// If not found, look through arcs for the click point
if (selectedObject == null)
selectedObject = Arcs.FindLast(arc => arc.HitTest(clickPoint));
selectedObject = arcs.FindLast(arc => arc.HitTest(clickPoint));

// If found object, select it.
if (selectedObject != null)
Expand Down Expand Up @@ -140,8 +175,35 @@ private void OnMouseMove(object o, MotionNotifyEventArgs args)
private void OnMouseButtonRelease(object o, ButtonReleaseEventArgs args)
{
mouseDown = false;
CheckSizing();
}


/// <summary>
/// Drawing area has been rendered - make sure it has enough space.
/// </summary>
/// <param name="sender">Sender object.</param>
/// <param name="args">Event arguments.</param>
private void OnRealized(object sender, EventArgs args)
{
CheckSizing();
}

/// <summary>
/// If the right-most node is out of the drawing area, doubles the width.
/// If the bottom-most node is out of the drawing area, doubles the height;
/// </summary>
private void CheckSizing()
{
if (nodes != null && nodes.Any())
{
DGNode rightMostNode = nodes.Aggregate((node1, node2) => node1.Location.X > node2.Location.X ? node1 : node2);
DGNode bottomMostNode = nodes.Aggregate((node1, node2) => node1.Location.Y > node2.Location.Y ? node1 : node2);
if (rightMostNode.Location.X + rightMostNode.Width >= drawable.Allocation.Width)
drawable.WidthRequest = 2 * drawable.Allocation.Width;
// I Assume that the nodes are circles such that width = height.
if (bottomMostNode.Location.Y + bottomMostNode.Width >= drawable.Allocation.Height)
drawable.HeightRequest = 2 * drawable.Allocation.Height;
}
}
}
}
6 changes: 6 additions & 0 deletions Models/Core/Attributes/LinkAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public class LinkByPathAttribute : LinkAttribute
{
/// <summary>The path to use to find a link match.</summary>
public string Path { get; set; }

/// <summary>Should the fields name be used when matching?</summary>
public override bool UseNameToMatch(IVariable field)
{
return false;
}
}

/// <summary>
Expand Down
9 changes: 9 additions & 0 deletions Models/Functions/ExpressionFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,18 @@ public void Document(List<AutoDocumentation.ITag> tags, int headingLevel, int in
{
// add a heading.
tags.Add(new AutoDocumentation.Heading(Name, headingLevel));
// write memos.
foreach (IModel memo in Apsim.Children(this, typeof(Memo)))
AutoDocumentation.DocumentModel(memo, tags, headingLevel + 1, indent);


string st = Expression.Replace(".Value()", "");
st = st.Replace("*", "x");
tags.Add(new AutoDocumentation.Paragraph(Name + " = " + st, indent));

foreach (IModel child in Apsim.Children(this, typeof(IFunction)))
AutoDocumentation.DocumentModel(child, tags, headingLevel + 1, indent + 1);

}
}

Expand Down
83 changes: 83 additions & 0 deletions Models/Functions/StringComparisonFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using Models.Core;


namespace Models.Functions
{
/// <summary>Value returned is determined according to given criteria</summary>
[Serializable]
[Description("Tests if value of a string property is equal to a given value and returns a value depending on the result.")]
[ViewName("UserInterface.Views.GridView")]
[PresenterName("UserInterface.Presenters.PropertyPresenter")]
public class StringComparisonFunction : Model, IFunction, ICustomDocumentation
{

/// <summary>The propertyname</summary>
[Description("Name of string property to compare")]
public string PropertyName { get; set; }

/// <summary>The string value</summary>
[Description("Text string for comparison to the property value")]
public string StringValue { get; set; }

/// <summary>The True Value</summary>
[Link]
IFunction TrueValue = null;

/// <summary>The False Value</summary>
[Link]
IFunction FalseValue = null;

[Link]
private ILocator locator = null;

/// <summary>Gets the value.</summary>
/// <value>The value.</value>
public double Value(int arrayIndex = -1)
{
object s = locator.Get(PropertyName);

string PropertyString;
if (s == null)
PropertyString = "";
else if (s is Array)
PropertyString = (string)(s as Array).GetValue(arrayIndex);
else if (s is IFunction)
PropertyString = (s as IFunction).Value(arrayIndex).ToString();
else
PropertyString = (string)s;

bool stringCompareTrue = PropertyString.Equals(StringValue, StringComparison.CurrentCultureIgnoreCase);

if (stringCompareTrue)
return TrueValue.Value(arrayIndex);
else
return FalseValue.Value(arrayIndex);
}

/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary>
/// <param name="tags">The list of tags to add to.</param>
/// <param name="headingLevel">The level (e.g. H2) of the headings.</param>
/// <param name="indent">The level of indentation 1, 2, 3 etc.</param>
public void Document(List<AutoDocumentation.ITag> tags, int headingLevel, int indent)
{
if (IncludeInDocumentation)
{

// add a heading.
tags.Add(new AutoDocumentation.Heading(Name, headingLevel));

// write memos.
foreach (IModel memo in Apsim.Children(this, typeof(Memo)))
AutoDocumentation.DocumentModel(memo, tags, headingLevel + 1, indent);

tags.Add(new AutoDocumentation.Paragraph("If " + PropertyName + " = " + StringValue + " Then", indent));
AutoDocumentation.DocumentModel(TrueValue as IModel,tags, headingLevel+1, indent+1);

tags.Add(new AutoDocumentation.Paragraph("Else", indent));
AutoDocumentation.DocumentModel(FalseValue as IModel, tags, headingLevel+1, indent+1);
}
}
}
}
Loading

0 comments on commit 5f0843a

Please sign in to comment.