patch.c 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449
  1. /*
  2. ************************************************************
  3. * MODULE: r.le.patch/patch.c *
  4. * Version 5.0 Nov. 1, 2001 *
  5. * *
  6. * AUTHOR: W.L. Baker, University of Wyoming *
  7. * BAKERWL@UWYO.EDU *
  8. * *
  9. * PURPOSE: To analyze attributes of patches in a landscape *
  10. * patch.c computes and saves the patch measures *
  11. * *
  12. * COPYRIGHT: (C) 2001 by W.L. Baker *
  13. * *
  14. * This program is free software under the GNU General *
  15. * Public License(>=v2). Read the file COPYING that comes *
  16. * with GRASS for details *
  17. * *
  18. ************************************************************/
  19. #include <grass/gis.h>
  20. #include <grass/config.h>
  21. #include "patch.h"
  22. extern struct CHOICE *choice;
  23. extern int total_patches, ntype, n_scale, n_unit, *recl_count;
  24. extern float *shape_PA, *shape_CPA, *shape_RCC, **recl_tb, *size_cl;
  25. FILE *a5, *a6, *a1_4, *a7, *a8, *c1_4, *c5, *c6, *c7, *c8, *c9c, *c9e, *c10c,
  26. *c10e, *s3, *s4, *s5, *s6, *s7_8, *s1_2, *h3, *h4, *h5, *h6, *h1_2, *n1_4,
  27. *p4, *p5, *p6, *p1_3, *outfile;
  28. int i;
  29. /************************************/
  30. /* RUN THE DEFAULT PATCH MEASURES */
  31. /************************************/
  32. void df_patch(PATCH * patch_list)
  33. {
  34. PATCH *tmp = patch_list;
  35. int *type_dens, type_coh;
  36. char path[GNAME_MAX+10];
  37. if (!total_patches)
  38. return;
  39. /* Write the scale and unit in each file */
  40. /***********************************************************/
  41. if (choice->att[1] || choice->att[2] || choice->att[3] || choice->att[4]) {
  42. a1_4 = fopen0("r.le.out/a1-4.out", "a");
  43. fprintf(a1_4, "%5d %5d", n_scale, n_unit);
  44. }
  45. if (choice->att[5]) {
  46. a5 = fopen0("r.le.out/a5.out", "a");
  47. fprintf(a5, "%5d %5d", n_scale, n_unit);
  48. }
  49. if (choice->att[6]) {
  50. a6 = fopen0("r.le.out/a6.out", "a");
  51. fprintf(a6, "%5d %5d", n_scale, n_unit);
  52. }
  53. if (choice->att[7]) {
  54. a7 = fopen0("r.le.out/a7.out", "a");
  55. fprintf(a7, "%5d %5d", n_scale, n_unit);
  56. }
  57. if (choice->att[8]) {
  58. a8 = fopen0("r.le.out/a8.out", "a");
  59. fprintf(a8, "%5d %5d", n_scale, n_unit);
  60. }
  61. /***********************************************************/
  62. if (choice->size[1] || choice->size[2]) {
  63. s1_2 = fopen0("r.le.out/s1-2.out", "a");
  64. fprintf(s1_2, "%5d %5d", n_scale, n_unit);
  65. }
  66. if (choice->size[3]) {
  67. s3 = fopen0("r.le.out/s3.out", "a");
  68. fprintf(s3, "%5d %5d", n_scale, n_unit);
  69. }
  70. if (choice->size[4]) {
  71. s4 = fopen0("r.le.out/s4.out", "a");
  72. fprintf(s4, "%5d %5d", n_scale, n_unit);
  73. }
  74. if (choice->size[5]) {
  75. s5 = fopen0("r.le.out/s5.out", "a");
  76. fprintf(s5, "%5d %5d", n_scale, n_unit);
  77. }
  78. if (choice->size[6]) {
  79. s6 = fopen0("r.le.out/s6.out", "a");
  80. fprintf(s6, "%5d %5d\n", n_scale, n_unit);
  81. }
  82. if (choice->size[7] || choice->size[8]) {
  83. s7_8 = fopen0("r.le.out/s7-8.out", "a");
  84. fprintf(s7_8, "%5d %5d", n_scale, n_unit);
  85. }
  86. /***********************************************************/
  87. if (choice->core[1] || choice->core[2] ||
  88. choice->core[3] || choice->core[4]) {
  89. c1_4 = fopen0("r.le.out/c1-4.out", "a");
  90. fprintf(c1_4, "%5d %5d", n_scale, n_unit);
  91. }
  92. if (choice->core[5]) {
  93. c5 = fopen0("r.le.out/c5.out", "a");
  94. fprintf(c5, "%5d %5d", n_scale, n_unit);
  95. }
  96. if (choice->core[6]) {
  97. c6 = fopen0("r.le.out/c6.out", "a");
  98. fprintf(c6, "%5d %5d", n_scale, n_unit);
  99. }
  100. if (choice->core[7]) {
  101. c7 = fopen0("r.le.out/c7.out", "a");
  102. fprintf(c7, "%5d %5d", n_scale, n_unit);
  103. }
  104. if (choice->core[8]) {
  105. c8 = fopen0("r.le.out/c8.out", "a");
  106. fprintf(c8, "%5d %5d", n_scale, n_unit);
  107. }
  108. if (choice->core[9]) {
  109. c9c = fopen0("r.le.out/c9c.out", "a");
  110. fprintf(c9c, "%5d %5d", n_scale, n_unit);
  111. c9e = fopen0("r.le.out/c9e.out", "a");
  112. fprintf(c9e, "%5d %5d", n_scale, n_unit);
  113. }
  114. if (choice->core[10]) {
  115. c10c = fopen0("r.le.out/c10c.out", "a");
  116. fprintf(c10c, "%5d %5d\n", n_scale, n_unit);
  117. c10e = fopen0("r.le.out/c10e.out", "a");
  118. fprintf(c10e, "%5d %5d\n", n_scale, n_unit);
  119. }
  120. /************************************************************/
  121. if (choice->shape[1] || choice->shape[2]) {
  122. h1_2 = fopen0("r.le.out/h1-2.out", "a");
  123. fprintf(h1_2, "%5d %5d", n_scale, n_unit);
  124. }
  125. if (choice->shape[3]) {
  126. h3 = fopen0("r.le.out/h3.out", "a");
  127. fprintf(h3, "%5d %5d", n_scale, n_unit);
  128. }
  129. if (choice->shape[4]) {
  130. h4 = fopen0("r.le.out/h4.out", "a");
  131. fprintf(h4, "%5d %5d", n_scale, n_unit);
  132. }
  133. if (choice->shape[5]) {
  134. h5 = fopen0("r.le.out/h5.out", "a");
  135. fprintf(h5, "%5d %5d", n_scale, n_unit);
  136. }
  137. if (choice->shape[6]) {
  138. h6 = fopen0("r.le.out/h6.out", "a");
  139. fprintf(h6, "%5d %5d\n", n_scale, n_unit);
  140. }
  141. /************************************************************/
  142. if (choice->boundary[1] || choice->boundary[2] ||
  143. choice->boundary[3] || choice->boundary[4]) {
  144. n1_4 = fopen0("r.le.out/n1-4.out", "a");
  145. fprintf(n1_4, "%5d %5d", n_scale, n_unit);
  146. }
  147. /************************************************************/
  148. if (choice->perim[1] || choice->perim[2] || choice->perim[3]) {
  149. p1_3 = fopen0("r.le.out/p1-3.out", "a");
  150. fprintf(p1_3, "%5d %5d", n_scale, n_unit);
  151. }
  152. if (choice->perim[4]) {
  153. p4 = fopen0("r.le.out/p4.out", "a");
  154. fprintf(p4, "%5d %5d", n_scale, n_unit);
  155. }
  156. if (choice->perim[5]) {
  157. p5 = fopen0("r.le.out/p5.out", "a");
  158. fprintf(p5, "%5d %5d", n_scale, n_unit);
  159. }
  160. if (choice->perim[6]) {
  161. p6 = fopen0("r.le.out/p6.out", "a");
  162. fprintf(p6, "%5d %5d", n_scale, n_unit);
  163. }
  164. type_dens = (int *)G_calloc(25, sizeof(int));
  165. for (i = 0; i < 25; i++)
  166. type_dens[i] = 0;
  167. /* for each patch on the patch list */
  168. while (tmp) {
  169. if ((type_coh = recl_coh(tmp->att)) >= 0)
  170. type_dens[type_coh]++;
  171. if (choice->att[0])
  172. df_att(tmp, type_coh, type_dens);
  173. if (choice->core[0])
  174. df_core(tmp, type_coh, type_dens);
  175. if (choice->size[0])
  176. df_size(tmp, type_coh, type_dens);
  177. if (choice->shape[0])
  178. df_shape(tmp, type_coh, type_dens);
  179. if (choice->perim[0])
  180. df_perim(tmp, type_coh, type_dens);
  181. if (choice->boundary[0])
  182. df_boundary(tmp);
  183. if (strcmp(choice->out, "") && choice->wrum != 'm') {
  184. sprintf(path, "r.le.out/%s", choice->out);
  185. outfile = fopen0(path, "a");
  186. fprintf(outfile, "%3d %3d %6d %7.1f %4.0f %4.0f %8.0f \
  187. %8.0f %8.0f %8.0f %6.3f %6.3f %6.3f %8d %4.3f\n", n_scale, n_unit, tmp->num, tmp->att, tmp->c_row, tmp->c_col, tmp->area, tmp->core, tmp->edge, tmp->perim, tmp->perim / tmp->area, 0.282 * tmp->perim / sqrt(tmp->area), 2.0 * sqrt(tmp->area / PI) / tmp->long_axis, tmp->twist, tmp->omega);
  188. fclose(outfile);
  189. }
  190. tmp = tmp->next;
  191. }
  192. if (choice->att[1] || choice->att[2] || choice->att[3] || choice->att[4])
  193. fclose(a1_4);
  194. if (choice->att[5])
  195. fclose(a5);
  196. if (choice->att[6])
  197. fclose(a6);
  198. if (choice->att[7])
  199. fclose(a7);
  200. if (choice->att[8])
  201. fclose(a8);
  202. if (choice->core[1] || choice->core[2] ||
  203. choice->core[3] || choice->core[4])
  204. fclose(c1_4);
  205. if (choice->core[5])
  206. fclose(c5);
  207. if (choice->core[6])
  208. fclose(c6);
  209. if (choice->core[7])
  210. fclose(c7);
  211. if (choice->core[8])
  212. fclose(c8);
  213. if (choice->core[9]) {
  214. fclose(c9c);
  215. fclose(c9e);
  216. }
  217. if (choice->core[10]) {
  218. fclose(c10c);
  219. fclose(c10e);
  220. }
  221. if (choice->size[1] || choice->size[2])
  222. fclose(s1_2);
  223. if (choice->size[3])
  224. fclose(s3);
  225. if (choice->size[4])
  226. fclose(s4);
  227. if (choice->size[5])
  228. fclose(s5);
  229. if (choice->size[6])
  230. fclose(s6);
  231. if (choice->size[7] || choice->size[8])
  232. fclose(s7_8);
  233. if (choice->shape[1] || choice->shape[2])
  234. fclose(h1_2);
  235. if (choice->shape[3])
  236. fclose(h3);
  237. if (choice->shape[4])
  238. fclose(h4);
  239. if (choice->shape[5])
  240. fclose(h5);
  241. if (choice->shape[6])
  242. fclose(h6);
  243. if (choice->boundary[1] || choice->boundary[2] ||
  244. choice->boundary[3] || choice->boundary[4])
  245. fclose(n1_4);
  246. if (choice->perim[1] || choice->perim[2] || choice->perim[3])
  247. fclose(p1_3);
  248. if (choice->perim[4])
  249. fclose(p4);
  250. if (choice->perim[5])
  251. fclose(p5);
  252. if (choice->perim[6])
  253. fclose(p6);
  254. G_free(type_dens);
  255. total_patches = 0;
  256. return;
  257. }
  258. /************************************/
  259. /* COMPUTE THE ATTRIBUTE MEASURES */
  260. /************************************/
  261. void df_att(PATCH * tmp, int type_coh, int *type_dens)
  262. {
  263. static double sumx = 0.0, sumx2 = 0.0, w_att = 0.0, w_att2 = 0.0, total =
  264. 0.0;
  265. static double *area, total2 = 0.0;
  266. /* variables:
  267. IN:
  268. tmp = the next patch on the patch list
  269. type_coh = identification no. for the group for this patch
  270. *type_dens = array of no. of patches by group
  271. INTERNAL:
  272. sumx = sum of all the patch attributes
  273. sumx2 = sum of all the patch attributes squared
  274. w_att = sum of (patch attributes x areas)
  275. w_att2 = sum of (patch attributes x areas squared)
  276. total = sum of all the patch areas
  277. *area = array of total areas by gp
  278. */
  279. if (tmp->num == 1)
  280. area = (double *)G_calloc(25, sizeof(double));
  281. sumx += tmp->att;
  282. sumx2 += tmp->att * tmp->att;
  283. w_att += tmp->area * tmp->att;
  284. w_att2 += tmp->area * tmp->att * tmp->att;
  285. total += tmp->area;
  286. total2 += tmp->area * tmp->area;
  287. area[type_coh] += tmp->area;
  288. if (!tmp->next) {
  289. save_att(w_att, w_att2, total, total2, sumx, sumx2, type_dens, area);
  290. w_att = w_att2 = total = sumx = sumx2 = 0.0;
  291. G_free(area);
  292. }
  293. return;
  294. }
  295. /************************************/
  296. /* SAVE THE ATTRIBUTE MEASURES */
  297. /************************************/
  298. void save_att(double w_att, double w_att2, double t_size, double t_size2,
  299. double sum, double sum2, int *density, double *area)
  300. {
  301. register int i;
  302. double wm, wstdv, m, stdv;
  303. /* variables:
  304. IN: from df_att
  305. w_att = sum of (patch attributes x areas)
  306. w_att2 = sum of (patch attributes x areas squared)
  307. t_size = sum of all the patch areas
  308. t_size2 = sum of all the patch areas squared
  309. sum = sum of all the patch attributes
  310. sum2 = sum of all the patch attributes squared
  311. *area = array of total areas by group
  312. *density = array of no. of patches by group
  313. INTERNAL:
  314. wm = mean pixel attribute (a1)
  315. wstdv = st. dev. pixel attribute (a2)
  316. m = mean patch attribute (a3)
  317. stdv = st. dev. patch attribute (a4)
  318. GLOBAL:
  319. total_patches = tot. no. patches in sampling area (fm. trace.c)
  320. */
  321. wm = w_att / t_size;
  322. wstdv = w_att2 / t_size - wm * wm;
  323. if (wstdv > 0)
  324. wstdv = sqrt(wstdv);
  325. else
  326. wstdv = 0;
  327. m = sum / total_patches;
  328. stdv = sum2 / total_patches - m * m;
  329. if (stdv > 0)
  330. stdv = sqrt(stdv);
  331. else
  332. stdv = 0;
  333. /* write a1=mn. pix. att., a2=s.d. pix. att.,
  334. a3=mn. patch att., a4=s.d. patch att. */
  335. if (choice->att[1] || choice->att[2] || choice->att[3] || choice->att[4]) {
  336. fprintf(a1_4, " %15.3f %15.3f %15.3f %15.3f\n", wm, wstdv, m,
  337. stdv);
  338. }
  339. /* write a5 = cover by gp */
  340. if (choice->att[5]) {
  341. for (i = 0; i < ntype; i++)
  342. fprintf(a5, " %11.3f", area[i] / t_size);
  343. fprintf(a5, "\n");
  344. }
  345. /* write a6 = density by gp */
  346. if (choice->att[6]) {
  347. for (i = 0; i < ntype; i++)
  348. fprintf(a6, " %10d", *(density + i));
  349. fprintf(a6, "\n");
  350. }
  351. /* write a7 = total patches */
  352. if (choice->att[7])
  353. fprintf(a7, " %11d\n", total_patches);
  354. /* write a8 = eff. mesh no. */
  355. if (choice->att[8]) {
  356. if (t_size2 > 0.0)
  357. fprintf(a8, " %11.3f\n", (t_size * t_size) / t_size2);
  358. else
  359. fprintf(a8, " %11.3f\n", t_size2);
  360. }
  361. return;
  362. }
  363. /************************************/
  364. /* COMPUTE THE CORE MEASURES */
  365. /************************************/
  366. void df_core(PATCH * tmp, int type_coh, int *type_dens)
  367. {
  368. static int **density1c = NULL, **density1e = NULL,
  369. *densityc = NULL, *densitye = NULL, first = 1;
  370. static double mcore = 0.0, medge = 0.0, *mcore1 = NULL, *medge1 = NULL,
  371. sumc2 = 0.0, sume2 = 0.0, *sum22c, *sum22e;
  372. register int i;
  373. int core_coh, edge_coh;
  374. /* variables:
  375. IN:
  376. tmp = the next patch on the patch list
  377. type_coh = identif. no. for the group for this patch
  378. type_dens[] = array of no. of patches by group
  379. INTERNAL:
  380. mcore = sum of patch core sizes
  381. medge = sum of patch edge sizes
  382. sumc2 = sum of patch cores squared
  383. sume2 = sum of patch edges squared
  384. mcore1[] = array of patch cores by group
  385. medge1[] = array of patch edges by group
  386. sum22c[] = array of patch cores squared by group
  387. sum22e[] = array of patch edges squared by group
  388. densityc[] = array of no. of patches by core size class
  389. densitye[] = array of no. of patches by edge size class
  390. density1c[] = array of no. of patches by core size class
  391. by group
  392. density1e[] = array of no. of patches by edge size class
  393. by group
  394. */
  395. if (first) {
  396. densityc = (int *)G_calloc(25, sizeof(int));
  397. densitye = (int *)G_calloc(25, sizeof(int));
  398. sum22c = (double *)G_calloc(25, sizeof(double));
  399. sum22e = (double *)G_calloc(25, sizeof(double));
  400. mcore1 = (double *)G_calloc(25, sizeof(double));
  401. medge1 = (double *)G_calloc(25, sizeof(double));
  402. }
  403. /* if output is by size class (c9 & c10) determine
  404. which size class the current patch is in */
  405. if (choice->core[9] || choice->core[10]) {
  406. core_coh = index_coh(tmp->core, size_cl);
  407. densityc[core_coh]++;
  408. edge_coh = index_coh(tmp->edge, size_cl);
  409. densitye[edge_coh]++;
  410. }
  411. mcore += tmp->core;
  412. medge += tmp->edge;
  413. sumc2 += tmp->core * tmp->core;
  414. sume2 += tmp->edge * tmp->edge;
  415. if (type_coh >= 0) {
  416. mcore1[type_coh] += tmp->core;
  417. medge1[type_coh] += tmp->edge;
  418. sum22c[type_coh] += tmp->core * tmp->core;
  419. sum22e[type_coh] += tmp->edge * tmp->edge;
  420. }
  421. /* if c10 */
  422. if (choice->core2) {
  423. if (first) {
  424. density1c = (int **)G_calloc(25, sizeof(int *));
  425. for (i = 0; i < 25; i++)
  426. density1c[i] = (int *)G_calloc(25, sizeof(int));
  427. density1e = (int **)G_calloc(25, sizeof(int *));
  428. for (i = 0; i < 25; i++)
  429. density1e[i] = (int *)G_calloc(25, sizeof(int));
  430. }
  431. if (type_coh >= 0) {
  432. if (core_coh >= 0)
  433. density1c[type_coh][core_coh]++;
  434. if (edge_coh >= 0)
  435. density1e[type_coh][edge_coh]++;
  436. }
  437. }
  438. if (first)
  439. first = 0;
  440. if (!tmp->next) {
  441. save_core(sumc2, sume2, mcore, medge, mcore1, medge1, sum22c, sum22e,
  442. densityc, densitye, type_dens, density1c, density1e);
  443. mcore = medge = sumc2 = sume2 = 0;
  444. G_free(densityc);
  445. G_free(densitye);
  446. G_free(sum22c);
  447. G_free(sum22e);
  448. G_free(mcore1);
  449. G_free(medge1);
  450. if (choice->core2) {
  451. for (i = 0; i < 25; i++) {
  452. G_free(density1c[i]);
  453. G_free(density1e[i]);
  454. }
  455. G_free(density1c);
  456. G_free(density1e);
  457. }
  458. first = 1;
  459. }
  460. return;
  461. }
  462. /************************************/
  463. /* SAVE THE CORE MEASURES */
  464. /************************************/
  465. void save_core(double sumc2, double sume2, double mcore, double medge,
  466. double *mcore1, double *medge1, double *sum22c, double *sum22e,
  467. int *densityc, int *densitye, int *type_dens, int **density1c,
  468. int **density1e)
  469. {
  470. register int i, j;
  471. double tmpc, tmpe, stdvc, stdve;
  472. /* variables:
  473. IN:
  474. sumc2 = sum of patch cores squared
  475. sume2 = sum of patch edges squared
  476. mcore = sum of patch cores
  477. medge = sum of patch edges
  478. mcore1[] = array of sums of patch cores by gp
  479. medge1[] = array of sums of patch edges by gp
  480. sum22c[] = array of patch cores squared by gp
  481. sum22e[] = array of patch edges squared by gp
  482. densityc[] = array of no. of patches by core size class
  483. densitye[] = array of no. of patches by edge size class
  484. type_dens[] = array of no. of patches by gp ?
  485. INTERNAL:
  486. tmpc = mean patch core (c1 & c5)
  487. stdvc = st. dev. patch core (c2 & c6)
  488. tmpe = mean patch edge (c3 & c7)
  489. stdve = st. dev. patch edge (c4 & c8)
  490. GLOBAL:
  491. total_patches = tot. no. patches in sampling area (fm. trace.c)
  492. */
  493. /* calc. & write c1=mn. core, c2=s.d. core,
  494. c3=mn. edge, c4=s.d. edge */
  495. if (choice->core[1] || choice->core[2] ||
  496. choice->core[3] || choice->core[4]) {
  497. tmpc = mcore / total_patches;
  498. stdvc = sumc2 / total_patches - tmpc * tmpc;
  499. if (stdvc > 0)
  500. stdvc = sqrt(stdvc);
  501. else
  502. stdvc = 0;
  503. tmpe = medge / total_patches;
  504. stdve = sume2 / total_patches - tmpe * tmpe;
  505. if (stdve > 0)
  506. stdve = sqrt(stdve);
  507. else
  508. stdve = 0;
  509. fprintf(c1_4, " %15.3f %15.3f %15.3f %15.3f\n", tmpc, stdvc,
  510. tmpe, stdve);
  511. }
  512. /* calc. & write c5=mn. core by gp */
  513. if (choice->core[5]) {
  514. for (i = 0; i < ntype; i++) {
  515. if ((tmpc = type_dens[i]))
  516. tmpc = mcore1[i] / tmpc;
  517. fprintf(c5, " %11.3f", tmpc);
  518. }
  519. fprintf(c5, "\n");
  520. }
  521. /* calc. & write c6=s.d. core by gp */
  522. if (choice->core[6]) {
  523. for (i = 0; i < ntype; i++) {
  524. stdvc = 0;
  525. if (type_dens[i]) {
  526. tmpc = mcore1[i] / type_dens[i];
  527. stdvc = sum22c[i] / type_dens[i] - tmpc * tmpc;
  528. if (stdvc > 0)
  529. stdvc = sqrt(stdvc);
  530. else
  531. stdvc = 0;
  532. }
  533. fprintf(c6, " %11.3f", stdvc);
  534. }
  535. fprintf(c6, "\n");
  536. }
  537. /* calc. & write c7=mn. edge by gp */
  538. if (choice->core[7]) {
  539. for (i = 0; i < ntype; i++) {
  540. if ((tmpe = type_dens[i]))
  541. tmpe = medge1[i] / tmpe;
  542. fprintf(c7, " %11.3f", tmpe);
  543. }
  544. fprintf(c7, "\n");
  545. }
  546. /* calc. & write c8=s.d. edge by gp */
  547. if (choice->core[8]) {
  548. for (i = 0; i < ntype; i++) {
  549. stdve = 0;
  550. if (type_dens[i]) {
  551. tmpe = medge1[i] / type_dens[i];
  552. stdve = sum22e[i] / type_dens[i] - tmpe * tmpe;
  553. if (stdve > 0)
  554. stdve = sqrt(stdve);
  555. else
  556. stdve = 0;
  557. }
  558. fprintf(c8, " %11.3f", stdve);
  559. }
  560. fprintf(c8, "\n");
  561. }
  562. /* write c9=no. by size class */
  563. if (choice->core[9]) {
  564. for (i = 0; i < size_cl[0] - 1; i++)
  565. fprintf(c9c, " %11d", *(densityc + i));
  566. fprintf(c9c, "\n");
  567. for (i = 0; i < size_cl[0] - 1; i++)
  568. fprintf(c9e, " %11d", *(densitye + i));
  569. fprintf(c9e, "\n");
  570. }
  571. /* write c10=no. by size class by gp */
  572. if (choice->core2) {
  573. for (i = 0; i < ntype; i++) {
  574. fprintf(c10c, " Gp[%2d]", i + 1);
  575. for (j = 0; j < *size_cl - 1; j++)
  576. fprintf(c10c, " %11d", density1c[i][j]);
  577. fprintf(c10c, "\n");
  578. }
  579. for (i = 0; i < ntype; i++) {
  580. fprintf(c10e, " Gp[%2d]", i + 1);
  581. for (j = 0; j < *size_cl - 1; j++)
  582. fprintf(c10e, " %11d", density1e[i][j]);
  583. fprintf(c10e, "\n");
  584. }
  585. }
  586. return;
  587. }
  588. /************************************/
  589. /* COMPUTE THE SIZE MEASURES */
  590. /************************************/
  591. void df_size(PATCH * tmp, int type_coh, int *type_dens)
  592. {
  593. static int **density1 = NULL, *density = NULL, first = 1;
  594. static double msize = 0.0, *msize1 = NULL, sum2 = 0.0, *sum22;
  595. register int i;
  596. int size_coh;
  597. /* variables:
  598. IN:
  599. tmp = the next patch on the patch list
  600. type_coh = identif. no. for the gp for this patch
  601. type_dens[] = array of no. of patches by gp
  602. INTERNAL:
  603. msize = sum of patch sizes
  604. msize1[] = array of patch sizes by gp
  605. sum2 = sum of patch sizes squared
  606. sum22[] = array of patch sizes squared by gp
  607. density[] = array of no. of patches by size class
  608. */
  609. if (first) {
  610. density = (int *)G_calloc(25, sizeof(int));
  611. sum22 = (double *)G_calloc(25, sizeof(double));
  612. msize1 = (double *)G_calloc(25, sizeof(double));
  613. }
  614. /* if output is by size class (s5 & s6) determine which
  615. size class the current patch is in */
  616. if (choice->size[5] || choice->size[6]) {
  617. size_coh = index_coh(tmp->area, size_cl);
  618. density[size_coh]++;
  619. }
  620. msize += tmp->area;
  621. sum2 += tmp->area * tmp->area;
  622. if (type_coh >= 0) {
  623. msize1[type_coh] += tmp->area;
  624. sum22[type_coh] += tmp->area * tmp->area;
  625. }
  626. if (choice->size2) {
  627. if (first) {
  628. density1 = (int **)G_calloc(25, sizeof(int *));
  629. for (i = 0; i < 25; i++)
  630. density1[i] = (int *)G_calloc(25, sizeof(int));
  631. }
  632. if (type_coh >= 0 && size_coh >= 0)
  633. density1[type_coh][size_coh]++;
  634. }
  635. if (first)
  636. first = 0;
  637. if (!tmp->next) {
  638. save_size(sum2, msize, msize1, sum22, density, type_dens, density1);
  639. msize = sum2 = 0.0;
  640. G_free(density);
  641. G_free(msize1);
  642. G_free(sum22);
  643. if (density1) {
  644. for (i = 0; i < 25; i++)
  645. G_free(density1[i]);
  646. G_free(density1);
  647. }
  648. first = 1;
  649. }
  650. return;
  651. }
  652. /************************************/
  653. /* SAVE THE SIZE MEASURES */
  654. /************************************/
  655. void save_size(double sum2, double msize, double *msize1, double *sum22,
  656. int *density, int *type_dens, int **density1)
  657. {
  658. register int i, j;
  659. double tmp, stdv;
  660. /* variables:
  661. IN:
  662. sum2 = sum of patch sizes squared
  663. msize = sum of patch sizes
  664. msize1[] = array of sums of patch sizes by gp
  665. sum22[] = array of patch sizes squared by gp
  666. density[] = array of no. of patches by size class
  667. type_dens[] = array of no. of patches by gp
  668. INTERNAL:
  669. tmp = mean patch size (s1 & s3)
  670. stdv = st. dev. patch size (s2 & s4)
  671. GLOBAL:
  672. total_patches = tot. no. patches in sampling area (fm. trace.c)
  673. */
  674. /* calc. & write s1=mn. size, s2=s.d. size */
  675. if (choice->size[1] || choice->size[2]) {
  676. tmp = msize / total_patches;
  677. stdv = sum2 / total_patches - tmp * tmp;
  678. if (stdv > 0)
  679. stdv = sqrt(stdv);
  680. else
  681. stdv = 0.0;
  682. fprintf(s1_2, " %15.3f %15.3f\n", tmp, stdv);
  683. }
  684. /* calc. & write s3=mn. size by gp */
  685. if (choice->size[3]) {
  686. for (i = 0; i < ntype; i++) {
  687. if ((tmp = type_dens[i]))
  688. tmp = msize1[i] / tmp;
  689. fprintf(s3, " %11.3f", tmp);
  690. }
  691. fprintf(s3, "\n");
  692. }
  693. /* calc. & write s4=s.d. size by gp */
  694. if (choice->size[4]) {
  695. for (i = 0; i < ntype; i++) {
  696. stdv = 0.0;
  697. if (type_dens[i]) {
  698. tmp = msize1[i] / type_dens[i];
  699. stdv = sum22[i] / type_dens[i] - tmp * tmp;
  700. if (stdv > 0)
  701. stdv = sqrt(stdv);
  702. else
  703. stdv = 0.0;
  704. }
  705. fprintf(s4, " %11.3f", stdv);
  706. }
  707. fprintf(s4, "\n");
  708. }
  709. /* write s5=no. by size class */
  710. if (choice->size[5]) {
  711. for (i = 0; i < size_cl[0] - 1; i++)
  712. fprintf(s5, " %11d", *(density + i));
  713. fprintf(s5, "\n");
  714. }
  715. /* write s6=no. by size class by gp */
  716. if (choice->size2) {
  717. /* if(!(fp = fopen("r.le.out/s6.out", "a")))
  718. G_fatal_error("Can't write file s6.out; do you have write permission?\n");
  719. fprintf(fp, "%5d %5d\n", n_scale, n_unit); */
  720. for (i = 0; i < ntype; i++) {
  721. fprintf(s6, " Gp[%2d]", i + 1);
  722. for (j = 0; j < *size_cl - 1; j++)
  723. fprintf(s6, " %11d", density1[i][j]);
  724. fprintf(s6, "\n");
  725. }
  726. }
  727. /* calculate & write s7 (eff. mesh size)
  728. & s8 (deg. landsc. division) */
  729. if (choice->size[7] || choice->size[8])
  730. fprintf(s7_8, " %15.3f %15.3f\n", (1.0 / msize) * sum2,
  731. 1.0 - (sum2 / (msize * msize)));
  732. return;
  733. }
  734. /************************************/
  735. /* COMPUTE THE SHAPE MEASURES */
  736. /************************************/
  737. void df_shape(PATCH * tmp, int type_coh, int *type_dens)
  738. {
  739. static int *den1, *den2, *den3, **density1 = NULL, **density2 = NULL,
  740. **density3, new = 1;
  741. static double mshape = 0.0, *mshape1 = NULL, mshape_p = 0.0, *mshape1_p,
  742. *sqr11, *sqr21, *sqr31, mshape_r = 0.0, *mshape1_r, sq1 = 0.0,
  743. sq2 = 0.0, sq3 = 0.0;
  744. register int i;
  745. int shape_coh1 = 0, shape_coh2 = 0, shape_coh3 = 0;
  746. double shp1, shp2, shp3;
  747. /* variables:
  748. IN:
  749. tmp = the next patch on the patch list
  750. type_coh = identif. no. for the gp for this patch
  751. type_dens[] = array of no. of patches by gp
  752. INTERNAL:
  753. shp1 = CPA shape index
  754. shp2 = PA shape index
  755. shp3 = RCC shape index
  756. mshape = sum of CPA shape indices for all patches
  757. mshape_p = sum of PA shape indices for all patches
  758. mshape_r = sum of RCC shape indices for all patches
  759. mshape1[] = array of CPA indices by gp
  760. mshape1_p[] = array of PA indices by gp
  761. mshape1_r[] = array of RCC indices by gp
  762. sq1 = sum of CPA indices squared
  763. sq2 = sum of PA indices squared
  764. sq3 = sum of RCC indices squared
  765. sqr11[] = array of CPA indices squared by gp
  766. sqr21[] = array of PA indices squared by gp
  767. sqr31[] = array of RCC indices squared by gp
  768. den1[] = array of CPA indices by index class
  769. den2[] = array of PA indices by index class
  770. den3[] = array of RCC indices by index class
  771. density1[] = array of CPA indices by index class by gp
  772. density2[] = array of PA indices by index class by gp
  773. density3[] = array of RCC indices by index class by gp
  774. */
  775. shp1 = 0.282 * tmp->perim / sqrt(tmp->area); /* CPA method m2 */
  776. shp2 = tmp->perim / tmp->area; /* PA method m1 */
  777. shp3 = 2.0 * sqrt(tmp->area / PI) / tmp->long_axis; /* RCC method m3 */
  778. if (new) {
  779. mshape1 = (double *)G_calloc(25, sizeof(double));
  780. mshape1_p = (double *)G_calloc(25, sizeof(double));
  781. mshape1_r = (double *)G_calloc(25, sizeof(double));
  782. sqr11 = (double *)G_calloc(25, sizeof(double));
  783. sqr21 = (double *)G_calloc(25, sizeof(double));
  784. sqr31 = (double *)G_calloc(25, sizeof(double));
  785. den1 = (int *)G_calloc(25, sizeof(int));
  786. den2 = (int *)G_calloc(25, sizeof(int));
  787. den3 = (int *)G_calloc(25, sizeof(int));
  788. }
  789. mshape += shp1;
  790. mshape_p += shp2;
  791. mshape_r += shp3;
  792. sq1 += shp1 * shp1;
  793. sq2 += shp2 * shp2;
  794. sq3 += shp3 * shp3;
  795. if (type_coh >= 0) {
  796. mshape1[type_coh] += shp1;
  797. mshape1_p[type_coh] += shp2;
  798. mshape1_r[type_coh] += shp3;
  799. sqr11[type_coh] += shp1 * shp1;
  800. sqr21[type_coh] += shp2 * shp2;
  801. sqr31[type_coh] += shp3 * shp3;
  802. }
  803. /* if sh2=h5 or h6 */
  804. if (choice->shape[5] || choice->shape[6]) {
  805. /* if sh1=m1 */
  806. if (choice->Mx[1]) {
  807. if (0 <= (shape_coh2 = index_coh(shp2, shape_PA)))
  808. den2[shape_coh2]++;
  809. }
  810. /* if sh1=m2 */
  811. if (choice->Mx[2]) {
  812. if (0 <= (shape_coh1 = index_coh(shp1, shape_CPA)))
  813. den1[shape_coh1]++;
  814. }
  815. /* if sh1=m3 */
  816. if (choice->Mx[3]) {
  817. if (0 <= (shape_coh3 = index_coh(shp3, shape_RCC)))
  818. den3[shape_coh3]++;
  819. }
  820. }
  821. /* if sh2=h6 */
  822. if (choice->shape2) {
  823. if (new) {
  824. density1 = (int **)G_calloc(25, sizeof(int *));
  825. density2 = (int **)G_calloc(25, sizeof(int *));
  826. density3 = (int **)G_calloc(25, sizeof(int *));
  827. for (i = 0; i < 25; i++)
  828. if (!(density1[i] = (int *)G_calloc(25, sizeof(int))) ||
  829. !(density2[i] = (int *)G_calloc(25, sizeof(int))) ||
  830. !(density3[i] = (int *)G_calloc(25, sizeof(int))))
  831. G_fatal_error
  832. ("Failure to allocate memory for sh2, exit.\n");
  833. }
  834. if (type_coh >= 0) {
  835. if (shape_coh1 >= 0)
  836. density1[type_coh][shape_coh1]++;
  837. if (shape_coh2 >= 0)
  838. density2[type_coh][shape_coh2]++;
  839. if (shape_coh3 >= 0)
  840. density3[type_coh][shape_coh3]++;
  841. }
  842. }
  843. if (new)
  844. new = 0;
  845. if (!tmp->next) {/** if all the patches are done **/
  846. save_shape(sq1, sq2, sq3, sqr11, sqr21, sqr31,
  847. mshape, mshape_p, mshape_r, mshape1, mshape1_p,
  848. mshape1_r, type_dens, den1, den2, den3, density1,
  849. density2, density3);
  850. mshape = sq1 = sq2 = sq3 = mshape_p = mshape_r = 0;
  851. G_free(mshape1);
  852. G_free(mshape1_p);
  853. G_free(mshape1_r);
  854. G_free(sqr11);
  855. G_free(sqr21);
  856. G_free(sqr31);
  857. G_free(den1);
  858. G_free(den2);
  859. G_free(den3);
  860. if (density1) {
  861. for (i = 0; i < 25; i++) {
  862. G_free(density1[i]);
  863. G_free(density2[i]);
  864. G_free(density3[i]);
  865. }
  866. G_free(density1);
  867. G_free(density2);
  868. G_free(density3);
  869. }
  870. new = 1;
  871. }
  872. return;
  873. }
  874. /************************************/
  875. /* SAVE THE SHAPE MEASURES */
  876. /************************************/
  877. void save_shape(double sq1, double sq2, double sq3, double *sqr11,
  878. double *sqr21, double *sqr31, double mshape, double mshape_p,
  879. double mshape_r, double *mshape1, double *mshape1_p,
  880. double *mshape1_r, int *type_dens, int *den1, int *den2,
  881. int *den3, int **density1, int **density2, int **density3)
  882. {
  883. register int i, j;
  884. double tmp, stdv;
  885. /* variables:
  886. IN:
  887. sq1 = sum of CPA indices squared
  888. sq2 = sum of PA indices squared
  889. sq3 = sum of RCC indices squared
  890. sqr11[] = array of CPA indices squared by gp
  891. sqr21[] = array of PA indices squared by gp
  892. sqr31[] = array of RCC indices squared by gp
  893. mshape = sum of CPA shape indices for all patches
  894. mshape_p = sum of PA shape indices for all patches
  895. mshape_r = sum of RCC shape indices for all patches
  896. mshape1[] = array of CPA indices by gp
  897. mshape1_p[] = array of PA indices by gp
  898. mshape1_r[] = array of RCC indices by gp
  899. type_dens[] = array of no. of patches by gp ?
  900. den1[] = array of CPA indices by index class
  901. den2[] = array of PA indices by index class
  902. den3[] = array of RCC indices by index class
  903. density1[] = array of CPA indices by index class by gp
  904. density2[] = array of PA indices by index class by gp
  905. density3[] = array of RCC indices by index class by gp
  906. INTERNAL:
  907. tmp = mean shape index (h1)
  908. stdv = st. dev. shape index (h2)
  909. GLOBAL:
  910. total_patches = tot. no. patches in sampling area (fm. trace.c)
  911. */
  912. /*CALC. & WRITE h1-h5 FOR CPA INDEX (m2) */
  913. /* calc. & write h1=mn. shape, h2=s.d. shape for CPA index (m2) */
  914. if ((choice->shape[1] || choice->shape[1]) && choice->Mx[2]) {
  915. tmp = mshape / total_patches;
  916. stdv = sq1 / total_patches - tmp * tmp;
  917. if (stdv > 0)
  918. stdv = sqrt(stdv);
  919. else
  920. stdv = 0.0;
  921. fprintf(h1_2, " %15.3f %15.3f\n", tmp, stdv);
  922. }
  923. /* calc. & write h3=mn. shape by gp for CPA index (m2) */
  924. if (choice->shape[3] && choice->Mx[2]) {
  925. for (i = 0; i < ntype; i++) {
  926. if ((tmp = type_dens[i]))
  927. tmp = mshape1[i] / tmp;
  928. fprintf(h3, " %10.3f", tmp);
  929. }
  930. fprintf(h3, "\n");
  931. }
  932. /* calc. & write h4=s.d. shape by gp for CPA index (m2) */
  933. if (choice->shape[4] && choice->Mx[2]) {
  934. for (i = 0; i < ntype; i++) {
  935. stdv = 0.0;
  936. if (type_dens[i] > 1) {
  937. tmp = mshape1[i] / type_dens[i];
  938. stdv = sqr11[i] / type_dens[i] - tmp * tmp;
  939. if (stdv > 0)
  940. stdv = sqrt(stdv);
  941. else
  942. stdv = 0.0;
  943. }
  944. fprintf(h4, " %10.3f", stdv);
  945. }
  946. fprintf(h4, "\n");
  947. }
  948. /* write h5=no. by shape index class for CPA index (m2) */
  949. if (choice->shape[5] && choice->Mx[2]) {
  950. for (j = 0; j < *shape_CPA - 1; j++)
  951. fprintf(h5, " %10d", den1[j]);
  952. fprintf(h5, "\n");
  953. }
  954. /*CALC. & WRITE h1-h5 FOR PA INDEX (m1) */
  955. /* calc. & write h1=mn. shape, h2=s.d. shape for PA index (m1) */
  956. if ((choice->shape[1] || choice->shape[2]) && choice->Mx[1]) {
  957. tmp = mshape_p / total_patches;
  958. stdv = sq2 / total_patches - tmp * tmp;
  959. if (stdv > 0)
  960. stdv = sqrt(stdv);
  961. else
  962. stdv = 0.0;
  963. fprintf(h1_2, " %15.3f %15.3f\n", tmp, stdv);
  964. }
  965. /* calc. & write h3=mn. shape by gp for PA index (m1) */
  966. if (choice->shape[3] && choice->Mx[1]) {
  967. for (i = 0; i < ntype; i++) {
  968. if ((tmp = type_dens[i]))
  969. tmp = mshape1_p[i] / tmp;
  970. fprintf(h3, " %10.3f", tmp);
  971. }
  972. fprintf(h3, "\n");
  973. }
  974. /* calc. & write h4=s.d. shape by gp for PA index (m1) */
  975. if (choice->shape[4] && choice->Mx[1]) {
  976. for (i = 0; i < ntype; i++) {
  977. stdv = 0.0;
  978. if (type_dens[i] > 1) {
  979. tmp = mshape1_p[i] / type_dens[i];
  980. stdv = sqr21[i] / type_dens[i] - tmp * tmp;
  981. if (stdv > 0)
  982. stdv = sqrt(stdv);
  983. else
  984. stdv = 0;
  985. }
  986. fprintf(h4, " %10.3f", stdv);
  987. }
  988. fprintf(h4, "\n");
  989. }
  990. /* write h5=no. by shape index class for PA index (m1) */
  991. if (choice->shape[5] && choice->Mx[1]) {
  992. for (j = 0; j < *shape_PA - 1; j++)
  993. fprintf(h5, " %10d", den2[j]);
  994. fprintf(h5, "\n");
  995. }
  996. /*CALC. & WRITE h1-h5 FOR RCC INDEX (m3) */
  997. /* calc. & write h1=mn. shape, h2=s.d. shape for RCC index (m3) */
  998. if ((choice->shape[1] || choice->shape[2]) && choice->Mx[3]) {
  999. tmp = mshape_r / total_patches;
  1000. stdv = sq3 / total_patches - tmp * tmp;
  1001. if (stdv > 0)
  1002. stdv = sqrt(stdv);
  1003. else
  1004. stdv = 0.0;
  1005. fprintf(h1_2, " %15.3f %15.3f\n", tmp, stdv);
  1006. }
  1007. /* calc. & write h3=mn. shape by gp for RCC index (m3) */
  1008. if (choice->shape[3] && choice->Mx[3]) {
  1009. for (i = 0; i < ntype; i++) {
  1010. if ((tmp = type_dens[i]))
  1011. tmp = mshape1_r[i] / tmp;
  1012. fprintf(h3, " %10.3f", tmp);
  1013. }
  1014. fprintf(h3, "\n");
  1015. }
  1016. /* calc. & write h4=s.d. shape by gp for RCC index (m3) */
  1017. if (choice->shape[4] && choice->Mx[3]) {
  1018. for (i = 0; i < ntype; i++) {
  1019. stdv = 0;
  1020. if (type_dens[i] > 1) {
  1021. tmp = mshape1_r[i] / type_dens[i];
  1022. stdv = sqr31[i] / type_dens[i] - tmp * tmp;
  1023. if (stdv > 0)
  1024. stdv = sqrt(stdv);
  1025. else
  1026. stdv = 0.0;
  1027. }
  1028. fprintf(h4, " %10.3f", stdv);
  1029. }
  1030. fprintf(h4, "\n");
  1031. }
  1032. /* write h5=no. by shape index class for RCC index (m3) */
  1033. if (choice->shape[5] && choice->Mx[3]) {
  1034. for (j = 0; j < *shape_RCC - 1; j++)
  1035. fprintf(h5, " %10d", den3[j]);
  1036. fprintf(h5, "\n");
  1037. }
  1038. /* CALC. & WRITE h6 = NO. IN EA. SHAPE INDEX CLASS BY GP */
  1039. if (choice->shape[6]) {
  1040. if (density1) {
  1041. if (choice->Mx[1]) {
  1042. for (i = 0; i < ntype; i++) {
  1043. fprintf(h6, " Gp[%2d]", i + 1);
  1044. for (j = 0; j < *shape_PA - 1; j++)
  1045. fprintf(h6, " %10d", density2[i][j]);
  1046. fprintf(h6, "\n");
  1047. }
  1048. }
  1049. if (choice->Mx[2]) {
  1050. for (i = 0; i < ntype; i++) {
  1051. fprintf(h6, " Gp[%2d]", i + 1);
  1052. for (j = 0; j < *shape_CPA - 1; j++)
  1053. fprintf(h6, " %10d", density1[i][j]);
  1054. fprintf(h6, "\n");
  1055. }
  1056. }
  1057. if (choice->Mx[3]) {
  1058. for (i = 0; i < ntype; i++) {
  1059. fprintf(h6, " Gp[%2d]", i + 1);
  1060. for (j = 0; j < *shape_RCC - 1; j++)
  1061. fprintf(h6, " %10d", density3[i][j]);
  1062. fprintf(h6, "\n");
  1063. }
  1064. }
  1065. }
  1066. }
  1067. return;
  1068. }
  1069. /****************************************************/
  1070. /* COMPUTE AND SAVE BOUNDARY COMPLEXITY MEASURES */
  1071. /****************************************************/
  1072. void df_boundary(PATCH * tmp)
  1073. {
  1074. static double sumomega = 0.0, sumomega2 = 0.0;
  1075. static int sumtwist = 0, sumtwist2 = 0;
  1076. double meantwist = 0.0, stdvtwist = 0.0, meanomega = 0.0, stdvomega = 0.0;
  1077. /* variables:
  1078. IN:
  1079. tmp = the next patch in the patch list
  1080. INTERNAL:
  1081. meantwist = mean twist number (n1)
  1082. stdvtwist = st. dev. twist number (n2)
  1083. meanomega = mean omega index (n3)
  1084. stdvomega = st. dev. omega index (n4)
  1085. GLOBAL:
  1086. total_patches = tot. no. patches in sampling area (fm. trace.c)
  1087. */
  1088. sumtwist += tmp->twist;
  1089. sumtwist2 += tmp->twist * tmp->twist;
  1090. sumomega += tmp->omega;
  1091. sumomega2 += tmp->omega * tmp->omega;
  1092. if (!tmp->next) {
  1093. meantwist = (double)sumtwist / total_patches;
  1094. stdvtwist = (double)sumtwist2 / total_patches - meantwist * meantwist;
  1095. if (stdvtwist > 0.0)
  1096. stdvtwist = sqrt(stdvtwist);
  1097. else
  1098. stdvtwist = 0.0;
  1099. meanomega = (double)sumomega / total_patches;
  1100. stdvomega = (double)sumomega2 / total_patches - meanomega * meanomega;
  1101. if (stdvomega > 0.0)
  1102. stdvomega = sqrt(stdvomega);
  1103. else
  1104. stdvomega = 0.0;
  1105. /* write n1=mn. twist, n2=s.d. twist, n3=mn. omega,
  1106. n4=s.d. omega */
  1107. if (choice->boundary[1] || choice->boundary[2] ||
  1108. choice->boundary[3] || choice->boundary[4])
  1109. fprintf(n1_4, " %15.3f %15.3f %15.3f %15.3f\n",
  1110. meantwist, stdvtwist, meanomega, stdvomega);
  1111. meantwist = stdvtwist = meanomega = stdvomega = 0.0;
  1112. }
  1113. return;
  1114. }
  1115. /*************************************/
  1116. /* COMPUTE & SAVE PERIMETER MEASURES */
  1117. /*************************************/
  1118. void df_perim(PATCH * tmp, int type_coh, int *type_dens)
  1119. {
  1120. static double perim = 0.0, *perim1, sum2 = 0.0, *sum21, first = 1.0;
  1121. register int i;
  1122. double mean, stdv;
  1123. if (first) {
  1124. perim1 = (double *)G_calloc(25, sizeof(double));
  1125. sum21 = (double *)G_calloc(25, sizeof(double));
  1126. first = 0.0;
  1127. }
  1128. /* variables:
  1129. IN:
  1130. tmp = the next patch in the patch list
  1131. type_coh = identif. no. of the gp for this patch
  1132. type_dens[] = array of no. of patches by gp
  1133. INTERNAL:
  1134. perim = sum of perimeters (p1)
  1135. sum2 = sum of perimeters squared
  1136. perim1[] = array of sum of perims by gp (pp4)
  1137. sum21[] = array of sum of perims squared by gp
  1138. mean = mean perim. (p2)
  1139. stdv = st. dev. perim. (p3)
  1140. GLOBAL:
  1141. total_patches = tot. no. patches in sampling area (fm. trace.c)
  1142. */
  1143. perim += tmp->perim;
  1144. sum2 += tmp->perim * tmp->perim;
  1145. if (type_coh >= 0) {
  1146. perim1[type_coh] += tmp->perim;
  1147. sum21[type_coh] += tmp->perim * tmp->perim;
  1148. }
  1149. if (!tmp->next) {/** save the perimeter measures **/
  1150. mean = perim / total_patches;
  1151. stdv = sum2 / total_patches - mean * mean;
  1152. if (stdv > 0)
  1153. stdv = sqrt(stdv);
  1154. else
  1155. stdv = 0.0;
  1156. /* write p1=sum per., p2=mn. per.,p3=s.d. per. */
  1157. if (choice->perim[1] || choice->perim[2] || choice->perim[3])
  1158. fprintf(p1_3, " %15.3f %15.3f %15.3f\n", perim, mean, stdv);
  1159. /* write p4=sum per. by gp */
  1160. if (choice->perim[4]) {
  1161. for (i = 0; i < ntype; i++)
  1162. fprintf(p4, " %11.3f", perim1[i]);
  1163. fputs("\n", p4);
  1164. }
  1165. /* write p5=mn. per. by gp */
  1166. if (choice->perim[5]) {
  1167. for (i = 0; i < ntype; i++) {
  1168. if (type_dens[i])
  1169. mean = perim1[i] / type_dens[i];
  1170. else
  1171. mean = 0.0;
  1172. fprintf(p5, " %11.3f", mean);
  1173. }
  1174. fputs("\n", p5);
  1175. }
  1176. /* calc. & write p6=s.d. per. by gp */
  1177. if (choice->perim[6]) {
  1178. for (i = 0; i < ntype; i++) {
  1179. stdv = 0;
  1180. if (type_dens[i]) {
  1181. mean = perim1[i] / type_dens[i];
  1182. stdv = sum21[i] / type_dens[i] - mean * mean;
  1183. if (stdv > 0)
  1184. stdv = sqrt(stdv);
  1185. else
  1186. stdv = 0.0;
  1187. }
  1188. fprintf(p6, " %11.3f", stdv);
  1189. }
  1190. fputs("\n", p6);
  1191. }
  1192. G_free(perim1);
  1193. G_free(sum21);
  1194. first = 1;
  1195. perim = sum2 = 0;
  1196. }
  1197. return;
  1198. }
  1199. /************************************/
  1200. /* RUN THE MOVING WINDOW PATCH */
  1201. /* MEASURES */
  1202. /************************************/
  1203. void mv_patch(PATCH * patch_list, double **value, int index)
  1204. {
  1205. PATCH *tmp = patch_list;
  1206. /* Variables:
  1207. IN:
  1208. patch_list = the list of patches
  1209. value = buffer containing a full row of the results of the moving
  1210. window if a moving window map, otherwise 0
  1211. index = number of the column in the moving window
  1212. INTERNAL:
  1213. *tmp = pointer to the list of patches
  1214. */
  1215. if (!total_patches)
  1216. return;
  1217. while (tmp) {
  1218. if (choice->att[0])
  1219. m_att(tmp, value, index);
  1220. if (choice->size[0])
  1221. m_size(tmp, value, index);
  1222. if (choice->core[0])
  1223. m_core(tmp, value, index);
  1224. if (choice->shape[0] && choice->Mx[1])
  1225. m_shape(tmp, 1, value, index);
  1226. if (choice->shape[0] && choice->Mx[2])
  1227. m_shape(tmp, 2, value, index);
  1228. if (choice->shape[0] && choice->Mx[3])
  1229. m_shape(tmp, 3, value, index);
  1230. if (choice->boundary)
  1231. m_boundary(tmp, value, index);
  1232. if (choice->perim[0])
  1233. m_perim(tmp, value, index);
  1234. tmp = tmp->next;
  1235. }
  1236. total_patches = 0;
  1237. return;
  1238. }
  1239. /************************************/
  1240. /* FOR DF_PATCH PROGRAM (NOT MOVING */
  1241. /* WINDOW) DETERMINE WHICH GROUP */
  1242. /* ATT BELONGS TO */
  1243. /************************************/
  1244. int recl_coh(double att)
  1245. {
  1246. register int i;
  1247. extern int ntype;
  1248. extern float **recl_tb;
  1249. for (i = 0; i < ntype; i++) {
  1250. if (in_group(att, recl_tb[i], i)) {
  1251. return i;
  1252. }
  1253. }
  1254. return -999;
  1255. }
  1256. /************************************/
  1257. /* DETERMINE WHETHER ATT BELONGS TO */
  1258. /* THE CHOSEN rTH GP IN THE RECLASS */
  1259. /* TABLE */
  1260. /************************************/
  1261. int in_group(double att, float *group, int r)
  1262. {
  1263. register int i;
  1264. /*Variables
  1265. EXTERNAL
  1266. recl_count = an array containing the number of elements in each
  1267. row of the reclass table
  1268. IN
  1269. att = the attribute value
  1270. group = an array containing the rth row of the reclass table
  1271. r = the chosen row of the reclass table
  1272. INTERNAL
  1273. i = index
  1274. */
  1275. /* For each element i in the rth row of the reclass
  1276. table. When this program is called by the
  1277. moving window programs r is always 0 */
  1278. for (i = 1; i < recl_count[r]; i++) {
  1279. /* if the i element of the rth row of the reclass
  1280. table is -999, this indicates "thru" in the
  1281. reclass table, so check to see if the attribute
  1282. lies in the range expressed in the "thru"
  1283. statement */
  1284. if (-999 == *(group + i)) {
  1285. if (*(group + i) &&
  1286. *(group + i - 1) <= att && att <= *(group + i + 1))
  1287. return 1;
  1288. else
  1289. i++;
  1290. }
  1291. /* if the rth row of the reclass table does not
  1292. contain a "thru" statement, then just check whether
  1293. the i element of the rth row of the reclass table
  1294. is equal to the attribute */
  1295. else if ((double)*(group + i) == att) {
  1296. return 1;
  1297. }
  1298. }
  1299. return 0;
  1300. }
  1301. /************************************/
  1302. /* DETERMINE WHICH INDEX CLASS ATT */
  1303. /* BELONGS TO */
  1304. /************************************/
  1305. int index_coh(double att, float *group)
  1306. {
  1307. register int i;
  1308. /*
  1309. Variables:
  1310. IN
  1311. att = the attribute to be checked
  1312. group = an array of index class limits (e.g., size classes)
  1313. */
  1314. for (i = (int)*group - 1; i >= 1; i--) {
  1315. if ((double)*(group + i) <= att)
  1316. return i - 1;
  1317. }
  1318. return -999;
  1319. }
  1320. /************************************/
  1321. /* MOVING WINDOW ATTRIBUTE MEASURES */
  1322. /************************************/
  1323. void m_att(PATCH * tmp, double **value, int index)
  1324. {
  1325. static double sum1 = 0.0, sum12 = 0.0, sum2 = 0.0, sum22 = 0.0, sum32 =
  1326. 0.0, total1 = 0.0, total2 = 0.0, area = 0.0, area2 = 0.0;
  1327. static int density = 0;
  1328. double mean, stdv;
  1329. /* choice->att 1 = mean pixel attrib. (a1)
  1330. 2 = st. dev. pixel attrib. (a2)
  1331. 3 = mean patch attrib. (a3)
  1332. 4 = st. dev. patch attrib. (a4)
  1333. 5 = cover in gp 1 (a5)
  1334. 6 = density in gp 1 (a6)
  1335. 7 = total density (a7)
  1336. 8 = eff. mesh no. (a8)
  1337. Variables:
  1338. IN:
  1339. tmp = the list of patches
  1340. value = buffer containing a full row of the results of the moving
  1341. window if a moving window map, otherwise 0
  1342. index = number of the column in the moving window
  1343. INTERNAL:
  1344. sum1 = sum of patch area x patch attrib.
  1345. sum2 = sum of patch attributes
  1346. sum12 = sum of patch area x patch attrib. squared
  1347. sum22 = sum of patch attributes squared
  1348. sum32 = sum of patch areas in gp 1
  1349. total1 = sum of patch areas for a1 and a2
  1350. total2 = sum of patch areas for a5
  1351. area = sum of patch areas for a8
  1352. area2 = sum of patch areas squared
  1353. density = no. of patches in gp 1
  1354. value = output value for selected att measure
  1355. GLOBAL:
  1356. total_patches = tot. no. patches in sampling area (fm. trace.c)
  1357. */
  1358. if (choice->att[1] || choice->att[2]) {
  1359. sum1 += tmp->area * tmp->att;
  1360. total1 += tmp->area;
  1361. if (choice->att[2])
  1362. sum12 += tmp->area * tmp->att * tmp->att;
  1363. }
  1364. if (choice->att[3] || choice->att[4]) {
  1365. sum2 += tmp->att;
  1366. if (choice->att[4])
  1367. sum22 += tmp->att * tmp->att;
  1368. }
  1369. if (choice->att[5]) {
  1370. total2 += tmp->area;
  1371. if (in_group(tmp->att, recl_tb[0], 0)) {
  1372. sum32 += tmp->area;
  1373. }
  1374. }
  1375. if (choice->att[6]) {
  1376. if (in_group(tmp->att, recl_tb[0], 0))
  1377. density++;
  1378. }
  1379. if (choice->att[8]) {
  1380. area += tmp->area;
  1381. area2 += tmp->area * tmp->area;
  1382. }
  1383. if (!tmp->next) {
  1384. /* calc. a1 = mn. pixel attrib. */
  1385. if (choice->att[1] && total1) {
  1386. value[index][0] = sum1 / total1;
  1387. }
  1388. /* calc. a2 = s.d. pixel attrib. */
  1389. if (choice->att[2] && total1) {
  1390. mean = sum1 / total1;
  1391. stdv = sum12 / total1 - mean * mean;
  1392. if (stdv > 0)
  1393. value[index][1] = sqrt(stdv);
  1394. }
  1395. /* calc. a3 = mn. patch attrib. */
  1396. if (choice->att[3] && total_patches) {
  1397. value[index][2] = sum2 / total_patches;
  1398. }
  1399. /* calc. a4 = s.d. patch attrib. */
  1400. if (choice->att[4] && total_patches) {
  1401. mean = sum2 / total_patches;
  1402. stdv = sum22 / total_patches - mean * mean;
  1403. if (stdv > 0)
  1404. value[index][3] = sqrt(stdv);
  1405. }
  1406. /* calc. a5 = cover in gp 1 */
  1407. if (choice->att[5] && total2) {
  1408. value[index][4] = sum32 / total2;
  1409. }
  1410. /* calc. a6 = density in gp 1 */
  1411. if (choice->att[6]) {
  1412. value[index][5] = density;
  1413. }
  1414. /* calc. a7 = total density */
  1415. if (choice->att[7])
  1416. value[index][6] = total_patches;
  1417. /* calc. a8 = eff. mesh no. */
  1418. if (choice->att[8]) {
  1419. value[index][36] = (area * area) / area2;
  1420. }
  1421. total1 = total2 = sum1 = sum12 = 0.0;
  1422. sum2 = sum22 = sum32 = area = area2 = 0.0;
  1423. density = 0;
  1424. }
  1425. return;
  1426. }
  1427. /************************************/
  1428. /* MOVING WINDOW SIZE MEASURES */
  1429. /************************************/
  1430. void m_size(PATCH * tmp, double **value, int index)
  1431. {
  1432. static double sum1 = 0.0, sum12 = 0.0, sum2 = 0.0, sum22 = 0.0;
  1433. static int density1 = 0, density2 = 0, density3 = 0;
  1434. double mean, stdv;
  1435. /* choice->size == 1 - mean patch size (s1)
  1436. 2 - st. dev. patch size (s2)
  1437. 3 - mean patch size by gp 1 (s3)
  1438. 4 - st. dev. patch size by gp 1 (s4)
  1439. 5 - no. by size class 1 (s5)
  1440. 6 - no. by size class 1 by gp 1 (s6)
  1441. Variables:
  1442. IN:
  1443. tmp = the list of patches
  1444. value = buffer containing a full row of the results of the moving
  1445. window if a moving window map, otherwise 0
  1446. index = number of the column in the moving window
  1447. INTERNAL:
  1448. sum1 = sum of patch sizes
  1449. sum12 = sum of patch sizes squared
  1450. sum2 = sum of patch sizes in gp 1
  1451. sum22 = sum of patch sizes in gp 1 squared
  1452. density1 = no. of patches in gp 1
  1453. density2 = no. of patches in size class 1
  1454. density3 = no. of patches in gp 1 and size class 1
  1455. */
  1456. if (choice->size[1] || choice->size[2] ||
  1457. choice->size[7] || choice->size[8]) {
  1458. sum1 += tmp->area;
  1459. if (choice->size[2] || choice->size[7] || choice->size[8])
  1460. sum12 += tmp->area * tmp->area;
  1461. }
  1462. if (choice->size[3] || choice->size[4]) {
  1463. if (in_group(tmp->att, recl_tb[0], 0)) {
  1464. density1++;
  1465. sum2 += tmp->area;
  1466. if (choice->size[4])
  1467. sum22 += tmp->area * tmp->area;
  1468. }
  1469. }
  1470. if (choice->size[5] && tmp->area < size_cl[2]) {
  1471. density2++;
  1472. }
  1473. if (choice->size[6] && tmp->area < size_cl[2] &&
  1474. in_group(tmp->att, recl_tb[0], 0)) {
  1475. density3++;
  1476. }
  1477. if (!tmp->next) {
  1478. /* calc. s1 = mn. patch size */
  1479. if (choice->size[1] && total_patches) {
  1480. value[index][7] = sum1 / total_patches;
  1481. }
  1482. /* calc. s2 = s.d. patch size */
  1483. if (choice->size[2] && total_patches) {
  1484. mean = sum1 / total_patches;
  1485. stdv = sum12 / total_patches - mean * mean;
  1486. if (stdv > 0)
  1487. value[index][8] = sqrt(stdv);
  1488. }
  1489. /* calc. s3 = mn. patch size by gp 1 */
  1490. if (choice->size[3] && density1) {
  1491. value[index][9] = sum2 / density1;
  1492. }
  1493. /* calc. s4 = s.d. patch size by gp 1 */
  1494. if (choice->size[4] && density1 > 1) {
  1495. mean = sum2 / density1;
  1496. stdv = sum22 / density1 - mean * mean;
  1497. if (stdv > 0)
  1498. value[index][10] = sqrt(stdv);
  1499. }
  1500. /* calc. s5 = no. by size class 1 */
  1501. if (choice->size[5]) {
  1502. value[index][11] = density2;
  1503. }
  1504. /* calc. s6 = no. by size class 1 by gp 1 */
  1505. if (choice->size[6]) {
  1506. value[index][12] = density3;
  1507. }
  1508. /* calc. s7 = eff. mesh size */
  1509. if (choice->size[7]) {
  1510. value[index][37] = (1.0 / sum1) * sum12;
  1511. }
  1512. /* calc. s8 = deg. landsc. division */
  1513. if (choice->size[8]) {
  1514. value[index][38] = 1.0 - (sum12 / (sum1 * sum1));
  1515. }
  1516. density1 = density2 = density3 = 0;
  1517. sum1 = sum12 = sum2 = sum22 = 0.0;
  1518. }
  1519. return;
  1520. }
  1521. /************************************/
  1522. /* MOVING WINDOW CORE MEASURES */
  1523. /************************************/
  1524. void m_core(PATCH * tmp, double **value, int index)
  1525. {
  1526. static double sum1c = 0.0, sum1e = 0.0, sum2c = 0.0, sum2e = 0.0,
  1527. sum12c = 0.0, sum12e = 0.0, sum22c = 0.0, sum22e = 0.0;
  1528. static int density1c = 0, density1e = 0, density2c = 0, density2e = 0,
  1529. density3c = 0, density3e = 0;
  1530. double meanc, stdvc, meane, stdve;
  1531. /* choice->core == 1 - mean core size (c1)
  1532. 2 - st. dev. core size (c2)
  1533. 3 - mean edge size (c3)
  1534. 4 - st. dev. edge size (c4)
  1535. 5 - mean core size by gp (c5)
  1536. 6 - st. dev. core size by gp (c6)
  1537. 7 - mean edge size by gp (c7)
  1538. 8 - st. dev. edge size by gp (c8)
  1539. 9 - no. by size class (c9)
  1540. 10 - no. by size class by gp (c10)
  1541. variables:
  1542. IN:
  1543. tmp = the list of patches
  1544. value = buffer containing a full row of the results of the moving
  1545. window if a moving window map, otherwise 0
  1546. index = number of the column in the moving window
  1547. INTERNAL:
  1548. sum1c = sum of core sizes
  1549. sum12c = sum of core sizes squared
  1550. sum1e = sum of edge sizes
  1551. sum12e = sum of edge sizes squared
  1552. sum2c = sum of core sizes in gp 1
  1553. sum22c = sum of core sizes in gp 1 squared
  1554. sum2e = sum of edge sizes in gp 1
  1555. sum22e = sum of edge sizes in gp 1 squared
  1556. density1c = no. of cores in gp 1
  1557. density1e = no. of edges in gp 1
  1558. density2c = no. of cores in size class 1
  1559. density2e = no. of edges in size class 1
  1560. density3c = no. of cores in size class 1 and gp 1
  1561. density3e = no. of edges in size class 1 and gp 1
  1562. meanc = mean core size
  1563. stdvc = standard deviation of mean core size
  1564. meane = mean edge size
  1565. stdve = standard deviation of mean edge size
  1566. */
  1567. if (choice->core[1] || choice->core[2]) {
  1568. sum1c += tmp->core;
  1569. if (choice->core[2])
  1570. sum12c += tmp->core * tmp->core;
  1571. }
  1572. if (choice->core[3] || choice->core[4]) {
  1573. sum1e += (int)tmp->edge;
  1574. if (choice->core[4])
  1575. sum12e += tmp->edge * tmp->edge;
  1576. }
  1577. if (choice->core[5] || choice->core[6] ||
  1578. choice->core[7] || choice->core[8])
  1579. if (in_group(tmp->att, recl_tb[0], 0)) {
  1580. if (choice->core[5] || choice->core[6]) {
  1581. density1c++;
  1582. sum2c += tmp->core;
  1583. if (choice->core[6])
  1584. sum22c += tmp->core * tmp->core;
  1585. }
  1586. if (choice->core[7] || choice->core[8]) {
  1587. density1e++;
  1588. sum2e += tmp->edge;
  1589. if (choice->core[8])
  1590. sum22e += tmp->edge * tmp->edge;
  1591. }
  1592. }
  1593. if (choice->core[9]) {
  1594. if (tmp->core < size_cl[2])
  1595. density2c++;
  1596. if (tmp->edge < size_cl[2])
  1597. density2e++;
  1598. }
  1599. if (choice->core[10]) {
  1600. if (tmp->core < size_cl[2] && in_group(tmp->att, recl_tb[0], 0))
  1601. density3c++;
  1602. if (tmp->edge < size_cl[2] && in_group(tmp->att, recl_tb[0], 0))
  1603. density3e++;
  1604. }
  1605. if (!tmp->next) {
  1606. /* calc. c1 = mn. core size */
  1607. if (choice->core[1] && total_patches) {
  1608. value[index][13] = sum1c / total_patches;
  1609. }
  1610. /* calc. c2 = s.d. core size */
  1611. if (choice->core[2] && total_patches) {
  1612. meanc = sum1c / total_patches;
  1613. stdvc = sum12c / total_patches - meanc * meanc;
  1614. if (stdvc > 0)
  1615. value[index][14] = sqrt(stdvc);
  1616. }
  1617. /* calc. c3 = mn. edge size */
  1618. if (choice->core[3] && total_patches) {
  1619. value[index][15] = sum1e / total_patches;
  1620. }
  1621. /* calc. c4 = s.d. edge size */
  1622. if (choice->core[4] && total_patches) {
  1623. meane = sum1e / total_patches;
  1624. stdve = sum12e / total_patches - meane * meane;
  1625. if (stdve > 0)
  1626. value[index][16] = sqrt(stdve);
  1627. }
  1628. /* calc. c5 = mn. core size by gp 1 */
  1629. if (choice->core[5] && density1c) {
  1630. value[index][17] = sum2c / density1c;
  1631. }
  1632. /* calc. c6 = s.d. core size by gp 1 */
  1633. if (choice->core[6] && density1c > 1) {
  1634. meanc = sum2c / density1c;
  1635. stdvc = sum22c / density1c - meanc * meanc;
  1636. if (stdvc > 0)
  1637. value[index][18] = sqrt(stdvc);
  1638. }
  1639. /* calc. c7 = mn. edge size by gp 1 */
  1640. if (choice->core[7] && density1e) {
  1641. value[index][19] = sum2e / density1e;
  1642. }
  1643. /* calc. c8 = s.d. edge size by gp 1 */
  1644. if (choice->core[8] && density1e > 1) {
  1645. meane = sum2e / density1e;
  1646. stdve = sum22e / density1e - meane * meane;
  1647. if (stdve > 0)
  1648. value[index][20] = sqrt(stdve);
  1649. }
  1650. /* calc. c9 = no. by size class 1 */
  1651. if (choice->core[9]) {
  1652. value[index][21] = density2c;
  1653. }
  1654. /* calc. c10 = no. by size class 1 by gp 1 */
  1655. if (choice->core[10]) {
  1656. value[index][22] = density3c;
  1657. }
  1658. density1c = density1e = 0;
  1659. density2c = density2e = 0;
  1660. density3c = density3e = 0;
  1661. sum1c = sum1e = sum2c = sum2e = 0.0;
  1662. sum12c = sum12e = sum22c = sum22e = 0.0;
  1663. }
  1664. return;
  1665. }
  1666. /************************************/
  1667. /* MOVING WINDOW SHAPE MEASURES */
  1668. /************************************/
  1669. void m_shape(PATCH * tmp, int way, double **value, int index)
  1670. {
  1671. static double sum1 = 0, sum12 = 0, sum2 = 0, sum22 = 0;
  1672. static int density1 = 0, density2 = 0, density3 = 0;
  1673. double mean, shp, stdv;
  1674. /* choice->shape 1 = mean patch shape (h1)
  1675. 2 = st.dev. patch shape (h2)
  1676. 3 = mean patch shape by gp 1 (h3)
  1677. 4 = st.dev. shape by gp 1 (h4)
  1678. 5 = number by shape class 1 (h5)
  1679. 6 = number by shape class 1 by gp 1 (h6)
  1680. Variables:
  1681. IN:
  1682. tmp = the list of patches
  1683. way = shape index choice (see shp)
  1684. value = buffer containing a full row of the results of the moving
  1685. window if a moving window map, otherwise 0
  1686. index = number of the column in the moving window
  1687. INTERNAL:
  1688. shp = P/A (way=1)
  1689. CPA (way=2)
  1690. RCC (way=3)
  1691. sum1 = sum of shape indices
  1692. sum12 = sum of shape indices squared
  1693. sum2 = sum of shape indices in gp 1
  1694. sum22 = sum of shape indices in gp 1 squared
  1695. density1 = no. of patches in gp 1
  1696. density2 = no. of patches in shape class 1
  1697. density3 = no. of patches in shape class 1 and gp 1
  1698. */
  1699. if (way == 1) {
  1700. if (tmp->area)
  1701. shp = tmp->perim / tmp->area;
  1702. else
  1703. shp = 0.0;
  1704. }
  1705. else if (way == 2) {
  1706. if (tmp->area)
  1707. shp = (0.282 * tmp->perim) / sqrt(tmp->area);
  1708. else
  1709. shp = 0.0;
  1710. }
  1711. else {
  1712. if (tmp->long_axis)
  1713. shp = 2 * sqrt(tmp->area / PI) / tmp->long_axis;
  1714. else
  1715. shp = 0.0;
  1716. }
  1717. if (choice->shape[1] || choice->shape[2]) {
  1718. sum1 += shp;
  1719. if (choice->shape[2])
  1720. sum12 += shp * shp;
  1721. }
  1722. if (choice->shape[3] || choice->shape[4]) {
  1723. if (in_group(tmp->att, recl_tb[0], 0)) {
  1724. density1++;
  1725. sum2 += shp;
  1726. if (choice->shape[4])
  1727. sum22 += shp * shp;
  1728. }
  1729. }
  1730. if (choice->shape[5] || choice->shape[6])
  1731. if ((way == 1 && (shp < shape_PA[2] && shp >= shape_PA[1])) ||
  1732. (way == 2 && (shp < shape_CPA[2] && shp >= shape_CPA[1])) ||
  1733. (way == 3 && (shp < shape_RCC[2] && shp >= shape_RCC[1]))) {
  1734. if (choice->shape[5])
  1735. density2++;
  1736. else if (in_group(tmp->att, recl_tb[0], 0))
  1737. density3++;
  1738. }
  1739. if (!tmp->next) {
  1740. /* calc. h1=mn. patch shape */
  1741. if (choice->shape[1] && total_patches)
  1742. value[index][23] = sum1 / total_patches;
  1743. /* calc. h2=s.d. patch shape */
  1744. if (choice->shape[2] && total_patches > 1) {
  1745. mean = sum1 / total_patches;
  1746. stdv = sum12 / total_patches - mean * mean;
  1747. if (stdv > 0)
  1748. value[index][24] = sqrt(stdv);
  1749. }
  1750. /* calc. h3=mn. patch shape in gp 1 */
  1751. if (choice->shape[3] && density1)
  1752. value[index][25] = sum2 / density1;
  1753. /* calc. h4=s.d. patch shape in gp 1 */
  1754. if (choice->shape[4] && density1 > 1) {
  1755. mean = sum2 / density1;
  1756. stdv = sum22 / density1 - mean * mean;
  1757. if (stdv > 0)
  1758. value[index][26] = sqrt(stdv);
  1759. }
  1760. /* calc. h5=no. in shape index class 1 */
  1761. if (choice->shape[5])
  1762. value[index][27] = density2;
  1763. /* calc. h6=no. in shape index class 1 & gp 1 */
  1764. if (choice->shape[6])
  1765. value[index][28] = density3;
  1766. density1 = density2 = density3 = 0;
  1767. sum1 = sum12 = sum2 = sum22 = 0.0;
  1768. }
  1769. return;
  1770. }
  1771. /******************************************/
  1772. /* COMPUTE AND SAVE BOUNDARY COMPLEXITY */
  1773. /* MEASURES FOR MOVING WINDOW ANALYSIS */
  1774. /******************************************/
  1775. void m_boundary(PATCH * tmp, double **value, int index)
  1776. {
  1777. static double sumomega = 0.0, sumomega2 = 0.0;
  1778. static int sumtwist = 0, sumtwist2 = 0;
  1779. double meantwist = 0.0, stdvtwist = 0.0, meanomega = 0.0, stdvomega = 0.0;
  1780. /* Variables:
  1781. IN:
  1782. tmp = the next patch in the patch list
  1783. value = buffer containing a full row of the results of the moving
  1784. window if a moving window map, otherwise 0
  1785. index = number of the column in the moving window
  1786. INTERNAL:
  1787. meantwist = mean twist number (n1)
  1788. stdvtwist = st. dev. twist number (n2)
  1789. meanomega = mean omega index (n3)
  1790. stdvomega = st. dev. omega index (n4)
  1791. GLOBAL:
  1792. total_patches = tot. no. patches in sampling area (fm. trace.c)
  1793. */
  1794. sumtwist += tmp->twist;
  1795. sumtwist2 += tmp->twist * tmp->twist;
  1796. sumomega += tmp->omega;
  1797. sumomega2 += tmp->omega * tmp->omega;
  1798. if (!tmp->next) {
  1799. if (choice->boundary[1] || choice->boundary[2]) {
  1800. meantwist = (double)sumtwist / total_patches;
  1801. stdvtwist =
  1802. (double)sumtwist2 / total_patches - meantwist * meantwist;
  1803. if (stdvtwist > 0.0)
  1804. stdvtwist = sqrt(stdvtwist);
  1805. else
  1806. stdvtwist = 0.0;
  1807. }
  1808. if (choice->boundary[3] || choice->boundary[4]) {
  1809. meanomega = (double)sumomega / total_patches;
  1810. stdvomega =
  1811. (double)sumomega2 / total_patches - meanomega * meanomega;
  1812. if (stdvomega > 0.0)
  1813. stdvomega = sqrt(stdvomega);
  1814. else
  1815. stdvomega = 0.0;
  1816. }
  1817. /* write n1=mean twist number */
  1818. if (choice->boundary[1]) {
  1819. value[index][29] = meantwist;
  1820. }
  1821. /* write n2=st. dev. twist number */
  1822. if (choice->boundary[2]) {
  1823. value[index][39] = stdvtwist;
  1824. }
  1825. /* write n3=mean omega index */
  1826. if (choice->boundary[3]) {
  1827. value[index][40] = meanomega;
  1828. }
  1829. /* write n4=st. dev. omega index */
  1830. if (choice->boundary[4]) {
  1831. value[index][41] = stdvomega;
  1832. }
  1833. sumtwist = sumtwist2 = meantwist = stdvtwist = 0.0;
  1834. sumomega = sumomega2 = meanomega = stdvomega = 0.0;
  1835. }
  1836. return;
  1837. }
  1838. /************************************/
  1839. /* MOVING WINDOW PERIMETER MEASURES */
  1840. /************************************/
  1841. void m_perim(PATCH * tmp, double **value, int index)
  1842. {
  1843. static double sum1 = 0.0, sum12 = 0.0, sum2 = 0.0, sum22 = 0.0;
  1844. static int density = 0;
  1845. double mean, stdv;
  1846. /* choice->perim == 1 - sum of perimeters (p1)
  1847. 2 - mean perimeter (p2)
  1848. 3 - st. dev. perimeters (p3)
  1849. 4 - sum of perimeters in gp 1 (p4)
  1850. 5 - mean perimeter in gp 1 (p5)
  1851. 6 - st. dev. perimeters in gp 1 (p6)
  1852. Variables:
  1853. IN:
  1854. tmp = the list of patches
  1855. value = buffer containing a full row of the results of the moving
  1856. window if a moving window map, otherwise 0
  1857. index = number of the column in the moving window
  1858. INTERNAL:
  1859. sum1 = sum of patch perimeters
  1860. sum12 = sum of patch perimeters squared
  1861. sum2 = sum of patch perimeters in gp 1
  1862. sum22 = sum of patch perimeters in gp 1 squared
  1863. density = no. of patches in gp 1
  1864. */
  1865. if (choice->perim[1] || choice->perim[2] || choice->perim[3]) {
  1866. sum1 += tmp->perim;
  1867. if (choice->perim[3])
  1868. sum12 += tmp->perim * tmp->perim;
  1869. }
  1870. if (choice->perim[4] || choice->perim[5] || choice->perim[6]) {
  1871. if (in_group(tmp->att, recl_tb[0], 0)) {
  1872. sum2 += tmp->perim;
  1873. if (choice->perim[5] || choice->perim[6]) {
  1874. density++;
  1875. if (choice->perim[6])
  1876. sum22 += tmp->perim * tmp->perim;
  1877. }
  1878. }
  1879. }
  1880. if (!tmp->next) {
  1881. /* calc. p1 = sum of perims. */
  1882. if (choice->perim[1])
  1883. value[index][30] = sum1;
  1884. /* calc. p2 = mn. perim. */
  1885. if (choice->perim[2] && total_patches)
  1886. value[index][31] = sum1 / total_patches;
  1887. /* calc. p3 = s.d. perim. */
  1888. if (choice->perim[3] && total_patches > 1) {
  1889. mean = sum1 / total_patches;
  1890. stdv = sum12 / total_patches - mean * mean;
  1891. if (stdv > 0)
  1892. value[index][32] = sqrt(stdv);
  1893. }
  1894. /* calc. p4 = sum of perims. in gp 1 */
  1895. if (choice->perim[4])
  1896. value[index][33] = sum2;
  1897. /* calc. p5 = mn. perim. in gp 1 */
  1898. if (choice->perim[5] && density)
  1899. value[index][34] = sum2 / density;
  1900. /* calc. p6 = s.d. perims. in gp 1 */
  1901. if (choice->perim[6] && density > 1) {
  1902. mean = sum2 / density;
  1903. stdv = sum22 / density - mean * mean;
  1904. if (stdv > 0)
  1905. value[index][35] = sqrt(stdv);
  1906. }
  1907. density = 0;
  1908. sum1 = sum12 = sum2 = sum22 = 0.0;
  1909. }
  1910. return;
  1911. }
  1912. double eu_d(double x1, double y1, double x2, double y2)
  1913. {
  1914. return (sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
  1915. }