/alaspatial/src/main/java/org/ala/spatial/util/AnalysisJobMaxent.java

http://alageospatialportal.googlecode.com/ · Java · 719 lines · 519 code · 101 blank · 99 comment · 100 complexity · f1422eb8530b751654661e2dee7d748c MD5 · raw file

  1. /**
  2. * ************************************************************************
  3. * Copyright (C) 2010 Atlas of Living Australia All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with the
  7. * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  11. * the specific language governing rights and limitations under the License.
  12. * *************************************************************************
  13. */
  14. package org.ala.spatial.util;
  15. import java.io.BufferedReader;
  16. import java.io.BufferedWriter;
  17. import java.io.File;
  18. import java.io.FileInputStream;
  19. import java.io.FileReader;
  20. import java.io.FileWriter;
  21. import java.io.IOException;
  22. import java.io.InputStreamReader;
  23. import java.io.PrintWriter;
  24. import java.io.RandomAccessFile;
  25. import java.util.Arrays;
  26. import java.util.Hashtable;
  27. import org.ala.layers.client.Client;
  28. import org.ala.layers.dao.LayerDAO;
  29. import org.ala.layers.dto.Field;
  30. import org.ala.layers.dto.Layer;
  31. import org.ala.layers.intersect.Grid;
  32. import org.ala.layers.intersect.SimpleRegion;
  33. import org.ala.spatial.analysis.index.LayerFilter;
  34. import org.ala.spatial.analysis.maxent.MaxentServiceImpl;
  35. import org.ala.spatial.analysis.maxent.MaxentSettings;
  36. import org.apache.commons.io.IOUtils;
  37. /**
  38. *
  39. * @author Adam
  40. */
  41. public class AnalysisJobMaxent extends AnalysisJob {
  42. long[] stageTimes;
  43. String currentPath;
  44. String taxon;
  45. String area;
  46. String envlist;
  47. String txtTestPercentage;
  48. String chkJackknife;
  49. String chkResponseCurves;
  50. LayerFilter[] envelope;
  51. SimpleRegion region;
  52. int cells;
  53. int speciesCount;
  54. String resolution;
  55. String[] envnameslist;
  56. public AnalysisJobMaxent(String pid, String currentPath_, String taxon_, String envlist_, SimpleRegion region_, LayerFilter[] filter_, String txtTestPercentage_, String chkJackknife_, String chkResponseCurves_, String resolution_) {
  57. super(pid);
  58. currentPath = currentPath_;
  59. taxon = taxon_;
  60. region = region_;
  61. envelope = filter_;
  62. txtTestPercentage = txtTestPercentage_;
  63. chkJackknife = chkJackknife_;
  64. chkResponseCurves = chkResponseCurves_;
  65. envlist = envlist_;
  66. resolution = resolution_;
  67. envnameslist = envlist.split(":");
  68. System.out.println("ENVLIST*** " + envlist);
  69. //TODO: remove rough estimate
  70. if (region != null) {
  71. cells = (int) Math.ceil(region.getWidth() / Double.parseDouble(resolution)
  72. * region.getHeight() / Double.parseDouble(resolution));
  73. } else {
  74. cells = 1000000; //or something
  75. }
  76. //cells = GridCutter.countCells(region, envelope);
  77. // SamplingService ss = SamplingService.newForLSID(taxon);
  78. // double[] p = ss.sampleSpeciesPoints(taxon, region, null);
  79. // if (p != null) {
  80. // speciesCount = p.length / 2;
  81. // }
  82. //TODO: dynamic species count
  83. speciesCount = 10000;
  84. stageTimes = new long[4];
  85. setStage(0);
  86. setProgress(0);
  87. }
  88. @Override
  89. public void run() {
  90. try {
  91. setCurrentState(RUNNING);
  92. setStage(0);
  93. // dump the species data to a file
  94. setProgress(0, "dumping species data");
  95. // SamplingService ss = SamplingService.newForLSID(taxon);
  96. //
  97. // StringBuffer removedSpecies = new StringBuffer();
  98. // double[] points = ss.sampleSpeciesPointsMinusSensitiveSpecies(taxon, region, null, removedSpecies);
  99. //
  100. // if (points == null) {
  101. // setProgress(1, "failed: No occurrence points found in selection region");
  102. // setCurrentState(FAILED);
  103. // setMessage("No species selected.\nHint: Make sure your active area includes species occurrences");
  104. //
  105. // return;
  106. // }
  107. //
  108. // StringBuffer sbSpecies = new StringBuffer();
  109. // // get the header
  110. // sbSpecies.append("species, longitude, latitude");
  111. // sbSpecies.append(System.getProperty("line.separator"));
  112. // for (int i = 0; i < points.length; i += 2) {
  113. // sbSpecies.append("species, " + points[i] + ", " + points[i + 1]);
  114. // sbSpecies.append(System.getProperty("line.separator"));
  115. // }
  116. setProgress(0, "preparing input files and run parameters");
  117. String cutDataPath = GridCutter.cut2(envnameslist, resolution, region, envelope, null);
  118. System.out.println("CUTDATAPATH: " + region + " " + cutDataPath);
  119. MaxentSettings msets = new MaxentSettings();
  120. msets.setMaxentPath(AlaspatialProperties.getAnalysisMaxentCmd());
  121. msets.setRandomTestPercentage(Integer.parseInt(txtTestPercentage));
  122. msets.setEnvPath(cutDataPath); //use (possibly) cut layers
  123. String ctxVarToggler = "";
  124. for (int l = 0; l < envnameslist.length; l++) {
  125. if (Client.getLayerDao().getLayerByName(envnameslist[l]) != null && Client.getLayerDao().getLayerByName(envnameslist[l]).getType().equals("contextual")) {
  126. ctxVarToggler += envnameslist[l] + " ";
  127. } else if (envnameslist[l].startsWith("aloc_")) {
  128. ctxVarToggler += envnameslist[l] + " ";
  129. }
  130. }
  131. msets.setEnvVarToggler(ctxVarToggler);
  132. msets.setEnvList(Arrays.asList(envnameslist.clone()));
  133. //msets.setSpeciesFilepath(setupSpecies(sbSpecies.toString(), currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator));
  134. msets.setSpeciesFilepath(currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator + "species_points.csv");
  135. msets.setOutputPath(currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator);
  136. if (chkJackknife != null) {
  137. msets.setDoJackknife(true);
  138. }
  139. if (chkResponseCurves != null) {
  140. msets.setDoResponsecurves(true);
  141. }
  142. MaxentServiceImpl maxent = new MaxentServiceImpl();
  143. maxent.setMaxentSettings(msets);
  144. System.out.println("To run: " + msets.toString());
  145. setStage(1);
  146. setProgress(0, "running Maxent");
  147. int exitValue = maxent.process(this);
  148. System.out.println("Completed: " + exitValue);
  149. setProgress(1, "Maxent finished with exit value=" + exitValue);
  150. setStage(2);
  151. setProgress(0, "exporting results");
  152. Hashtable htProcess = new Hashtable();
  153. String[] imgExtensions = {".png", "_only.png", "_only_thumb.png", "_thumb.png"};
  154. if (isCancelled()) {
  155. //
  156. } else if (exitValue == 0) {
  157. // check if there is an error
  158. String maxentError = getMaxentError(new File(msets.getOutputPath() + "maxent.log"), 2);
  159. if (maxentError != null) {
  160. System.out.println("Has error, sending maxent error message");
  161. setProgress(1, "failed: " + maxentError);
  162. setCurrentState(FAILED);
  163. if (maxentError.equals("Warning: Skipping species because it has 0 test samples")) {
  164. setMessage("Warning: Skipping species because it has 0 test samples." + (msets.getRandomTestPercentage() > 0 ? "\nHint: Try to set the test percetage to '0'" : ""));
  165. } else if (maxentError.equals("No species selected")) {
  166. setMessage("No species selected.\nHint: Make sure your active area includes species occurrences");
  167. }
  168. } else {
  169. // rename the env filenames to their display names
  170. String pth_plots = currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator + "plots" + File.separator;
  171. String pth = currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator;
  172. // for (int ei = 0; ei < envnameslist.length; ei++) {
  173. // readReplace(pth + "species.html", ".*?\\b"+envpathlist[ei]+"\\b.*?", Layers.layerNameToDisplayName(envnameslist[ei].replace(" ", "_")) + "("+envnameslist[ei]+")" );
  174. // for (int j = 0; j < imgExtensions.length; j++) {
  175. // try {
  176. // FileUtils.moveFile(
  177. // new File(pth_plots + "species_" + envpathlist[ei] + imgExtensions[j]),
  178. // new File(pth_plots + "species_" + Layers.layerNameToDisplayName(envnameslist[ei].replace(" ", "_")) + "("+envnameslist[ei]+")" + imgExtensions[j]));
  179. // } catch (Exception ex) {
  180. // }
  181. // }
  182. // }
  183. // //remove species image path in output species.html
  184. // readReplaceBetween(pth + "species.html", "<HR><H2>Pictures of the model", "<HR>","<HR>");
  185. // readReplace(pth + "species.html", "<a href = \"plots/\"> <img src=\"plots/\" width=600></a>", "see map window");
  186. // readReplace(pth + "species.html", "plots\\\\", "plots/");
  187. //
  188. // readReplace(pth + "species.html", "<a href = \"species_samplePredictions.csv\">The prediction strength at the training and (optionally) test presence sites</a><br>", "");
  189. String input = getInputs();
  190. // String sciname = input.substring(input.indexOf("scientificName:") + 15, input.indexOf(";", input.indexOf("scientificName:") + 15));
  191. // String scirank = input.substring(input.indexOf("taxonRank:") + 10, input.indexOf(";", input.indexOf("taxonRank:") + 10));
  192. readReplace(pth + "species.html", "Maxent model for species", "Maxent model for " + taxon);
  193. String paramlist = "Model reference number: " + getName()
  194. + "<br>Species: " + taxon //+ " (" + scirank + ")"
  195. + "<br>Layers: <ul>";
  196. LayerDAO layerDao = Client.getLayerDao();
  197. for (int ei = 0; ei < envnameslist.length; ei++) {
  198. System.out.println("LAYER NAME: " + envnameslist[ei]);
  199. Layer lyr = layerDao.getLayerByName(envnameslist[ei]);
  200. if (lyr != null) {
  201. paramlist += "<li>" + lyr.getDisplayname() + " (" + envnameslist[ei] + ")</li>";
  202. } else {
  203. if (envnameslist[ei].startsWith("aloc_")) {
  204. paramlist += "<li>Classification (" + envnameslist[ei].split("_")[1] + ")</li>";
  205. } else {
  206. paramlist += "<li>" + envnameslist[ei] + "</li>";
  207. }
  208. }
  209. }
  210. paramlist += "</ul>";
  211. readReplace(pth + "species.html", "end of this page.<br>", "end of this page.<br><p>" + paramlist + "</p>");
  212. readReplace(pth + "species.html", msets.getOutputPath(), "");
  213. readReplaceBetween(pth + "species.html", "Command line", "<br>", "");
  214. readReplaceBetween(pth + "species.html", "Command line", "<br>", "");
  215. // replace the summary
  216. readReplace(pth + "species.html", "This page contains some analysis of the Maxent model for", "This <a href='http://www.cs.princeton.edu/~schapire/maxent/'>Maxent</a> v3.3.3e predictive model for");
  217. readReplace(pth + "species.html", ", created", " was created");
  218. readReplace(pth + "species.html", " using Maxent version 3.3.3e.", ".");
  219. readReplace(pth + "species.html", "If you would like to do further analyses, the raw data used here is linked to at the end of this page", "Links at the bottom of this page to the raw data may be used for further analysis");
  220. if (chkResponseCurves != null) {
  221. StringBuffer sbTable = new StringBuffer();
  222. String[] ctxlist = msets.getEnvVarToggler().split(" ");
  223. if (msets.getEnvVarToggler().length() > 0) {
  224. sbTable.append("<pre>");
  225. for (String ctx : ctxlist) {
  226. if (ctx.startsWith("aloc_")) {
  227. continue;
  228. }
  229. sbTable.append("<span style='font-weight: bold; text-decoration: underline'>" + ctx + " legend</span><br />");
  230. //sbTable.append(IOUtils.toString(new FileInputStream(/*TabulationSettings.environmental_data_path + ctx + ".txt"*/"")));
  231. sbTable.append(IOUtils.toString(new FileInputStream(GridCutter.getLayerPath(resolution, ctx) + ".txt")));
  232. sbTable.append("<br /><br />");
  233. }
  234. sbTable.append("</pre>");
  235. readReplace(pth + "species.html", "<br><HR><H2>Analysis of variable contributions</H2><br>", sbTable.toString() + "<br><HR><H2>Analysis of variable contributions</H2><br>");
  236. }
  237. }
  238. readReplaceBetween(pth + "species.html", "<br>Click <a href=species_explain.bat", "memory.<br>", "");
  239. readReplaceBetween(pth + "species.html", "(A link to the Explain", "additive models.)", "");
  240. StringBuffer removedSpecies = new StringBuffer();
  241. try {
  242. BufferedReader br = new BufferedReader(new FileReader(
  243. currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator + "Prediction_removedSpecies.txt"));
  244. String s;
  245. while ((s = br.readLine()) != null) {
  246. removedSpecies.append(s);
  247. }
  248. br.close();
  249. } catch (Exception e) {
  250. }
  251. if (removedSpecies.length() > 0) {
  252. String header = "'Sensitive species' have been masked out of the model. See: http://www.ala.org.au/about/program-of-projects/sds/\r\n\r\nLSID,Species scientific name,Taxon rank";
  253. writeToFile(header + removedSpecies.toString(),
  254. currentPath + "output" + File.separator + "maxent" + File.separator + getName() + File.separator + "Prediction_maskedOutSensitiveSpecies.csv");
  255. String insertBefore = "<a href = \"species.asc\">The";
  256. String insertText = "<b><a href = \"Prediction_maskedOutSensitiveSpecies.csv\">'Sensitive species' masked out of the model</a></br></b>";
  257. readReplace(pth + "species.html", insertBefore, insertText + insertBefore);
  258. }
  259. // //delete image
  260. // FileUtils.deleteQuietly(new File(pth_plots + "species.png"));
  261. // FileUtils.deleteQuietly(new File(pth + "species_samplePredictions.csv"));
  262. // FileUtils.deleteQuietly(new File(pth + "maxent.log"));
  263. // FileUtils.deleteQuietly(new File(msets.getSpeciesFilepath()));
  264. writeProjectionFile(msets.getOutputPath());
  265. // if generated successfully, then add it to geoserver
  266. String url = AlaspatialProperties.getGeoserverUrl() + "/rest/workspaces/ALA/coveragestores/maxent_" + getName() + "/file.arcgrid?coverageName=species_" + getName();
  267. String extra = "";
  268. String username = AlaspatialProperties.getGeoserverUsername();
  269. String password = AlaspatialProperties.getGeoserverPassword();
  270. // first zip up the file as it's going to be sent as binary
  271. //String ascZipFile = Zipper.zipFile(msets.getOutputPath() + "species.asc");
  272. String[] infiles = {msets.getOutputPath() + "species.asc", msets.getOutputPath() + "species.prj"};
  273. String ascZipFile = msets.getOutputPath() + "species.zip";
  274. Zipper.zipFiles(infiles, ascZipFile);
  275. // Upload the file to GeoServer using REST calls
  276. System.out.println("Uploading file: " + ascZipFile + " to \n" + url);
  277. UploadSpatialResource.loadResource(url, extra, username, password, ascZipFile);
  278. //Enable browser caching, FIX for zoom to extent required.
  279. // String data = "<coverage><metadata><entry key=\"cacheAgeMax\">3600</entry><entry key=\"cachingEnabled\">true</entry><entry key=\"dirName\">maxent_" + getName() + "_species</entry></metadata></coverage>";
  280. // url = (String) htGeoserver.get("geoserver_url") + "/rest/workspaces/ALA/coveragestores/maxent_" + getName() + "/coverages/maxent_" + getName() + ".xml";
  281. // UploadSpatialResource.assignSld(url, extra, username, password, data);
  282. htProcess.put("status", "success"); ///
  283. htProcess.put("pid", getName());
  284. htProcess.put("info", "/output/maxent/" + getName() + "/species.html");
  285. //convert .asc to .grd/.gri
  286. convertAscToDiva(msets.getOutputPath() + "species.asc", msets.getOutputPath() + getName());
  287. setStage(3);
  288. // generate the readme.txt file
  289. CitationService.generatePredictionReadme(msets.getOutputPath(), msets.getSpeciesFilepath().substring(msets.getSpeciesFilepath().lastIndexOf("points")));
  290. setProgress(1, "finished");
  291. setCurrentState(SUCCESSFUL);
  292. //write out infor for adjusting input parameters
  293. System.out.println("MAXENT:" + cells + "," + envnameslist.length + " " + speciesCount + " " + (stageTimes[1] - stageTimes[0]) + " " + (stageTimes[2] - stageTimes[0]) + " " + (stageTimes[3] - stageTimes[2]));
  294. }
  295. } else {
  296. System.out.println("Failed 1");
  297. setProgress(1, "failed");
  298. setCurrentState(FAILED);
  299. }
  300. } catch (Exception e) {
  301. e.printStackTrace();
  302. System.out.println("Failed with exception: " + e.getMessage());
  303. setProgress(1, "failed: " + e.getMessage());
  304. setCurrentState(FAILED);
  305. setMessage("Error processing your Prediction request. Please try again or if problem persists, contact the Administrator.\n\nPlease quote the Prediction ID: " + getName());
  306. }
  307. }
  308. @Override
  309. public long getEstimate() {
  310. if (getProgress() == 0) {
  311. return 0;
  312. }
  313. long progTime;
  314. synchronized (progress) {
  315. progTime = progressTime;
  316. }
  317. long timeRemaining = 0;
  318. long t1 = 0, t2 = 0, t3 = 0;
  319. if (stage <= 0) { //data load; 0 to 0.2
  320. t1 += (cells * AlaspatialProperties.getAnalysisMaxentEstimateMult0()) * envnameslist.length; //default
  321. t1 = t1 + progTime - stageTimes[0];
  322. }
  323. if (stage <= 1) { //running; 0.2 to 0.9
  324. t2 += (cells * AlaspatialProperties.getAnalysisMaxentEstimateMult1()) * envnameslist.length; //default
  325. if (stage == 1) {
  326. t2 = t2 + progTime - stageTimes[1];
  327. }
  328. }
  329. if (stage > 1) { //data export + done
  330. t3 += 5000 * AlaspatialProperties.getAnalysisMaxentEstimateMult2(); //default
  331. if (stage == 2) {
  332. t3 = t3 + progTime - stageTimes[2];
  333. }
  334. }
  335. timeRemaining = t1 + t2 + t3;
  336. return timeRemaining; //smoothEstimate(timeRemaining);
  337. }
  338. @Override
  339. public void setProgress(double d) {
  340. if (stage == 0) { //data load; 0 to 0.2
  341. progress = d / 5.0;
  342. } else if (stage == 1) { //running; 0.2 to 0.9
  343. progress = 0.2 + 10 * d / 7.0;
  344. } else { //exporting/done
  345. progress = 0.9 + d / 10.0;
  346. }
  347. super.setProgress(progress);
  348. }
  349. @Override
  350. public double getProgress() {
  351. //return expected progress since cannot track internals
  352. long currentTime = System.currentTimeMillis();
  353. long progTime;
  354. synchronized (progress) {
  355. progTime = progressTime;
  356. }
  357. long t1 = 0, t2 = 0, t3 = 0;
  358. double d1, d2, d3;
  359. //progress is [time passed] / [time expected]
  360. if (stage <= 0) { //data load; 0 to 0.2
  361. t1 += (cells * AlaspatialProperties.getAnalysisMaxentEstimateMult0()) * envnameslist.length; //default
  362. d1 = (currentTime - stageTimes[0]) / (double) t1;
  363. if (d1 > 0.9) {
  364. d1 = 0.9;
  365. }
  366. d1 *= 0.2; //range limit
  367. } else {
  368. d1 = 0.2;
  369. }
  370. if (stage <= 1) { //running; 0.2 to 0.9
  371. t2 += (cells * AlaspatialProperties.getAnalysisMaxentEstimateMult1()) * envnameslist.length; //default
  372. if (stage == 1) {
  373. d2 = (currentTime - stageTimes[1]) / (double) t2;
  374. } else {
  375. d2 = 0;
  376. }
  377. if (d2 > 0.9) {
  378. d2 = 0.9;
  379. }
  380. d2 *= 0.7; //range limit
  381. } else {
  382. d2 = 0.7;
  383. }
  384. if (stage > 1) { //data export + done
  385. t3 += 5000 * AlaspatialProperties.getAnalysisMaxentEstimateMult2(); //default
  386. if (stage == 2) {
  387. d3 = (currentTime - stageTimes[2]) / (double) t3;
  388. } else {
  389. d3 = 0;
  390. }
  391. if (d3 > 0.9) {
  392. d3 = 0.9;
  393. }
  394. d3 *= 0.1; //range limit
  395. } else {
  396. d3 = 0.1;
  397. }
  398. return d1 + d2 + d3;
  399. }
  400. @Override
  401. public String getStatus() {
  402. if (getProgress() < 1) {
  403. String msg;
  404. if (stage == 0) { //data load; 0 to 0.2
  405. msg = "Data preparation, ";
  406. } else if (stage == 1) { //seeding; 0.2 to 0.9
  407. msg = "Running, ";
  408. } else { //transforming data; 0.9 to 1.0
  409. msg = "Exporting results, ";
  410. }
  411. return msg + "est remaining: " + getEstimateInMinutes() + " min";
  412. } else {
  413. if (stage == -1) {
  414. return "not started, est: " + getEstimateInMinutes() + " min";
  415. } else {
  416. return "finished, total run time=" + Math.round(getRunTime() / 1000) + "s";
  417. }
  418. }
  419. }
  420. @Override
  421. public void setStage(int i) {
  422. super.setStage(i);
  423. if (i < 4) {
  424. stageTimes[i] = System.currentTimeMillis();
  425. }
  426. }
  427. public void setCells(int i) {
  428. cells = i;
  429. }
  430. public String toString() {
  431. StringBuffer sb = new StringBuffer();
  432. sb.append(getName());
  433. sb.append("; Maxent");
  434. sb.append("; state=").append(getCurrentState());
  435. sb.append("; status=").append(getStatus());
  436. sb.append("; grid cell count=").append(cells);
  437. sb.append("; number of layers=").append(envnameslist.length);
  438. return sb.toString();
  439. }
  440. static public void readReplace(String fname, String oldPattern, String replPattern) {
  441. String line;
  442. StringBuffer sb = new StringBuffer();
  443. try {
  444. FileInputStream fis = new FileInputStream(fname);
  445. BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
  446. while ((line = reader.readLine()) != null) {
  447. line = line.replaceAll(oldPattern, replPattern);
  448. sb.append(line + "\n");
  449. }
  450. reader.close();
  451. BufferedWriter out = new BufferedWriter(new FileWriter(fname));
  452. out.write(sb.toString());
  453. out.close();
  454. } catch (Throwable e) {
  455. System.err.println("*** exception ***");
  456. e.printStackTrace(System.out);
  457. }
  458. }
  459. public void readReplaceBetween(String fname, String startOldText, String endOldText, String replText) {
  460. String line;
  461. StringBuffer sb = new StringBuffer();
  462. try {
  463. FileInputStream fis = new FileInputStream(fname);
  464. BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
  465. while ((line = reader.readLine()) != null) {
  466. sb.append(line + "\n");
  467. }
  468. int start, end;
  469. start = sb.indexOf(startOldText);
  470. if (start >= 0) {
  471. end = sb.indexOf(endOldText, start + 1);
  472. sb.replace(start, end + endOldText.length(), replText);
  473. }
  474. reader.close();
  475. BufferedWriter out = new BufferedWriter(new FileWriter(fname));
  476. out.write(sb.toString());
  477. out.close();
  478. } catch (Throwable e) {
  479. System.err.println("*** exception ***");
  480. e.printStackTrace(System.out);
  481. }
  482. }
  483. private String setupSpecies(String speciesList, String outputpath) {
  484. try {
  485. File fDir = new File(outputpath);
  486. fDir.mkdir();
  487. //File spFile = File.createTempFile("points_", ".csv", fDir);
  488. File spFile = new File(fDir, "species_points.csv");
  489. PrintWriter spWriter = new PrintWriter(new BufferedWriter(new FileWriter(spFile)));
  490. //spWriter.write("spname, longitude, latitude \n");
  491. spWriter.write(speciesList);
  492. spWriter.close();
  493. return spFile.getAbsolutePath();
  494. } catch (IOException ex) {
  495. //Logger.getLogger(MaxentServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
  496. System.out.println("error writing species file:");
  497. ex.printStackTrace(System.out);
  498. }
  499. return null;
  500. }
  501. private void writeToFile(String text, String filename) {
  502. try {
  503. FileWriter fw = new FileWriter(filename);
  504. fw.append(text);
  505. fw.close();
  506. } catch (Exception e) {
  507. e.printStackTrace();
  508. }
  509. }
  510. private void writeProjectionFile(String outputpath) {
  511. try {
  512. File fDir = new File(outputpath);
  513. fDir.mkdir();
  514. PrintWriter spWriter = new PrintWriter(new BufferedWriter(new FileWriter(outputpath + "species.prj")));
  515. StringBuffer sbProjection = new StringBuffer();
  516. sbProjection.append("GEOGCS[\"WGS 84\", ").append("\n");
  517. sbProjection.append(" DATUM[\"WGS_1984\", ").append("\n");
  518. sbProjection.append(" SPHEROID[\"WGS 84\",6378137,298.257223563, ").append("\n");
  519. sbProjection.append(" AUTHORITY[\"EPSG\",\"7030\"]], ").append("\n");
  520. sbProjection.append(" AUTHORITY[\"EPSG\",\"6326\"]], ").append("\n");
  521. sbProjection.append(" PRIMEM[\"Greenwich\",0, ").append("\n");
  522. sbProjection.append(" AUTHORITY[\"EPSG\",\"8901\"]], ").append("\n");
  523. sbProjection.append(" UNIT[\"degree\",0.01745329251994328, ").append("\n");
  524. sbProjection.append(" AUTHORITY[\"EPSG\",\"9122\"]], ").append("\n");
  525. sbProjection.append(" AUTHORITY[\"EPSG\",\"4326\"]] ").append("\n");
  526. //spWriter.write("spname, longitude, latitude \n");
  527. spWriter.write(sbProjection.toString());
  528. spWriter.close();
  529. } catch (IOException ex) {
  530. //Logger.getLogger(MaxentServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
  531. System.out.println("error writing species file:");
  532. ex.printStackTrace(System.out);
  533. }
  534. }
  535. public String getImage() {
  536. return "output/maxent/" + getName() + "/plots/species_hidden.png";
  537. }
  538. AnalysisJob copy() {
  539. return new AnalysisJobMaxent(String.valueOf(System.currentTimeMillis()),
  540. currentPath, taxon, envlist, region, envelope, txtTestPercentage, chkJackknife, chkResponseCurves, resolution);
  541. }
  542. private String getMaxentError(File file, int count) {
  543. try {
  544. RandomAccessFile rf = new RandomAccessFile(file, "r");
  545. // first check if maxent threw a 'No species selected' error
  546. String nosp = rf.readLine(); // first line: date/time
  547. nosp = rf.readLine(); // second line: maxent version
  548. nosp = rf.readLine(); // third line: "No species selected"
  549. if (nosp.equals("No species selected")) {
  550. return "No species selected";
  551. }
  552. long flen = file.length() - 1;
  553. int nlcnt = -1;
  554. StringBuilder lines = new StringBuilder();
  555. while (nlcnt != count) {
  556. rf.seek(flen--);
  557. char c = (char) rf.read();
  558. lines.append(c);
  559. if (c == '\n') {
  560. nlcnt++;
  561. }
  562. }
  563. String line = lines.reverse().toString();
  564. if (line.contains("Warning: Skipping species because it has 0 test samples")) {
  565. return "Warning: Skipping species because it has 0 test samples";
  566. }
  567. rf.close();
  568. } catch (Exception e) {
  569. System.out.println("Unable to read lines");
  570. e.printStackTrace(System.out);
  571. }
  572. // return false anyways
  573. return null;
  574. }
  575. private void convertAscToDiva(String asc, String grd) {
  576. try {
  577. //read asc
  578. BufferedReader br = new BufferedReader(new FileReader(asc));
  579. String s;
  580. //maxent output grid is:
  581. s = br.readLine();
  582. int ncols = Integer.parseInt(s.replace("ncols", "").trim());
  583. s = br.readLine();
  584. int nrows = Integer.parseInt(s.replace("nrows", "").trim());
  585. s = br.readLine();
  586. double lng1 = Double.parseDouble(s.replace("xllcorner", "").trim());
  587. s = br.readLine();
  588. double lat1 = Double.parseDouble(s.replace("yllcorner", "").trim());
  589. s = br.readLine();
  590. double div = Double.parseDouble(s.replace("cellsize", "").trim());
  591. s = br.readLine();
  592. double nodata = Double.parseDouble(s.replace("NODATA_value", "").trim());
  593. double[] data = new double[ncols * nrows];
  594. for (int i = 0; i < ncols * nrows; i++) {
  595. data[i] = Double.NaN;
  596. }
  597. int r = 0;
  598. while ((s = br.readLine()) != null) {
  599. String[] row = s.split(" ");
  600. for (int i = 0; i < row.length && i < ncols; i++) {
  601. double v = Double.parseDouble(row[i]);
  602. if (v != nodata) {
  603. data[r * ncols + i] = v;
  604. }
  605. }
  606. r++;
  607. if (r == nrows) {
  608. break;
  609. }
  610. }
  611. br.close();
  612. Grid g = new Grid(null);
  613. g.writeGrid(grd, data, lng1, lat1, lng1 + ncols * div, lat1 + nrows * div, div, div, nrows, ncols);
  614. } catch (Exception e) {
  615. e.printStackTrace();
  616. }
  617. }
  618. }