IFCData.java [src/java/d/dataNodes] Revision: default  Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2017, 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 d.dataNodes;

import csip.SessionLogger;
import d.util.SoilUtil;
import d.util.Utils;
import static d.dataNodes.IFCRanges.layerList;
import static d.dataNodes.IFCRanges.surfaceList;
import d.soils.wwe02_wepssoilinput.ErrorRange;
import java.text.NumberFormat;
import java.util.logging.Level;

/**
 *
 * @author brad
 */
public class IFCData {
    
    SessionLogger LOG;
    
    private String localPhase = "local phase";
    private String taxOrder = "tax order";
    private int soilLossTolerance = 0;
    private double surfaceAlbedo = Double.NaN;
    private double surfaceSlope = -1;
    private double surfaceFragmentCover = 0;
    private double bedrockDepth = 9999;
    private double impermiableDepth = 9999;
    private double layerThickness[];
    private double fractionSand[];
    private double fractionSilt[];
    private double fractionClay[];
    private double fractionRock[];
    private double veryCoarseSandFraction[];
    private double coarseSandFraction[];
    private double mediumSandFraction[];
    private double fineSandFraction[];
    private double veryFineSandFraction[];
    private double wetBulkDensity[];
    private double organicMaterial[];
    private double soilpH[];
    private double calciumCarbonateEquivalent[];
    private double cationExchangeCapacity[];
    private double linearExtensibility[];
    private double aggregateMeanDiameter[];
    private double aggregateStdDeviation[];
    private double maxAggregateSize[];
    private double minAggregateSize[];
    private double aggregateDensity[];
    private double aggregateStability[];
    private double crustThickness = 0.01;
    private double crustDensity = Double.NaN;
    private double crustStability = Double.NaN;
    private double crustFraction = 0;
    private double crustLooseMaterialMass = 0;
    private double crustLooseMaterialFraction = 0;
    private double randomRoughness = 4.0;
    private double roughnessOrientation = 0;
    private double roughnessHeight = 0;
    private double roughnessSpacing = 10.0;
    private double roughnessWidth = 10.0;
    private double initialBulkDensity[];
    private double initialSWC[];
    private double saturatedSWC[];
    private double fieldCapacitySWC[];
    private double wiltingPointSWC[];
    private double soilCB[];
    private double airEntryPotential[];
    private double saturatedHydraulicConductivity[];
    private String errorsInIfcFile;
    private int numberOfSoilLayers;
    private double layerDepthBottom[];
    private double layerDepthTop[];
    private double dryBulkDensity[];
    private double tenthBarSWC[];
    private String state;
    private String county;
    private String soilSurveyAreaName;
    private String soilSurveyID;
    private String mapUnitSymbol;
    private String componentName;
    private String componentPercent;
    private String surfaceTexture;
    
    static final ErrorRange ER_crustLooseMaterialFraction = surfaceList[6];				// loose material fraction
    static final ErrorRange ER_crustFraction = surfaceList[4];				// soil crust surface fraction
    
    
    
    public IFCData(NASIS nasinp,SessionLogger log) {
        LOG = log;
        numberOfSoilLayers = nasinp.getAdjlay();
        copyNasData(nasinp);
        convertUnits();
        calculateFactors();
        ER_crustLooseMaterialFraction.setHighValue(crustFraction);
        ER_crustFraction.setLowValue(crustLooseMaterialFraction);
        //System.out.println("IFC_IFC num_lay: " + nsl + errorsInIfcFile);

    }

    public int getNumberOfSoilLayers() {
        return numberOfSoilLayers;
    }

    public void setNumberOfSoilLayers(int numberOfSoilLayers) {
        this.numberOfSoilLayers = numberOfSoilLayers;
    }
    
    
    public String getLocalPhase() {
        return localPhase;
    }

    public void setLocalPhase(String localPhase) {
        this.localPhase = localPhase;
    }

    public String getTaxOrder() {
        return taxOrder;
    }

    public void setTaxOrder(String taxOrder) {
        this.taxOrder = taxOrder;
    }

    public int getSoilLossTolerance() {
        return soilLossTolerance;
    }

    public void setSoilLossTolerance(int soilLossTolerance) {
        this.soilLossTolerance = soilLossTolerance;
    }

    public double getSurfaceAlbedo() {
        return surfaceAlbedo;
    }

    public void setSurfaceAlbedo(double surfaceAlbedo) {
        this.surfaceAlbedo = surfaceAlbedo;
    }

    public double getSurfaceSlope() {
        return surfaceSlope;
    }

    public void setSurfaceSlope(double surfaceSlope) {
        this.surfaceSlope = surfaceSlope;
    }

    public double getSurfaceFragmentCover() {
        return surfaceFragmentCover;
    }

    public void setSurfaceFragmentCover(double surfaceFragmentCover) {
        this.surfaceFragmentCover = surfaceFragmentCover;
    }

