Note: This page is no longer being maintained and is kept for archival purposes only.
For current information see our main page.
GWI Kurtz-Fernhout Software
Developers of custom software and educational simulations.
Home ... News ... Products ... Download ... Order ... Support ... Consulting ... Company
Garden with Insight
Download it
Screen shots
Help system
Source code
About GWI
Why free?
Book proposal
NSF proposal
Tech support

The Garden with Insight garden simulator - Programmer's guide

The following is the entire text of the Garden with Insight™ programmer's guide, available as an ASCII text file with the source code (for details on downloading the source code see the Garden with Insight main page). This web page is about 26 printed pages long. We put it here on the web site to give you an idea of what the source code base is like.

Programmer's Guide for Garden with Insight source code version 1.0
Source code page

======== Introduction

Thank you for downloading this source code base. Please see the license file (license.txt) for details on use and redistribution restrictions. This introduction will cover 1) what we have done in making this software, 2) what you might get out of using this source code, and 3) future directions in which we would like to see this software and source code base develop.

== What we have done

* We translated EPIC from FORTRAN to Pascal. The EPIC (Erosion/Productivity Impact Calculator) model represents decades of solid scientific research, and is freely available, well validated and respected. But its 17,500 lines of FORTRAN source code are dense and difficult to understand. One of us spent nearly a year laboriously translating each line of FORTRAN code to readable Pascal. One of the main reasons we are releasing this source code is that we hope our translation work will create some positive feedback in the agricultural science community. Also, because we are not soil scientists (our backgrounds are in Ecology), we feel some interaction with the soil science community would benefit the source code and make the product a better educational resource.

* During translation we made the EPIC code much more readable. One of the changes we made while translating EPIC from FORTRAN is this: we greatly expanded all variable names. For example, the variable "xi" might become "percolationThisLayer_mm". We also rearranged several arrays of parameters that were designated only by indexes into data structures with complete names for each field (e.g., "smy4" became "params. fractionOfIrrigationWaterLostToRunoff"). Each variable in the GWI code has a unit suffix after an underscore. Such obvious unit designations make it easier to work out the units in each equation and understand conversion constants (which otherwise are "magic numbers"). Here is an comparison of some EPIC code with the GWI code it was translated to:

GWI: waterContent_mm := waterContent_mm + rainfallAndIrrigation_mm - totalRunoff_mm

Granted, the EPIC code is much shorter; but finding out what "RFV" and "QD" mean can literally take all day. And you can see right away in the GWI code that all the units match up. This renaming makes the source code so much more readable that it may prove to be the most important part of the project.

* We changed EPIC to make it fit a home garden with multiple plants and multiple soil patches. The biggest difference between EPIC and Garden with Insight is this: EPIC models one field and one crop only, and GWI models multiple soil patches with multiple plants (of any species) in each soil patch. Soil patches in GWI do not communicate, so that part of the model is like several EPIC models side by side. But GWI plants do compete for water and nutrients within each soil patch (but not for sunlight). We also made other changes from the original EPIC code, mainly the following: 1) we added a plant biomass allocation model more complex than EPIC's, so we could model individual harvested fruits; 2) we removed the pesticide movement and economic model components (the reason for removing pesticides is discussed later in this document); and 3) we encapsulated the EPIC code into objects which interact (though this object-oriented approach could have been taken much further).

Please note that we do not believe we have done a better job than EPIC at simulating a complex situation. In fact, we may have introduced all sorts of errors in the changes we have made. We made these changes only to make the simulation better fit our goal of simulating a home garden. To make our changes we surveyed existing models and theory in the research literature. Some significant gaps remain, which we will discuss later in this document.

== What you might get out of the source code

Our hope in releasing this source code is that it will draw a community of users who will help us improve the simulation to make it more accurate and educational. Here are some reasons you might want to join us in this community.

* You can study the model to learn soil science, plant growth, hydrology, etc. If you are using the simulation to learn, you can use the source code to go deeper into these subjects than you can by using the simulation. Why use the source code to learn?
- You can get a better understanding of the vocabulary.
- You can get a better look at how science really moves forward (by building on successive generations of research and thought) than you can by reading a textbook.
- You can see how a modeling effort starts and grows, and what difficult decisions are made along the way.
- You can get a better understanding of some complex concepts like how the soil texture affects the percolation of water through the soil, or how soil cover affects soil temperature, by following through all the calculations that impact the outcomes.
- You can learn to look critically at scientific modeling and research by comparing the model to other models and published data, and deciding what you think is lacking or inaccurate.

* You can expand the simulation to cover an area of interest to you. Several areas of the simulation are sketchy and would benefit from development, such as pH, soil biology, etc (see below). By filling in these areas you can use the simulation as a background for testing equations and ideas. Writing a new section of equations really involves you in learning about your subject -- reading up on the literature, getting a handle on the important concepts, coming up with the best way to simulate the new topic with the competing demands of simplicity and accuracy, integrating the new area with the existing equations and variables. In the same way that teaching about a subject is a great way to learn about it, creating a new submodel is a great way to test and develop your knowledge in a particular area. Of course, you can also use portions of the simulation in other models (see the license for restrictions).

* You can use the simulation in science classes. If you are a science teacher at the secondary or post- secondary level, you can can use GWI with the source code as a foundation for a group or individual project in many areas, including soil science, plant growth, meterology, geology, hydrology, environmental issues, mathematics, chemistry, and programming. Using the simulation with source code is not something you can squeeze into short class periods or restrictive curricula. But if you have some time and freedom to experiment -- if your students want to do some after-class exploring, or if you have some lab sections or a long-term project that allow some unstructured time, there are many possibilities you can explore.

To mention just a few quick ideas, you can ask your students to:
- add a new section of equations (such as a potassium model) based on library research, or plan out the addition in pseudocode, and write documentation explaining how the section works and why they wrote it the way they did;
- critique one section of the source code based on library research using the references cited and other literature in the field, and write a paper in a format acceptable to current scientific journals;
- compare the results of one component of the simulation (such as the simulation of precipitation or water movement through the soil) with real research data to validate the model in that respect, and prepare a report on how well that part of the simulation matches reality;
- do a physical experiment that duplicates some part of the simulation (like water moving through a column of soil, or the relative weights of different plant parts) and explain how the simulation accurately portrays the reality of the experiment and how it doesn't;
- write a short textbook chapter on one set of model equations for students in a lower grade level using simple language and building vocabulary from words students in those classes might know already.

== Future directions

* Our dream is to develop this program into a version 2.0 system that has these elements:

- a strong base of understandable source code that becomes a standard for educational science simulation;
- an open modeling system that allows easy sharing of model components and communication of ideas;
- a learning environment for modeling that allows users to start with simple models and work their way up to more complex understandings;
- an object-oriented database system for easy sharing of model data throughout changes in the model;
- a strong user community of academic researchers, teachers, students, and interested amateurs who collaborate on improving the system for educational and research use;
- educational resources such as lesson plans and project ideas contributed to and used by many educators.

We submitted a National Science Foundation grant pre-proposal in the spring of 1997 to this effect (a copy of the proposal can be found elsewhere on this web site). The NSF's response was something like: "We don't understand why you don't want to sell the program commercially." We don't want to sell the program as proprietary software because 1) we would like the source code to be used and improved by others; and 2) we don't have the time and money to market the program. Our hope is that someday we may get to the version 2.0 modeling environment another way: through the help of many interested individuals.

We invite you to participate in this community. You can participate by reading the source code, by tinkering with it, by researching it, by making changes, by talking about it, by using it, by improving it.

* Specific parts of the program that could use improvement are as follows.

In the weather model,
- a better way to characterize, describe and choose microclimates as distinct from the climate in an area;
- more climate data for areas outside the US;
- a better way of displaying and choosing climates rather than point sources from weather stations, as with maps showing areas of variables such as temperature that fall inside certain ranges;

