Using VDDT state-and-transition models in Envision Dave Conklin 1/11/10 Contents page 1 2 3 3 4 4 5 5 6 7 8 9 10 10 11 11 13 The General Idea IDU attributes needed for VDDTadapter Fig. 1. Envision’s screen for adding an autonomous process, with entries for the VDDTadapter. Capacities Initialization Fig. 2. Sample output from initialization of VDDTadapter. Testing a VDDT model on Envision Fig. 3. Example graphs of VDDTadapter output data from Envision. Fig. 4. Graphs from VDDT corresponding to those in fig. 3. Fig. 5 Conceptual diagram of VDDT adapter and FLAMMAP plug-in modules operation VDDTadapter structure The VDDT .mdb file and its representation in VDDTadapter Transition Types the VDDTadapter::Init() entry point the VDDTadapter::InitRun() entry point the VDDTadapter::Run() entry point Assumptions and Limitations The General Idea The idea is to use VDDT as a prototyping tool for state-and-transition rules in Envision. One starts by developing a non-spatial collection of state-and-transition models for the IDUs, using VDDT. VDDT stores the resulting collection of models as an Access database (.mdb file) and a few associated text files (.csv files). Then, you import the .mdb file into Envision (the initialization process of the VDDTadapter autonomous process). Then, during a simulation (i.e. during an execution of Envision), at each time step the VDDTadapter autonomous process carries out the appropriate state transitions for each IDU. VDDT’s state variables (state class, cover type, structural stage, stand age, TSD) are stored in Envision as attributes of the IDUs. The file name of the VDDT .mdb file containing the VDDT state-and-transition models is specified as the initialization string for the VDDTadapter autonomous process (fig. 1). The VDDT user interface refers to the individual models as “projects”. If the .mdb file contains multiple projects, the particular project to be used may be specified at the end of the initialization string, separated from the file name by a comma. Alternatively, the VDDTadapter will try to load all the projects contained in the .mdb file. 1 It is also possible to load projects from more than one .mdb file. Each separate .mdb file is assigned to a separate autonomous process. All the processes point to the same VDDTadapter.dll, but the processes have different IDs. IDU attributes needed for VDDTadapter VDDTadapter requires the IDU layer to include 4 attributes which specify the initial state for each IDU: STMname0 – the name of the VDDT project which applies to the IDU, or “none” StateClass0 – the letter of the initial state class, or ‘ ‘, the blank character StandAge0 – initial stand age, integer years, or -9999 if unknown or inapplicable origTSD – initial time since disturbance, integer years, or -9999 if unknown or inapplicable VDDTadapter also uses several more columns, but will add them if they don’t already exist: STMindex – internal index to current state, integer StateClass – current state class ID, integer CoverType – current cover type ID, integer StructStg – current structural stage ID, integer TofStand – the time step index corresponding to stand initiation LastTrans – the ID of the most recent state transition TofD0, TofD1, … - columns for each TSD group, containing the time step index corresponding to when the disturbance occurred 2 Fig. 1 Envision’s screen for adding an autonomous process, with entries for the VDDTadapter. Capacities Capacities given here are as defined in the VDDTadapter source code as of 6/15/09. Capacities may be changed by editing the corresponding #define statements at the beginning of the VDDTadapter.h source file and recompiling. The VDDTadapter program should be tested for proper operation after such changes. VDDTadapter can accommodate up to 25 VDDT projects (MAX_NUM_STMS). The largest acceptable value in the ID field of the Autonomous Process dialog box is 10 (MAX_NUM_ID). VDDTadapter can accommodate 1 time-since-disturbance group (MAX_NUM_TSDS). 3 Initialization VDDTadapter’s initialization entry point reads the specified .mdb file(s) and loads the state and transition definitions into its internal data structures. It writes several messages to Envision’s Output Panel to let the user know what it has done (fig. 2). Fig. 2. Sample output from initialization of VDDTadapter. 4 Testing a VDDT model on Envision At present, prior to the availability of IDU coverages with pre-loaded initial states in the STMname0, StateClass0, StandAge0, and origTSD columns, VDDTadapter runs in test mode. It initializes the STMindex with 0 for all the IDUs, and uses the initial condition information for the first VDDT model (from the InitialConditions and InitialConditionsDetails tables in the .mdb file) to set the values in the StateClass0, StandAge0, and origTSD columns. During an Envision run, at each timestep VDDTadapter outputs the percentage of IDUs in each of the first five states, the number of transitions in the first 10 disturbance groups, and the number of deterministic transitions. After the run, graphs of these data are available from Envision’s Post Run Results function (fig.3). These graphs may be compared to the corresponding graphs from VDDT itself to confirm that VDDTadapter is working properly (fig. 4). Fig. 3 Example graphs of VDDTadapter output data from Envision. 5 Fig. 4. Graphs from VDDT corresponding to those in fig. 3. 6 Fig. 5 Conceptual diagram of VDDT adapter and FLAMMAP plug-in modules operation in Envision. 7 VDDTadapter structure VDDTadapter is a Microsoft Foundation Class dynamically linked library (.dll), written in C++. It uses the resources provided by the Envision SDK. Textually, it consists of 3 source files unique to itself (VDDTadapter.cpp, VDDTadapter.h, and dllmain.cpp), together with the source files in the SDK. Structurally, it creates three C++ classes: VDDTadapter – the autonomous process itself VDDTmodel – the internal Envision version of the VDDT .mdb file PTtable – the internal Envision version of the ProbabilisticTransition table from the .mdb file VDDTadapter inherits from Envision’s EnvAutoProcess class, and overrides the Init(), InitRun(), and Run() procedures. VDDTadapter has several entry points: VDDTadapter::Init() – called during Envision’s startup VDDTadapter::InitRun() - called at the beginning of each simulation run VDDTadapter::Run() – called at each timestep of a simulation run Entry points to allow the user to specify a random number seed, and to show output data VDDTadapter::Init() is called when Envision first starts up (and when the VDDTadapter autonomous process is first added?). The Init() entry point reads the appropriate portions of the .mdb file and stores the data on the heap with pointers in a VDDTmodel object and a PTtable object. Conceptually, objects of the three VDDTadapter classes can be valid or invalid; each class contains a Boolean validity flag in its member data. When an object is constructed, the validity flag starts out as FALSE; its value is changed to TRUE after it has been initialized and has been found to be complete and internally consistent. Heap pointers in the member data of VDDTadapter objects are initialized to NULL when the object is constructed, and by convention are held at that value whenever the object is invalid. This convention has the consequence that invalid objects should have no associated heap memory, other than that used for the object itself. For valid objects, the convention is that all heap pointers should be valid or NULL. The rule is that when the object transitions from valid to invalid, all associated heap memory should be released and the pointers set back to NULL. 8 Object PTtable VDDTmodel VDDTadapter Heap pointers intcolsP, KeepRelAgeP, netProbP DTtblP, SCtblP, DG_PTTtblP, DGtblP m_possibleTransitionsListP The VDDT .mdb file and its representation in VDDTadapter A single VDDT database (.mdb) file can contain the information for several VDDT “projects”, called models here. It holds data in 28 tables. VDDTadapter loads data into the VDDTmodel and PTtable objects for only a single model at a time, and from only a subset of the tables. VDDTadapter accesses the Project table in order to determine which project to load. Heap pointer, # of records intcolsP, numPT KeepRelAgeP, numPT netProbP, numPT DTtblP, numDT SCtblP, numSC DG_PTTtblP, numDG_PTT DGtblP, numDG m_possibleTransitionsListP, numPT+1 .mdb table ProbabilisticTransition Content of each record ProbabilisticTransitionID ProbabilisticTransitionTypeID StateClassID ToStateClassID MinAge MaxAge TSD TSDMax RelativeAge RelTSD ProbabilisticTransition KeepRelAge ProbabilisticTransition Probability x Proportion DeterministicTransition StateClassID ToStateClassID StartAge EndAge StateClass StateClassID CoverTypeID StructuralStageID ProbTransGroupProbTrans ProbabilisticTransitionGroupID ProbabilisticTransitionTypeID ProbabilisticTransitionGroup ProbabilisticTransitionGroupID none ID of a possible probabilistic transition Transition Types 9 VDDT classifies state transitions as deterministic transitions (DTs) or probabilistic transitions (PTs). There is one deterministic transition associated with each state, so numDT = numSC. Probabilistic transitions are grouped into “probabilistic transition types” (e.g. clearcut, thinning, low intensity fire, prescribed fire) and the types are further aggregated into “probabilistic transition groups” (e.g. harvest, fire). Probabilistic transition types (PTTs) are also sometimes referred to as disturbances, as in “time since disturbance” (TSD). There is one TSD value kept for each probabilistic transition type. Probabilistic transition groups (PTGs) are also known as disturbance groups (DGs). Each PT has a single PTT; one PTT may have multiple PTs associated with it. The PT-PTT relationship is many-to-one. Each PTT may be in multiple DGs, and each DG may contain multiple PTTs. The PTT-DG relationship is many-to-many. the VDDTadapter::Init() entry point VDDTadapter::Init first reads the Project table to determine whether the .mdb file contains more than one model; if so, the user is asked to select a model. Then the data for the appropriate model is loaded into memory. Finally, Init() confirms that the IDU layer has columns named “CoverType”, “StructuralStage”, and “StandAge”. Init() populates the StateClass column in the IDU layer with the StateClassIDs which correspond to the values in the CoverType and StructuralStage columns, first creating the StateClass column if it does not already exist. Init checks for the existence of, and creates if necessary, a contiguous series of columns named “TSD0”, “TSD1”, …, out to the number of different probabilistic transition types. Some VDDT features will be omitted from VDDTadapter: Probabilistic transition multipliers Area limits Temporal multipliers Calculated, categorical, and numeric attributes This list of omitted VDDT features is subject to change. Features can be added back to VDDTadapter as needs are identified. VDDTadapter::Init will look for these columns in the IDU layer data table (which correspond to tables in the VDDT .mdb file: CoverType StructuralStage StandAge 10 TSD[i], i = 1..number of disturbance types timesteps since the most recent occurrence of disturbance type i VDDTadapter ::Init will check, for each IDU, that the entries in the CoverType, and StructuralStage are values that appear in the associated tables in the VDDT .mdb file, and that their combination appears in the StateClass table. VDDTadapter::Init will force the StandAge values onto the integer range [0, 999] and will force the TSD[i] values onto the integer range [-1,999]. A TSD[i] of -1 indicates that the given disturbance has not occurred on the IDU. If there are more disturbance types in the VDDT .mdb file than there are TSD columns, then VDDTadapter::Init will add TSD columns as appropriate and populate them with -1. VDDTadapter::Init will populate the StateClass column with the appropriate values from the VDDT .mdb StateClass table, given the IDU’s values for CoverType and StructuralStage. It will create the StateClass column if it does not already exist. the VDDTadapter::InitRun() entry point The InitRun() entry point resets the random number seed to a user-defined input value, which defaults to 1. VDDTadapter includes a portable random number generator, designed to produce the same series of random numbers, given a particular seed, no matter which processor/computer/operating system it is running on. the VDDTadapter::Run() entry point This entry point is called once per time step. It loops thru all the IDUs. Conceptually, it does for each IDU what VDDT would do for each cell in a single timestep. Here is how the VDDT User Guide describes what it does for a single cell in a single timestep: For each cell, VDDT randomly permutes the order of the disturbance list for the current class of the cell. • For each cell, the model makes a random draw from a uniform distribution between zero and one. If that random draw is less than the total of all transition probabilities for the cell’s current class, then a transition occurs for that cell. The decision about which transition occurs is based on the same random draw and on the relative probability of all the possible transitions. For example: Class A has three possible probabilistic transitions in this order: Fire (p=0.01), Wind (p=0.001) and Insects (p=0.02). A random number R is drawn. R≤ 0.01 would result in a fire, 0.01<R≤0.011 would result in Wind, 0.011<R≤0.031 would result in Insects, and 0.031<R would result in • 11 no transition. Beware that when the sum of input probabilities for a class exceeds 1, the observed probabilities will not match the inputs. This is because only a single probabilistic transition can occur to a cell per time-step. [VDDT User Guide Version 6.0, Appendix A, p.121] [VDDT User Guide Version 6.0, Appendix A, p.122] The Run() entry point loops thru all the IDUs. For each IDU, several tasks are performed: - an AddDelta() call is made to increment its StandAge - a random number is drawn from a uniform distribution on [0,1] - a list of possible probabilistic transitions is made, and their net probabilities summed - if the random number is less than or equal to the probability sum, then the list is permuted and a transition is chosen and applied, by making appropriate AddDelta() calls - otherwise, if the new StandAge is equal to the max age for the StateClass, then the deterministic transition is applied, via an AddDelta() call. Major subroutines of the Run() entry point are ListPossibleTransitions(), permuteList(), chooseAndApplyDisturbance(), and applyProbabilisticDisturbance(). They are all methods of the VDDTadapter class. 12 Assumptions and Limitations Some VDDT features will be omitted from VDDTadapter: Area limits Temporal multipliers Calculated, categorical, and numeric attributes This list of omitted VDDT features is subject to change. Features can be added back to VDDTadapter as needs are identified. The VDDTadapter code expects: 1<=numTSD<=99 -1<=startTSD<=9999 0<=StandAge<=9999 numSC>0 numPT>0 numDG>0 13