renyi.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /****************************************************************************
  2. *
  3. * MODULE: r.li.renyi
  4. *
  5. * PURPOSE: brief calculates renyi's diversity index
  6. *
  7. * AUTHOR(S): Luca Delucchi, Fondazione Edmund Mach
  8. * Serena Pallecchi student of Computer Science University of Pisa (Italy)
  9. *
  10. * COPYRIGHT:
  11. * This program is free software under the GPL (>=v2)
  12. * Read the COPYING file that comes with GRASS for details.
  13. *
  14. ***************************************************************************/
  15. #include <stdlib.h>
  16. #include <fcntl.h>
  17. #include <math.h>
  18. #include <grass/gis.h>
  19. #include <grass/glocale.h>
  20. #include "../r.li.daemon/defs.h"
  21. #include "../r.li.daemon/avlDefs.h"
  22. #include "../r.li.daemon/avl.h"
  23. #include "../r.li.daemon/daemon.h"
  24. double calculate(struct area_entry *ad, int fd, char **par, double *result);
  25. double calculateD(struct area_entry *ad, int fd, char **par, double *result);
  26. double calculateF(struct area_entry *ad, int fd, char **par, double *result);
  27. int main(int argc, char *argv[])
  28. {
  29. struct Option *raster, *conf, *output, *alpha;
  30. struct GModule *module;
  31. char **par = NULL;
  32. G_gisinit(argv[0]);
  33. module = G_define_module();
  34. module->description =
  35. _("Calculates Renyi's diversity index on a raster map");
  36. G_add_keyword(_("raster"));
  37. G_add_keyword(_("landscape structure analysis"));
  38. G_add_keyword(_("diversity index"));
  39. /* define options */
  40. raster = G_define_standard_option(G_OPT_R_INPUT);
  41. conf = G_define_standard_option(G_OPT_F_INPUT);
  42. conf->key = "config";
  43. conf->description = _("Configuration file");
  44. conf->required = YES;
  45. alpha = G_define_option();
  46. alpha->key = "alpha";
  47. alpha->description =
  48. _("Alpha value is the order of the generalized entropy");
  49. alpha->type = TYPE_STRING;
  50. alpha->required = YES;
  51. output = G_define_standard_option(G_OPT_R_OUTPUT);
  52. if (G_parser(argc, argv))
  53. exit(EXIT_FAILURE);
  54. if (atoi(alpha->answer) == 1) {
  55. G_fatal_error
  56. ("If alpha = 1 Renyi index is not defined. (Ricotta et al., 2003, Environ. Model. Softw.)");
  57. exit(RLI_ERRORE);
  58. }
  59. else if (atof(alpha->answer) < 0.) {
  60. G_fatal_error
  61. ("Alpha must be > 0 otherwise Renyi index is not defined. (Ricotta et al., 2003, Environ. Model. Softw.)");
  62. exit(RLI_ERRORE);
  63. }
  64. else {
  65. par = &alpha->answer;
  66. }
  67. return calculateIndex(conf->answer, renyi, par, raster->answer,
  68. output->answer);
  69. }
  70. int renyi(int fd, char **par, struct area_entry *ad, double *result)
  71. {
  72. int ris = RLI_OK;
  73. double indice = 0;
  74. struct Cell_head hd;
  75. Rast_get_cellhd(ad->raster, "", &hd);
  76. switch (ad->data_type) {
  77. case CELL_TYPE:
  78. {
  79. ris = calculate(ad, fd, par, &indice);
  80. break;
  81. }
  82. case DCELL_TYPE:
  83. {
  84. ris = calculateD(ad, fd, par, &indice);
  85. break;
  86. }
  87. case FCELL_TYPE:
  88. {
  89. ris = calculateF(ad, fd, par, &indice);
  90. break;
  91. }
  92. default:
  93. {
  94. G_fatal_error("data type unknown");
  95. return RLI_ERRORE;
  96. }
  97. }
  98. if (ris != RLI_OK)
  99. return RLI_ERRORE;
  100. *result = indice;
  101. return RLI_OK;
  102. }
  103. double calculate(struct area_entry *ad, int fd, char **par, double *result)
  104. {
  105. CELL *buf;
  106. CELL corrCell;
  107. CELL precCell;
  108. int i, j;
  109. int mask_fd = -1, *mask_buf;
  110. int ris = 0;
  111. int masked = FALSE;
  112. int a = 0; /* a=0 if all cells are null */
  113. long m = 0;
  114. long tot = 0;
  115. long zero = 0;
  116. long totCorr = 0;
  117. double indice = 0;
  118. double somma = 0;
  119. double p = 0;
  120. double area = 0;
  121. double t;
  122. avl_tree albero = NULL;
  123. AVL_table *array;
  124. generic_cell uc;
  125. uc.t = CELL_TYPE;
  126. /* open mask if needed */
  127. if (ad->mask == 1) {
  128. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
  129. return RLI_ERRORE;
  130. mask_buf = G_malloc(ad->cl * sizeof(int));
  131. if (mask_buf == NULL) {
  132. G_fatal_error("malloc mask_buf failed");
  133. return RLI_ERRORE;
  134. }
  135. masked = TRUE;
  136. }
  137. Rast_set_c_null_value(&precCell, 1);
  138. for (j = 0; j < ad->rl; j++) { /* for each row */
  139. if (masked) {
  140. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
  141. G_fatal_error("mask read failed");
  142. return RLI_ERRORE;
  143. }
  144. }
  145. buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
  146. for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
  147. area++;
  148. corrCell = buf[i + ad->x];
  149. if ((masked) && (mask_buf[i + ad->x] == 0)) {
  150. Rast_set_c_null_value(&corrCell, 1);
  151. area--;
  152. }
  153. if (!(Rast_is_null_value(&corrCell, uc.t))) {
  154. a = 1;
  155. if (Rast_is_null_value(&precCell, uc.t)) {
  156. precCell = corrCell;
  157. }
  158. if (corrCell != precCell) {
  159. if (albero == NULL) {
  160. uc.val.c = precCell;
  161. albero = avl_make(uc, totCorr);
  162. if (albero == NULL) {
  163. G_fatal_error("avl_make error");
  164. return RLI_ERRORE;
  165. }
  166. else
  167. m++;
  168. }
  169. else {
  170. uc.val.c = precCell;
  171. ris = avl_add(&albero, uc, totCorr);
  172. switch (ris) {
  173. case AVL_ERR:
  174. {
  175. G_fatal_error("avl_add error");
  176. return RLI_ERRORE;
  177. }
  178. case AVL_ADD:
  179. {
  180. m++;
  181. break;
  182. }
  183. case AVL_PRES:
  184. {
  185. break;
  186. }
  187. default:
  188. {
  189. G_fatal_error("avl_make unknown error");
  190. return RLI_ERRORE;
  191. }
  192. }
  193. }
  194. totCorr = 1;
  195. } /* endif not equal cells */
  196. else { /*equal cells */
  197. totCorr++;
  198. }
  199. precCell = corrCell;
  200. }
  201. }
  202. }
  203. /*last closing */
  204. if (a != 0) {
  205. if (albero == NULL) {
  206. uc.val.c = precCell;
  207. albero = avl_make(uc, totCorr);
  208. if (albero == NULL) {
  209. G_fatal_error("avl_make error");
  210. return RLI_ERRORE;
  211. }
  212. m++;
  213. }
  214. else {
  215. uc.val.c = precCell;
  216. ris = avl_add(&albero, uc, totCorr);
  217. switch (ris) {
  218. case AVL_ERR:
  219. {
  220. G_fatal_error("avl_add error");
  221. return RLI_ERRORE;
  222. }
  223. case AVL_ADD:
  224. {
  225. m++;
  226. break;
  227. }
  228. case AVL_PRES:
  229. {
  230. break;
  231. }
  232. default:
  233. {
  234. G_fatal_error("avl_add unknown error");
  235. return RLI_ERRORE;
  236. }
  237. }
  238. }
  239. }
  240. array = G_malloc(m * sizeof(AVL_tableRow));
  241. if (array == NULL) {
  242. G_fatal_error("malloc array failed");
  243. return RLI_ERRORE;
  244. }
  245. tot = avl_to_array(albero, zero, array);
  246. if (tot != m) {
  247. G_warning("avl_to_array unaspected value. the result could be wrong");
  248. return RLI_ERRORE;
  249. }
  250. char *sval;
  251. sval = par[0];
  252. double alpha_double;
  253. alpha_double = (double)atof(sval);
  254. /* claculate index summary */
  255. for (i = 0; i < m; i++) {
  256. t = (double)(array[i]->tot);
  257. p = t / area;
  258. G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
  259. somma = somma + pow(p, alpha_double);
  260. }
  261. indice = (1 / (1 - alpha_double)) * log(somma);
  262. if (isnan(indice) || isinf(indice)) {
  263. indice = -1;
  264. }
  265. G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);
  266. *result = indice;
  267. G_free(array);
  268. if (masked)
  269. G_free(mask_buf);
  270. return RLI_OK;
  271. }
  272. double calculateD(struct area_entry *ad, int fd, char **par, double *result)
  273. {
  274. DCELL *buf;
  275. DCELL corrCell;
  276. DCELL precCell;
  277. int i, j;
  278. int mask_fd = -1, *mask_buf;
  279. int ris = 0;
  280. int masked = FALSE;
  281. int a = 0; /* a=0 if all cells are null */
  282. long m = 0;
  283. long tot = 0;
  284. long zero = 0;
  285. long totCorr = 0;
  286. double indice = 0;
  287. double somma = 0;
  288. double p = 0;
  289. double area = 0;
  290. double t;
  291. avl_tree albero = NULL;
  292. AVL_table *array;
  293. generic_cell uc;
  294. uc.t = DCELL_TYPE;
  295. /* open mask if needed */
  296. if (ad->mask == 1) {
  297. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
  298. return RLI_ERRORE;
  299. mask_buf = G_malloc(ad->cl * sizeof(int));
  300. if (mask_buf == NULL) {
  301. G_fatal_error("malloc mask_buffailed");
  302. return RLI_ERRORE;
  303. }
  304. masked = TRUE;
  305. }
  306. Rast_set_d_null_value(&precCell, 1);
  307. for (j = 0; j < ad->rl; j++) { /* for each row */
  308. if (masked) {
  309. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
  310. G_fatal_error("mask read failed");
  311. return RLI_ERRORE;
  312. }
  313. }
  314. buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
  315. for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
  316. area++;
  317. corrCell = buf[i + ad->x];
  318. if (masked && mask_buf[i + ad->x] == 0) {
  319. Rast_set_d_null_value(&corrCell, 1);
  320. area--;
  321. }
  322. if (!(Rast_is_null_value(&corrCell, uc.t))) {
  323. a = 1;
  324. if (Rast_is_null_value(&precCell, uc.t)) {
  325. precCell = corrCell;
  326. }
  327. if (corrCell != precCell) {
  328. if (albero == NULL) {
  329. uc.val.dc = precCell;
  330. albero = avl_make(uc, totCorr);
  331. if (albero == NULL) {
  332. G_fatal_error("avl_make error");
  333. return RLI_ERRORE;
  334. }
  335. m++;
  336. }
  337. else {
  338. uc.val.dc = precCell;
  339. ris = avl_add(&albero, uc, totCorr);
  340. switch (ris) {
  341. case AVL_ERR:
  342. {
  343. G_fatal_error("avl_add error");
  344. return RLI_ERRORE;
  345. }
  346. case AVL_ADD:
  347. {
  348. m++;
  349. break;
  350. }
  351. case AVL_PRES:
  352. {
  353. break;
  354. }
  355. default:
  356. {
  357. G_fatal_error("avl_make unknown error");
  358. return RLI_ERRORE;
  359. }
  360. }
  361. }
  362. totCorr = 1;
  363. } /* endif not equal dcells */
  364. else { /*equal dcells */
  365. totCorr++;
  366. }
  367. precCell = corrCell;
  368. }
  369. }
  370. }
  371. /*last closing */
  372. if (a != 0) {
  373. if (albero == NULL) {
  374. uc.val.dc = precCell;
  375. albero = avl_make(uc, totCorr);
  376. if (albero == NULL) {
  377. G_fatal_error("avl_make error");
  378. return RLI_ERRORE;
  379. }
  380. m++;
  381. }
  382. else {
  383. uc.val.dc = precCell;
  384. ris = avl_add(&albero, uc, totCorr);
  385. switch (ris) {
  386. case AVL_ERR:
  387. {
  388. G_fatal_error("avl_add error");
  389. return RLI_ERRORE;
  390. }
  391. case AVL_ADD:
  392. {
  393. m++;
  394. break;
  395. }
  396. case AVL_PRES:
  397. {
  398. break;
  399. }
  400. default:
  401. {
  402. G_fatal_error("avl_add unknown error");
  403. return RLI_ERRORE;
  404. }
  405. }
  406. }
  407. }
  408. array = G_malloc(m * sizeof(AVL_tableRow));
  409. if (array == NULL) {
  410. G_fatal_error("malloc array failed");
  411. return RLI_ERRORE;
  412. }
  413. tot = avl_to_array(albero, zero, array);
  414. if (tot != m) {
  415. G_warning("avl_to_array unaspected value. the result could be wrong");
  416. return RLI_ERRORE;
  417. }
  418. char *sval;
  419. sval = par[0];
  420. double alpha_double;
  421. alpha_double = (double)atof(sval);
  422. /* claculate index summary */
  423. for (i = 0; i < m; i++) {
  424. t = (double)(array[i]->tot);
  425. p = t / area;
  426. G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
  427. somma = somma + pow(p, alpha_double);
  428. }
  429. indice = (1 / (1 - alpha_double)) * log(somma);
  430. if (isnan(indice) || isinf(indice)) {
  431. indice = -1;
  432. }
  433. G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);
  434. *result = indice;
  435. G_free(array);
  436. if (masked)
  437. G_free(mask_buf);
  438. return RLI_OK;
  439. }
  440. double calculateF(struct area_entry *ad, int fd, char **par, double *result)
  441. {
  442. FCELL *buf;
  443. FCELL corrCell;
  444. FCELL precCell;
  445. int i, j;
  446. int mask_fd = -1, *mask_buf;
  447. int ris = 0;
  448. int masked = FALSE;
  449. int a = 0; /* a=0 if all cells are null */
  450. long m = 0;
  451. long tot = 0;
  452. long zero = 0;
  453. long totCorr = 0;
  454. double indice = 0;
  455. double somma = 0;
  456. double p = 0;
  457. double area = 0;
  458. double t;
  459. avl_tree albero = NULL;
  460. AVL_table *array;
  461. generic_cell uc;
  462. uc.t = FCELL_TYPE;
  463. /* open mask if needed */
  464. if (ad->mask == 1) {
  465. if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
  466. return RLI_ERRORE;
  467. mask_buf = G_malloc(ad->cl * sizeof(int));
  468. if (mask_buf == NULL) {
  469. G_fatal_error("malloc mask_buf failed");
  470. return RLI_ERRORE;
  471. }
  472. masked = TRUE;
  473. }
  474. Rast_set_f_null_value(&precCell, 1);
  475. for (j = 0; j < ad->rl; j++) { /* for each row */
  476. if (masked) {
  477. if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
  478. G_fatal_error("mask read failed");
  479. return RLI_ERRORE;
  480. }
  481. }
  482. buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
  483. for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
  484. area++;
  485. corrCell = buf[i + ad->x];
  486. if (masked && mask_buf[i + ad->x] == 0) {
  487. Rast_set_f_null_value(&corrCell, 1);
  488. area--;
  489. }
  490. if (!(Rast_is_null_value(&corrCell, uc.t))) {
  491. a = 1;
  492. if (Rast_is_null_value(&precCell, uc.t)) {
  493. precCell = corrCell;
  494. }
  495. if (corrCell != precCell) {
  496. if (albero == NULL) {
  497. uc.val.fc = precCell;
  498. albero = avl_make(uc, totCorr);
  499. if (albero == NULL) {
  500. G_fatal_error("avl_make error");
  501. return RLI_ERRORE;
  502. }
  503. m++;
  504. }
  505. else {
  506. uc.val.fc = precCell;
  507. ris = avl_add(&albero, uc, totCorr);
  508. switch (ris) {
  509. case AVL_ERR:
  510. {
  511. G_fatal_error("avl_add error");
  512. return RLI_ERRORE;
  513. }
  514. case AVL_ADD:
  515. {
  516. m++;
  517. break;
  518. }
  519. case AVL_PRES:
  520. {
  521. break;
  522. }
  523. default:
  524. {
  525. G_fatal_error("avl_make unknown error");
  526. return RLI_ERRORE;
  527. }
  528. }
  529. }
  530. totCorr = 1;
  531. } /* endif not equal fcells */
  532. else { /*equal fcells */
  533. totCorr++;
  534. }
  535. precCell = corrCell;
  536. }
  537. }
  538. }
  539. /*last closing */
  540. if (a != 0) {
  541. if (albero == NULL) {
  542. uc.val.fc = precCell;
  543. albero = avl_make(uc, totCorr);
  544. if (albero == NULL) {
  545. G_fatal_error("avl_make error");
  546. return RLI_ERRORE;
  547. }
  548. m++;
  549. }
  550. else {
  551. uc.val.fc = precCell;
  552. ris = avl_add(&albero, uc, totCorr);
  553. switch (ris) {
  554. case AVL_ERR:
  555. {
  556. G_fatal_error("avl_add error");
  557. return RLI_ERRORE;
  558. }
  559. case AVL_ADD:
  560. {
  561. m++;
  562. break;
  563. }
  564. case AVL_PRES:
  565. {
  566. break;
  567. }
  568. default:
  569. {
  570. G_fatal_error("avl_add unknown error");
  571. return RLI_ERRORE;
  572. }
  573. }
  574. }
  575. }
  576. array = G_malloc(m * sizeof(AVL_tableRow));
  577. if (array == NULL) {
  578. G_fatal_error("malloc array failed");
  579. return RLI_ERRORE;
  580. }
  581. tot = avl_to_array(albero, zero, array);
  582. if (tot != m) {
  583. G_warning("avl_to_array unaspected value. the result could be wrong");
  584. return RLI_ERRORE;
  585. }
  586. char *sval;
  587. sval = par[0];
  588. double alpha_double;
  589. alpha_double = (double)atof(sval);
  590. /* calculate index summary */
  591. for (i = 0; i < m; i++) {
  592. t = (double)(array[i]->tot);
  593. p = t / area;
  594. G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
  595. somma = somma + pow(p, alpha_double);
  596. }
  597. indice = (1 / (1 - alpha_double)) * log(somma);
  598. if (isnan(indice) || isinf(indice)) {
  599. indice = -1;
  600. }
  601. G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);
  602. *result = indice;
  603. G_free(array);
  604. if (masked)
  605. G_free(mask_buf);
  606. return RLI_OK;
  607. }