    public double getBedrockDepth() {
        return bedrockDepth;
    }

    public void setBedrockDepth(double bedrockDepth) {
        this.bedrockDepth = bedrockDepth;
    }

    public double getImpermiableDepth() {
        return impermiableDepth;
    }

    public void setImpermiableDepth(double impermiableDepth) {
        this.impermiableDepth = impermiableDepth;
    }

    public double[] getLayerThickness() {
        return layerThickness;
    }

    public void setLayerThickness(double[] layerThickness) {
        this.layerThickness = layerThickness;
    }

    public double[] getFractionSand() {
        return fractionSand;
    }

    public void setFractionSand(double[] fractionSand) {
        this.fractionSand = fractionSand;
    }

    public double[] getFractionSilt() {
        return fractionSilt;
    }

    public void setFractionSilt(double[] fractionSilt) {
        this.fractionSilt = fractionSilt;
    }

    public double[] getFractionClay() {
        return fractionClay;
    }

    public void setFractionClay(double[] fractionClay) {
        this.fractionClay = fractionClay;
    }

    public double[] getFractionRock() {
        return fractionRock;
    }

    public void setFractionRock(double[] fractionRock) {
        this.fractionRock = fractionRock;
    }

    public double[] getVeryCoarseSandFraction() {
        return veryCoarseSandFraction;
    }

    public void setVeryCoarseSandFraction(double[] veryCoarseSandFraction) {
        this.veryCoarseSandFraction = veryCoarseSandFraction;
    }

    public double[] getCoarseSandFraction() {
        return coarseSandFraction;
    }

    public void setCoarseSandFraction(double[] coarseSandFraction) {
        this.coarseSandFraction = coarseSandFraction;
    }

    public double[] getMediumSandFraction() {
        return mediumSandFraction;
    }

    public void setMediumSandFraction(double[] mediumSandFraction) {
        this.mediumSandFraction = mediumSandFraction;
    }

    public double[] getFineSandFraction() {
        return fineSandFraction;
    }

    public void setFineSandFraction(double[] fineSandFraction) {
        this.fineSandFraction = fineSandFraction;
    }

    public double[] getVeryFineSandFraction() {
        return veryFineSandFraction;
    }

    public void setVeryFineSandFraction(double[] veryFineSandFraction) {
        this.veryFineSandFraction = veryFineSandFraction;
    }

    public double[] getWetBulkDensity() {
        return wetBulkDensity;
    }

    public void setWetBulkDensity(double[] wetBulkDensity) {
        this.wetBulkDensity = wetBulkDensity;
    }

    public double[] getOrganicMaterial() {
        return organicMaterial;
    }

    public void setOrganicMaterial(double[] organicMaterial) {
        this.organicMaterial = organicMaterial;
    }

    public double[] getSoilpH() {
        return soilpH;
    }

    public void setSoilpH(double[] soilpH) {
        this.soilpH = soilpH;
    }

    public double[] getCalciumCarbonateEquivalent() {
        return calciumCarbonateEquivalent;
    }

    public void setCalciumCarbonateEquivalent(double[] calciumCarbonateEquivalent) {
        this.calciumCarbonateEquivalent = calciumCarbonateEquivalent;
    }

    public double[] getCationExchangeCapacity() {
        return cationExchangeCapacity;
    }

    public void setCationExchangeCapacity(double[] cationExchangeCapacity) {
        this.cationExchangeCapacity = cationExchangeCapacity;
    }

    public double[] getLinearExtensibility() {
        return linearExtensibility;
    }

    public void setLinearExtensibility(double[] linearExtensibility) {
        this.linearExtensibility = linearExtensibility;
    }

    public double[] getAggregateMeanDiameter() {
        return aggregateMeanDiameter;
    }

    public void setAggregateMeanDiameter(double[] aggregateMeanDiameter) {
        this.aggregateMeanDiameter = aggregateMeanDiameter;
    }

    public double[] getAggregateStdDeviation() {
        return aggregateStdDeviation;
    }

    public void setAggregateStdDeviation(double[] aggregateStdDeviation) {
        this.aggregateStdDeviation = aggregateStdDeviation;
    }

    public double[] getMaxAggregateSize() {
        return maxAggregateSize;
    }

    public void setMaxAggregateSize(double[] maxAggregateSize) {
        this.maxAggregateSize = maxAggregateSize;
    }

    public double[] getMinAggregateSize() {
        return minAggregateSize;
    }

    public void setMinAggregateSize(double[] minAggregateSize) {
        this.minAggregateSize = minAggregateSize;
    }

    public double[] getAggregateDensity() {
        return aggregateDensity;
    }

    public void setAggregateDensity(double[] aggregateDensity) {
        this.aggregateDensity = aggregateDensity;
    }

    public double[] getAggregateStability() {
        return aggregateStability;
    }