In the soil model,
- communication between soil patches, so that for example water flowing out of one soil patch flows into another (this would entail some sort of 3D spatial model so that water would flow in the correct directions down hills);
- a reasonable pesticide model which includes all the effects pesticides and their breakdown compounds have on the soil and water and biota;
- a better pH model (including its affects on soil biota;
- a soil biota submodel, including the significant effect of earthworms;
- more soil chemistry including the actions of other nutrients (potassium, calcium, magnesium, etc) and a more detailed cation-exchange model;
- a better way of generating soil types based on simple easy-to-understand terms such as the ribbon test (can you make a ribbon of soil in your hand, or is it too crumbly) and typical soil test results;
- a better way of choosing soil types based on geography, possibly with a simple large-soil-class soils map of the US and world;

In the plant model,
- a better plant growth and resource allocation model, especially in mobilization of nutrients between different parts of the plant and the simulation of simple growth regulation hormones;
- a better model for growth of individual plant parts, photoperiodism, and plant drawing;
- more work on calibration of yield estimates to yield data in important garden and crop plants;
- better plant parameterization, including a better way of estimating plant and soil parameters based on large classes (monocot, dicot, etc);
- a weed seed bank model and weed competition with garden plants, and weed parameters for the most common weeds;

In general,
- library research to make sure the equations in the simulation code agree with the original research papers (e.g., following the EPIC explanations back to the original cited papers and seeing what equations are given there, and what exceptions are given that might make the equations not work as well in the situations in which they are used, etc);
- better validation of all aspects of the model.

======== Comments on Delphi

Delphi 1.0 (under Windows 3.1) was used for most development. Therefore all the form files (dfm) in this source code package are in Delphi 1.0 format (see the note below about using form files under Delphi 2.0). Delphi 2.0 was used for compiling, testing and debugging under Windows 95 and NT, but no major changes were made there.

Problems with Delphi 1.0

* We fixed several bugs in the Delphi 1.0 VCL, and if you don't make the same fixes you might have problems running our code. Most of our fixes were the same ones as are recommended by the MemMonD (the patches are only available to registered users of MemMonD). If you have strange or unexplained problems running the code, especially ones to do with TMenuItems, check out discussion on these VCL patches.

* The biggest problem we had with Delphi 1.0 was with a bug that caused the development environment to crash ungracefully when a floating point error was encountered (a divide by zero, overflow, underflow, etc.). We tried to reduce the effect of this problem by putting in extensive error-handling code. See the description of udebug.pas and ueutils.pas for more on this problem.

Problems with Delphi 2.0

* Since we did most code development under Delphi 1.0, we kept the form files in Delphi 1.0 format when we started working in Delphi 2.0. If you edit and save a Delphi 1.0 form file in Delphi 2.0, you can never again read that file in Delphi 1.0. So we have never edited the form files in Delphi 2.0. If you never use Delphi 1.0, this should not be a problem, but it might be a problem in communicating with others.

* We were having a problem in Delphi 2.0 where any change to any file caused linking errors if you choose "Compile" and not "Build all". We traced this to the use of floating point constants. We reported the bug to Borland, and they said it had been fixed in a patch, and we loaded the patch, but it was never fixed. The complete workaround for this bug would be to remove all floating point constants from the code (replacing them with initialized variables), but there are many in the code (the uunits.pas file has many, for example). So we have just been rebuilding the whole project each time we changed anything (it doesn't take that long).

======== General comments on the source code

* All model code is based in part on EPIC3090 in FORTRAN by J.R. Williams et. al., USDA ARS.

* Conditional defines that affect the code are:
- GS_DEBUG: Causes the numerical exceptions window to show a "break on exception" check box. See the description of the numerical exceptions window for details (udebug).
- ALLOW_HARDCODING: Causes hardcoding functions for some templates to be called if the program is started up with no templates file (see udomain and uhardcd).
- DEBUG_TURTLE: Causes the 3D turtle to draw x, y, and z axis lines when it draws each line segment. See uturt3d.pas for details.

* We left in a lot of comments that raise questions or suggest improvements; many say "PDF fix" or "CFK fix" (the initials are for Paul Fernhout and Cynthia Kurtz).

* The reason the initials "Gs" are at the start of many objects is that the project used to be called "Garden Simulator."

* The initials "Kf" at the start of some objects are for Kurtz-Fernhout Software.

* Often you will see the following code:
newString: string;
newString: ansistring;
This is because in 32-bit if you are going to pass a string to some Windows functions, it must be an ansistring string. Failing to do this causes compile errors in Delphi 2.0.

======== Hierarchy of domain objects by reference

domain (GsDomain in udomain) (GsGarden in uegarden) (GsWeather in ueweath)  
....soil patches (GsSoilPatch in uesoil)  
......plants (GsPlant in ueplant)  
........drawing plant (one per plant)  
..........drawing plant parts:  
..........meristems (buds)  
..........internodes (stem sections)  
..........flower/fruits matter blobs (GsOrganicMatter in ueorgmat)  
..aspect manager (GsAspectManager in uaspects)  
....aspects (GsAspect in uaspects) manager (GsGroupManager in ugroups)  
....groups (GsGroup in ugroups) items (GsGroupItem in ugroups)  
..tool manager (GsToolManager in utools) (GsTool in utools)  
......tool actions (GsToolAction in utools)  
..template manager (GsTemplateManager in utempman)  
....climates (GsWeather in ueweath)  
....soilTypes (GsSoilPatch in uesoil)  
....cultivars (GsPlant in ueplant)  
....amendments (GsBag in uebag)  
....harvest item templates (GsHarvestItemTemplate in uharvprt)  
....icons (GsIcon in uicon)  
....3D objects (KfObject3D in uturt3d)  
..harvest manager (GsHarvestManager in uharvprt)  
....harvest items (GsHarvestItem in harvprt)  
....harvest reports (GsHarvestReport in uharvprt)  
..tool parameter list manager (GsToolParamListManager in utools)  
....tool parameters (GsToolRateOrAmountParam in utools)  
..window manager (GsWindowManager in uwindman)  
..hints manager (GsHintsManager in uhints) 

======== Hierarchy of forms by what forms can be brought up from where

garden form(TGardenForm in ugsim) [non-modal] 
..File menu 
....exit form (TExitForm in uexit) 
..Edit menu editor form (TGroupEditorForm in ugrped) 
......derivation options form (TAspectDerivationForm in uderopt) 
......layer options form (TlayerOptionsForm in ulayers) 
....harvest item editor form (THarvestItemTemplateEditorForm in uharved) 
......icon chooser form (TIconChooserForm in uiconch) 
....harvest report editor form (THarvestReportEditorForm in uhvrpted) 
....templates form (TTemplatesForm in utempl) 
......template mover form (TTemplateMoverForm in umovtemp) 
......EPIC import form (TEpicImportForm in ugetepic) 
......through text filer (ufilertx), duplicate object form (TDuplicateObjectForm in uduplic) 
....tool editor form (TToolEditorForm in utooledt) 
......notes form (TNotesForm in unotes) 
....tool parameter list editor form (TToolParamListEditorForm in utlpmed) 
..Options menu 
....backdrop chooser form (TBackdropChooserForm in ubackdrp) 
....display options form (TDisplayOptionsForm in udisplay) 
....simulation options form (TSimulationOptionsForm in usimop) 
......templates form (TTemplatesForm in utempl, see above) 
....reseeding options form (TReseedingOptionsForm in ureseed) 
..Windows menu 
....browser (TBrowserForm in ubrowser) [non-modal] 
......notes form (TNotesForm in unotes) 
......graph form (TGraphForm in ugraph, see below) editor form (TGroupEditorForm in ugrped, see above) 
......through browser components: 
........harvest item component (KfHarvestItemTemplateBrowserComponent in ubrowhar) 
..........harvest item editor form (THarvestItemTemplateEditorForm in uharved, see above) 
........single real component (KfRealSliderBrowserComponent in ubrowrl) 
..........derivation options form (TAspectDerivationForm in uderopt) 
..........bounds change form (TBoundsChangeForm uboundch) 
........array of reals component (KfRealSliderArrayBrowserComponent in ubrowrla) 
..........derivation options form (TAspectDerivationForm in uderopt) 
..........bounds change form (TBoundsChangeForm uboundch) 
........3D object component (KfObject3DBrowserComponent in ubrowtdo) 
..........3D object chooser form (TThreeDObjectChooserForm in utdoch) 
............3D object editor form (TtdoEditorForm in utdoed) 
....graph form (TGraphForm in ugraph) [non-modal] 
......graph item options form (TPlotOptionsForm in uplotopt) 
......layer options form (TlayerOptionsForm in ulayer) 
......graph titles and scales form (TGraphTitleForm in utitlech) 
......through logged var (GsLoggedVar in ulogvar), 
........derivation options form (TAspectDerivationForm in uderopt) 
....harvest form (THarvestForm in uharvest) [non-modal] 
......harvest report editor form (THarvestReportEditorForm in uhvrpted) 
....numerical exceptions form (TDebugForm in udebug) [non-modal] 
....timeline form (TtimelineForm in utimelin) 
..Help menu 
....about box form (TAboutBoxForm in uabout) 
from main form but not through menus: 
..splash screen, during startup (TSplashForm in usplash) form, hidden, plays music at startup (TMusicForm in umusic) 
..patch area form, during creation of soil patch (TPatchArea in upatarea) 
..wait form, during save at exit (TWaitForm in uwait) 

======== Comments at head of each file (alphabetically)

== uabout.pas, dfm
About box form (modal). Displays a picture and a few text labels with an OK button.

== uaspects.pas
Aspects are objects that hold information about simulation variables in order to display them in the browser and graph window. Aspects are held by the aspect manager through which they are accessed by the domain and windows. Aspects are created at program startup by the domain. Code to create aspects is generated by the supporting program "tab2asp.exe", which takes the information in the tab-delimited file "" and creates six Pascal files: uasp_pla (plant), uasp_dpl (drawing plant), uasp_s1,2,3 (soil patch - in 3 pieces because it was too big to compile), uasp_wea (weather), and umconsts (constants and transfer functions). The tab2asp program has its own project and source code (one form file). This system allows the over 800 aspects to be modified in the tab file more easily (using a spreadsheet to sort and resort the columns to compare) than editing the source code directly. To add a new aspect, add it to the file, then run tab2asp, then make sure you add a line to the file to fill in a hint for the aspect. If you change the ID constant of an aspect, you must change the ID in the file also. Make sure to always sort the file by the ID column ONLY when you are finished with it. See the description of the file at the end of the programmer's guide for explanations of columns in, which correspond to fields of the GsAspect object.

== ubackdrp.pas, dfm
Backdrop chooser window. Displays current backdrop in picture, allows user to choose new one or choose not to use one. Allows user to change background color even if still using backdrop (because can turn off display of backdrop in options menu). Deals with loading new bitmap into domain.

== ubitmap.pas
Mainly handles bitmap reading from files. GsBitmap is subclassed to make it streamable with our system.

== uboundch.pas, dfm
Bounds change window for aspects in browser components. Fairly stupid form; caller must initialize with pointers to aspect and groupItem, then accept or reject changes to bounds based on whether OK was clicked. Note that changes to things in the aspect and groupItem that can be changed in this dialog (only the unit) carry back to the browser component. This means if I open the bounds change window and the aspect is in meters, and I change the unit to feet in the window, it will be in feet when I get back to the browser. Called by ubrowrl, ubrowrla, ubrowscv.

== ubrowcom.pas
Base class for browser components. Has pointers to aspect (info on representation of variable data), object (plant, soil patch, etc), and groupItem (info on bounds, unit, etc). Sets defaults for displaying. Methods for drawing and accessing data are used by subclasses. In all browser components, the user can use the tab key to move between interface items on the component. This is important because to save resources we replaced normal window-handle sliders and other components with no-resource sliders that have no handles and therefore can have no focus. So there is an internal "unofficial" focus system used to know how to interpret keystrokes based on the index number of the item selected. The browser components are therefore (sort of) able to handle keyboard-only input. A lot of the other code in this file has to do with resizing and determining the smallest/largest size the browser component can take. Also notice that the invalidation system for ALL the browser components is very bad; they just invalidate their whole selves when that is often not necessary. But on a fast enough computer you can't tell anyway. The internal tab system must include: a) overriding the maxSelectedItemIndex function if there is more than one tab stop; and b) handling the enter keypress (override the dokeypress method) at each tab stop (make it a tab stop only if something happens when you click on it).

== ubrowhar.pas
Browser component for harvest item template (uharvprt). Displays name of icon and picture of icon. Clicking on name or icon brings up harvest item editor (uharved) to change harvest item template. Harvest item templates are objects that hold information (nutritional and otherwise) about things that can be harvested. NOTE that this is a little confusing in the code the objects that contain information about what can be harvested are called "harvest item TEMPLATES" and the objects that contain information about particular fruits, leaves, etc are called "harvest items". BUT in the help system we just call the harvest item templates (hits) "harvest items" because the whole term is too difficult to grasp. In the help system we just call the fruits, leaves, etc "harvested items". It seemed like a good idea at the time.

== ubrowint.pas
Browser component for integer. There are no integer arrays allowed, so far. Displays slider with upper and lower bounds, and value beneath. Does NOT allow user to change the unit.

== ubrowlis.pas
Browser component for list of enumerated items. Items are displayed as a list of radio buttons. Strings for items are got from object in superclass, using fillEnumStringList method of each object. This represents a case where you can't just add an aspect to If you add an aspect of this type, you must change the fillEnumStringList for the object to add this list.

== ubrowrl.pas
Browser component for one real value (single). Displays one slider with bounds, a value, and a unit. User can slide slider, click on value to change in dialog, or click on unit. Clicking on bound brings up bound change dialog (uboundch). There are two types of bounds: recommended and absolute. Recommended bounds are our guesses for what we expect these things to be. Absolute bounds matter only for editable aspects and they cannot be overridden. For read-only aspects, bounds are always overridden if the values range outside the bounds.

== ubrowrla.pas
Browser component for multiple real numbers (singles). Actually, there is no reason whatsoever for this component to be separate from ubrowrl, which shows only one single value. It's just that we started out thinking it was necessary to separate them for speed, and we never took the time to put them together. So every change to one must usually result in a change to the other. It displays from 1 (though we never use it for one) to 12 sliders (12 is for months), one set of bounds, one value (for the selected slider), and one unit (for all sliders). The user can change any value (by clicking on its slider or clicking on the value when it is selected). Can select a slider by clicking on it or by tabbing to it. Note that you CANNOT just say how many array elements you want; it works off the indexCount field in the aspect.

== ubrowscv.pas
Browser component for s curve. Displays little graph of curve, xy coordinates of two points that define curve, units. Curve is calculated by giving parameters to s curve function (ueutils) to generate smooth function. User can drag each of the two points that define the curve or click on any of the four numbers to change it by itself. User can click on bound to change for X direction only -- y axis is always from zero to one. Because curve is being drawn during paint method and therefore s curve function is being calculated during paint method, uses special s curve function that returns whether or not an exception occurred during the function. If so, the paint method stops without finishing the curve.

== ubrowser.pas, dfm
The browser is one of the few non-modal windows. It does a gazillion things. The browser is divided into the left side (numbers side in the help system), which shows the browser components, and the right side (pictures side) which shows any one of several displays for weather, soil or plants. The browser file is a little messy and too large. You should look at the help system on the browser thoroughly before reading this file.

== ubrowtdo.pas
Browser component for 3D object (tdo). Displays name of tdo and drawing of it. Under drawing are text characters user can click to turn left, right, enlarge and reduce. User can drag tdo inside box to move around. Clicking on name opens tdo chooser window. Clicking on picture of tdo does NOT open tdo chooser because clicking is used (with drag) to move the tdo around in the drawing.

== ubrowtri.pas
Browser component for soil texture triangle. This used to be used on the left side of the browser (numbers side), but now it is used on the right side. Because it is not a "normal" browser component (BC), it has to have several weird things to make sure it acts differently for being on the right side. There are a few other right-side BCs like this. To be clean, there really should have been a right-side BC class instead and they could have been subclassed from it (but they weren't planned, they just grew). The system for tabbing is the same as for the left-side BCs, but this has a pointer to a soil patch and NOT an aspect or groupItem. Because the aspects for the soil texture triangle (sand, silt, clay) don't change, they are hard-coded here (note this means you can't change them in the file without changing this file). The values for divisions between soil-texture classes are hard-coded and taken from Figure 3.1 on p. 39 in Troeh & Thompson, "Soils and Soil Fertility" (5th ed.) which is based on USDA guidelines. User can click on layer number to change the layer shown, or move the point around to change the percentages, or change each percentage separately by clicking on it. The method for making sure the percentages add up to 100 is not very good, and we had always wanted to have time to make all the layers show at once somehow.

== ucommand.pas
Base class for all undoable commands, and command list that manages the commands to create and maintain undoable/redoable commands in the menu. See ugscom for all the undoable command subclasses.

== udate.pas
Functions for manipulating dates. Note that our date system starts counting at zero, and the Delphi date system starts counting at one. (ours is left over from C++.) The conversion functions take this into account, but watch out for it.

== udebug.pas, dfm
The numerical exceptions window. All calls to the global procedure debugPrint cause this window to add a text line to its list box. If the "appear" check box is checked, the window comes to the front. If the "log to file" check box is checked, the line is added to a text file. The "break" check box only appears if the GS_DEBUG conditional define is set (see ueutils). If the "stop simulation" check box is checked, the simulation stops running at the end of the day. The messages that appear are not that complex; they are mostly in calls to the errorMessage function (ueutils) which just calls debugPrint. All the EQ and EP level functions in the EPIC part of the code have error messages in their exception code, and they usually pass on the primary error string as well.

== udefault.pas
This file contains functions that set defaults for weather, soil and plant parameters and variables based on 1) the EPIC code, 2) the UTIL code, and 3) the EPIC help files (.fmt) for all the parameters. It is called only by uhardcd, which initializes some default templates (but only if the ALLOW_HARDCODING conditional define is set), and ugetepic, which imports data from EPIC files. The defaulting here as taken from the EPIC code may not be all correct, especially some of the more involved soil calculations. This code was used when the current list of templates was generated. See the help file explanation of differences between EPIC and GWI for more information on our changes.

== uderopt.pas, dfm
Derivation options form. Aspects can be derived from simulation variables in a few ways.
* kDeriveTypeUndefined is no derivation (just uses the simulation variable);
* kDeriveTypeDepth divides the liquid depth (mm) by the soil layer depth to get the relative depth fraction of the soil layer (m/m);
* kDeriveTypeConcentration divides an amount in the soil (t/ha or kg/ha) by the weight of the soil layer to get an amount per unit soil weight (g/t);
* kDeriveTypeArea divides an amount in the soil (t/ha or kg/ha) by the soil area to get an absolute amount (t or kg);
* kDeriveTypeConcentrationFromPercent is just for the bag, and turns a percentage concentration by weight into a concentration by weight (g/t) by simple conversion.
This dialog allows the user to choose between whatever derivation options are available for any aspect. It is accessed from the group editor, browser or graph window. (In the browser and graph window you ctrl- click on the unit.) The dialog is pretty stupid and lets the caller fill it and get the results.

== udisplay.pas, dfm
Display options form. Allows user to change various options related to drawing in garden window and browser. Simple dialog, no interactions, just filling at start (from domain) and setting when OK is clicked.

== udomain.pas
Important file. The domain works somewhat like a document, keeping track of everything in the garden file. At this point there can only be one domain at a time (therefore the global var "domain"). Several menu options and other options set in dialogs (such as the display dialog) are kept here as well as a pointer to the garden. The domain handles saving and loading of the garden file, and the loading of all ancillary files (palette, hints, aspect hints, templates, groups) at startup. It also does aspect creation. The domain is used all over the program to access things in the garden (e.g.,

== udpfruit.pas
Flower/fruit object. Connected to inflorescence. Stages are bud, open flower, unripe fruit, ripe fruit, fallen flower (if flower drops), fallen fruit (if fruit drops). Flower grows linearly, fruit grows by s curve.

== udpinflo.pas
Inflorescence object. Connected to phytomer at base, one or more flower/fruit objects at end. Handles creation of flowers (according to timetable), draws itself and places flowers (they draw themselves). Can be harvested whole with all flowers/fruits. Uses recursion to draw either as tiny little plant (with or w/o branches) or as head. The "head" shape doesn't have ray flowers and center flowers but draws flowers in a circle, each having one long petal, so it looks like ray flowers. Grows in size linearly with some influence from water stress only on the day it is created.

== udpinter.pas
Internode object. Skeleton of plant. Plant starts with one internode with an apical meristem and one (monocot) or two (dicot) axillary meristems. Meristems produce new internodes. Each internode points forward to up to three forward plant parts (meristems, internodes, or inflorescences) and backward to one plant part (usually an internode). Leaves are separate pointers. Internodes grow in size both by biomass accumulation and water uptake. The bottom internode draws the root top. A "phytomer" is an internode and its associated leaves. At the correct time internodes can also expand by bolting (defined by parameters). The internode used to be combined with the leaves into a phytomer and it was recently separated, so some things in this file refer to the phytomer instead of internode.

== udplant.pas
Drawing plant. Draws plant at any time, contains information on how to draw plant, models partitioning of plant biomass into individual plant parts (meristems, internodes, leaves, inflorescences, flowers, fruits). Drawing plant model has NO feedback to rest of plant model and is for display only. This is because it is not very accurate in terms of partitioning and size. The main idea here is give users an idea of how the plant is doing visually so they can see how well it is growing and what they need to do to keep it healthy. Also in this file is the traverser object, which moves through the drawing plant structure calling specific functions of all the drawing plant parts with several activities such as demanding photosynthate, growing, drawing, etc. The traverser was created to get around stack size limits in Delphi 1.0; otherwise it would not have been needed and these functions could have been recursive. The access-> comments are for the tab2asp program to read when it checks for correspondence between these variables and aspects.

== udpleaf.pas
Leaf object. Created by a meristem (when its internode is created). Has no pointers to any plant parts (pointed to by internode). Fairly simple. Grows by s curve. Draws using 3d object with scale based on biomass over optimal biomass. If is first leaf on plant (cotyledon), draws using seedling leaf 3d object. Can draw compound leaves (pinnate or palmate) using recursive method. Wilts based on plant water stress for day.

== udpmeris.pas
Meristem (bud) object. Creates new internodes (with leaves) if in vegetative mode or inflorescences (with flower/fruits) if in reproductive mode. Switches to repro mode at start of flowering if random number is below repro. Probability. Can be apical (at end of stem) or axillary (in leaf axil). If axillary, decides whether to branch every day based on branching index of plant (branchiness) and branching distance (distance from stem apex when axillary buds can branch).

== udppart.pas
Drawing plant part. Subclasses are: internode, leaf (including seedling leaf), meristem (apical or axillary), inflorescence, and flower/fruit. A phytomer is one unit of an internode and one or two leaves (whorled leaves are not simulated). The superclass just has a few drawing and stream methods the other classes have in common. Possibly some of the demand and growth methods could have been placed here.

== udsoil.pas
Browser pictures side component for displaying soil color, texture, materials, temperature, pH, N and P. Uses bitmap to double-buffer picture drawn. Descended from browser component superclass (ubrowcom) but overrides many functions to change behaviors. Has no aspect or groupItem, but has a soil patch. See ubrowtri for more information on right-side browser components.

== uduplic.pas, dfm
Duplicate object form. Used when importing templates from a tab-delimited file. Since objects in the file are identified only by their names, the user must resolve problems with duplicate names. In the templates tab-delimited file are: 3d objects (tdos), icons, harvest items, cultivars, climates, soil types, and bags. Any of these things can duplicate an existing object of that type. The dialog asks the user whether to overwrite the existing object, stop importing the new object, or rename the new object. The form is absolutely stupid; it must be filled and checked by the caller. It is called only by a method in the text filer (ufilertx) which is used by the templates manager (utempl).

== udweath.pas
Browser pictures side component for displaying weather values for the past month. The weather object holds on to an array of 30 structures that hold daily weather for this display. See ubrowtri for more information on right-side browser components.

== uebag.pas
Bag model object. Not very complicated; just holds materials. Functions in soil patch operations file (uesoilop) handle using the bag. This file mainly just has methods for data transfer and streaming.

== ueg.pas
Our additions to the EPIC model. The division makes little sense at this point since we have made major changes all over the model code. These are mainly functions that we made entirely from scratch. These functions deal mainly with plant biomass allocation and plant reproduction.

== uegarden.pas
Garden object. The garden object has very little to do as most of the parameters have been moved into the soil patch. In EPIC, the garden and soil patch are the same thing since the simulation models only one field. In GWI, the garden is a container for any number of soil patches. At this point, the garden is just a container. With improvement the garden could manage communication between soil patches and model the surrounding areas to more completely simulate water flow between areas. Simulation options are stored here -- both whether each option is to be overridden from individual choices, and what the overridden option is set to. The garden also handles a few garden-wide tasks such as drawing and reseeding all plants.

== ueorgmat.pas
Organic matter blob object. Holding place for dead plant biomass before it decays into soil patch. Whole reason for this object's existence is so user can drag organic matter around and see it as a useful and important resource. Each soil patch keeps a list of OM blobs and clears the list out on each day of simulation. Important to understand that the OM blob biomass is added to the soil patch as well as the OM blob when the OM blob is created, so nothing has to be added when the OM blob "decays". This double-accounting is done so that the user can see the amount of OM on the patch increase as they drag OM blobs to it and harvest plants (otherwise it looks like OM is missing).

== uep.pas
Second-level EPIC functions (EP = EPIC Procedures). These are most of the functions called by the next day functions in the soil, plants and weather. These functions in turn call the EQ (EPIC equations) functions (ueq, and ueqh for hydrology functions). Some of this code is directly as translated from EPIC; some has been modified by us. The most major modification in this file is the change of N and P and water allocation to model competing plants in a soil patch. Otherwise there are many small changes, some of which are marked. Some of the pesticide transport code remains (commented out) from when we had it working. We also made some changes in the methods used for splitting soil layers. And we changed porosity so it maintains a closer relationship to bulk density instead of following along with field capacity and wilting point.

== ueq.pas
Bottom-level EPIC functions (EQ = EPIC equations). Hydrology-related bottom-level EPIC functions are found in ueqh. Into this code we have typed the entire text of a document by JR Williams which he gave us in 1994. We call this document "the chapter" here. The equation numbers here correspond to that chapter and are referred to in the text. Some low-level functions that were not mentioned in the chapter are included without equation numbers. Under the text preceding each function is a comparison of the function as denoted in the chapter and the function as we found it in the EPIC FORTRAN code. Just before each function is a short list of important variables in each function. We have not tried especially hard to keep these lists of variables up to date, so some might be wrong. Some extremely complex functions we split into two. Please note that we started translating with EPIC3090, which was put out in 1993, so there may be significant differences between our translation and the current EPIC code. There may also be significant errors in translation we have not yet found. Many of our changes to the EPIC code are noted here, but some are not. The asterisks everywhere make it slightly easier to find specific topics in this large file (for example, searching for "*CROP" will find the crop growth section). Note: we have left a lot of pesticide-related code here (commented out) for review. We chose not to use EPIC's pesticide-movement code because we did not want to present such a simplistic pesticide model in a teaching simulation. An effective pesticide movement model would include the effect of pesticides on soil fauna, organic matter and nutrients and would model the breakdown of pesticides into secondary compounds, which might themselves have significant impacts on the soil and groundwater.

== ueqh.pas
Bottom-level EPIC functions (EQ = EPIC equations) having to do with hydrology. Actually this file was only removed from the ueq file because Delphi 1.0 choked on the large file. See the comment at the start of the ueq file for more information on the bottom-level EPIC functions.

== uesoil.pas
Soil patch object. Information in the soil patch is in several record structures as specified in uestruct. Most of the soil patch information is in the layers structure which has all of the information that is by layer. Most functions are called in the next day function (a few in the end year function). Actions by tools on the soil patch were moved to uesoilop, and the soil patch is passed in (because this file was too long). The soil patch has a TListCollection of plants and a pointer back to the garden. Read uestruct to understand the structures here before reading this code.

== uesoilop.pas
Tool actions on the soil patch object. These were moved out of uesoil (because the file was too big for Delphi 1.0), and the soil patch is now passed in. "mixSoil" is the only function here that is largely unchanged from the EPIC. The liming function is pretty shaky because it was derived from autoliming. (But then the entire pH model is extremely simple and should not be relied upon.) The sulfur application function is ridiculously shaky. The bag function is theoretically okay but could use more work. The simpler functions (add/remove soil, add/remove mulch, aerate) are probably fine since they don't do that much. Read uestruct to understand the structures used here before reading this code.

== uestruct.pas
Many structures used by model objects. Structures are in this file instead of each separate file so uep and ueq can just include this file and not the object files (avoids circularity). Important: to add a variable to an object, add it to the end of any structure that has a buffer at the end (usually called reservedArray), and reduce the size of the buffer by the proper amount (single=4 bytes,smallint=2 bytes, etc, see the Delphi documentation to be sure). After a new var is added here you must initialize it on reading from files in two ways.
1) For binary files, increment the version number of the object (in its classAndVersionInformation function), then respond when the file is streamed in by setting the value to an initial default. Files streamed out with the new version number will save the information. (See the streamDataWithFiler methods in the model object files for some examples of this versioning technique.) You can also add a var to an object at the top level (not in a structure), but then you have to pass it more explicitly to any functions that need it (not just inside the structure). Adding a new var to a structure works best when you don't need an aspect or to save it in the template (like something you just need when the simulation is running).
2) For tabbed-text importing (from tabbed-text template files or from EPIC files), the problem is harder: you cannot add a new variable to the tabbed-text data files unless you create a new version number in the tabbed-text files and deal with it in your code (see utempman and ufilertx). But if you create a new tabbed-text version number, your files will be unreadable by anyone else unless they have your code. Probably it is best to just default the new value on reading the object from a tabbed-text data file (see udefault), and that info can't be saved in tabbed-text format until there is a new global tabbed-text version.
Note that there are some "unused" vars in some structures that are no longer used but were left in place to keep the binary files intact; these can be used but again cannot be put into the tabbed-text files.
We are using only singles for float vars and only smallints for integer vars.
Comments with -> arrows are for use by the tab2asp program to compare against existing aspects to see if any were left out (an NA on a line means the checking program will ignore the var). See the description of the tab2asp program at the end of the programmer's guide for more information on aspect delineation comments.

