SOLFile.java [tools/MetaModelTools/src/data/interpretors] Revision: ec5f4cade4553a8341e1cd241b111bfdb77a87a8 Date: Fri Jan 10 10:59:55 MST 2020
/*
* $Id$
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API, and application suite.
*
* 2012-2019, OMSLab, Colorado State University.
*
* OMSLab licenses this file to you under the MIT license.
* See the LICENSE file in the project root for more information.
*/
package data.interpretors;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
*/
public class SOLFile {
private static final Logger LOGGER = Logger.getLogger(IFCFile.class.getName());
//Logs for errors and warnings.
private String errorsInSolFile = ""; // list of variables adjusted on output
public String comments = "";
//File Line 4 values
public String soilName; // a) soil name for current OFE or channel - character (slid)
public String soilTexture; // b) soil texture for current OFE or channel - character (texid)
public int numLayers; // c) number of soil layers for current OFE or channel - integer (nsl)
public double salb; // d) albedo of the bare dry surface soil on the current OFE or channel - real (salb)
public double sat; // e) initial saturation level of the soil profile porosity (m/m) - real (sat)
public double ki; // f) baseline interrill erodibility parameter (kg*s/m4) - real (ki)
public double kr; // g) baseline rill erodibility parameter (s/m) - real (kr)
public double shcrit; // h) baseline critical shear parameter (N/m2) - real (shcrit)
public double avke; // i) effective hydraulic conductivity of surface soil (mm/h) - real (avke)
//File starting line 5 values for each horizon/layer
public double[] solthk; // a) depth from soil surface to bottom of soil layer (mm) - real (solthk)
public double[] sand; // b) percentage of sand in the layer (%) - real (sand)
public double[] clay; // c) percentage of clay in the layer (%) - real (clay)
public double[] orgmat; // d) percentage of organic matter (volume) in the layer (%) - real (orgmat)
public double[] cec; // e) cation exchange capacity in the layer (meq/100 g of soil) - real (cec)
public double[] rfg; // f) percentage of rock fragments by volume in the layer (%) - real (rfg)
//File last line values: Bedrock restricting layer info (Most of the soils are not going to have any bedrock layer defined so this line ends up being all 0's)
public int restrictingFlag; // a) flag to indicate if present
public int restrictingType; // b) type
public double anisotropyRatio; // c) anisotropy ratio
public double ksat; // d) ksat
public SOLFile(String fileData) throws IOException {
readSol(fileData);
}
/**
* ********************************************************************************************************
*/
/* reads line from file skipping comments */
private String readLine(BufferedReader inpf) {
String line;
try {
line = inpf.readLine();
} catch (IOException e) {
return null;
}
if (line == null || line.length() == 0) {
return null;
}
return line;
}
// Sol file description
// Line 1: version control number (95.7) - real (datver)
// Line 2: a) User comment line - character*80, (solcom)
// Line 3: a) number of overland flow elements(OFE's) or channels integer (ntemp)
// b) flag to to use internal hydraulic conductivity adjustments - integer (ksflag)
// 0 - do not use adjustments (conductivity will be held constant)
// 1 - use internal adjustments
// [ALWAYS "1 1" if generated by us...
// Lines 4 & 5 are repeated for the number of OFE's or channels on Line 3a.
// Line 4: a) soil name for current OFE or channel - character (slid)
// b) soil texture for current OFE or channel - character (texid)
// c) number of soil layers for current OFE or channel - integer (nsl)
// d) albedo of the bare dry surface soil on the current OFE or channel - real (salb)
// e) initial saturation level of the soil profile porosity (m/m) - real (sat)
// f) baseline interrill erodibility parameter (kg*s/m4) - real (ki)
// g) baseline rill erodibility parameter (s/m) - real (kr)
// h) baseline critical shear parameter (N/m2) - real (shcrit)
// i) effective hydraulic conductivity of surface soil (mm/h) - real (avke)
// Line 5: (repeated for the number of soil layers indicated on Line 4c.)
// a) depth from soil surface to bottom of soil layer (mm) - real (solthk)
// b) percentage of sand in the layer (%) - real (sand)
// c) percentage of clay in the layer (%) - real (clay)
// d) percentage of organic matter (volume) in the layer (%) - real (orgmat)
// e) cation exchange capacity in the layer (meq/100 g of soil) - real (cec)
// f) percentage of rock fragments by volume in the layer (%) - real (rfg)
// Line 6: Bedrock restricting layer info (Most of the soils are not going to have any bedrock layer defined so this line ends up being all 0's)
// a) flag to indicate if present
// b) type
// c) anisotropy ratio
// d) ksat
private void readNewSol(BufferedReader inpf) throws IOException {
try {
//Should now be starting with line 4:
String line4 = readLine(inpf);
String[] line4Parts = line4.trim().split(" ");
if (line4Parts.length != 9) {
throw new IOException("SOL file does not contain a valid line 4. Expected 9 values on line 4 but found " + line4Parts.length);
}
// Read initial data about soil
soilName = line4Parts[0];
soilTexture = line4Parts[1];
numLayers = Integer.parseInt(line4Parts[2]);
salb = Double.parseDouble(line4Parts[3]);
sat = Double.parseDouble(line4Parts[4]);
ki = Double.parseDouble(line4Parts[5]);
kr = Double.parseDouble(line4Parts[6]);
shcrit = Double.parseDouble(line4Parts[7]);
avke = Double.parseDouble(line4Parts[8]);
solthk = new double[numLayers];
sand = new double[numLayers];
clay = new double[numLayers];
orgmat = new double[numLayers];
cec = new double[numLayers];
rfg = new double[numLayers];
// Read each soil horizon/layer present in file
for (int i = 0; i < numLayers; i++) {
String horizonLine = readLine(inpf);
if ((null != horizonLine) && (!horizonLine.isEmpty())) {
String[] lineParts = horizonLine.trim().split(" ");
if (lineParts.length != 6) {
throw new IOException("Invlalid horizon line found in SOL file on line " + (5 + i)
+ ". Line does not contain 6 values as expected, but has " + lineParts.length + " values instead.");
}
solthk[i] = Double.parseDouble(lineParts[0]);
sand[i] = Double.parseDouble(lineParts[1]);
clay[i] = Double.parseDouble(lineParts[2]);
orgmat[i] = Double.parseDouble(lineParts[3]);
cec[i] = Double.parseDouble(lineParts[4]);
rfg[i] = Double.parseDouble(lineParts[5]);
} else {
throw new IOException("Invalid horizon line found in SOL file on line " + (5 + i) + ".");
}
}
// Now read bedrock line
String bedrockLine = readLine(inpf);
if ((null != bedrockLine) && (!bedrockLine.isEmpty())) {
String[] lineParts = bedrockLine.trim().split(" ");
if (lineParts.length != 4) {
throw new IOException("SOL file does not contain a valid bedrock line. Expected 4 values on line 4 but found " + lineParts.length);
}
restrictingFlag = Integer.parseInt(lineParts[0]);
restrictingType = Integer.parseInt(lineParts[1]);
anisotropyRatio = Double.parseDouble(lineParts[2]);
ksat = Double.parseDouble(lineParts[2]);
} else {
throw new IOException("No bedrock line found in this SOL file.");
}
} finally {
try {
inpf.close();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Unable to close soil input stream.", e);
}
}
//System.out.println(errorsInSolFile);
}
/**
*
* @param fileData
* @throws java.io.IOException
*/
/* reads ifc file */
private void readSol(String fileData) throws IOException {
BufferedReader inpf;
inpf = new BufferedReader(new StringReader(fileData));
String firstLine = readLine(inpf);
if (firstLine.startsWith("2006.2")) {
comments = readLine(inpf);
if ((null != comments) && (!comments.isEmpty())) {
comments = comments.replace("Comments:", "").trim();
}
String line3 = readLine(inpf);
if (null != line3) {
line3 = line3.trim();
if (!line3.equalsIgnoreCase("1 1")) {
throw new IOException("Invalid SOL File. Line 3 shold be '1 1' but is: " + line3);
}
}
readNewSol(inpf);
} else {
throw new IOException("Invalid SOL File. Version tag not found or does not match '2006.2'");
}
}
}