IFCWriter.java [src/java/d/util] 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.util;

import csip.api.server.ServiceException;
import d.dataNodes.IFCData;
import d.dataNodes.IFCRanges;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.util.function.Function;
import soils.Component;
import soils.Horizon;
import soils.MapUnit;
import soils.utils.EvalResult;

/**
 *
 * @author brad
 * @author <a href="mailto:shaun.case@colostate.edu">Shaun Case</a>
 */
public class IFCWriter {

    public String writeIFCfile(IFCData ifcData, String filePath) throws IOException {

        PrintWriter outprtWriter;
        String warnings = null;

        //adjustIfc(); I don't think this is needed if there is no user input
        if ((warnings = ifcData.chkSoilandSandPcts()) == null) {

            outprtWriter = new PrintWriter(new FileWriter(new File(filePath)));

            outprtWriter.println("Version: 1.0");
            outprtWriter.println("#");
            outprtWriter.println("# Soil ID");
            outprtWriter.println(ifcData.getSoilSurveyID() + "-" + ifcData.getMapUnitSymbol() + "-" + ifcData.getComponentName()
                    + "-" + ifcData.getComponentPercent() + "-" + ifcData.getSurfaceTexture()
                    + "-" + ifcData.getState() + "-" + ifcData.getCounty() + "-" + ifcData.getSoilSurveyAreaName());
            outprtWriter.println("#");

            writeValue(outprtWriter, IFCRanges.idList[9].getTitle(), ifcData.getLocalPhase());  // local phase
            writeValue(outprtWriter, IFCRanges.idList[8].getTitle(), ifcData.getTaxOrder());  // tax order

            writeValue(outprtWriter, IFCRanges.idList[11].getTitle(), ifcData.getSoilLossTolerance());
            writeValue(outprtWriter, IFCRanges.surfaceList[12].getTitle(), ifcData.getSurfaceAlbedo(), 3);
            writeValue(outprtWriter, IFCRanges.surfaceList[13].getTitle(), ifcData.getSurfaceSlope(), 3);
            writeValue(outprtWriter, IFCRanges.surfaceList[14].getTitle(), ifcData.getSurfaceFragmentCover(), 3);

            outprtWriter.println("#");
            writeValue(outprtWriter, IFCRanges.surfaceList[15].getTitle(), ifcData.getBedrockDepth(), 0);
            writeValue(outprtWriter, IFCRanges.surfaceList[16].getTitle(), ifcData.getImpermiableDepth(), 0);
            outprtWriter.println("#");

            writeValue(outprtWriter, IFCRanges.layerList[0].getTitle(), ifcData.getNumberOfSoilLayers());  // number of layers
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[1].getTitle(), ifcData.getLayerThickness(), 0);  // soil characteristics by layer
            outprtWriter.println("#");

            writeArray(outprtWriter, ifcData, IFCRanges.layerList[3].getTitle(), ifcData.getFractionSand(), 3);				// soil fractions
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[4].getTitle(), ifcData.getFractionSilt(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[5].getTitle(), ifcData.getFractionClay(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[6].getTitle(), ifcData.getFractionRock(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[7].getTitle(), ifcData.getVeryCoarseSandFraction(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[8].getTitle(), ifcData.getCoarseSandFraction(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[9].getTitle(), ifcData.getMediumSandFraction(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[10].getTitle(), ifcData.getFineSandFraction(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[11].getTitle(), ifcData.getVeryFineSandFraction(), 3);
            outprtWriter.println("#");

            writeArray(outprtWriter, ifcData, IFCRanges.layerList[12].getTitle(), ifcData.getWetBulkDensity(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[2].getTitle(), ifcData.getOrganicMaterial(), 4);				// soil chemical properties
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[27].getTitle(), ifcData.getSoilpH(), 2);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[28].getTitle(), ifcData.getCalciumCarbonateEquivalent(), 2);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[29].getTitle(), ifcData.getCationExchangeCapacity(), 2);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[30].getTitle(), ifcData.getLinearExtensibility(), 3);
            outprtWriter.println("#");

            writeArray(outprtWriter, ifcData, IFCRanges.layerList[14].getTitle(), ifcData.getAggregateMeanDiameter(), 3);	// aggregate characteristics
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[15].getTitle(), ifcData.getAggregateStdDeviation(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[16].getTitle(), ifcData.getMaxAggregateSize(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[17].getTitle(), ifcData.getMinAggregateSize(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[18].getTitle(), ifcData.getAggregateDensity(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[19].getTitle(), ifcData.getAggregateStability(), 3);
            outprtWriter.println("#");

            writeValue(outprtWriter, IFCRanges.surfaceList[1].getTitle(), ifcData.getCrustThickness(), 3);  // crust and surface characteristics
            writeValue(outprtWriter, IFCRanges.surfaceList[2].getTitle(), ifcData.getCrustDensity(), 3);
            writeValue(outprtWriter, IFCRanges.surfaceList[3].getTitle(), ifcData.getCrustStability(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[4].getTitle(), ifcData.getCrustFraction(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[5].getTitle(), ifcData.getCrustLooseMaterialMass(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[6].getTitle(), ifcData.getCrustLooseMaterialFraction(), 2);
            outprtWriter.println("#");

            writeValue(outprtWriter, IFCRanges.surfaceList[7].getTitle(), ifcData.getRandomRoughness(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[8].getTitle(), ifcData.getRoughnessOrientation(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[9].getTitle(), ifcData.getRoughnessHeight(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[10].getTitle(), ifcData.getRoughnessSpacing(), 2);
            writeValue(outprtWriter, IFCRanges.surfaceList[11].getTitle(), ifcData.getRoughnessWidth(), 2);
            outprtWriter.println("#");

            writeArray(outprtWriter, ifcData, IFCRanges.layerList[13].getTitle(), ifcData.getInitialBulkDensity(), 3);  // hydrology by layers
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[20].getTitle(), ifcData.getInitialSWC(), 3);  // hydrology by layers
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[21].getTitle(), ifcData.getSaturatedSWC(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[22].getTitle(), ifcData.getFieldCapacitySWC(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[23].getTitle(), ifcData.getWiltingPointSWC(), 3);
            outprtWriter.println("#");

            writeArray(outprtWriter, ifcData, IFCRanges.layerList[24].getTitle(), ifcData.getSoilCB(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[25].getTitle(), ifcData.getAirEntryPotential(), 3);
            writeArray(outprtWriter, ifcData, IFCRanges.layerList[26].getTitle(), ifcData.getSaturatedHydraulicConductivity(), 10);
            outprtWriter.println("#");

            //outprtWriter.println(writeNotes(ifcData));
            outprtWriter.close();
        }
        return warnings;
    }

    public String getIFCFileData(MapUnit mapUnit, Component comp) {

        String ret_val = "";
        String state;
        String county;

        //adjustIfc(); I don't think this is needed if there is no user input
        //if ((warnings = Utils.chkSoilandSandPcts(comp)) == null) {        
        String[] parts = mapUnit.areaname().split(",", -1);
        if (parts.length == 0) {
            state = null;
            county = "";
        } else if (parts.length == 1) {
            state = parts[0].trim();
            county = "";
        } else {
            county = parts[0].trim();
            state = parts[1].trim();
        }

        ret_val += println("Version: 1.0");
        ret_val += println("#");
        ret_val += println("# Soil ID");
        ret_val += println(mapUnit.areasymbol() + "-" + mapUnit.musym() + "-" + comp.compname()
                + "-" + comp.comppct_r() + "-" + SoilCalc.getSurfaceTexture(comp)
                + "-" + state + "-" + county + "-" + mapUnit.areaname());
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.idList[9].getTitle(), comp.localphase());  // local phase
        ret_val += writeValue(IFCRanges.idList[8].getTitle(), comp.taxorder());  // tax order

        ret_val += writeValue(IFCRanges.idList[11].getTitle(), (int) comp.tfact());
        ret_val += writeValue(IFCRanges.surfaceList[12].getTitle(), SoilCalc.getSurfaceAlbedo(comp.albedodry_r(), Utils.getSurfaceHorizon(comp).om_r()), 3);
        ret_val += writeValue(IFCRanges.surfaceList[13].getTitle(), comp.slope_r(), 3);
        ret_val += writeValue(IFCRanges.surfaceList[14].getTitle(), SoilCalc.getSurfaceFragmentCover(), 3);

        ret_val += println("#");
        ret_val += writeValue(IFCRanges.surfaceList[15].getTitle(), mapUnit.brockdepmin(), 0);
        ret_val += writeValue(IFCRanges.surfaceList[16].getTitle(), comp.calculated_resdeptmin_r(), 0);
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.layerList[0].getTitle(), comp.horizons.size());  // number of layers
        ret_val += writeArray(IFCRanges.layerList[1].getTitle(), comp, 0, (Horizon h) -> h.hzdepb_r() - h.hzdept_r());  // soil characteristics by layer
        ret_val += println("#");

        ret_val += writeArray(IFCRanges.layerList[3].getTitle(), comp, 3, (Horizon h) -> h.sandtotal_r());			// soil fractions
        ret_val += writeArray(IFCRanges.layerList[4].getTitle(), comp, 3, (Horizon h) -> h.silttotal_r());
        ret_val += writeArray(IFCRanges.layerList[5].getTitle(), comp, 3, (Horizon h) -> h.claytotal_r());
        ret_val += writeArray(IFCRanges.layerList[6].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getRockFrags(h));
        ret_val += writeArray(IFCRanges.layerList[7].getTitle(), comp, 3, (Horizon h) -> h.sandvc_r());
        ret_val += writeArray(IFCRanges.layerList[8].getTitle(), comp, 3, (Horizon h) -> h.sandco_r());
        ret_val += writeArray(IFCRanges.layerList[9].getTitle(), comp, 3, (Horizon h) -> h.sandmed_r());
        ret_val += writeArray(IFCRanges.layerList[10].getTitle(), comp, 3, (Horizon h) -> h.sandfine_r());
        ret_val += writeArray(IFCRanges.layerList[11].getTitle(), comp, 3, (Horizon h) -> h.sandvf_r());
        ret_val += println("#");

        ret_val += writeArray(IFCRanges.layerList[12].getTitle(), comp, 3, (Horizon h) -> h.dbthirdbar_r());
        ret_val += writeArray(IFCRanges.layerList[2].getTitle(), comp, 4, (Horizon h) -> h.om_r());				// soil chemical properties
        ret_val += writeArray(IFCRanges.layerList[27].getTitle(), comp, 2, (Horizon h) -> SoilCalc.getSoilpH(h));
        ret_val += writeArray(IFCRanges.layerList[28].getTitle(), comp, 2, (Horizon h) -> h.caco3_r());
        ret_val += writeArray(IFCRanges.layerList[29].getTitle(), comp, 2, (Horizon h) -> SoilCalc.getCationExchangeCapacity(h));
        ret_val += writeArray(IFCRanges.layerList[30].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getLinearExtensibility(h));
        ret_val += println("#");

        ret_val += writeArray(IFCRanges.layerList[14].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateMeanDiameter(h));	// aggregate characteristics
        ret_val += writeArray(IFCRanges.layerList[15].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateStdDeviation(h));
        ret_val += writeArray(IFCRanges.layerList[16].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getMaxAggregateSize(h));
        ret_val += writeArray(IFCRanges.layerList[17].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getMinAggregateSize());
        ret_val += writeArray(IFCRanges.layerList[18].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateDensity(h));
        ret_val += writeArray(IFCRanges.layerList[19].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateStability(h));
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.surfaceList[1].getTitle(), SoilCalc.getCrustThickness(), 3);  // crust and surface characteristics
        ret_val += writeValue(IFCRanges.surfaceList[2].getTitle(), SoilCalc.getCrustDensity(Utils.getSurfaceHorizon(comp)), 3);
        ret_val += writeValue(IFCRanges.surfaceList[3].getTitle(), SoilCalc.getCrustStability(Utils.getSurfaceHorizon(comp)), 2);
        ret_val += writeValue(IFCRanges.surfaceList[4].getTitle(), SoilCalc.getCrustFraction(), 2);
        ret_val += writeValue(IFCRanges.surfaceList[5].getTitle(), SoilCalc.getCrustLooseMaterialMass(), 2);
        ret_val += writeValue(IFCRanges.surfaceList[6].getTitle(), SoilCalc.getCrustLooseMaterialFraction(), 2);
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.surfaceList[7].getTitle(), SoilCalc.getRandomRoughness(), 2);
        ret_val += writeValue(IFCRanges.surfaceList[8].getTitle(), SoilCalc.getRoughnessOrientation(), 2);
        ret_val += writeValue(IFCRanges.surfaceList[9].getTitle(), SoilCalc.getRoughnessHeight(), 2);
        ret_val += writeValue(IFCRanges.surfaceList[10].getTitle(), SoilCalc.getRoughnessSpacing(), 2);
        ret_val += writeValue(IFCRanges.surfaceList[11].getTitle(), SoilCalc.getRoughnessWidth(), 2);
        ret_val += println("#");

        ret_val += writeArray(IFCRanges.layerList[13].getTitle(), comp, 3, (Horizon h) -> h.dbthirdbar_r());  // hydrology by layers
        ret_val += writeArray(IFCRanges.layerList[20].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getInitialSWC(h));  // hydrology by layers
        ret_val += writeArray(IFCRanges.layerList[21].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getSaturatedSWC(h));
        ret_val += writeArray(IFCRanges.layerList[22].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getFieldCapacitySWC(h));
        ret_val += writeArray(IFCRanges.layerList[23].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getWiltingPointSWC(h));
        ret_val += println("#");

        ret_val += writeArray(IFCRanges.layerList[24].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getSoilCB(h));
        ret_val += writeArray(IFCRanges.layerList[25].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAirEntryPotential(h));
        ret_val += writeArray(IFCRanges.layerList[26].getTitle(), comp, 10, (Horizon h) -> SoilCalc.getSaturatedHydraulicConductivity(h));
        ret_val += println("#");

        return ret_val;
    }

    public String writeIFCfile(MapUnit mapUnit, Component comp, File ifcFile) throws IOException, ServiceException {

        PrintWriter outprtWriter;
        String warnings = null;
        String state;
        String county;

        //adjustIfc(); I don't think this is needed if there is no user input
        //if ((warnings = Utils.chkSoilandSandPcts(comp)) == null) {        
        outprtWriter = new PrintWriter(new FileWriter(ifcFile));

        String[] parts = mapUnit.areaname().split(",", -1);
        if (parts.length == 0) {
            state = null;
            county = "";
        } else if (parts.length == 1) {
            state = parts[0].trim();
            county = "";
        } else {
            county = parts[0].trim();
            state = parts[1].trim();
        }

        outprtWriter.println("Version: 1.0");
        outprtWriter.println("#");
        outprtWriter.println("# Soil ID");
        outprtWriter.println(mapUnit.areasymbol() + "-" + mapUnit.musym() + "-" + comp.compname()
                + "-" + comp.comppct_r() + "-" + SoilCalc.getSurfaceTexture(comp)
                + "-" + state + "-" + county + "-" + mapUnit.areaname());
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.idList[9].getTitle(), comp.localphase());  // local phase
        writeValue(outprtWriter, IFCRanges.idList[8].getTitle(), comp.taxorder());  // tax order

        writeValue(outprtWriter, IFCRanges.idList[11].getTitle(), (int) comp.tfact());
        writeValue(outprtWriter, IFCRanges.surfaceList[12].getTitle(), SoilCalc.getSurfaceAlbedo(comp.albedodry_r(), Utils.getSurfaceHorizon(comp).om_r()), 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[13].getTitle(), comp.slope_r(), 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[14].getTitle(), SoilCalc.getSurfaceFragmentCover(), 3);

        outprtWriter.println("#");
        writeValue(outprtWriter, IFCRanges.surfaceList[15].getTitle(), mapUnit.brockdepmin(), 0);
        writeValue(outprtWriter, IFCRanges.surfaceList[16].getTitle(), comp.calculated_resdeptmin_r(), 0);
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.layerList[0].getTitle(), comp.horizons.size());  // number of layers
        writeArray(outprtWriter, IFCRanges.layerList[1].getTitle(), comp, 0, (Horizon h) -> h.hzdepb_r() - h.hzdept_r());  // soil characteristics by layer
        outprtWriter.println("#");

        writeArray(outprtWriter, IFCRanges.layerList[3].getTitle(), comp, 3, (Horizon h) -> h.sandtotal_r());			// soil fractions
        writeArray(outprtWriter, IFCRanges.layerList[4].getTitle(), comp, 3, (Horizon h) -> h.silttotal_r());
        writeArray(outprtWriter, IFCRanges.layerList[5].getTitle(), comp, 3, (Horizon h) -> h.claytotal_r());
        writeArray(outprtWriter, IFCRanges.layerList[6].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getRockFrags(h));
        writeArray(outprtWriter, IFCRanges.layerList[7].getTitle(), comp, 3, (Horizon h) -> h.sandvc_r());
        writeArray(outprtWriter, IFCRanges.layerList[8].getTitle(), comp, 3, (Horizon h) -> h.sandco_r());
        writeArray(outprtWriter, IFCRanges.layerList[9].getTitle(), comp, 3, (Horizon h) -> h.sandmed_r());
        writeArray(outprtWriter, IFCRanges.layerList[10].getTitle(), comp, 3, (Horizon h) -> h.sandfine_r());
        writeArray(outprtWriter, IFCRanges.layerList[11].getTitle(), comp, 3, (Horizon h) -> h.sandvf_r());
        outprtWriter.println("#");

        writeArray(outprtWriter, IFCRanges.layerList[12].getTitle(), comp, 3, (Horizon h) -> h.dbthirdbar_r());
        writeArray(outprtWriter, IFCRanges.layerList[2].getTitle(), comp, 4, (Horizon h) -> h.om_r());				// soil chemical properties
        writeArray(outprtWriter, IFCRanges.layerList[27].getTitle(), comp, 2, (Horizon h) -> SoilCalc.getSoilpH(h));
        writeArray(outprtWriter, IFCRanges.layerList[28].getTitle(), comp, 2, (Horizon h) -> h.caco3_r());
        writeArray(outprtWriter, IFCRanges.layerList[29].getTitle(), comp, 2, (Horizon h) -> SoilCalc.getCationExchangeCapacity(h));
        writeArray(outprtWriter, IFCRanges.layerList[30].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getLinearExtensibility(h));
        outprtWriter.println("#");

        writeArray(outprtWriter, IFCRanges.layerList[14].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateMeanDiameter(h));	// aggregate characteristics
        writeArray(outprtWriter, IFCRanges.layerList[15].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateStdDeviation(h));
        writeArray(outprtWriter, IFCRanges.layerList[16].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getMaxAggregateSize(h));
        writeArray(outprtWriter, IFCRanges.layerList[17].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getMinAggregateSize());
        writeArray(outprtWriter, IFCRanges.layerList[18].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateDensity(h));
        writeArray(outprtWriter, IFCRanges.layerList[19].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAggregateStability(h));
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.surfaceList[1].getTitle(), SoilCalc.getCrustThickness(), 3);  // crust and surface characteristics
        writeValue(outprtWriter, IFCRanges.surfaceList[2].getTitle(), SoilCalc.getCrustDensity(Utils.getSurfaceHorizon(comp)), 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[3].getTitle(), SoilCalc.getCrustStability(Utils.getSurfaceHorizon(comp)), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[4].getTitle(), SoilCalc.getCrustFraction(), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[5].getTitle(), SoilCalc.getCrustLooseMaterialMass(), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[6].getTitle(), SoilCalc.getCrustLooseMaterialFraction(), 2);
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.surfaceList[7].getTitle(), SoilCalc.getRandomRoughness(), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[8].getTitle(), SoilCalc.getRoughnessOrientation(), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[9].getTitle(), SoilCalc.getRoughnessHeight(), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[10].getTitle(), SoilCalc.getRoughnessSpacing(), 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[11].getTitle(), SoilCalc.getRoughnessWidth(), 2);
        outprtWriter.println("#");

        writeArray(outprtWriter, IFCRanges.layerList[13].getTitle(), comp, 3, (Horizon h) -> h.dbthirdbar_r());  // hydrology by layers
        writeArray(outprtWriter, IFCRanges.layerList[20].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getInitialSWC(h));  // hydrology by layers
        writeArray(outprtWriter, IFCRanges.layerList[21].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getSaturatedSWC(h));
        writeArray(outprtWriter, IFCRanges.layerList[22].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getFieldCapacitySWC(h));
        writeArray(outprtWriter, IFCRanges.layerList[23].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getWiltingPointSWC(h));
        outprtWriter.println("#");

        writeArray(outprtWriter, IFCRanges.layerList[24].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getSoilCB(h));
        writeArray(outprtWriter, IFCRanges.layerList[25].getTitle(), comp, 3, (Horizon h) -> SoilCalc.getAirEntryPotential(h));
        writeArray(outprtWriter, IFCRanges.layerList[26].getTitle(), comp, 10, (Horizon h) -> SoilCalc.getSaturatedHydraulicConductivity(h));
        outprtWriter.println("#");

        //outprtWriter.println(writeNotes(ifcData));
        outprtWriter.close();
        //}
        return warnings;
    }

    public String getDefaultOrganicFileData() {
        String ret_val = "";

        ret_val += println("Version: 1.0");
        ret_val += println("#");
        ret_val += println("# Soil ID");
        ret_val += println("NA-NA-Organic Soil Mod-100-MUCK-NA-NA-NA");
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.idList[9].getTitle(), "NA");  // local phase
        ret_val += writeValue(IFCRanges.idList[8].getTitle(), "NA");  // tax order

        ret_val += writeValue(IFCRanges.idList[11].getTitle(), 3);
        ret_val += writeValue(IFCRanges.surfaceList[12].getTitle(), 0.090, 3);
        ret_val += writeValue(IFCRanges.surfaceList[13].getTitle(), 0.0, 3);
        ret_val += writeValue(IFCRanges.surfaceList[14].getTitle(), 0.0, 3);

        ret_val += println("#");
        ret_val += writeValue(IFCRanges.surfaceList[15].getTitle(), 99990, 0);
        ret_val += writeValue(IFCRanges.surfaceList[16].getTitle(), 99990, 0);
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.layerList[0].getTitle(), 2);  // number of layers
        ret_val += writeArray(2, IFCRanges.layerList[1].getTitle(), new double[]{400, 1100}, 0);  // soil characteristics by layer
        ret_val += println("#");

        ret_val += writeArray(2, IFCRanges.layerList[3].getTitle(), new double[]{0.5, 0.13}, 3);				// soil fractions
        ret_val += writeArray(2, IFCRanges.layerList[4].getTitle(), new double[]{0.4, 0.820}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[5].getTitle(), new double[]{0.1, 0.05}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[6].getTitle(), new double[]{0.0, 0.0}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[7].getTitle(), new double[]{0.0, 0.0}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[8].getTitle(), new double[]{0.02, 0.003}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[9].getTitle(), new double[]{0.128, 0.023}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[10].getTitle(), new double[]{0.332, 0.065}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[11].getTitle(), new double[]{0.02, 0.039}, 3);
        ret_val += println("#");

        ret_val += writeArray(2, IFCRanges.layerList[12].getTitle(), new double[]{0.39, 0.22}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[2].getTitle(), new double[]{0.77, 0.81}, 4);				// soil chemical properties
        ret_val += writeArray(2, IFCRanges.layerList[27].getTitle(), new double[]{5, 5}, 2);
        ret_val += writeArray(2, IFCRanges.layerList[28].getTitle(), new double[]{0.0, 0.0}, 2);
        ret_val += writeArray(2, IFCRanges.layerList[29].getTitle(), new double[]{40, 45}, 2);
        ret_val += writeArray(2, IFCRanges.layerList[30].getTitle(), new double[]{0.0, 0.0}, 3);
        ret_val += println("#");

        ret_val += writeArray(2, IFCRanges.layerList[14].getTitle(), new double[]{5, 5}, 3);	// aggregate characteristics
        ret_val += writeArray(2, IFCRanges.layerList[15].getTitle(), new double[]{5, 5}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[16].getTitle(), new double[]{30, 30}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[17].getTitle(), new double[]{0.01, 0.01}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[18].getTitle(), new double[]{0.7, 0.7}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[19].getTitle(), new double[]{4, 4}, 3);
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.surfaceList[1].getTitle(), 0.01, 3);  // crust and surface characteristics
        ret_val += writeValue(IFCRanges.surfaceList[2].getTitle(), 0.6, 3);
        ret_val += writeValue(IFCRanges.surfaceList[3].getTitle(), 4, 2);
        ret_val += writeValue(IFCRanges.surfaceList[4].getTitle(), 0.0, 2);
        ret_val += writeValue(IFCRanges.surfaceList[5].getTitle(), 0.0, 2);
        ret_val += writeValue(IFCRanges.surfaceList[6].getTitle(), 0.0, 2);
        ret_val += println("#");

        ret_val += writeValue(IFCRanges.surfaceList[7].getTitle(), 4, 2);
        ret_val += writeValue(IFCRanges.surfaceList[8].getTitle(), 0.0, 2);
        ret_val += writeValue(IFCRanges.surfaceList[9].getTitle(), 0.0, 2);
        ret_val += writeValue(IFCRanges.surfaceList[10].getTitle(), 10, 2);
        ret_val += writeValue(IFCRanges.surfaceList[11].getTitle(), 10, 2);
        ret_val += println("#");

        ret_val += writeArray(2, IFCRanges.layerList[13].getTitle(), new double[]{0.39, 0.22}, 3);  // hydrology by layers
        ret_val += writeArray(2, IFCRanges.layerList[20].getTitle(), new double[]{0.379, 0.379}, 3);  // hydrology by layers
        ret_val += writeArray(2, IFCRanges.layerList[21].getTitle(), new double[]{0.55, 0.55}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[22].getTitle(), new double[]{0.335, 0.335}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[23].getTitle(), new double[]{0.24, 0.24}, 3);
        ret_val += println("#");

        ret_val += writeArray(2, IFCRanges.layerList[24].getTitle(), new double[]{6.831, 6.831}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[25].getTitle(), new double[]{-4.379, -4.379}, 3);
        ret_val += writeArray(2, IFCRanges.layerList[26].getTitle(), new double[]{.00005, .000025}, 10);
        ret_val += println("#");
        
        return ret_val;
    }

    public void writeOrganicDefault(String filePath) throws IOException {

        PrintWriter outprtWriter;

        outprtWriter = new PrintWriter(new FileWriter(new File(filePath)));

        outprtWriter.println("Version: 1.0");
        outprtWriter.println("#");
        outprtWriter.println("# Soil ID");
        outprtWriter.println("NA-NA-Organic Soil Mod-100-MUCK-NA-NA-NA");
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.idList[9].getTitle(), "NA");  // local phase
        writeValue(outprtWriter, IFCRanges.idList[8].getTitle(), "NA");  // tax order

        writeValue(outprtWriter, IFCRanges.idList[11].getTitle(), 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[12].getTitle(), 0.090, 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[13].getTitle(), 0.0, 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[14].getTitle(), 0.0, 3);

        outprtWriter.println("#");
        writeValue(outprtWriter, IFCRanges.surfaceList[15].getTitle(), 99990, 0);
        writeValue(outprtWriter, IFCRanges.surfaceList[16].getTitle(), 99990, 0);
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.layerList[0].getTitle(), 2);  // number of layers
        writeArray(outprtWriter, 2, IFCRanges.layerList[1].getTitle(), new double[]{400, 1100}, 0);  // soil characteristics by layer
        outprtWriter.println("#");