== ueplant.pas
Plant object. Information in the plant is in several record structures as specified in uestruct. Always make sure to recalculate biomass relationships when changing any of the biomass components. And tell the drawing plant when doing this by setting a var for the daily change in X, then changing the drawing plant code to look at the change in X when it does its next day routine. Read uestruct to understand the structures here before reading this code.

== ueutils.pas
Assorted math and other functions used by the model objects. The soil layer manipulation functions are here because they didn't fit in the soil file under Delphi 1.0.
NOTE: The words RE-RAISES EXCEPTION mean that any function that calls the function SHOULD have a try/except handler somewhere around the function call, because the function re-throws the exception. This is for reporting, so we know in which function the function was called when it went wrong. This whole exception handling scheme was to deal with a bug in Delphi 1.0 in which floating point exceptions (overflow, underflow, divide by zero, etc) cause the development environment to crash. If you are using the source code under Delphi 1.0 be aware of this bug. If you have the compiler directive "GS_DEBUG" on, the numerical exceptions window (udebug) will show an extra "break on exception" check box. If you check this box, the program will stop execution with a "debugBreak" call. The "debugBreak" call doesn't work very well and Delphi doesn't know where the execution point is, but if you press F7 or F8 at this point the system (usually) comes to the correct line without crashing. Note that we're not sure the "debugBreak" call works under Delphi 2.0.

