Show:
  1. /**
  2. The `Management` object is used to for operations that remove trees from the simulation environment.
  3. The iLand management is accessible using the global object `management`, which is available
  4. when script code is invoked from the iLand management subsystem.
  5.  
  6. Main functions
  7. --------------
  8.  
  9. + Loading trees from iLand: use {{#crossLink "Management/load:method"}}{{/crossLink}} and {{#crossLink "Management/loadFromMap:method"}}{{/crossLink}} to load a list of trees
  10. + manipulating lists of trees: use {{#crossLink "Management/filter:method"}}{{/crossLink}} to select a sub set based on some criterion,
  11. or {{#crossLink "Management/sort:method"}}{{/crossLink}} to bring the list in a specific order; you can calculate {{#crossLink "Management/sum:method"}}{{/crossLink}}
  12. or {{#crossLink "Management/mean:method"}}{{/crossLink}} values from all trees in the list
  13. + removing trees: {{#crossLink "Management/manage:method"}}{{/crossLink}} and {{#crossLink "Management/kill:method"}}{{/crossLink}}
  14. + other functions such as....
  15.  
  16. Note that by default only living trees are processed.
  17. Several special functions exists, e.g. a function to filter based on a predefined list of tree-ids (filter()), of methods
  18. that select trees based on some rastered GIS data.
  19.  
  20. There are several distinct tree removal modes in iLand, namely by harvesting a tree, or by killing a tree, or due to a disturbance.
  21. In general, harvesting removes all (aboveground) biomass from the system, while a killed trees' biomass is moved to the soil pools.
  22. Disturbed trees behave similar to killed trees. Note, that there are further subtle differences between removal modes: for instance, resprouting
  23. is only possible from harvested trees; or, trees killed by disturbance might be treated differently by management.
  24.  
  25. The management functions typically affect only individual trees in iLand with a height >4m. However, there are some functions available
  26. to alter the state of the saplings (tree cohorts < 4m height).
  27.  
  28.  
  29.  
  30. Expressions and tree variables
  31. ------------------------------
  32. Many function of the `management` object allow to specify a filter ([Expression](https://iland-model.org/Expression)). In the context of
  33. management, tree variables can be used within filter expressions: see https://iland-model.org/tree+variables
  34.  
  35. Tree species can be included in Expressions by using the short name as is; internally, the species (identity) is
  36. a integer index of the species, and species short names (such as 'piab', 'fasy', or 'pico') are used as placeholders.
  37.  
  38.  
  39. Examples
  40. --------
  41. The wiki contains a small collection of useful management scripts.
  42.  
  43. @module iLand
  44. @class Management
  45. */
  46.  
  47. /**
  48. The number of trees that are currently in the internal list.
  49.  
  50. See also: {{#crossLink "SpatialAnalysis/load:method"}}{{/crossLink}}
  51.  
  52. @property count
  53. @type integer
  54. */
  55. /**
  56. The removal fraction for foliage [0..1]. 0: 0% will be removed, 1: 100% will be removed from the forest by management operations (i.e. calls to manage())
  57.  
  58. The default value is 0 (all foliage remains in the forest)
  59.  
  60. See also: {{#crossLink "SpatialAnalysis/removeBranch:method"}}{{/crossLink}}, {{#crossLink "SpatialAnalysis/removeStem:method"}}{{/crossLink}}
  61.  
  62. @property removeFoliage
  63. @type double
  64. @Example
  65. // full tree extraction
  66. management.removeFoliage = 1; management.removeBranch=1; management.removeStem = 1;
  67. management.manageAll();
  68.  
  69. */
  70. /**
  71. The removal fraction for branches [0..1]. 0: 0% will be removed, 1: 100% will be removed from the forest by management operations (i.e. calls to manage())
  72.  
  73. The default value is 0 (all branches remain in the forest)
  74.  
  75. See also: {{#crossLink "SpatialAnalysis/removeFoliage:method"}}{{/crossLink}}, {{#crossLink "SpatialAnalysis/removeStem:method"}}{{/crossLink}}
  76.  
  77. @property removeBranch
  78. @type double
  79. */
  80. /**
  81. The removal fraction for the stem biomass [0..1]. 0: 0% will be removed, 1: 100% will be removed from the forest by management operations (i.e. calls to manage())
  82.  
  83. The default value is 1 (100% of the stem is removed in case of management). Note that root biomass is never extracted.
  84.  
  85. See also: {{#crossLink "SpatialAnalysis/removeFoliage:method"}}{{/crossLink}}, {{#crossLink "SpatialAnalysis/removeBranch:method"}}{{/crossLink}}
  86.  
  87. @property removeStem
  88. @type double
  89. */
  90.  
  91. /**
  92. Load all trees into the internal list and return the number of trees.
  93.  
  94. @method loadAll
  95. @return {integer} the number of trees that were loaded.
  96. */
  97. /**
  98. Load all trees passing the filter criterion specified in `filter` and return number of trees in the list.
  99. `filter` can be any tree-related Expression.
  100.  
  101. @method load
  102. @param {string} filter A valid filter Expression that is applied during the loading of the list.
  103. @return {integer} the number of trees that were loaded.
  104. @Example
  105. // load all trees with a dbh >30 cm
  106. management.load('dbh>30');
  107. */
  108. /**
  109. Load all trees of a resource unit with the index `ruindex` and return the number of loaded trees.
  110.  
  111. @method loadResourceUnit
  112. @param {int} ruindex The index (0-based) of the resource unit that should be loaded
  113. @return {integer} the number of trees that were loaded.
  114. @Example
  115. for (var i=0; i<Globals.resourceUnitCount; ++) {
  116. management.loadResourceUnit(i);
  117. // further processing....
  118. }
  119. */
  120.  
  121. /**
  122. Load all trees that are located on grid pixels with the value `standID` on the grid `map`.
  123.  
  124. @method loadFromMap
  125. @param {Map} map a GIS grid that defines stand IDs.
  126. @param {integer} standID the ID of the stand that should be loaded.
  127. @param {boolean} do_append if `true`, the list is not cleared and trees are added to the existing list. Default is `false`.
  128. @return {integer} the number of trees that were loaded.
  129. @Example
  130. // Access to the global stand grid (required only once)
  131. var stand_grid = new Map();
  132. // load all trees of the forest stand with ID=1
  133. management.loadFromMap(stand_grid, 1);
  134. */
  135.  
  136. /**
  137. Clears the list without affecting any trees.
  138.  
  139. @method clear
  140. */
  141. /**
  142. Sort the trees in the internal list in ascending order according to a criterion given
  143. by `expression` (a valid [iLand Expression](https://iland-model.org/Expression)).
  144.  
  145. See also: {{#crossLink "Management/percentile:method"}}{{/crossLink}}
  146.  
  147. @method sort
  148. @param {string} expression Expression used for sorting
  149. @Example
  150. management.sort('dbh'); // sort by diameter, largest tree are now in the end of the list
  151. management.sort('-dbh'); // to sort in descending order, reverse the sign of the expression
  152. */
  153. /**
  154. Apply a filter `expression` on the list of trees (`expression`is a valid [iLand Expression](https://iland-model.org/Expression))
  155. and return the number of trees remaining in the lists. After calling this function, the list of
  156. trees is typically reduced and contains only those trees, who meet the condition in `expression`.
  157.  
  158. See the example how to filter by species, and how to combine multiple criteria.
  159.  
  160. See also: {{#crossLink "Management/sort:method"}}{{/crossLink}}, {{#crossLink "Management/load:method"}}{{/crossLink}}
  161.  
  162. @method filter
  163. @param {string} expression Expression used for filtering
  164. @return {integer} the number of trees in the list after filtering.
  165. @Example
  166. management.loadAll();
  167. management.filter('dbh>10');
  168. // is the same as:
  169. management.load('dbh>10');
  170. // using tree species names: note, that no "'" or '"" signs
  171. // are used with species IDs; note also the boolean 'and' operator
  172. management.filter('species=piab and dbh>20');
  173. management.loadAll(); // all trees
  174. management.filter('dbh>10 and species=piab'); // reduce list
  175. // ... some processing....
  176. management.filter('dbh>20'); // now only spruce trees > 20cm are still in the list
  177. management.filter('stress>0'); // now only spruce trees >20cm, that have a non-zero stress rating are in the list
  178. // ...
  179.  
  180. */
  181. /**
  182. Apply a filter in form of a `list` of ids, return number of remaining trees. This can be useful
  183. to pre-define a management on individual trees.
  184.  
  185.  
  186. See the example below.
  187.  
  188.  
  189. See also: {{#crossLink "Management/filter:method"}}{{/crossLink}}, https://iland-model.org/initialize+trees
  190.  
  191. @method filterIdList
  192. @param {array} list A list of unique tree IDs.
  193. @return {integer} the number of trees in the list after filtering.
  194. @Example
  195. // array of tree IDs
  196. var treelist = [10,20,40,43]; // can be loaded form file...
  197. management.load(); // load all trees
  198. management.filter(treelist); // filter trees using the tree list
  199. management.kill(); // remove all trees remaining, i.e. the trees in the tree list.
  200.  
  201. */
  202. /**
  203. Shuffle all trees in the list randomly.
  204.  
  205. @method randomize
  206. */
  207.  
  208. /**
  209. Retrieve the value associated with the `pct` percentile [0..100] of the currently loaded trees. A call
  210. to {{#crossLink "Management/sort:method"}}{{/crossLink}}() is required in order to prepare valid
  211. data.
  212.  
  213. See also: {{#crossLink "Management/sort:method"}}{{/crossLink}}
  214.  
  215. @method percentile
  216. @param {integer} pct the percentile [0..100] for which to return the value
  217. @return {dobule} the value associated with the `pct` percentile
  218. */
  219.  
  220. /**
  221. Calculate the mean value for all trees in the internal list for `expression` (optionally filtered by the `filter` criterion).
  222.  
  223. See also: {{#crossLink "Management/sum:method"}}{{/crossLink}}
  224.  
  225. @method mean
  226. @param {string} expression The expression used for calculating the mean value
  227. @param {string} filter If not empty, the mean is calculated only from those trees that meet the criterion in the expression
  228. @return {dobule} the mean value of `expression`
  229. @Example
  230. var mean_dbh = management.mean('dbh');
  231.  
  232. */
  233. /**
  234. Calculate the sum of `expression` for all trees in the internal list (optionally filtered by the `filter` criterion).
  235.  
  236. See also: {{#crossLink "Management/sum:method"}}{{/crossLink}}
  237.  
  238. @method sum
  239. @param {string} expression The expression used for calculating the mean value
  240. @param {string} filter If not empty, the mean is calculated only from those trees that meet the criterion in the expression
  241. @return {dobule} the mean value of `expression`
  242. @Example
  243. // select trees that represent 50% of the total basal area
  244. management.loadAll();
  245. var total_ba = management.sum('basalarea');
  246. management.randomize();
  247. management.filter('incsum(basalarea)<' + total_ba * 0.5 );
  248. console.log(management.sum('basalarea'));
  249. */
  250.  
  251.  
  252. /**
  253. Use `killPct` to remove `n` trees sampled randomly from a given percentile range (given by `from` and `to`). All
  254. trees are removed, if `n` is higher than the number of trees in that range.
  255.  
  256. The tree list needs to be sorted, before percentile based selection makes sense.
  257.  
  258. See also: {{#crossLink "Management/sort:method"}}{{/crossLink}}, {{#crossLink "Management/percentile:method"}}{{/crossLink}}
  259.  
  260. @method killPct
  261. @param {integer} from lower percentile of the current tree distribution (0..100)
  262. @param {integer} to higher percentile of the current tree distribution (0..100)
  263. @param {integer} n the number of trees to kill in the given percentile
  264. @return {integer} the number of killed trees
  265. @Example
  266. var n = management.loadAll();
  267. management.sort('dbh');
  268. var n_killed = management.killPct(0,50, n*0.25);
  269. console.log('killed ' + n_killed + ' below median: ' + management.percentile(50) );
  270. // kill 33% of the trees between the 80th and the 100th percentile.
  271. management.killPct(80,100, n*0.2 * 0.33);
  272. */
  273. /**
  274. Kill all trees which are currently in the tree list.
  275.  
  276. See also: {{#crossLink "Management/kill:method"}}{{/crossLink}}, {{#crossLink "Management/manageAll:method"}}{{/crossLink}}
  277. @method killAll
  278. @return {integer} the number of killed trees.
  279. */
  280. /**
  281. Kill all and cut down all trees in the list. The biomass of cut down trees bypasses the standing dead wood pool, and
  282. such trees can act as trap trees with regard to bark beetles.
  283.  
  284. See also: {{#crossLink "Management/kill:method"}}{{/crossLink}}, {{#crossLink "Management/manageAll:method"}}{{/crossLink}}
  285. @method cutAndDrop
  286. */
  287. /**
  288. Remove all selected trees with with the _disturbance_ flag set. Disturbed trees are treated
  289. differently with regard to carbon flows and {{#crossLinkModule "ABE"}}{{/crossLinkModule}}. Biomass of the stem and
  290. the branches is routed to the soil and snag pools as indicated by the parameters of the function. The rest of the biomass
  291. is removed from the system (e.g., consumed by fire). For example, if `stem_to_soil_fraction`=0.2, `stem_to_snag_fraction`=0.3, then
  292. 50% of the biomass leaves the system, 20% are added to the soil, 30% to the snag pools.
  293.  
  294. The `agent` parameter is the reason of death (i.e. the process that should be mimicked). Recognized values are 'fire', 'wind', 'barkbeetle', and 'cutdown'. For instance,
  295. tree that are removed with the `agent` set to 'wind' act as a breeding material for bark beetles. If the `agent` parameter is `'fire'`, then serotinous trees produce extra seeds.
  296.  
  297. See also: {{#crossLink "Management/killAll:method"}}{{/crossLink}}, {{#crossLink "Management/manageAll:method"}}{{/crossLink}}
  298. @method disturbanceKill
  299. @param {double} stem_to_soil_fraction (0..1) of stem biomass that is routed to the soil
  300. @param {double} stem_to_snag_fraction (0..1) of the stem biomass continues as standing dead
  301. @param {double} branch_to_soil_fraction (0..1) of branch biomass that is routed to the soil
  302. @param {double} branch_to_snag_fraction (0..1) of the branch biomass continues as standing dead
  303. @param {string} agent the disturbance agent that is mimicked ('fire' 'wind', 'barkbeetle', 'cutdown' ...)
  304. @return {integer} the number of killed trees.
  305. */
  306. /**
  307. Kill `fraction` (0..1) of all trees for which the Expression `filter` is _true_.
  308.  
  309. See also: {{#crossLink "Management/killAll:method"}}{{/crossLink}}, {{#crossLink "Management/manage:method"}}{{/crossLink}}
  310. @method kill
  311. @param {string} filter A expression to select a subset of the trees.
  312. @param {double} fraction give the fraction (0..1) of trees that should be killed.
  313. @return {integer} the number of killed trees.
  314. @Example
  315. management.loadAll();
  316. // kill 30% of larch trees, and 60% of pine
  317. management.kill('species = lade', 0.3);
  318. management.kill('species = pisy', 0.6);
  319. */
  320.  
  321.  
  322. /**
  323. Use `managePct` to remove `n` trees sampled randomly from a given percentile range (given by `from` and `to`). All
  324. trees are removed, if `n` is higher than the number of trees in that range.
  325.  
  326. The tree list needs to be sorted, before percentile based selection makes sense.
  327.  
  328. See also: {{#crossLink "Management/sort:method"}}{{/crossLink}}, {{#crossLink "Management/percentile:method"}}{{/crossLink}}
  329.  
  330. @method managePct
  331. @param {integer} from lower percentile of the current tree distribution (0..100)
  332. @param {integer} to higher percentile of the current tree distribution (0..100)
  333. @param {integer} n the number of trees to harvest in the given percentile
  334. @return {integer} the number of harvested trees
  335. @Example
  336. var n = management.loadAll();
  337. management.sort('dbh');
  338. var n_rem = management.managePct(0,50, n*0.25);
  339. console.log('removed ' + n_rem + ' below median: ' + management.percentile(50) );
  340. // harvest 33% of the trees between the 80th and the 100th percentile.
  341. management.managePct(80,100, n*0.2 * 0.33);
  342. */
  343. /**
  344. Harvest all trees which are currently in the tree list.
  345.  
  346. See also: {{#crossLink "Management/manage:method"}}{{/crossLink}}, {{#crossLink "Management/killAll:method"}}{{/crossLink}}
  347. @method manageAll
  348. @return {integer} the number of harvested trees.
  349. */
  350.  
  351. /**
  352. Remove a `fraction` (0..1) of all trees for which the Expression `filter` is _true_.
  353.  
  354. See also: {{#crossLink "Management/manageAll:method"}}{{/crossLink}}, {{#crossLink "Management/kill:method"}}{{/crossLink}}
  355. @method manage
  356. @param {string} filter A expression to select a subset of the trees.
  357. @param {double} fraction give the fraction (0..1) of trees that should be harvested.
  358. @return {integer} the number of harvested trees.
  359. @Example
  360. management.loadAll();
  361. // kill 30% of larch trees, and 60% of pine
  362. management.manage('species = lade', 0.3);
  363. management.manage('species = pisy', 0.6);
  364. */
  365.  
  366.  
  367. /**
  368. Kill all saplings (i.e. trees <4m) which are located on grid pixels with the value `standID` on the grid `map`.
  369.  
  370. @method killSaplings
  371. @param {Map} map A Map object with a stand grid.
  372. @param {integer} standID the ID of the stand to process.
  373. */
  374.  
  375. /**
  376. Kill all saplings (i.e. trees <4m) which are located on the resource unit identified by `ruindex`.
  377.  
  378. @method killSaplingsResourceUnit
  379. @param {integer} ruindex the index of the resource unit to process.
  380. */
  381.  
  382. /**
  383. (Hacky) function to modify the carbon content of the snag/soil pools of resource units covered by pixels with `standID` on the `map`.
  384. If the resource unit is only partially covered, the factors are scaled accordingly.
  385. The parameters are remove-fractions, i.e. values of 0 mean no change, values of 1 mean removal of 100% of the carbon of the respective pool.
  386.  
  387. @method removeSoilCarbon
  388. @param {Map} map A Map object with a stand grid.
  389. @param {integer} standID the ID of the stand to process.
  390. @param {double} SWDfrac fraction of standing woody debris to remove.
  391. @param {double} DWDfrac fraction of downed woody debris to remove.
  392. @param {double} litterFrac fraction of litter (yL) to remove.
  393. @param {double} soilFrac fraction of SOM to remove..
  394. */
  395.  
  396.  
  397. /**
  398. `tree(index)` returns the tree with index `index` (index is 0-based) from the current list. The returned Javascript object
  399. is a reference to the represented tree in iLand. See {{#crossLink "Tree"}}{{/crossLink}} for more details.
  400.  
  401. See also: {{#crossLink "TreeList/treeObject:method"}}{{/crossLink}}
  402.  
  403. @method tree
  404. @return {Tree} a reference to the tree with index `index` (see above). If the index is out of range, the `valid` property of the returned object is `false`.
  405. @Example
  406. management.loadAll(); // fill the tree list
  407. // loop over all trees
  408. for (var i=0;i<management.count;++i)
  409. console.log( management.tree(i).dbh );
  410.  
  411. **/
  412.  
  413. /**
  414. `treeObject(index)` returns the tree with index `index` (index is 0-based) from the current list. A new Javascript object
  415. is created for the tree. See {{#crossLink "Tree"}}{{/crossLink}} for more details.
  416.  
  417. See also: {{#crossLink "TreeList/tree:method"}}{{/crossLink}}
  418.  
  419. @method treeObject
  420. @return {Tree} a object representing the tree with index `index` (see above), or an invalid Tree object (if index is out of range).
  421. @Example
  422. management.loadAll(); // fill the tree list
  423. var x = management.treeObject(7); // 8th tree in the list
  424. // access the tree
  425. if (x.valid == true)
  426. console.log(x.dbh);
  427.  
  428. **/
  429.  
  430.  
  431.  
  432.  
  433. Management = {}
  434.