    public void setAggregateStability(double[] aggregateStability) {
        this.aggregateStability = aggregateStability;
    }

    public double getCrustThickness() {
        return crustThickness;
    }

    public void setCrustThickness(double crustThickness) {
        this.crustThickness = crustThickness;
    }

    public double getCrustDensity() {
        return crustDensity;
    }

    public void setCrustDensity(double crustDensity) {
        this.crustDensity = crustDensity;
    }

    public double getCrustStability() {
        return crustStability;
    }

    public void setCrustStability(double crustStability) {
        this.crustStability = crustStability;
    }

    public double getCrustFraction() {
        return crustFraction;
    }

    public void setCrustFraction(double crustFraction) {
        this.crustFraction = crustFraction;
    }

    public double getCrustLooseMaterialMass() {
        return crustLooseMaterialMass;
    }

    public void setCrustLooseMaterialMass(double crustLooseMaterialMass) {
        this.crustLooseMaterialMass = crustLooseMaterialMass;
    }

    public double getCrustLooseMaterialFraction() {
        return crustLooseMaterialFraction;
    }

    public void setCrustLooseMaterialFraction(double crustLooseMaterialFraction) {
        this.crustLooseMaterialFraction = crustLooseMaterialFraction;
    }

    public double getRandomRoughness() {
        return randomRoughness;
    }

    public void setRandomRoughness(double randomRoughness) {
        this.randomRoughness = randomRoughness;
    }

    public double getRoughnessOrientation() {
        return roughnessOrientation;
    }

    public void setRoughnessOrientation(double roughnessOrientation) {
        this.roughnessOrientation = roughnessOrientation;
    }

    public double getRoughnessHeight() {
        return roughnessHeight;
    }

    public void setRoughnessHeight(double roughnessHeight) {
        this.roughnessHeight = roughnessHeight;
    }

    public double getRoughnessSpacing() {
        return roughnessSpacing;
    }

    public void setRoughnessSpacing(double roughnessSpacing) {
        this.roughnessSpacing = roughnessSpacing;
    }

    public double getRoughnessWidth() {
        return roughnessWidth;
    }

    public void setRoughnessWidth(double roughnessWidth) {
        this.roughnessWidth = roughnessWidth;
    }

    public double[] getInitialBulkDensity() {
        return initialBulkDensity;
    }

    public void setInitialBulkDensity(double[] initialBulkDensity) {
        this.initialBulkDensity = initialBulkDensity;
    }

    public double[] getInitialSWC() {
        return initialSWC;
    }

    public void setInitialSWC(double[] initialSWC) {
        this.initialSWC = initialSWC;
    }

    public double[] getSaturatedSWC() {
        return saturatedSWC;
    }

    public void setSaturatedSWC(double[] saturatedSWC) {
        this.saturatedSWC = saturatedSWC;
    }

    public double[] getFieldCapacitySWC() {
        return fieldCapacitySWC;
    }

    public void setFieldCapacitySWC(double[] fieldCapacitySWC) {
        this.fieldCapacitySWC = fieldCapacitySWC;
    }

    public double[] getWiltingPointSWC() {
        return wiltingPointSWC;
    }

    public void setWiltingPointSWC(double[] wiltingPointSWC) {
        this.wiltingPointSWC = wiltingPointSWC;
    }

    public double[] getSoilCB() {
        return soilCB;
    }

    public void setSoilCB(double[] soilCB) {
        this.soilCB = soilCB;
    }

    public double[] getAirEntryPotential() {
        return airEntryPotential;
    }

    public void setAirEntryPotential(double[] airEntryPotential) {
        this.airEntryPotential = airEntryPotential;
    }

    public double[] getSaturatedHydraulicConductivity() {
        return saturatedHydraulicConductivity;
    }

    public void setSaturatedHydraulicConductivity(double[] saturatedHydraulicConductivity) {
        this.saturatedHydraulicConductivity = saturatedHydraulicConductivity;
    }

    public String getErrorsInIfcFile() {
        return errorsInIfcFile;
    }

    public void setErrorsInIfcFile(String errorsInIfcFile) {
        this.errorsInIfcFile = errorsInIfcFile;
    }

    public double[] getLayerDepthBottom() {
        return layerDepthBottom;
    }

    public void setLayerDepthBottom(double[] layerDepthBottom) {
        this.layerDepthBottom = layerDepthBottom;
    }

    public double[] getLayerDepthTop() {
        return layerDepthTop;
    }

    public void setLayerDepthTop(double[] layerDepthTop) {
        this.layerDepthTop = layerDepthTop;
    }

    public double[] getDryBulkDensity() {
        return dryBulkDensity;
    }

    public void setDryBulkDensity(double[] dryBulkDensity) {
        this.dryBulkDensity = dryBulkDensity;
    }

    public double[] getTenthBarSWC() {
        return tenthBarSWC;
    }