== uweath.pas
Weather object. Information in the weather is in several record structures as specified in uestruct. Monthly parameters are used to create daily means, and daily values are generated based on the daily means. The weather also keeps 30 days of recent weather vars for displaying in the browser pictures side. Read uestruct to understand the structures here before reading this code.

== uexit.pas, dfm
Exit form. Appears when user leaves the program. Suggests files the user might want to save (from garden, groups, templates, tools files). User can check boxes for which files to save. Choices are to save checked files and exit, don't save any files and exit, or go back to the program. No code here; initialized and run by the garden window (ugsim). Notice this is not created when needed, in case of a memory problem.

== uexcept.pas
Exception-handling code for pointers, wrapping around Delphi exception-handling system.

== ufiler.pas
Filer object for document streaming system (binary). Also defined here is gsStreamableObject, which is the base class for all objects which can be streamed with this filer. Filer has methods to stream all major types of data. Records (such as those used in uestruct) are streamed simply using streamBytes. All classes to be streamed must be registered in uclasses. On streaming out, the filer writes out each object's class ID, version number and size. On streaming in, the filer checks each object's class ID, version number and size against the current ones. If there is a discrepancy it raises an exception and aborts the streaming in.

== ufilertx.pas
A filer for tab-delimited text files. Used only for text versions of templates. Some assumptions about tab- delimited text files:
1) each object takes up one line;
2) each object has a version number and type;
3) the number of columns is constant as is the order (if the number of columns is wrong it will choke);
4) objects are identified by their names and therefore cannot have duplicate names (if they do, the duplicate options dialog appears - uduplic).
Another complication is that Excel (and possibly other spreadsheets) puts double quotes around any cell in a tab-delimited file that contains a comma (,) to make sure the comma isn't misunderstood as a secondary delimiter. This means if we write out a file with some cells containing commas, edit the file in Excel, save it from Excel as a tab-delimited file, then read the file again, the cells containing commas will "magically" have double quotes as their first and last characters. To get around this problem, for text data stored in Delphi as a string variable, the text filer strips off double quotes in the first and last positions (only) when they occur. For text data stored in Delphi as a PChar (notes) the text filer strips out ANY double quotes that are not preceded by a slash.

