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