        writeArray(outprtWriter, 2, IFCRanges.layerList[3].getTitle(), new double[]{0.5, 0.13}, 3);				// soil fractions
        writeArray(outprtWriter, 2, IFCRanges.layerList[4].getTitle(), new double[]{0.4, 0.820}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[5].getTitle(), new double[]{0.1, 0.05}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[6].getTitle(), new double[]{0.0, 0.0}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[7].getTitle(), new double[]{0.0, 0.0}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[8].getTitle(), new double[]{0.02, 0.003}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[9].getTitle(), new double[]{0.128, 0.023}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[10].getTitle(), new double[]{0.332, 0.065}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[11].getTitle(), new double[]{0.02, 0.039}, 3);
        outprtWriter.println("#");

        writeArray(outprtWriter, 2, IFCRanges.layerList[12].getTitle(), new double[]{0.39, 0.22}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[2].getTitle(), new double[]{0.77, 0.81}, 4);				// soil chemical properties
        writeArray(outprtWriter, 2, IFCRanges.layerList[27].getTitle(), new double[]{5, 5}, 2);
        writeArray(outprtWriter, 2, IFCRanges.layerList[28].getTitle(), new double[]{0.0, 0.0}, 2);
        writeArray(outprtWriter, 2, IFCRanges.layerList[29].getTitle(), new double[]{40, 45}, 2);
        writeArray(outprtWriter, 2, IFCRanges.layerList[30].getTitle(), new double[]{0.0, 0.0}, 3);
        outprtWriter.println("#");