== ugetepic.pas, dfm
Epic import form. This form is kind of secret, because you can only access it by opening the templates window then pressing Ctrl-Shift-E, at which point a button appears. This is so the general user doesn't mess with it as it is not clean. It was created mainly to aid us in using the EPIC weather and soil files and is not as user-friendly as the rest of the program. For example, it does not recover well when there is anything (at all) wrong during file input. The help system has a description of the window in the EPIC section, under Auto Operations. We have left the form around in the program for any soil scientists who have special EPIC files they want to import. It does import plant data, but we have added so many parameters to the plants that it's not advisable. It does not know how to read the soils5 data files at this point. We have tried to put in defaults for all non-EPIC parameters, but some may have slipped by as it was not a priority.

== ugrafcom.pas
Graphing component, a subclass of TImage. Handles graphing with data from logged vars (ulogvar) in graph window (ugraph). Also a graph scale object which keeps data on graph scales and recalculates scales as needed. The graph has two scale objects, left and right; vars are graphed on one of the scales. Graph can draw in either normal time-series mode (where each Y point is graphed against X of the simulation date) or xy mode (where each Y point is from one var and each X point is from another var). Graph uses a TBitmap to double-buffer itself. Whole system works with data points for each var associated with simulation dates.

== ugraph.pas, dfm
Graph form. Simulation aspects are graphed using the browser, placed under the graph in a legend, drawn on the graph. The list box below the graph has logged var objects (ulogvar) that contain the information for each graphed aspect. The graph is drawing using a special TImage descendant (ugrafcom) that deals with the graphing and the special date-related data. User can click on different columns of the list box (owner-draw) to change different things about the graphed aspects. Each data point has a date, and the user can select what dates to look at.

== ugroups.pas
The group manager manages groups. Each group has some number of group items. A group item has the text ID of an aspect and some display information for it (unit, bounds, derivation, layer options). There are several class functions at the end of the file that are used for accessing and displaying information in common to all group items. Since the groups can be input and output in tab-delimited form, the options stored here can be changed by the user (as opposed to the aspects, which can only be changed in the source code).

== ugrped.pas, dfm
Group editor form. Used to edit groups in the groups file and to change some characteristics of each group item. Groups are defined in ugroups and controlled by the group manager (which the domain has). List boxes of group items ("choices") and aspects ("variables") have pointers to the correct group items or aspects. A NEW group manager is made inside the form, and if the user clicks OK the new group manager is made current and the old one is freed. If the user clicks Cancel the new group manager is freed and nothing is done to the current group manager. The user can also save or load a group file from here, or import/export a tabbed text groups file. Note that the tab import/export here works differently than in the templates window. In fact, this way of doing tabbed text i/o is the norm, and the templates way (with ufilertx) is the exception.

== ugscom.pas
All the commands that can be undone. See ucommand for the base class of undoable commands and the command list manager. Each mouse down/move/up in the garden window can potentially create a command. Depending on the tool action (as defined in utools), a command is created and put into the command list, where it can be done, undone, and redone. In some of these subclasses redo is the same as do; if so, redoCommand is not overridden and it calls doCommand. Each command must override at least trackMouse, doCommand, undoCommand, and description. There are two subclasses that have several related subclasses hanging off them: GsSoilOperationCommand (in which one soil patch is modified, and a copy is kept of the original), and GsTwoSoilPatchOperationCommand (in which two soil patches are modified at once, and copies are kept of both originals). For many soil operations it is not really necessary to copy the whole soil patch, but that is the simplest and safest way though it might be slower and more expensive in memory terms. Several of the plant changing methods also keep a copy of a plant. A few of these commands are not created from the garden window but from other windows (such as ResetHarvestListCommand), and some can be done both from the garden window and from the other windows (ReseedPlantCommand can be done from the browser). They act in the same way as the mouse- created commands in the command list.