    public void setTenthBarSWC(double[] tenthBarSWC) {
        this.tenthBarSWC = tenthBarSWC;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getCounty() {
        return county;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    public String getSoilSurveyAreaName() {
        return soilSurveyAreaName;
    }

    public void setSoilSurveyAreaName(String soilSurveyAreaName) {
        this.soilSurveyAreaName = soilSurveyAreaName;
    }

    public String getSoilSurveyID() {
        return soilSurveyID;
    }

    public void setSoilSurveyID(String soilSurveyID) {
        this.soilSurveyID = soilSurveyID;
    }

    public String getMapUnitSymbol() {
        return mapUnitSymbol;
    }

    public void setMapUnitSymbol(String mapUnitSymbol) {
        this.mapUnitSymbol = mapUnitSymbol;
    }

    public String getComponentName() {
        return componentName;
    }

    public void setComponentName(String componentName) {
        this.componentName = componentName;
    }

    public String getComponentPercent() {
        return componentPercent;
    }

    public void setComponentPercent(String componentPercent) {
        this.componentPercent = componentPercent;
    }

    public String getSurfaceTexture() {
        return surfaceTexture;
    }

    public void setSurfaceTexture(String surfaceTexture) {
        this.surfaceTexture = surfaceTexture;
    }
    
    

    private void initIfc(int inpnsl) {

        numberOfSoilLayers = inpnsl;

        double[] tmpArr = new double[inpnsl];
        for (int idx = 0; idx < inpnsl; idx++) {
            tmpArr[idx] = Double.NaN;
        }

        // create layer arrays
        layerDepthTop = tmpArr.clone();			// depth to top of layer
        layerDepthBottom = tmpArr.clone();			// depth to bottom of layer
        layerThickness = tmpArr.clone();			// thickness in mm
        fractionSand = tmpArr.clone();			// % sand
        fractionSilt = tmpArr.clone();			// % silt
        fractionClay = tmpArr.clone();			// % clay
        fractionRock = tmpArr.clone();			// rock %
        veryCoarseSandFraction = tmpArr.clone();			// sand fraction coarse
        coarseSandFraction = tmpArr.clone();			// sand fraction coarse
        mediumSandFraction = tmpArr.clone();			// sand fraction medium
        fineSandFraction = tmpArr.clone();			// sand fraction fine
        veryFineSandFraction = tmpArr.clone();			// sand fraction very find
        dryBulkDensity = tmpArr.clone();			// bulk density dry
        initialBulkDensity = tmpArr.clone();			// bulk density dry
        wetBulkDensity = tmpArr.clone();			// bulk density 1/3 bar
        aggregateMeanDiameter = tmpArr.clone();			// aggregate mean diameter
        aggregateStdDeviation = tmpArr.clone();			// aggregate standard deviation
        maxAggregateSize = tmpArr.clone();		// max aggregate size
        minAggregateSize = tmpArr.clone();		// min aggregate size
        aggregateDensity = tmpArr.clone();		// aggregate density
        aggregateStability = tmpArr.clone();		// aggregate stability
        initialSWC = tmpArr.clone();			// initial soil water content (swc)
        saturatedSWC = tmpArr.clone();			// saturated swc
        fieldCapacitySWC = tmpArr.clone();			// field capacity swc
        wiltingPointSWC = tmpArr.clone();			// wilting point swc
        tenthBarSWC = tmpArr.clone();			// 0.1 bar on sand soil
        soilCB = tmpArr.clone();			// soil CB
        airEntryPotential = tmpArr.clone();			// air entry potential
        saturatedHydraulicConductivity = tmpArr.clone();			// sat hydraulic conductivity
        organicMaterial = tmpArr.clone();			// organic matter
        soilpH = tmpArr.clone();			// soil pH
        calciumCarbonateEquivalent = tmpArr.clone();			// calcium carbonate equiv
        cationExchangeCapacity = tmpArr.clone();			// cation exchange capacity
        linearExtensibility = tmpArr.clone();			// linear extensibility

    }
    
    public String chkSoilandSandPcts() {
        String warningMessage = null;
        
        NumberFormat.getInstance().setMaximumFractionDigits(4);
        for (int ldx = 0; ldx < numberOfSoilLayers; ldx++) {
            if ((Math.abs(fractionSand[ldx] + fractionSilt[ldx] + fractionClay[ldx] - 1.0) > 0.0001)) {
                 warningMessage = "Bad soil fractions for layer "
                        + (ldx + 1) + " sand " + Utils.formatDouble(fractionSand[ldx], 4)
                        + " silt " + Utils.formatDouble(fractionSilt[ldx], 4) + " clay "
                        + Utils.formatDouble(fractionClay[ldx], 4);
            }
            
            if(warningMessage != null)
                break;

            if (veryCoarseSandFraction[ldx] + coarseSandFraction[ldx] + mediumSandFraction[ldx]
                    + fineSandFraction[ldx] + veryFineSandFraction[ldx] > fractionSand[ldx] + 0.0001) {
                warningMessage = "sand fractions exceed total sand for layer "
                        + (ldx + 1) + " sand " + Utils.formatDouble(fractionSand[ldx], 4)
                        + " veryCoarseSandFraction " + Utils.formatDouble(veryCoarseSandFraction[ldx], 4)
                        + " coarseSandFraction " + Utils.formatDouble(coarseSandFraction[ldx], 4)
                        + " mediumSandFraction " + Utils.formatDouble(mediumSandFraction[ldx], 4)
                        + " fineSandFraction " + Utils.formatDouble(fineSandFraction[ldx], 4)
                        + " veryFineSandFraction " + Utils.formatDouble(veryFineSandFraction[ldx], 4);
            }
            if(warningMessage != null)
                break;
        }
        return warningMessage;
    }
    
    private void copyNasData(NASIS nasinp) {

        // create ifc structure
        initIfc(numberOfSoilLayers);

        layerDepthBottom = nasinp.getHzdepb().clone();
        layerThickness[0] = nasinp.getHzdepb()[0];
        for (int ldx = 1; ldx < numberOfSoilLayers; ldx++) {					// fill in top depth & thickness
            layerDepthTop[ldx] = nasinp.getHzdepb()[ldx - 1];					// current top is previous bottom
            layerThickness[ldx] = nasinp.getHzdepb()[ldx] - layerDepthTop[ldx];	// thickness is bottom - top
        }

        fractionClay = nasinp.getClaytotal().clone();			// clay
        fractionSand = nasinp.getSandtotal().clone();			// sand
        for (int ldx = 0; ldx < numberOfSoilLayers; ldx++) {				// remainder is silt
            if (fractionClay[ldx] < 1) {
                fractionClay[ldx] = 1;				// define minimum clay to be 1%
            }
            if (fractionSand[ldx] > 99) {
                fractionSand[ldx] = 99;				// define maximum sand to be 99%
            }
            fractionSilt[ldx] = 100 - (fractionClay[ldx] + fractionSand[ldx]);
            if (fractionSilt[ldx] < 0) {
                fractionSilt[ldx] = Double.NaN;
            }
        }
        fractionRock = nasinp.getFragvol().clone();				// rock %
        veryCoarseSandFraction = nasinp.getSandvco().clone();				// coarseSandFraction
        coarseSandFraction = nasinp.getSandco().clone();				// coarseSandFraction
        mediumSandFraction = nasinp.getSandmed().clone();				// mediumSandFraction
        fineSandFraction = nasinp.getSandfine().clone();				// fineSandFraction
        veryFineSandFraction = nasinp.getSandvf().clone();				// veryFineSandFraction
        wetBulkDensity = nasinp.getDbthirdbar().clone();			// wetBulkDensity
        initialBulkDensity = nasinp.getDbthirdbar().clone();			// wetBulkDensity
        tenthBarSWC = nasinp.getWtenthbar().clone();			// b1ss
        fieldCapacitySWC = nasinp.getWthirdbar().clone();			// fieldCapacitySWC
        wiltingPointSWC = nasinp.getW15thbar().clone();				// wiltingPointSWC
        saturatedHydraulicConductivity = nasinp.getKsat().clone();					// satk
        organicMaterial = nasinp.getOm().clone();						// om
        linearExtensibility = nasinp.getLep().clone();					// lep

        double[] phtmp = new double[nasinp.getAdjlay()];
        for (int ldx = 0; ldx < nasinp.getAdjlay(); ldx++) {
            // ph
            phtmp[ldx] = (!Double.isNaN(nasinp.getPh1to1h2o()[ldx])) ? nasinp.getPh1to1h2o()[ldx] : nasinp.getPh01mcacl2()[ldx];
        }

        soilpH = phtmp;

        double[] cectmp = new double[nasinp.getAdjlay()];
        for (int ldx = 0; ldx < nasinp.getAdjlay(); ldx++) {
            cectmp[ldx] = (!Double.isNaN(nasinp.getCec7()[ldx]))
                    ? nasinp.getCec7()[ldx] : nasinp.getEcec()[ldx];			// cec
        }
        cationExchangeCapacity = cectmp;

// I think this should be commented out because of above code to deal with populated cec7 and ecec fields varying by layer
// So, I will do so and test it - LEW
//	if (nasinp.cec7[0] > 0)											// cec
//		cec = nasinp.cec7/*.clone()*/;
//	else
//		cec = nasinp.ecec/*.clone()*/;
////System.out.println("cND: " + nasinp.calciumCarbonateEquivalent[cdx]
        calciumCarbonateEquivalent = nasinp.getCaco3()/*.clone()*/;				// caco3

        state = nasinp.getState();
        county = nasinp.getCounty();
        soilSurveyAreaName = nasinp.getSsaname();
        soilSurveyID = nasinp.getSsaid();
        mapUnitSymbol = nasinp.getMusym();
        componentName = nasinp.getCompname();
        componentPercent = nasinp.getComppct();
        taxOrder = nasinp.getTaxorder();
        surfaceAlbedo = nasinp.getAlbedodry();
        surfaceSlope = nasinp.getSlope();
        surfaceTexture = nasinp.getTexture()[0];				// surface texture
        localPhase = nasinp.getLocalphase();

        //1143.2
        bedrockDepth = nasinp.getBedrockDepth();
        impermiableDepth = nasinp.getImpermiableDepth();

        soilLossTolerance = (int) nasinp.getLosstolerance();

    }
    
    private void convertUnits() {

////System.out.println("split nsl: " + nsl);
        for (int ldx = 0; ldx < numberOfSoilLayers; ldx++) {
            layerThickness[ldx] *= 10.;				// thk				// cvt from cm to mm
            layerDepthBottom[ldx] *= 10.;				// depb
            layerDepthTop[ldx] *= 10.;				// dept
            fractionSand[ldx] /= 100.;				// sand				// cvt from % to fraction
            fractionClay[ldx] /= 100.;				// clay
            fractionSilt[ldx] /= 100.;				// silt
            fractionRock[ldx] /= 100.;				// rock
            veryCoarseSandFraction[ldx] /= 100.;				// sand coarse
            coarseSandFraction[ldx] /= 100.;				// sand coarse
            mediumSandFraction[ldx] /= 100.;				// sand medium
            fineSandFraction[ldx] /= 100.;				// sand fine
            veryFineSandFraction[ldx] /= 100.;				// sand very fine
//		[ldx]/= 100.;					// water dispersible clay
            fieldCapacitySWC[ldx] /= 100.;				// field capacity swc
            wiltingPointSWC[ldx] /= 100.;				// wilting point swc
            organicMaterial[ldx] /= 100.;				// organic matter
            calciumCarbonateEquivalent[ldx] /= 100.;				// caco3
            saturatedHydraulicConductivity[ldx] /= 1000000.;			// saturation k		// cvt from ppm to p
            //linearExtensibility[ldx] /= 100;	// linear extensibility, 1143.3 commented out so that units remain as LEP
        }

        surfaceSlope /= 100;							// surface slope from % to fraction
        bedrockDepth *= 10;                                                           //Bedrockdepth cm -> mm
        impermiableDepth *= 10;                                                       //Restrictive Depth cm -> mm
    }
    
    private void calculateFactors() {

        for (int ldx = 0; ldx < numberOfSoilLayers; ldx++) {									// parameters by layer
            // formula from 12/6/95 memo from LJH to JT

            double rtnval = 0;

            aggregateMeanDiameter[ldx] = Math.exp(1.343 - 2.235 * fractionSand[ldx] - // aggregate geometric mean diameter
                    1.226 * fractionSilt[ldx] - 0.0238 * fractionSand[ldx] / fractionClay[ldx]
                    + 33.6 * organicMaterial[ldx] + 6.85
                    * calciumCarbonateEquivalent[ldx]) * (1 + 0.006 * layerDepthBottom[ldx]);
            rtnval = layerList[14].adjValue(aggregateMeanDiameter[ldx]);
            if (rtnval != aggregateMeanDiameter[ldx]) {
                String msgText = layerList[14].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(aggregateMeanDiameter[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                aggregateMeanDiameter[ldx] = rtnval;
            }

            aggregateStdDeviation[ldx] = 1 / (0.012448 + 0.002463 * aggregateMeanDiameter[ldx]
                    + (0.093467 / (Math.pow(aggregateMeanDiameter[ldx], 0.5))));
            rtnval = layerList[15].adjValue(aggregateStdDeviation[ldx]);
            if (rtnval != aggregateStdDeviation[ldx]) {
                String msgText = layerList[15].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(aggregateStdDeviation[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING,msgText);
                aggregateStdDeviation[ldx] = rtnval;
            }

            maxAggregateSize[ldx] = Math.pow(aggregateStdDeviation[ldx],
                    (1.52 * (Math.pow(aggregateMeanDiameter[ldx], -0.449)))) * aggregateMeanDiameter[ldx];
            rtnval = layerList[16].adjValue(maxAggregateSize[ldx]);
            if (rtnval != maxAggregateSize[ldx]) {
                String msgText = layerList[16].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(maxAggregateSize[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                maxAggregateSize[ldx] = rtnval;
            }

            minAggregateSize[ldx] = 0.01;												// minimum aggregate size

            aggregateDensity[ldx] = 1.8;
            rtnval = layerList[18].adjValue(aggregateDensity[ldx]);
            if (rtnval != aggregateDensity[ldx]) {
                String msgText = layerList[18].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(aggregateDensity[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                aggregateDensity[ldx] = rtnval;
            }

            aggregateStability[ldx] = (fractionClay[ldx] > 0.5) ? 2.73 : 0.83 + 15.7 * fractionClay[ldx]
                    - 23.8 * Math.pow(fractionClay[ldx], 2);								// aggregate stability
            rtnval = layerList[19].adjValue(aggregateStability[ldx]);
            if (rtnval != aggregateStability[ldx]) {
                String msgText = layerList[19].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(aggregateStability[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                aggregateStability[ldx] = rtnval;
            }

            /**
             * saxton95.for
             * calculate cb, thetas & pote.  do not calc satk, thetaw or thetaf as they
             * come from input file.
             */
            double sax_e = -3.140, sax_f = -2.22e-3, sax_g = -3.484e-5;			// coef used to calc CB
            double sax_m = -0.108, sax_n = 0.341;								// coef used to calc POTE  (not used in this code)
            double sax_x = 0.332, sax_y = -7.251e-4, sax_z = 0.1276;			// coef used to calc THETAS

            saturatedSWC[ldx] = sax_x + sax_y * fractionSand[ldx] * 100. + // saturated soil water content
                    sax_z * (Math.log(fractionClay[ldx] * 100.) / Math.log(10.));
            rtnval = layerList[21].adjValue(saturatedSWC[ldx]);
            if (rtnval != saturatedSWC[ldx]) {
                String msgText = layerList[21].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(saturatedSWC[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                saturatedSWC[ldx] = rtnval;
            }

            soilCB[ldx] = -(sax_e + // cb(k) == ifc3_layer[][23]
                    (sax_f * Math.pow(fractionClay[ldx] * 100., 2.0))
                    + (sax_g * Math.pow(fractionSand[ldx] * 100., 2.0) * fractionClay[ldx] * 100.));
            rtnval = layerList[24].adjValue(soilCB[ldx]);
            if (rtnval != soilCB[ldx]) {
                String msgText = layerList[24].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(soilCB[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                soilCB[ldx] = rtnval;
            }

            double sax_a = 100 * Math.exp(-4.396 - // calc A factor for pote
                    0.0715 * (fractionClay[ldx] * 100.) - // using two steps because that is how
                    (4.880e-4) * Math.pow(fractionSand[ldx] * 100., 2) - // saxton95 does it
                    (4.285e-5) * Math.pow(fractionSand[ldx] * 100., 2) * (fractionClay[ldx] * 100.));

            airEntryPotential[ldx] = -sax_a * Math.pow(saturatedSWC[ldx], -soilCB[ldx]); // calc pote
            rtnval = layerList[25].adjValue(airEntryPotential[ldx]);
            if (rtnval != airEntryPotential[ldx]) {
                String msgText = layerList[25].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(airEntryPotential[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                airEntryPotential[ldx] = rtnval;
            }

            if (fieldCapacitySWC[ldx] == 0.0 || Double.isNaN(fieldCapacitySWC[ldx])) {
                fieldCapacitySWC[ldx] = Math.pow((33.0 / sax_a), (1 / -soilCB[ldx]));
                rtnval = layerList[22].adjValue(fieldCapacitySWC[ldx]);
                if (rtnval != fieldCapacitySWC[ldx]) {
                    String msgText = layerList[22].getTitle() + " adjusted: old value "
                            + Utils.formatDouble(fieldCapacitySWC[ldx], 4) + " new value " + rtnval;
                    LOG.log(Level.WARNING, msgText);
                    fieldCapacitySWC[ldx] = rtnval;
                } else {
                    String msgText = "field capacity layer " + (ldx + 1)
                            + " input as 0.0 or NaN; replaced with estimate " + Utils.formatDouble(fieldCapacitySWC[ldx], 4);
                    LOG.log(Level.WARNING, msgText);
                }

            }

            if (wiltingPointSWC[ldx] == 0.0 || Double.isNaN(wiltingPointSWC[ldx])) {
                wiltingPointSWC[ldx] = Math.pow((1500.0 / sax_a), (1 / -soilCB[ldx]));
                rtnval = layerList[23].adjValue(wiltingPointSWC[ldx]);
                if (rtnval != wiltingPointSWC[ldx]) {
                    String msgText = layerList[23].getTitle() + " adjusted: old value "
                            + Utils.formatDouble(wiltingPointSWC[ldx], 4) + " new value " + rtnval;
                    LOG.log(Level.WARNING, msgText);
                    wiltingPointSWC[ldx] = rtnval;
                } else {
                    String msgText = "wilting point layer " + (ldx + 1)
                            + " input as 0.0 or NaN; replaced with estimate " + Utils.formatDouble(wiltingPointSWC[ldx], 4);
                    LOG.log(Level.WARNING, msgText);
                }
            }

            if (saturatedHydraulicConductivity[ldx] == 0.0 || Double.isNaN(saturatedHydraulicConductivity[ldx])) {
                double sk = 9.6 - 0.81 * Math.log(fractionSilt[ldx] * 100.) / Math.log(10.)
                        - 1.09 * Math.log(fractionClay[ldx] * 100.) / Math.log(10.) - 4.64 * initialBulkDensity[ldx];
                saturatedHydraulicConductivity[ldx] = Math.pow(10, sk) * 0.24 * (1.0 / 86400);
                rtnval = layerList[26].adjValue(saturatedHydraulicConductivity[ldx]);
                if (rtnval != saturatedHydraulicConductivity[ldx]) {
                    String msgText = layerList[26].getTitle() + " adjusted: old value "
                            + Utils.formatDouble(saturatedHydraulicConductivity[ldx], 4) + " new value " + rtnval;
                    LOG.log(Level.WARNING, msgText);
                    saturatedHydraulicConductivity[ldx] = rtnval;
                } else {
                    String msgText = "satk layer " + (ldx + 1)
                            + " input as 0.0 or NaN; replaced with estimate "
                            + Utils.formatDouble(saturatedHydraulicConductivity[ldx], 4);
                    LOG.log(Level.WARNING, msgText);
                }
            }

            if (soilpH[ldx] == 0.0 || Double.isNaN(soilpH[ldx])) {
                rtnval = 7;
                String msgText = layerList[27].getTitle() + " adjusted: old value "
                        + Utils.formatDouble(soilpH[ldx], 4) + " new value " + rtnval;
                LOG.log(Level.WARNING, msgText);
                soilpH[ldx] = rtnval;
            }

            if (cationExchangeCapacity[ldx] == 0.0 || Double.isNaN(cationExchangeCapacity[ldx])) {
                cationExchangeCapacity[ldx] = fractionClay[ldx] * 100 * 0.5 + organicMaterial[ldx] * 100. * 2.0;
                rtnval = layerList[29].adjValue(cationExchangeCapacity[ldx]);
                if (rtnval != cationExchangeCapacity[ldx]) {
                    String msgText = layerList[29].getTitle() + " adjusted: old value "
                            + Utils.formatDouble(cationExchangeCapacity[ldx], 4) + " new value " + rtnval;
                    LOG.log(Level.WARNING, msgText);
                    cationExchangeCapacity[ldx] = rtnval;
                } else {
                    String msgText = "cec layer " + (ldx + 1)
                            + " input as 0.0 or NaN; replaced with estimate "
                            + Utils.formatDouble(cationExchangeCapacity[ldx], 4);
                    LOG.log(Level.WARNING, msgText);
                }
            }

            if (linearExtensibility[ldx] == 0.0 || Double.isNaN(linearExtensibility[ldx])) {
                double bsd = SoilUtil.estimateSettledBulkDensity(fractionClay[ldx], fractionSand[ldx], organicMaterial[ldx]);

                if (wetBulkDensity[ldx] > bsd) {
                    bsd = wetBulkDensity[ldx];
                    String msgText = "Settled bulk density adjusted: Set to wet bulk density.";
                    LOG.log(Level.WARNING, msgText);
                } else {
                    String msgText = "Settled bulk density estimated: " + Utils.formatDouble(bsd, 4);
                    LOG.log(Level.WARNING, msgText);
                }

                linearExtensibility[ldx] = SoilUtil.estimateLinearExtensibility(bsd, wetBulkDensity[ldx]);
                rtnval = layerList[30].adjValue(linearExtensibility[ldx]);
                if (rtnval != linearExtensibility[ldx]) {
                    String msgText = layerList[30].getTitle()+ " adjusted: old value "
                            + Utils.formatDouble(linearExtensibility[ldx], 4) + " new value " + rtnval;
                    LOG.log(Level.WARNING, msgText);
                    linearExtensibility[ldx] = rtnval;
                } else {
                    String msgText = "cec layer " + (ldx + 1)
                            + " input as 0.0 or NaN; replaced with estimate "
                            + Utils.formatDouble(linearExtensibility[ldx], 4);
                    LOG.log(Level.WARNING, msgText);
                }
            }

            initialSWC[ldx] = (fieldCapacitySWC[ldx] + wiltingPointSWC[ldx]) / 2;			// initial soil water content

        }

        // parameters not by layer
        crustThickness = 0.01;											// soil crust thickness
        crustDensity = aggregateDensity[0];								// soil crust density
        crustStability = aggregateStability[0];								// soil crust stability
        randomRoughness = 4;												// random roughness
        if (surfaceAlbedo == 0.0 || Double.isNaN(surfaceAlbedo)) {
            surfaceAlbedo = 0.6 / (Math.exp(0.4 * organicMaterial[0] * 100.0));
            String msgText = "dry albedo input as 0.0 or NaN; replaced with estimate"
                    + Utils.formatDouble(surfaceAlbedo, 4);
            LOG.log(Level.WARNING, msgText);
        }

    }
}