        writeArray(outprtWriter, 2, IFCRanges.layerList[14].getTitle(), new double[]{5, 5}, 3);	// aggregate characteristics
        writeArray(outprtWriter, 2, IFCRanges.layerList[15].getTitle(), new double[]{5, 5}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[16].getTitle(), new double[]{30, 30}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[17].getTitle(), new double[]{0.01, 0.01}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[18].getTitle(), new double[]{0.7, 0.7}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[19].getTitle(), new double[]{4, 4}, 3);
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.surfaceList[1].getTitle(), 0.01, 3);  // crust and surface characteristics
        writeValue(outprtWriter, IFCRanges.surfaceList[2].getTitle(), 0.6, 3);
        writeValue(outprtWriter, IFCRanges.surfaceList[3].getTitle(), 4, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[4].getTitle(), 0.0, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[5].getTitle(), 0.0, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[6].getTitle(), 0.0, 2);
        outprtWriter.println("#");

        writeValue(outprtWriter, IFCRanges.surfaceList[7].getTitle(), 4, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[8].getTitle(), 0.0, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[9].getTitle(), 0.0, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[10].getTitle(), 10, 2);
        writeValue(outprtWriter, IFCRanges.surfaceList[11].getTitle(), 10, 2);
        outprtWriter.println("#");

        writeArray(outprtWriter, 2, IFCRanges.layerList[13].getTitle(), new double[]{0.39, 0.22}, 3);  // hydrology by layers
        writeArray(outprtWriter, 2, IFCRanges.layerList[20].getTitle(), new double[]{0.379, 0.379}, 3);  // hydrology by layers
        writeArray(outprtWriter, 2, IFCRanges.layerList[21].getTitle(), new double[]{0.55, 0.55}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[22].getTitle(), new double[]{0.335, 0.335}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[23].getTitle(), new double[]{0.24, 0.24}, 3);
        outprtWriter.println("#");

        writeArray(outprtWriter, 2, IFCRanges.layerList[24].getTitle(), new double[]{6.831, 6.831}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[25].getTitle(), new double[]{-4.379, -4.379}, 3);
        writeArray(outprtWriter, 2, IFCRanges.layerList[26].getTitle(), new double[]{.00005, .000025}, 10);
        outprtWriter.println("#");

        outprtWriter.close();

    }

    private String writeNotes(IFCData ifcData) {
        StringTokenizer st = new StringTokenizer(ifcData.getErrorsInIfcFile(), "\n");

        StringBuilder sb = new StringBuilder("# Notes:\n");
        while (st.hasMoreTokens()) {
            sb.append("# " + st.nextToken() + "\n");
        }

        return sb.toString();
    }

    private void writeValue(PrintWriter outprt, String nam, String val) {
        outprt.println("# " + nam);
        outprt.println(val);
    }

    private void writeValue(PrintWriter outprt, String nam, int val) {
        outprt.println("# " + nam);
        outprt.println(val);
    }

    private void writeValue(PrintWriter outprt, String nam, double val, int numdig) {
        outprt.println("# " + nam);
        if (EvalResult.testDefaultDouble(val)) {
            throw new ArithmeticException("Soil property not found in one or more layers - " + nam);
        } else {
            outprt.println(Utils.formatDouble(val, numdig));
        }
    }

    private void writeArray(PrintWriter outprt, IFCData ifcData, String nam, double arr[], int numdig) {

        outprt.println("# " + nam);
        for (int ldx = 0; ldx < ifcData.getNumberOfSoilLayers(); ldx++) {	// check to make sure nsl is correct
            if (Double.isNaN(arr[ldx])) {
                throw new ArithmeticException("Soil property not found in one or more layers - " + nam);
            } else {
                outprt.print(Utils.formatDouble(arr[ldx], numdig) + "     ");
            }
        }
        outprt.println();
    }

    private void writeArray(PrintWriter outprt, int numLayers, String nam, double arr[], int numdig) {

        outprt.println("# " + nam);
        for (int ldx = 0; ldx < numLayers; ldx++) {	// check to make sure nsl is correct
            if (Double.isNaN(arr[ldx])) {
                throw new ArithmeticException("Soil property not found in one or more layers - " + nam);
            } else {
                outprt.print(Utils.formatDouble(arr[ldx], numdig) + "     ");
            }
        }
        outprt.println();
    }

    private void writeArray(PrintWriter outprt, String name, Component comp, int numdig, Function<Horizon, Double> getter) {
        double value;
        outprt.println("# " + name);
        for (Horizon horizon : comp.horizons.values()) {
            value = getter.apply(horizon);
            if (EvalResult.testDefaultDouble(value)) {
                throw new ArithmeticException("Soil property not found in one or more layers - " + name);
            } else {
                outprt.print(Utils.formatDouble(value, numdig) + "     ");
            }
        }
        outprt.println();
    }

    private String writeValue(String nam, String val) {
        return println("# " + nam) + println(val);
    }

    private String writeValue(String nam, int val) {
        return println("# " + nam) + println(Integer.toString(val));
    }

    private String writeValue(String nam, double val, int numdig) {
        String ret_val = println("# " + nam);
        if (EvalResult.testDefaultDouble(val)) {
            throw new ArithmeticException("Soil property not found in one or more layers - " + nam);
        } else {
            ret_val += println(Utils.formatDouble(val, numdig));
        }

        return ret_val;
    }

    private String writeArray(IFCData ifcData, String nam, double arr[], int numdig) {
        String ret_val = println("# " + nam);
        for (int ldx = 0; ldx < ifcData.getNumberOfSoilLayers(); ldx++) {	// check to make sure nsl is correct
            if (Double.isNaN(arr[ldx])) {
                throw new ArithmeticException("Soil property not found in one or more layers - " + nam);
            } else {
                ret_val += Utils.formatDouble(arr[ldx], numdig) + "     ";
            }
        }

        ret_val += println("");

        return ret_val;
    }

    private String writeArray(int numLayers, String nam, double arr[], int numdig) {
        String ret_val = println("# " + nam);
        for (int ldx = 0; ldx < numLayers; ldx++) {	// check to make sure nsl is correct
            if (Double.isNaN(arr[ldx])) {
                throw new ArithmeticException("Soil property not found in one or more layers - " + nam);
            } else {
                ret_val += Utils.formatDouble(arr[ldx], numdig) + "     ";
            }
        }
        ret_val += println("");
        return ret_val;
    }

    private String writeArray(String name, Component comp, int numdig, Function<Horizon, Double> getter) {
        double value;
        String ret_val = println("# " + name);

        for (Horizon horizon : comp.horizons.values()) {
            value = getter.apply(horizon);
            if (EvalResult.testDefaultDouble(value)) {
                throw new ArithmeticException("Soil property not found in one or more layers - " + name);
            } else {
                ret_val += Utils.formatDouble(value, numdig) + "     ";
            }
        }
        ret_val += println("");
        return ret_val;
    }

    String println(String line) {
        return line + System.lineSeparator();
    }
}