== ugsform.pas
GWI form superclass. This class exists solely to allow extra hint handling in uhints and ugsim for the long and aspect hints, which are read in from tab-delimited files at the start of program operation. Most of the forms in the project are descended from this class (only a few small forms aren't). See uhints for a list of what types of interface elements have hints in our long hint system.

== ugsim.pas, dfm
The main form for the application. It is called ugsim because the old name was "Garden Simulator". This form file is long and does MANY things. Handles tool actions (with mouse down, move, up); opens and saves files; opens other windows from menu; changes menu options; manages transfer of model data; draws garden and manages bitmaps to layer picture (bitmaps are in domain). You should look over the domain file (udomain) before reading this as you need to understand some of the things in the domain.

== uhardcd.pas
Sets up some default templates. Only called if the program is started up with no templates file AND the ALLOW_HARDCODING conditional define is set during compiling.

== uharved.pas, dfm
Harvest item template (HIT) editor. There is a naming discrepancy here; in the help system, HITs are called simply "harvest items" because it is shorter. But in the code harvest items are not HITs, they are objects that represent real fruits or leaves or plants that were harvested. The HITs just contain information about what is in a "typical" harvested item for a cultivar. For example, there might be a HIT called "Tomato fruit", and a particular harvested item might be of the TYPE "Tomato fruit", but it was harvested from a particular tomato on a particular date. The HIT editor presents a list box of HITs and allows the user to change the nutritional information in a columned list box, the icon by clicking on the icon (or on "Set icon"), and the note by typing in a memo. The group editor supports canceling the edit by making a copy of the whole group manager and replacing it when the user clicks OK, but here there is no HIT manager; the HIT list is in the template manager along with a lot of other things. So the HIT editor makes a copy of the list of HITs, then compares the two lists after the OK button is pressed. The HIT editor can be called from the browser (from a HIT browser component - ubrowhar) or from the main menu.

== uharvest.pas, dfm
Harvest form. This form is fairly simple. All it has to do is draw the list of harvested items, with or without pictures. It uses a TImage to draw the report instead of a list box, because we wanted to handle wrapping the icons around ourselves and we don't know the height of each line until it is drawn. An owner-draw variable-height list box would also allow this, but we tried it and it was flickery and had size/resource limits.

== uharvpnl.pas
Harvest item panel. Used both in the garden window (at the bottom) and in the browser right side (under the plant drawing). Note that items harvested from one plant show up in both the browser and the garden window. This is a fairly simple panel descendant that draws a quantity of icons in one row with up and down buttons to show the other rows. The blue bar on the right side of the panel shows how many rows of icons there are and acts like a little "progress bar". The two buttons are created at run-time as this component is not available at design time. The panel can have its own harvest list; at this point the garden window lets its harvest panel use the domain harvest list (since it needs the whole thing), and the browser fills a harvest list in the harvest panel with only the items for the plant in question. When another plant is selected the harvest list is cleared and a new one is made.

== uharvprt.pas
Defines several objects.
* The harvest item template (HIT) contains information about types of things that can be harvested, including nutritional information about a typical item of that type (calories, energy, vitamins, minerals), and which icon is used to show the item in the garden window and harvest panels.
* The harvest item models a specific fruit, leaf or other object that was harvested from a particular plant. It keeps track of which plant it was harvested from, which cultivar the plant belonged to, which soil patch it was in, what date it was harvested, and what kind of item it is (which leads to a HIT).
* The harvest report specifies what information to show about harvested items in the harvest window, and how to sort that information. See the constant lists below for what the "show" and "sort by" possibilities are.
* The harvest item sorting group is an object used when sorting and totaling the harvest item nutritional information. For example, if the harvest report says (in effect) "show calories per week", the harvest manager sorts the harvested items by week, and the harvest item sorting group keeps the total amount of calories in each week so it can display that total in the harvest window.
* The harvest manager handles all the harvest information. It resides in the domain, and the harvest window (uharvest), HIT editor (uharved), and harvest report editor (uhvrpted) access and change it.

== uhints.pas
The hint manager. Makes the long hints and aspect hints show instead of normal short hints. Hints come from two files that are read in at startup, usually and (though the names can be changed in the ini file). Almost all of the forms in the project descend from gsform (in ugsform) which has a constructor that sets all the showHint properties of its objects to true. This is done by subclassing instead of setting all the showHint properties by hand because a) it was quicker, and b) it can be changed back easily simply by commenting out the line that sets all the showHints to true. In the main form file (ugsim) the hint catching function calls the functions here to display the proper hint for the focused control or aspect. The hint manager also reads the button hints from the file and sets them up into a list of gshint objects. Identification of components is by form name and component name so two forms can have buttons with identical names (like helpButton). Aspect hints are loaded by the aspect manager (uaspects) called by the domain at startup.

== uhvrpted.pas, dfm
Harvest report editor form. Edits harvest reports (read uharvprt first before reading this). Fairly simple; two arrays ("show" and "sort by") are edited by moving items into and out of them from the list of available options. User can also make new reports, copy, delete, export, import, etc. Because there is no discrete harvest report manager to make a copy of for canceling, the form copies to a list of harvest reports (in the list box) and checks the list against the original list (in the harvest manager) when OK is clicked. This is the same scheme as in the harvest item template editor. There are some fancy things here to deal with the fact that the information is kept in arrays (show and sort by) and not in objects.

== uicon.pas
Just an icon that is subclassed to be streamable with our system (see ufiler). It also knows its name. Not very complicated.

== uiconch.pas, dfm
Icon chooser form. Used to set the icon for a harvest item template (HIT). Called only from the HIT editor. Like the HIT editor and the harvest report editor, makes a copy of the list of icons (in the template manager) at startup and checks the copy against the original list when OK is pressed. This allows the user to cancel all changes in the form. Otherwise fairly simple; user can pick a different icon, or import or export to an icon file (.ico). There is no icon editor.

== ulayers.pas, dfm
Layer options form. Lets user choose options for displaying an aspect having to do with soil layers. Note this is for soil layer aspects only, not for aspects having to do with other arrays such as weather months. This is called by the group editor and by the graph editor. Choices are to show data from only one layer, to select data from any number of layers, or to show summary information for all or some layers (min, max, mean, sum). This form is mainly stupid, but has a few checks.

== ulogvar.pas
A logged variable, or an object to hold information about a simulation aspect for graphing. The "loggedVar" as we call it has its data in a long array of singles in memory, which is expanded and contracted as needed. A loggedVar can only hold singles (not integers). The loggedVar keeps track of many things about how to display itself, including which axis it is on (left or right - see ugrafcom), if it is an array and if so how to display it, its model in the domain (to get the data), its aspect (to get the name, hint, etc), information taken from a group item for it (doesn't have a group item pointer because of possible changes by the group editor), information on how to draw the line on the graph (which is edited in the graph window), and the start and end dates of its data. Since data is linked to simulation dates, the data is looked up that way.

== umconsts.pas
Aspect creation constants and transferField functions. Created by tab2asp program.

== umodel.pas
GsModel is the base class for model objects. Based on streamable object (in ufiler). Encapsulates some transfer functions for browser/grapher access to models and for streaming and creating. The graphical model subclass adds some basic drawing code (keeping a bounds rectangle, checking if a point is in it), a name, and a note. All the model objects (garden, weather, plant, soil, amendment, OM blob) are descended from the graphical model.

== umovtemp.pas, dfm
Template mover form. Used to copy templates from one template file to another. Called from the templates window (utempl). Standard mover-type dialog. Current templates library opens by default on left side; on right side user opens another template file. But user can open another file on the left side also. Also here you can import tab-delimited templates singly from a template file by opening the file on the right using Import and choosing templates to copy over. (much easier than using the whole-file import in the templates window.) A little messiness with keeping track of the two list boxes with accompanying objects (templates) and the file names. Some redundancy between the two sides. Had meant to make group, tool, etc movers like this one but never got around to it.

== umusic.pas, dfm
This form does nothing but play the startup music. Don't even remember why we thought it was necessary to have a separate form. Something to do with starting the music right away, or making the music play better during startup...

== unotes.pas, dfm
Notes editor. Each graphical model (see umodel) descendant has a note which is a PChar. This includes garden, weather, soil, plant, amendment, and OM blob objects. Also tools have notes (same type). The notes editor can be opened from the browser or from the tool editor. If opened from the browser, it shows the notes for all objects in the garden and templates in the current templates file. If opened from the tool editor, it shows the notes for all tools in the current tools file. The form has no cancel ability mainly because we just didn't have time and the notes aren't especially important. If tool notes are being edited, the Rename button is hidden because there is already a rename button in the tool editor. Either set of notes can be exported to a tab-delimited file for use in other programs, but they cannot be imported (again for lack of time and importance).

== upatarea.pas, dfm
Soil patch area form. Also contains some other stuff about the soil patch. We need this information right away when the soil patch is created, so it pops up right when the user is done sizing the soil patch after creation. The form can also appear if the user selects the tool action "change soil patch" (usually in the shovel). If the soil patch has just been created, the area and soil type are editable; if the soil patch was created previously (and "change soil patch" is being done) the area and soil type are not editable. Actually it would not be that big a deal to change the soil patch area now, because we divorced it from the watershed area (it used to be the same thing). But we have not looked into changing it. Because this form is needed often and we don't want it to fail, it is created automatically at startup like the non-modal windows (garden, browser, graph, harvest). The other modal windows that have this distinction are the wait form (for progress messages), the about box form, the numerical exceptions form (udebug), and the exit form.

== uplotopt.pas, dfm
Plot options form. This form appears in two circumstances: 1) the user graphed an aspect from the browser and the domain option to show the options window at the time of graphing was turned on; and 2) the user clicked on one of several columns in the graph list box on the graph window. The window shows several options that can be changed for a loggedVar (see ulogvar for details). The window works by making a copy of the loggedVar and updating the original if OK is pressed. The aspect pointer is used only for reference and nothing there is changed.

== uprofile.pas
Code for reading an ini file. Used only by domain. We used to use this for more complex things at a time when we had data files stored in profile format, but now most of this code is unused.

== urandom.pas
An object that generates random numbers. All the model objects have one (weather, soil, plant, drawing plant), but only the drawing plant uses the one it has (actually it has two). Meant to use these in calculations but did not get around to it. Most of the model code instead uses the random functions in ueutils (mainly Utils_RandomZeroToOne). So this code is used right now only by the drawing plant, though the objects are created and maintained by several classes. The idea is to move into a situation where each model object has its own generator that operates independently of others, which is more reliable. The generation algorithm for zeroToOne is almost identical to the function in ueutils.

== ureseed.pas, dfm
Reseeding options form. User can choose when to reseed all the plants in the garden (choose from radio buttons), or reseed now (click check box). Sets things directly in domain if OK pressed, but the calling form (ugsim) does updating and immediate reseeding based on the result of the form.

