ServiceUtils.java [src/java/util] Revision: default Date:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package util;
import csip.api.server.PayloadParameter;
import csip.api.server.ServiceException;
import csip.utils.TextParser;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDate;
import java.time.Year;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Scanner;
import static m.ghg.ApplicationResources.MODEL_OFFSET;
/**
*
* @author od
*/
public class ServiceUtils {
// crop types
public static final String CORN = "C[1-9][1-9]?";
public static final String SOYB = "SYBN[1-9]";
public static final String OAT = "OAT1";
public static final String GCP = "GCP";
public static final String GI = "GI2";
public static final String WHEAT = "W[1-9]";
public static final String SPRINGWHEAT = "SW[1-9]";
public static final String SORGHUM = "SORG[1-9]";
public static final String SORGHUMFORAGE = "FSORG";
public static final String ALFALFA = "ALF";
public static final String GRASSHAY = "G3CPI";
public static final String COTTON = "COT";
public static final String PUMPKIN = "JTOM";
public static final String CORNSILAGE = "CSL13";
public static final String SUNFLOWER = "SUN";
public static final String BARLEY = "BAR[1-9]";
public static final String RYEGRASS = "RYE";
public static String checkRemoveExtension(String filename) {
return Optional.ofNullable(filename)
.filter(f -> f.contains("."))
.map(f -> f.substring(0, filename.lastIndexOf("."))).orElse(filename);
}
public static double[] getColumnData(File lisFile, String column) throws IOException {
List<String> l = new ArrayList<>();
try ( TextParser p = new TextParser(lisFile).autoClose(false).nextLine()) {
int col = p.tokens().indexOf(column);
while (p.nextLineSkipEmpty().notEOF()) {
l.add(p.getWsTokenAt(col));
}
}
return l.stream().mapToDouble(Double::parseDouble).toArray();
}
public static String[] getStringColumnData(File lisFile, String column) throws IOException {
List<String> l = new ArrayList<>();
try ( TextParser p = new TextParser(lisFile).autoClose(false).nextLine()) {
int col = p.tokens().indexOf(column);
while (p.nextLineSkipEmpty().notEOF()) {
l.add(p.getWsTokenAt(col));
}
}
return l.toArray(new String[0]);
}
public static String[] getStringColumnDataCSV(File lisFile, String column) throws IOException {
int rowLines = 0;
try ( Scanner scanner = new Scanner(lisFile)) {
while (scanner.hasNextLine()) {
scanner.nextLine();
rowLines++;
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e.getMessage());
}
rowLines--;
String[] tot = new String[rowLines];
try ( Scanner scanner = new Scanner(lisFile)) {
String header = scanner.nextLine();
String[] cols = header.split(",");
int c = 0;
for (int i = 0; i < cols.length; i++) {
if (cols[i].toLowerCase().trim().equals(column.toLowerCase().trim())) {
c = i;
}
}
int index = 0;
//Read line
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] items = line.split(",");
tot[index] = items[c];
index++;
//Scan the line for tokens
// try (Scanner rowScanner = new Scanner(line)) {
// rowScanner.useDelimiter(",");
// while (rowScanner.hasNext()) {
// System.out.print(scanner.next());
// }
// }
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e.getMessage());
}
return tot;
}
public static double[] getColumnData(File outFile, int columnIndex) throws FileNotFoundException, IOException {
List<String> l = new ArrayList<>();
try ( TextParser p = new TextParser(outFile).autoClose(false).nextLine()) {
while (p.nextLineSkipEmpty().notEOF()) {
l.add(p.getWsTokenAt(columnIndex));
}
}
return l.stream().mapToDouble(Double::parseDouble).toArray();
}
public static int[] getIntegerColumnData(File outFile, int columnIndex) throws FileNotFoundException, IOException {
List<String> l = new ArrayList<>();
try ( TextParser p = new TextParser(outFile).autoClose(false).nextLine()) {
while (p.nextLineSkipEmpty().notEOF()) {
l.add(p.getWsTokenAt(columnIndex));
}
}
return l.stream().mapToInt(Integer::parseInt).toArray();
}
public static List<String> getCropHarvest(File schFile, String croptype, String termination) throws IOException {
List<String> years = new ArrayList<>();
try ( TextParser p = new TextParser(schFile).autoClose(false)) {
// p.toLineStaringWith("3943"); // just for lRR C
p.toLineStartingWith("3901");
// p.toLineStaringWith("3960"); // just for LRR B
try ( TextParser block = p.allUntil("-999 -999 X").autoClose(false)) {
cropHarvestFromBlock(block, years, croptype, termination);
}
while (true) {
p.toLineContaining("Last year");
if (p.isEOF()) {
break;
}
// System.out.println(p);
try ( TextParser block = p.allUntil("-999 -999 X")) {
if (block == null) {
break;
}
block.autoClose(false);
cropHarvestFromBlock(block, years, croptype, termination);
}
}
}
return years;
}
public static void cropHarvestFromBlock(TextParser block, List<String> years, String croptype, String termination)
throws IOException {
// System.out.println("In Block " + block);
int endYear = block.nextLine().leftOfFirst("Last").asInteger(); // last year
int repeats = block.nextLine().leftOfFirst("Repeats").asInteger(); // Repeats
int startingYear = block.nextLine().leftOfFirst("Output").asInteger(); // starting year
block.toLineContaining(" 1"); // first operation in block
int startyear = startingYear - MODEL_OFFSET;
int endyear = endYear - MODEL_OFFSET;
while (block.notEOF()) {
// String[] crop = block.toLineContaining("CROP " + croptype).tokens().asStringArray();
String[] crop = block.toLineMatching("^.*\\sCROP " + croptype + "\\s*$").tokens().asStringArray();
// System.out.println("CR " + Arrays.toString(crop));
if (crop.length == 0) {
break;
}
// System.out.println(crop[3]);
String[] harv = block.toLineContaining(termination).tokens().asStringArray();
if (harv.length == 0) {
break;
}
// System.out.println("HA " + Arrays.toString(harv));
int op_year = Integer.parseInt(harv[0]);
int op_doy = Integer.parseInt(harv[1]);
for (int year = startyear; year <= endyear; year = year + repeats) {
// get day of the year one month earlier
// because daycent doesn't manage two crops
// at the same time
if (termination.equals("HERB")
|| termination.equals("WKIL")) {
int y = year + op_year - 1;
Year yObj = Year.of(y);
LocalDate ld = yObj.atDay(op_doy);
LocalDate ld_mm = ld.minusMonths(1);
op_doy = ld_mm.getDayOfYear();
}
years.add(year + op_year - 1 + "." + op_doy);
}
}
}
public static List<String> getHarvest(File schFile, String termination) throws IOException {
List<String> years = new ArrayList<>();
try ( TextParser p = new TextParser(schFile).autoClose(false)) {
// p.toLineStaringWith("3943"); // just for lRR C
p.toLineStartingWith("3950");
// p.toLineStaringWith("3960"); // just for LRR B
try ( TextParser block = p.allUntil("-999 -999 X").autoClose(false)) {
cropHarvestFromBlock(block, years, termination);
}
while (true) {
p.toLineContaining("Last year");
if (p.isEOF()) {
break;
}
// System.out.println(p);
try ( TextParser block = p.allUntil("-999 -999 X")) {
if (block == null) {
break;
}
block.autoClose(false);
cropHarvestFromBlock(block, years, termination);
}
}
}
return years;
}
public static void cropHarvestFromBlock(TextParser block, List<String> years, String termination)
throws IOException {
// System.out.println("In Block " + block);
int endYear = block.nextLine().leftOfFirst("Last").asInteger(); // last year
int repeats = block.nextLine().leftOfFirst("Repeats").asInteger(); // Repeats
int startingYear = block.nextLine().leftOfFirst("Output").asInteger(); // starting year
block.toLineContaining(" 1"); // first operation in block
int startyear = startingYear - MODEL_OFFSET;
int endyear = endYear - MODEL_OFFSET;
while (block.notEOF()) {
//// String[] crop = block.toLineContaining("CROP " + croptype).tokens().asStringArray();
// String[] crop = block.toLineMatching("^.*\\sCROP " + croptype + "\\s*$").tokens().asStringArray();
//// System.out.println("CR " + Arrays.toString(crop));
// if (crop.length == 0) {
// break;
// }
// System.out.println(crop[3]);
String[] harv = block.toLineContaining(termination).tokens().asStringArray();
if (harv.length == 0) {
break;
}
// System.out.println("HA " + Arrays.toString(harv));
int op_year = Integer.parseInt(harv[0]);
int op_doy = Integer.parseInt(harv[1]);
for (int year = startyear; year <= endyear; year = year + repeats) {
// get day of the year one month earlier
// because daycent doesn't manage two crops
// at the same time
if (termination.equals("HERB")
|| termination.equals("WKIL")) {
int y = year + op_year - 1;
Year yObj = Year.of(y);
LocalDate ld = yObj.atDay(op_doy);
LocalDate ld_mm = ld.minusMonths(1);
op_doy = ld_mm.getDayOfYear();
}
years.add(year + op_year - 1 + "." + op_doy);
}
}
}
static Map<String, String> createlookup(String[] key, String[] val) {
Map<String, String> m = new LinkedHashMap<>();
for (int i = 0; i < val.length; i++) {
m.put(key[i], val[i]);
}
return m;
}
static Map<String, String> createlookup(String[] key, double[] val) {
Map<String, String> m = new LinkedHashMap<>();
for (int i = 0; i < val.length; i++) {
m.put(key[i], String.valueOf(val[i]));
}
return m;
}
static Map<String, List<String>> createlookuplist(String[] key, String[] val) {
Map<String, List<String>> m = new LinkedHashMap<>();
for (int i = 0; i < val.length; i++) {
if (m.containsKey(key[i])) {
List<String> tmpList = m.get(key[i]);
tmpList.add(String.valueOf(val[i]));
m.put(key[i], tmpList);
} else {
List<String> tmpList = new ArrayList<>();
tmpList.add(String.valueOf(val[i]));
m.put(key[i], tmpList);
}
}
return m;
}
public static Map<String, String> getMapFor(File wsFile, String column) throws IOException {
String[] time = getStringColumnData(wsFile, "time");
String[] col = getStringColumnData(wsFile, column);
return createlookup(time, col);
}
public static Map<String, List<String>> getMapList(File wsFile, String column) throws IOException {
String[] time = getStringColumnDataCSV(wsFile, "time");
String[] col = getStringColumnDataCSV(wsFile, column);
return createlookuplist(time, col);
}
public static Map<String, String> getMapFor(File wsFile, int column) throws IOException {
double[] year = getColumnData(wsFile, 0);
int[] doy = getIntegerColumnData(wsFile, 1);
String[] time = getTime(year, doy);
double[] col = getColumnData(wsFile, column);
return createlookup(time, col);
}
public static String[] getTime(double[] year, int[] doy) {
if (year.length != doy.length) {
String msg = "Year and doy have different size " + year.length + " " + doy.length;
throw new IllegalArgumentException(msg);
}
List<String> time = new ArrayList<>();
for (int i = 0; i < year.length; i++) {
int y = (int) year[i] - MODEL_OFFSET;
int d = doy[i];
// Year yy = Year.of(y);
// LocalDate ld = yy.atDay(d);
// time.add(ld.format(DateTimeFormatter.ISO_DATE));
time.add(y + "-" + String.format("%03d", d));
}
return time.stream().toArray(String[]::new);
}
public static void dictPopulation(Map<String, Map<String, Double>> hashmap, String s, PayloadParameter parameter) throws ServiceException {
String[] parts = s.split("\\.");
String cropName = parts[1];
String parameterName = parts[2];
Double parameterValue = parameter.getDouble(s);
if (hashmap.containsKey(cropName)) {
hashmap.get(cropName).put(parameterName, parameterValue);
} else {
Map<String, Double> val1 = new HashMap<>();
val1.put(parameterName, parameterValue);
hashmap.put(cropName, val1);
}
}
public static void main(String[] args) throws IOException {
// Pattern p = Pattern.compile("^.*\\sCROP C[1-9][1-9]?\\s*$");
// System.out.println(p.matcher(" 1 110 CROP C3").matches());
// List<String> l = getCropHarvest(new File("/od/tmp/Truterra.sch"), "C3");
List<String> l = getCropHarvest(new File("/tmp/csip/work/22/13/d09fae44-d38c-11eb-8191-f1753a1bc9f5/Truterra.sch"), "C3", "HARV");
for (String s : l) {
System.out.println(s);
}
// Map<String, String> c = getMapFor(new File("/od/tmp/Truterra.lis"), "cgracc");
}
}