== usimop.pas, dfm
Simulation options form. Many options, but most are fairly simple 3-state check boxes. Loading and saving are directly from garden ( using simple transfer functions for all elements. There are some interactions between some options; for example, if runoff is turned off, water erosion from runoff is automatically disabled. And the user can get to the templates window from here to add another climate or soil type from another template file, and this form must update its list correctly. Otherwise the window is straightforward though large.

== usliders.pas
Slider component for displaying/editing numerical info in the numbers side of the browser. Fairly simple drawing. Has no windows handle, but keeps track of an unofficial focus for keyboard control. Used in some browser components (ubrowint, ubrowrl, ubrowrla, ubrowcol) and also in the soil patch area window (upatarea).

== usound.pas
Sound object for tool sounds. Uses Delphi function sndPlaySound (in the MMSYSTEM system included in WinTypes). Sounds are played when tool actions are done in garden window (and "play tool sounds" option is on), and sounds are played, imported and exported in the tool editor. Because the sounds are streamed with the tools, this is a streamable object.

== usplant.pas
Plant statistics drawing component. Used on browser right (pictures) side. This is used to draw the plant biomasses (called "statistics" here) and the plant growth stresses. Uses a bitmap to double-buffer. Keeps pointer to plant; otherwise is like other right-side descendants of browser components (see ubrowtri for explanation of these descendants). Plant statistics are gathered by the drawing plant using the function getDrawingPlantStatistics which fills the statistics record with information by traversing the drawing plant (in a statistics-gathering traversal mode). Plant stress information is gotten directly from the model plant. Note that in the browser the plant display options are "drawing", "biomass" or "stresses". This panel is visible when either "biomass" or "stresses" is selected, and hidden when "drawing" is selected.

== usplash.pas, dfm
Splash screen form. Does nothing but appear. While domain is loading, it calls loadNextAnimationPicture as each stage in loading files is completed, and the splash screen changes the animation picture. The pictures come from nine TImages that are hidden from view.

== usstream.pas
String stream. Used by text filer (ufilertx) to parse strings, usually those associated with points or arrays (because there are delimiters inside the string in these cases). Also used by 3d object (in uturt3d) to read strings from tdo file.

== usupport.pas
Many commonly used functions, mostly dealing with text manipulation. Functions for opening and saving any kinds of files are also here. The file save function makes a temporary file and a backup file and tries to handle problems. Also this is where global vars are for whether ancillary files opened by the program might have been changed during a session (templates, tools, groups, ini file).

== utdoch.pas, dfm
3D object (tdo) chooser form. Opened from browser component for 3D object (ubrowtdo). Fairly simple, just has owner-draw list box with drawings of tdos, and set of buttons for import/export, edit, etc. User can choose a tdo from the list for the model aspect (a drawing plant part tdo). Like harvest item template editor and harvest report editor, makes copy of list of tdos (from template manager), then when user clicks OK compares the copy to the original.

== utdoed.pas, dfm
3D object (tdo) editor. This window was made at the last minute and is not very easy to use. It just acts as an interpreter for the tdo specification. Probably making a new tdo would be very difficult in this window (the original tdos were made in a separate tdo editor written in Visual Basic some time ago). Eventually one would want to add the ability to move the points in the tdo by clicking on them and dragging them, and to make new points graphically. The way it is now, it is no different from exporting a tdo to a file, editing the file in a text editor, then importing the file again.

== utempl.pas, dfm
Templates form. See template manager (utempman) for description of templates. When any garden file is open, the program needs an open templates file to use to make new garden objects. This window shows the templates in the open templates file (in a list box) and allows the user to change the templates file, import templates into it from another file, import/export tab-delimited templates files, save changes to the current templates file, and do various things with individual templates in the list. The form makes a copy of the current template manager (in the domain) at creation and replaces the original with the copy if the user clicks OK. If the user clicks Cancel, the copy is removed. Sometimes under the 16-bit app, making a copy of the whole template manager makes the program run out of resources; if this happens the window shows with no templates and the user has to go out and close something and try again (but this doesn't happen often and possibly not at all under 32-bit). It would be better if the templates window didn't make a copy of the whole template manager because if you have a large templates file it could be too memory- consuming (never mind resources). This is the same problem as with the tools editor.

== utempman.pas
Template manager. Templates are objects used to create garden objects by making copies of them. Climate templates are used to make weather objects; soil type templates are used to make soil patches; cultivar templates are used to make plants. Soil amendment templates are used differently - they are used when applying fertilizers with the bag tool (the "apply" tool action) and have no corresponding garden objects. Note that the template manager has a pesticide list; this is left over from when we had implemented pesticides and taking it out would make the garden files unreadable. The icons and harvest item templates (hits) are a little complicated: plants just have pointers (references) to them so that memory is not used redundantly. This means the methods for assigning and streaming them are a little complicated.

== utimelin.pas, dfm
Time line form. Displays (read-only) time line of year with frost dates and "normal" planting/harvest dates for cultivar selected in list box. "Normal" dates are based on parameters for the plant and the frost dates for the current climate. User can use this window to decide when to plant various plants. Reaches right into to use weather info; reaches into domain.templateManager to get information on list of cultivars. This is OK because nothing is changed here. No interactions between this window and anything else. Was thrown together quickly.

== utitlech.pas, dfm
Graph title form. User can change graph title, axis titles, and choose whether to auto-title axes (from aspects graphed) and whether to autoscale or input scale for each axis. Called only from graph window. Graph window calls initializeForAxis for each axis, then gets the data back after OK is clicked. Nothing has to be copied as the graph window directly inspects the values of the interface elements. Some complications arise from interdependence of axis title edit boxes and "auto-title" check boxes. If "auto- title" is checked, the appropriate edit box becomes read-only.

== utlpmed.pas, dfm
Tool parameter list editor. Allows user to change lists of choices available when doing a tool action. These are the lists that show up in the combo boxes in the garden window toolbar when the user picks up a tool. What we are editing here is GsToolRateOrAmountParam objects (utools), which know their type, units, and bounds. Bounds are hard-coded with hardCodeBoundsForModelUnit (in utools). The user can also export/import the information for use in other gardens. The list of GsToolRateOrAmountParams is in the toolParamListManager (in the domain), and the dialog makes a copy of that manager when it starts up and overwrites the original if OK is pressed. The lists themselves cannot be created or deleted or renamed. The five lists are:
* carrying amount (for carrying soil or mulch - t/ha or t),
* adding amount for solids (for applying amendments - t/ha or t),
* adding amount for liquids (not used),
* planting depth (not used),
* mixing depth (for mixing soil - meters), and
* tool area (size of tool - m2).
The "amount per second" option is invisible and code that deals with it commented out, because we have not implemented the code the implements that type of tool action (it would be in ugscom).

== utools.pas
Several classes for tool use.
* GsToolRateOrAmountParam: Holds information on one parameter for a tool action, such as how deep to dig or how much material to apply. When the user picks up a tool and choices appear in the one or two combo boxes after the tool list in the garden window toolbar, each one of the choices is one of these objects. Bounds are hard-coded in this file.
* GsToolParamListManager: In the domain; keeps several lists of GsToolRateOrAmountParams for use when displaying tool action options and carrying out tool actions. The only lists that are used at this point are adding amount for solids (for applying an amendment), carrying amount (for carrying soil or mulch), mixing depth, and tool area. Tool area is used with all the mixing tools to decide how much of the soil patch is affected by the tool action (tool area/soil patch area). The tool params list editor (utlpmed) is used to edit these items. The tool param list manager is saved in the garden file with the domain.
* GsToolAction: The tool action object has the job of creating the command to place in the undo list and actually carry out what should happen after the mouse was clicked. Each tool has a list of tool actions (which can be changed in the tool editor - utooledt). The tool actions use case statements to decide several things about the tool action that are necessary to carry it out - how many parameters it needs, the string to put in the combo box, what command to create, etc. The types of tool actions are a hard-coded list of constants.
* GsToolSettings: This object stores some information about a tool in the garden file separate from the information stored in the tool file. This is so we can save the position of each tool in the garden picture and whether the tool is visible or not. When the garden file is opened this information is written over the information from the tool file in the tool manager. There is actually no list of tool settings saved in the domain, since this information is in the tool manager. On streaming in, the information is copied into the current tool manager; on streaming out, the information in the current tool manager is used to create a temporary tool settings list which is streamed out. Look at the streamDataWithFiler and readDataWithFiler functions in udomain for how this works.
* GsTool: A tool object, which carries out tool actions on soil patches and plants. The tool object has some number of tool actions (a TListCollection), a name, a note (PChar), several bitmaps (up, down, full, and masks for all these), and sounds to play at various stages of mouse use. Tools are read from a tool file and stored in the tool manager in the domain. Tools encapsulate the behavior of transparent bitmaps as well as action handling.
* GsToolManager: Keeps and handles all the tools. Held onto by the domain. Has code for locating tools at a cursor position, streaming tools, etc. Treats glove tool specially, because it is "up" when all the other tools are down.

== utooledt.pas, dfm
Tool editor. Edits tools and their actions, pictures and sounds. Pictures are from bitmaps (separate for down, up, and full states); sounds are from wav files (separate for pick up, holding (loop), put down, starting use, using (loop), finishing use); actions are chosen from a list of hard-coded possibilities. Each tool can have any set of actions (including all of them). See utools for a description of how the tools and tool manager work. The tool editor works by making a copy of the entire tool manager at startup (from the one in the domain), then replacing the domain version when OK is pressed. Note that this uses a lot of memory and resources and could not work correctly if either is stressed.

== utr55.pas
This file contains only a constant array used in the SCS-TR55 method of peak runoff rate from rainfall.

== utstream.pas
Functions to stream model templates to/from a tab-delimited text file. These methods were removed from the object files because they made them too long. For soil patches and plants there are separate streaming functions for version 0.90 and version 1.0. For the weather there were no changes so there is only one function. If there were a version 1.1, each object might need a third function to stream in/out the correct fields. A few other objects have streamUsingTextFiler methods, namely the drawing plant (udplant), 3D objects (uturt3d), icons (uicon), harvest item templates (uharvprt), and soil amendments (uebag). These functions are in their own files.

== uturt3d.pas
Defines several objects important in 3D plant drawing.
* KfMatrix: A matrix used to transform 3D points to produce new 3D points based on current turtle rotations along X, Y, and Z axes.
* KfDrawingSurface: A device-independent representation of a canvas on which to draw lines and triangles.
* KfIndexTriangle: A representation of a triangle as indexes into an array of points.
* KfObject3D: An object to be drawn in 3D - represented as an array of triangles which refer to 3D points.
* KfTurtle: A turtle object that can be moved in 3D space and has an X, Y, and Z rotation for drawing lines.

== uunits.pas
Functions for conversion of units in whole system. There are 32 unit sets, and each unit set contains units that are inter-convertible. For example, the temperature unit set contains degrees C and degrees F. The unit set must be saved and given during any conversion so the function knows which code to use to convert the units. Numbers cannot be converted between unit sets. The file also contains information for displaying the units (the string to show, etc).

== uwait.pas, dfm
A little window that just shows a short message telling the user something is going on and they should wait. Right now this window is only used if files are saved after the user exits the program (if they click "Save and exit"). The form is created at startup to make sure it is available at exit.

== uwindman.pas
Window manager. This class creates the forms that are to be created when the domain is streamed in (if they are not created already, that is, if this is the first garden opened in the session); and it manages the streaming of data about the garden window, browser, graph window, and harvest window during file streaming. Information saved is mainly positional (place on screen, size, position of splitter, etc) and what is selected in the forms (the object in the browser, the current tool, etc). Note that since the forms are not streamable objects, the window manager acts as a proxy to the filer (ufiler) to stream the information for them.

======== Tab2asp program

This separate program (with its own project files) is used primarily to generate several files of code that create the 800 or so aspects when the program starts up. Code generation works from a data file ( with all information for the aspects in tab-delimited format. The tab2asp program also does some other housekeeping and comparison functions for general maintenance of the code. By the buttons on the tab2asp form, these are as follows.

== Generate aspect code
The function discussed above (the program's primary function).

== Generate aspect report
Compares list of existing aspects (as read from with model variables marked in the code files uestruct, udplant and uebag. The report file (asp_rep.txt) tells 1) what variables are in the aspects file but not in the Pascal files; 2) what variables are in the Pascal files but not in the aspects file; and 3) what variables have conflicting data types in the Pascal and aspects files. In uestruct, udplant and uebag, aspect variables are designated by special codes in comments. The special codes are:
* {aspects->start}: Start reading variables here.
* {object->plant}: Start reading variables for the "plant" object here.
* {access->params}: Start reading variables for the "params" data structure here.
* {ENUM}: Consider this variable an enumerated string variable, not just an integer.
* {NA}: Don't look for an aspect for this variable. After each NA variable there is usually an explanation of why there is no aspect for it.
* {aspects->stop}: Stop reading variables here.

== Generate group aspect report
Creates a report file (asp_grp.txt) showing discrepancies between the aspects file ( and a groups tab-delimited file (created in the group editor by exporting the groups). The report shows 1) which aspects are in but not in; 2) which aspects are in but not in; and 3) which aspects are in twice. The report always produces some discrepancies that are not real, mainly for aspects in that have hard-coded array indexes.

== Generate button hints file from code
The long hints used for buttons, list boxes, etc come from a tab-delimited file called If you add new windows or substantially change existing ones, you must update to reflect the changes. This function reads all the Pascal files in the directory you choose, pulls out the names and types of all the "important" items on each form, and writes out a new file. It also asks you to choose an existing file, and writes the hints for any existing items in that file into the new file. If you created a new form, for example, then ran this, you would end up with a new hints file ( with all the old hints plus lines with blank hint cells for the items on your new form. Which items are "important" is hard- coded below with a list of enumerated item types (find the "componentConstants" list below).

== Merge aspects file with existing hints
Hints for each aspect are read when the program starts from a tab-delimited text file, usually If you add new aspects or delete aspects, you can run this function to create a new aspect hints file ( from the aspects file ( and your existing aspect hints file. For example, if you add two new aspects then run this function, you will end up with a with all the existing hints and blank cells on the lines for your two new aspects. Generate aspects help file: Reads an aspects file (, an aspect hints file (, and a groups file (, exported from the group editor), and creates an RTF (rich-text format) file with aspect hints for all the aspects in the groups, ordered by group and the order they are in each group. The RTF file can be read by Microsoft Word (and possibly other word processors) to format a document for printing or for use in the help system.

======== file

We also include here a description of what is in each column of the file. Keeping the aspects information in the tab file and generating Pascal code from it makes it easier to compare aspects (by simply sorting the file) and make changes to many aspects at once. When you sort, make sure you keep the row of labels at the top of the file.

== FieldID
A text string (no spaces, only alphanumeric) that uniquely identifies the aspect. Often taken from the variable name in the object, but not always, and sometimes the variable name changed later. The file should always be sorted by the FieldID column when you are finished with it and when you run the tab2asp program. The fieldIDs are named so that the objects come out sorted when the FieldIDs are sorted.

== name
What shows in the browser (etc) when the aspect is shown. Actually, this column is not used anymore because the aspect hints file ( has a "name" column and we use that column instead to show in the browser, etc. So this is really obsolete. If you want to change how an aspect shows in the program, change the "name" column in (that does not require recompiling, either).

== fieldType
The data type of the aspect. The types are: float, integer, unsigned long, unsigned char, string, file string (unused), color, boolean, icon, 3D object, enumerated list (shown in the browser as a radio button or check box group), and harvest item template. This list of constants is in uaspects.pas. You could add a new type by adding it to this list and checking for any case statements you need to add it to. NOTE that in each of the columns here that start with a number, only the initial number is read by the tab2asp program, but the text is for your reference. It's best never to type these cells but to copy and paste from another cell that contains the same thing, so you don't get the wrong number for what you want.

== IndexType
The type of array this represents. The types are: none, soil layer (array of 10), month (for weather, array of 12), s curve (array of 4 singles), soil texture triangle (array of 3), male/female (array of 2), harvest item types (array of 12), weather autocorrelation matrix (array of 3), MUSI coefficients (array of 4). This list of constants is in uaspects.pas. You could add a new type by adding it to this list and checking for any case statements you need to add it to.

== unitSet
The unit set. The list of 32 unit sets is in uunits. See that file for more on unit conversions.

== unitModel
The type of unit (within its unit set) in which the model variable is stored. This is very important because if this unit is wrong the browser will report the wrong number.

== unitMetric
The type of unit (within its unit set) to show when the user chooses to set all units to metric. Usually these are determined by the unit set (concentration, weight, etc).

== unitEnglish
The type of unit (within its unit set) to show when the user chooses to set all uints to English.

== SLower, SUpper
The "soft" lower and upper bounds. Soft bounds are our recommended bounds for displaying values. For input values, the user can override the soft bounds to input a value outside of them. We made these up mostly by looking at the unit and variable types and thinking of the normal garden scale (biomass, for example, will usually be in grams or kilograms, not tons).

== HLower, HUpper
The "hard" lower and upper bounds. For input variables, the user cannot input a value outside of them. Most of the hard bounds came from EPIC (see the Source column below); some of them came from our own guesses as to what extreme values might be. In some cases we might have set the hard bounds too restrictingly. We tried to stop values from reaching extremes that might crash the simulation. Of course read-only values need no bounds so they have mostly just initial display meanings for output variables.

== Source
Where the hard or absolute bounds came from. Usually these are from EPIC, from the unit set, or from our guesses.

== Type
Whether the variable is an input parameter, a state variable, or an output variable. These distinctions are not extremely important or accurate. The "parameter" versus everything else distinction is used in the group editor to choose what to look at, but otherwise this column is not used by anything.

== ReadOnly
Whether the user can change the value for this aspect in the browser. We used to have more changeable aspects, but in our run-through trying to make the code a little less vulnerable to messy side effects, we removed a lot of these. In most cases variables the user can change affect other variables either 1) right away (in which case there will be a side effect function in the object for it), 2) during the next day of simulation (in which case there will be no effect until you run the simulation), or 3) not at all. It is not advisable to make read-only variables changeable without at least perusing the code to look for potentially damaging side effects.

== HasHelp
Whether this aspect has a help topic in the help system. This column is not used anymore because we decided not to implement separate help topics for all 800 aspects.

== Access
A VERY IMPORTANT COLUMN. This is how the data for this aspect is retrieved from its model object. Any changes to model code which change variable names MUST update this field, or the program will choke when it attempts to fetch data for the aspect (when drawing the browser, group editor, or graph window).

== Transfer
Also important - HOW the data for this aspect is collected.
- MFD: The transfer type is MFD (MoveFieldData), a simple one-for-one data transfer using the Access column string.
- S Curve, 3D object, harvest item: These is nearly the same as one-for-one transfer, but a little fancy work is done in maintaining the special structures.
- BDConvert: Here the transfer type is a basic-derived (BD) conversion. In basic-derived conversion, the next three sets of ten columns (D1, D2, D3) each come into play. They specify alternate ways in which the aspect can be derived from the simulation variable described in the Access column. For example, the aspect named "Actual increase in biomass today" can be shown in its "basic" derivation as kg/m2 (under the "unitMetric" column), OR it can be shown in its "first derived" derivation as grams (under the "D1 metric" column). The D1, D2, and D3 sets of columns determine how each alternative derivation (up to three) is calculated from the simulation variable. Note that so far we have no "D3" derivations.

The remaining columns in the file are as follows and repeat similar columns for the derived representations.
D1 type, D1 set, D1 model, D1 metric, D1 English, D1 BSL, D1 BSU, D1 BHL, D1 BHU, D1 source
D2 type, D2 set, D2 model, D2 metric, D2 English, D2 BSL, D2 BSU, D2 BHL, D2 BHU, D2 source
D3 type, D3 set, D3 model, D3 metric, D3 English, D3 BSL, D3 BSU, D3 BHL, D3 BHU, D3 source

======== Conclusion

If there are any questions that remain unanswered by this programmer's guide, please see our web site for updates, and send us an e-mail if you don't find an answer there. Thanks and good luck!

Home ... News ... Products ... Download ... Order ... Support ... Consulting ... Company
Updated: December 1, 1998. Questions/comments on site to
Copyright © 1998 Paul D. Fernhout & Cynthia F. Kurtz.