Beispiel #1
0
def function(outputFolder, inputShp, PTFOption, BCPressArray, fcVal, sicVal,
             pwpVal, carbContent, carbonConFactor):

    try:
        # Set temporary variables
        prefix = os.path.join(arcpy.env.scratchGDB, "bc_")

        tempSoils = prefix + "tempSoils"

        # Set output filename
        outputShp = os.path.join(outputFolder, "BrooksCorey.shp")

        # Copy the input shapefile to the output folder
        arcpy.CopyFeatures_management(inputShp, outputShp)

        # Get the nameArray
        nameArray = []
        with arcpy.da.SearchCursor(outputShp, "LUCIname") as searchCursor:
            for row in searchCursor:
                name = row[0]
                nameArray.append(name)

        # PTFs should return: WC_res, WC_sat, lambda_BC, hb_BC

        if PTFOption == "Cosby_1984_SandC_BC":
            warning, WC_res, WC_sat, lambda_BC, hb_BC = bc_PTFs.Cosby_1984_SandC_BC(
                outputShp, PTFOption)

        elif PTFOption == "Cosby_1984_SSC_BC":
            warning, WC_res, WC_sat, lambda_BC, hb_BC = bc_PTFs.Cosby_1984_SSC_BC(
                outputShp, PTFOption)

        elif PTFOption == "RawlsBrakensiek_1985_BC":
            warning, WC_res, WC_sat, lambda_BC, hb_BC = bc_PTFs.RawlsBrakensiek_1985_BC(
                outputShp, PTFOption)

        elif PTFOption == "CampbellShiozawa_1992_BC":
            warning, WC_res, WC_sat, lambda_BC, hb_BC = bc_PTFs.CampbellShiozawa_1992_BC(
                outputShp, PTFOption)

        elif PTFOption == "Saxton_1986_BC":
            warning, WC_res, WC_sat, lambda_BC, hb_BC = bc_PTFs.Saxton_1986_BC(
                outputShp, PTFOption)

        elif PTFOption == "SaxtonRawls_2006_BC":
            warning, WC_res, WC_sat, lambda_BC, hb_BC = bc_PTFs.SaxtonRawls_2006_BC(
                outputShp, PTFOption, carbonConFactor, carbContent)

        else:
            log.error("Brooks-Corey option not recognised: " + str(PTFOption))
            sys.exit()

        # Write to shapefile
        brooksCorey.writeBCParams(outputShp, warning, WC_res, WC_sat,
                                  lambda_BC, hb_BC)

        log.info("Brooks-Corey parameters written to output shapefile")

        # Create plots
        brooksCorey.plotBrooksCorey(outputFolder, WC_res, WC_sat, hb_BC,
                                    lambda_BC, nameArray, fcVal, sicVal,
                                    pwpVal)

        ###############################################
        ### Calculate water content using BC params ###
        ###############################################

        # Check for any soils that we were not able to calculate BC parameters for
        # lambda_BC[i] == -9999

        errors = []
        for i in range(0, len(lambda_BC)):
            if lambda_BC[i] == -9999:
                log.warning('Invalid lambda found for ' + str(nameArray[i]))
                errors.append(i)

        # Calculate water content at default pressures
        WC_1kPaArray = []
        WC_3kPaArray = []
        WC_10kPaArray = []
        WC_33kPaArray = []
        WC_100kPaArray = []
        WC_200kPaArray = []
        WC_1000kPaArray = []
        WC_1500kPaArray = []

        for i in range(0, len(nameArray)):

            pressures = [1.0, 3.0, 10.0, 33.0, 100.0, 200.0, 1000.0, 1500.0]

            if lambda_BC[i] != -9999:
                bc_WC = brooksCorey.calcBrooksCoreyFXN(pressures, hb_BC[i],
                                                       WC_res[i], WC_sat[i],
                                                       lambda_BC[i])

            else:
                bc_WC = [-9999] * len(pressures)

            WC_1kPaArray.append(bc_WC[0])
            WC_3kPaArray.append(bc_WC[1])
            WC_10kPaArray.append(bc_WC[2])
            WC_33kPaArray.append(bc_WC[3])
            WC_100kPaArray.append(bc_WC[4])
            WC_200kPaArray.append(bc_WC[5])
            WC_1000kPaArray.append(bc_WC[6])
            WC_1500kPaArray.append(bc_WC[7])

        common.writeOutputWC(outputShp, WC_1kPaArray, WC_3kPaArray,
                             WC_10kPaArray, WC_33kPaArray, WC_100kPaArray,
                             WC_200kPaArray, WC_1000kPaArray, WC_1500kPaArray)

        # Write water content at user-input pressures

        # Initialise the pressure head array
        x = np.array(BCPressArray)
        bcPressures = x.astype(np.float)

        # For the headings
        headings = ['Name']

        for pressure in bcPressures:
            headName = 'WC_' + str(pressure) + "kPa"
            headings.append(headName)

        wcHeadings = headings[1:]

        wcArrays = []

        # Calculate soil moisture content at custom VG pressures
        for i in range(0, len(nameArray)):

            if lambda_BC[i] != -9999:
                wcValues = brooksCorey.calcBrooksCoreyFXN(
                    bcPressures, hb_BC[i], WC_res[i], WC_sat[i], lambda_BC[i])
            else:
                wcValues = [-9999] * len(bcPressures)

            wcValues.insert(0, nameArray[i])

            wcArrays.append(wcValues)

        # Write to output CSV
        outCSV = os.path.join(outputFolder, 'WaterContent.csv')

        with open(outCSV, 'wb') as csv_file:
            writer = csv.writer(csv_file)
            writer.writerow(headings)

            for i in range(0, len(nameArray)):
                row = wcArrays[i]
                writer.writerow(row)

            msg = 'Output CSV with water content saved to: ' + str(outCSV)
            log.info(msg)

        csv_file.close()

        ##################################################
        ### Calculate water content at critical points ###
        ##################################################

        # Initialise water content arrays
        wc_satCalc = []
        wc_fcCalc = []
        wc_sicCalc = []
        wc_pwpCalc = []

        wc_DW = []
        wc_RAW = []
        wc_NRAW = []
        wc_PAW = []

        wcCriticalPressures = [0.0, fcVal, sicVal, pwpVal]

        for x in range(0, len(nameArray)):

            if lambda_BC[x] != -9999:
                wcCriticals = brooksCorey.calcBrooksCoreyFXN(
                    wcCriticalPressures, hb_BC[x], WC_res[x], WC_sat[x],
                    lambda_BC[x])

                wc_sat = wcCriticals[0]
                wc_fc = wcCriticals[1]
                wc_sic = wcCriticals[2]
                wc_pwp = wcCriticals[3]

                drainWater = wc_sat - wc_fc
                readilyAvailWater = wc_fc - wc_sic
                notRAW = wc_sic - wc_pwp
                PAW = wc_fc - wc_pwp

                checks_PTFs.checkNegValue("Drainable water", drainWater,
                                          nameArray[i])
                checks_PTFs.checkNegValue("Readily available water",
                                          readilyAvailWater, nameArray[i])
                checks_PTFs.checkNegValue("Not readily available water",
                                          notRAW, nameArray[i])
                checks_PTFs.checkNegValue("Not readily available water", PAW,
                                          nameArray[i])

            else:
                wc_sat = -9999
                wc_fc = -9999
                wc_sic = -9999
                wc_pwp = -9999
                drainWater = -9999
                readilyAvailWater = -9999
                notRAW = -9999
                PAW = -9999

            wc_satCalc.append(wc_sat)
            wc_fcCalc.append(wc_fc)
            wc_sicCalc.append(wc_sic)
            wc_pwpCalc.append(wc_pwp)
            wc_DW.append(drainWater)
            wc_RAW.append(readilyAvailWater)
            wc_NRAW.append(notRAW)
            wc_PAW.append(PAW)

        common.writeOutputCriticalWC(outputShp, wc_satCalc, wc_fcCalc,
                                     wc_sicCalc, wc_pwpCalc, wc_DW, wc_RAW,
                                     wc_NRAW, wc_PAW)

    except Exception:
        arcpy.AddError("Brooks-Corey function failed")
        raise

    finally:
        # Remove feature layers from memory
        try:
            for lyr in common.listFeatureLayers(locals()):
                arcpy.Delete_management(locals()[lyr])
                exec(lyr + ' = None') in locals()
        except Exception:
            pass
Beispiel #2
0
def function(outputFolder, inputShp, PTFOption, fcVal, sicVal, pwpVal,
             carbContent, carbonConFactor):

    try:
        # Set temporary variables
        prefix = os.path.join(arcpy.env.scratchGDB, "soil_")

        # Set output filename
        outputShp = os.path.join(outputFolder, "soil_point_ptf.shp")

        # Copy the input shapefile to the output folder
        arcpy.CopyFeatures_management(inputShp, outputShp)

        ####################################
        ### Calculate the water contents ###
        ####################################

        # Get the nameArray
        nameArray = []
        with arcpy.da.SearchCursor(outputShp, "LUCIname") as searchCursor:
            for row in searchCursor:
                name = row[0]

                nameArray.append(name)

        # Get PTF fields
        PTFxml = os.path.join(outputFolder, "ptfinfo.xml")
        PTFFields = common.readXML(PTFxml, 'PTFFields')
        PTFPressures = common.readXML(PTFxml, 'PTFPressures')
        PTFUnit = common.readXML(PTFxml, 'PTFUnit')

        # Call point-PTF here depending on PTFOption
        if PTFOption == "Nguyen_2014":
            results = point_PTFs.Nguyen_2014(outputFolder, outputShp,
                                             carbonConFactor, carbContent)

        elif PTFOption == "Adhikary_2008":
            results = point_PTFs.Adhikary_2008(outputFolder, outputShp)

        elif PTFOption == "Rawls_1982":
            results = point_PTFs.Rawls_1982(outputFolder, outputShp,
                                            carbonConFactor, carbContent)

        elif PTFOption == "Hall_1977_top":
            results = point_PTFs.Hall_1977_top(outputFolder, outputShp,
                                               carbonConFactor, carbContent)

        elif PTFOption == "Hall_1977_sub":
            results = point_PTFs.Hall_1977_sub(outputFolder, outputShp,
                                               carbonConFactor, carbContent)

        elif PTFOption == "GuptaLarson_1979":
            results = point_PTFs.GuptaLarson_1979(outputFolder, outputShp,
                                                  carbonConFactor, carbContent)

        elif PTFOption == "Batjes_1996":
            results = point_PTFs.Batjes_1996(outputFolder, outputShp,
                                             carbonConFactor, carbContent)

        elif PTFOption == "SaxtonRawls_2006":
            results = point_PTFs.SaxtonRawls_2006(outputFolder, outputShp,
                                                  carbonConFactor, carbContent)

        elif PTFOption == "Pidgeon_1972":
            results = point_PTFs.Pidgeon_1972(outputFolder, outputShp,
                                              carbonConFactor, carbContent)

        elif str(PTFOption[0:8]) == "Lal_1978":
            results = point_PTFs.Lal_1978(outputFolder, outputShp, PTFOption)

        elif PTFOption == "AinaPeriaswamy_1985":
            results = point_PTFs.AinaPeriaswamy_1985(outputFolder, outputShp)

        elif PTFOption == "ManriqueJones_1991":
            results = point_PTFs.ManriqueJones_1991(outputFolder, outputShp)

        elif PTFOption == "vanDenBerg_1997":
            results = point_PTFs.vanDenBerg_1997(outputFolder, outputShp,
                                                 carbonConFactor, carbContent)

        elif PTFOption == "TomasellaHodnett_1998":
            results = point_PTFs.TomasellaHodnett_1998(outputFolder, outputShp,
                                                       carbonConFactor,
                                                       carbContent)

        elif PTFOption == "Reichert_2009_OM":
            results = point_PTFs.Reichert_2009_OM(outputFolder, outputShp,
                                                  carbonConFactor, carbContent)

        elif PTFOption == "Reichert_2009":
            results = point_PTFs.Reichert_2009(outputFolder, outputShp)

        elif PTFOption == "Botula_2013":
            results = point_PTFs.Botula_2013(outputFolder, outputShp)

        elif PTFOption == "ShwethaVarija_2013":
            results = point_PTFs.ShwethaVarija_2013(outputFolder, outputShp)

        elif PTFOption == "Dashtaki_2010_point":
            results = point_PTFs.Dashtaki_2010(outputFolder, outputShp)

        elif PTFOption == "Santra_2018_OC":
            results = point_PTFs.Santra_2018_OC(outputFolder, outputShp,
                                                carbonConFactor, carbContent)

        elif PTFOption == "Santra_2018":
            results = point_PTFs.Santra_2018(outputFolder, outputShp)

        else:
            log.error("PTF option not recognised")
            sys.exit()

        # Plots
        plots.plotPTF(outputFolder, outputShp, PTFOption, nameArray, results)

        ######################################################
        ### Calculate water content at critical thresholds ###
        ######################################################

        satStatus = False
        fcStatus = False
        sicStatus = False
        pwpStatus = False

        wc_satCalc = []
        wc_fcCalc = []
        wc_sicCalc = []
        wc_pwpCalc = []

        if PTFOption == "Reichert_2009_OM":
            log.info(
                'For Reichert et al. (2009) - Sand, silt, clay, OM, BD saturation is at 6kPa'
            )
            satField = "WC_6kPa"

        else:
            satField = "WC_0" + str(PTFUnit)

        fcField = "WC_" + str(int(fcVal)) + str(PTFUnit)
        sicField = "WC_" + str(int(sicVal)) + str(PTFUnit)
        pwpField = "WC_" + str(int(pwpVal)) + str(PTFUnit)

        wcFields = []
        wcArrays = []

        if satField in PTFFields:
            # Saturation set to 0kPa
            # PTFs with 0kPa:
            ## Saxton_1986, Batjes_1996, SaxtonRawls_2006
            ## Lal_1978_Group1, Lal_1978_Group2
            ## TomasellaHodnett_1998

            log.info('Field with WC at saturation found!')

            with arcpy.da.SearchCursor(outputShp, satField) as searchCursor:
                for row in searchCursor:
                    wc_sat = row[0]

                    if wc_sat > 1.0:
                        log.warning('Water content at saturation over 1.0')

                    wc_satCalc.append(wc_sat)

            satStatus = True

            wcFields.append("wc_satCalc")
            wcArrays.append(wc_satCalc)

            # Add sat field to output shapefile
            arcpy.AddField_management(outputShp, "wc_satCalc", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_satCalc") as cursor:
                for row in cursor:
                    row[0] = wc_satCalc[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        else:
            log.warning('Field with WC at saturation not found')
            satStatus = False

        if fcField in PTFFields:
            log.info('Field with WC at field capacity found!')

            with arcpy.da.SearchCursor(outputShp, fcField) as searchCursor:
                for row in searchCursor:
                    wc_fc = row[0]
                    wc_fcCalc.append(wc_fc)

            fcStatus = True

            wcFields.append("wc_fcCalc")
            wcArrays.append(wc_fcCalc)

            # Add FC field to output shapefile
            arcpy.AddField_management(outputShp, "wc_fcCalc", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_fcCalc") as cursor:
                for row in cursor:
                    row[0] = wc_fcCalc[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        else:
            log.warning('Field with WC at field capacity not found')
            fcStatus = False

        if sicField in PTFFields:
            log.info(
                'Field with WC at water stress-induced stomatal closure found!'
            )

            with arcpy.da.SearchCursor(outputShp, sicField) as searchCursor:
                for row in searchCursor:
                    wc_sic = row[0]
                    wc_sicCalc.append(wc_sic)

            sicStatus = True

            wcFields.append("wc_sicCalc")
            wcArrays.append(wc_sicCalc)

            # Add sic field to output shapefile
            arcpy.AddField_management(outputShp, "wc_sicCalc", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_sicCalc") as cursor:
                for row in cursor:
                    row[0] = wc_sicCalc[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        else:
            log.warning(
                'Field with WC at water stress-induced stomatal closure not found'
            )

            sicStatus = False

        if pwpField in PTFFields:
            log.info('Field with WC at permanent wilting point found!')

            with arcpy.da.SearchCursor(outputShp, pwpField) as searchCursor:
                for row in searchCursor:
                    wc_pwp = row[0]

                    if wc_pwp < 0.01:
                        log.warning(
                            'WARNING: Water content at PWP is below 0.01')

                    elif wc_pwp < 0.05:
                        log.warning('Water content at PWP is below 0.05')

                    wc_pwpCalc.append(wc_pwp)

            pwpStatus = True

            wcFields.append("wc_pwpCalc")
            wcArrays.append(wc_pwpCalc)

            # Add pwp field to output shapefile
            arcpy.AddField_management(outputShp, "wc_pwpCalc", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_pwpCalc") as cursor:
                for row in cursor:
                    row[0] = wc_pwpCalc[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        else:
            log.warning('Field with WC at permanent wilting point not found')

            pwpStatus = False

        drainWater = []
        PAW = []
        RAW = []
        NRAW = []

        if satStatus == True and fcStatus == True:
            # drainWater = wc_sat - wc_fc

            drainWater = point_PTFs.calcWaterContent(wc_satCalc, wc_fcCalc,
                                                     'drainable water',
                                                     nameArray)
            log.info('Drainable water calculated')

            wcFields.append("wc_DW")
            wcArrays.append(drainWater)

            # Add DW field to output shapefile
            arcpy.AddField_management(outputShp, "wc_DW", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_DW") as cursor:
                for row in cursor:
                    row[0] = drainWater[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        if fcStatus == True and pwpStatus == True:
            # PAW = wc_fc - wc_pwp
            PAW = point_PTFs.calcWaterContent(wc_fcCalc, wc_pwpCalc,
                                              'plant available water',
                                              nameArray)
            log.info('Plant available water calculated')

            wcFields.append("wc_PAW")
            wcArrays.append(PAW)

            # Add PAW field to output shapefile
            arcpy.AddField_management(outputShp, "wc_PAW", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_PAW") as cursor:
                for row in cursor:
                    row[0] = PAW[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

            pawStatus = True

        if fcStatus == True and sicStatus == True:
            # readilyAvailWater = wc_fc - wc_sic
            RAW = point_PTFs.calcWaterContent(wc_fcCalc, wc_sicCalc,
                                              'readily available water',
                                              nameArray)
            log.info('Readily available water calculated')

            wcFields.append("wc_RAW")
            wcArrays.append(RAW)

            # Add wc_RAW field to output shapefile
            arcpy.AddField_management(outputShp, "wc_RAW", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_RAW") as cursor:
                for row in cursor:
                    row[0] = RAW[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        elif pawStatus == True:
            # If PAW exists, get RAW = 0.5 * RAW
            PAW = point_PTFs.calcWaterContent(wc_fcCalc, wc_pwpCalc,
                                              'plant available water',
                                              nameArray)

            RAW = [(float(i) * 0.5) for i in PAW]
            log.info('Readily available water calculated based on PAW')

            wcFields.append("wc_RAW")
            wcArrays.append(RAW)

            # Add wc_RAW field to output shapefile
            arcpy.AddField_management(outputShp, "wc_RAW", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_RAW") as cursor:
                for row in cursor:
                    row[0] = RAW[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1
        else:
            log.info('Readily available water not calculated')

        if sicStatus == True and pwpStatus == True:
            # notRAW = wc_sic - wc_pwp
            NRAW = point_PTFs.calcWaterContent(wc_sicCalc, wc_pwpCalc,
                                               'not readily available water',
                                               nameArray)
            log.info('Not readily available water calculated')

            wcFields.append("wc_NRAW")
            wcArrays.append(NRAW)

            # Add sat field to output shapefile
            arcpy.AddField_management(outputShp, "wc_NRAW", "DOUBLE", 10, 6)

            recordNum = 0
            with arcpy.da.UpdateCursor(outputShp, "wc_NRAW") as cursor:
                for row in cursor:
                    row[0] = NRAW[recordNum]

                    cursor.updateRow(row)
                    recordNum += 1

        log.info(
            'Water contents at critical thresholds written to output shapefile'
        )

    except Exception:
        arcpy.AddError("Point-PTFs function failed")
        raise

    finally:
        # Remove feature layers from memory
        try:
            for lyr in common.listFeatureLayers(locals()):
                arcpy.Delete_management(locals()[lyr])
                exec(lyr + ' = None') in locals()
        except Exception:
            pass
Beispiel #3
0
def function(outputFolder, inputFolder, KsatOption, carbContent,
             carbonConFactor):

    try:
        # Set temporary variables
        prefix = os.path.join(arcpy.env.scratchGDB, "moist_")

        # Set output filename
        outputShp = os.path.join(outputFolder, "Ksat.shp")

        ## From the input folder, pull the PTFinfo
        PTFxml = os.path.join(inputFolder, "ptfinfo.xml")

        if not os.path.exists(PTFxml):
            log.error(
                'Please run the point-PTF or vg-PTF tool first before running this tool'
            )
            sys.exit()

        else:
            PTFType = common.readXML(PTFxml, 'PTFType')

        if PTFType == "pointPTF":
            inputShp = os.path.join(inputFolder, "soil_point_ptf.shp")

        elif PTFType == "vgPTF":
            inputShp = os.path.join(inputFolder, "soil_vg.shp")

        else:
            log.error(
                'Please run the point-PTF or vg-PTF tool first before running this tool'
            )
            sys.exit()

        # Copy the input shapefile to the output folder
        arcpy.CopyFeatures_management(inputShp, outputShp)

        # Check if the K_sat field already exists in the shapefile
        if common.CheckField(outputShp, "K_sat"):
            log.error('K_sat field already present in the output shapefile')
            sys.exit()

        if KsatOption == 'Cosby_1984':
            warningArray, K_satArray = ksat_PTFs.Cosby_1984(
                outputFolder, outputShp)

        elif KsatOption == 'Puckett_1985':
            warningArray, K_satArray = ksat_PTFs.Puckett_1985(
                outputFolder, outputShp)

        elif KsatOption == 'Jabro_1992':
            warningArray, K_satArray = ksat_PTFs.Jabro_1992(
                outputFolder, outputShp)

        elif KsatOption == 'CampbellShiozawa_1994':
            warningArray, K_satArray = ksat_PTFs.CampbellShiozawa_1994(
                outputFolder, outputShp)

        elif KsatOption == 'FerrerJulia_2004_1':
            warningArray, K_satArray = ksat_PTFs.FerrerJulia_2004_1(
                outputFolder, outputShp)

        elif KsatOption == 'FerrerJulia_2004_2':
            warningArray, K_satArray = ksat_PTFs.FerrerJulia_2004_2(
                outputFolder, outputShp, carbonConFactor, carbContent)

        elif KsatOption == 'Ahuja_1989':
            warningArray, K_satArray = ksat_PTFs.Ahuja_1989(
                outputFolder, outputShp)

        elif KsatOption == 'MinasnyMcBratney_2000':
            warningArray, K_satArray = ksat_PTFs.MinasnyMcBratney_2000(
                outputFolder, outputShp)

        elif KsatOption == 'Brakensiek_1984':
            warningArray, K_satArray = ksat_PTFs.Brakensiek_1984(
                outputFolder, outputShp)

        else:
            log.error("Invalid KsatOption: " + str(KsatOption))
            sys.exit()

        # Write results to output shapefile
        arcpy.AddField_management(outputShp, "warning", "TEXT")
        arcpy.AddField_management(outputShp, "K_sat", "DOUBLE", 10, 6)

        outputFields = ["warning", "K_sat"]

        recordNum = 0
        with arcpy.da.UpdateCursor(outputShp, outputFields) as cursor:
            for row in cursor:
                row[0] = warningArray[recordNum]
                row[1] = K_satArray[recordNum]

                cursor.updateRow(row)
                recordNum += 1

        log.info(
            "Results written to the output shapefile inside the output folder")

    except Exception:
        arcpy.AddError("Saturated hydraulic conductivity function failed")
        raise

    finally:
        # Remove feature layers from memory
        try:
            for lyr in common.listFeatureLayers(locals()):
                arcpy.Delete_management(locals()[lyr])
                exec(lyr + ' = None') in locals()
        except Exception:
            pass
Beispiel #4
0
def function(outputFolder, inputShp, VGOption, VGPressArray, MVGChoice, fcVal, sicVal, pwpVal, carbContent, carbonConFactor):

    try:
        # Set temporary variables
        prefix = os.path.join(arcpy.env.scratchGDB, "soil_")

        # Set output filename
        if MVGChoice == True:
            outputShp = os.path.join(outputFolder, "soil_mvg.shp")
        else:
            outputShp = os.path.join(outputFolder, "soil_vg.shp")

        # Copy the input shapefile to the output folder
        arcpy.CopyFeatures_management(inputShp, outputShp)

        ##############################################
        ### Calculate the van Genuchten parameters ###
        ##############################################

        # Get the nameArray
        nameArray = []
        with arcpy.da.SearchCursor(outputShp, "LUCIname") as searchCursor:
            for row in searchCursor:
                name = row[0]

                nameArray.append(name)

        # Initialise the van Genuchten parameter arrays
        # All VG PTFs should return these arrays        
        WC_residualArray = []
        WC_satArray = []
        alpha_VGArray = []
        n_VGArray = []
        m_VGArray = []

        # Call VG PTF here depending on VGOption
        if str(VGOption[0:11]) == "Wosten_1999":
            # Has option to calculate Mualem-van Genuchten
            WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray, l_MvGArray, K_satArray = vg_PTFs.Wosten_1999(outputShp, VGOption, carbonConFactor, carbContent, MVGChoice)

        elif VGOption == "Vereecken_1989":
            WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray = vg_PTFs.Vereecken_1989(outputShp, VGOption, carbonConFactor, carbContent)

        elif VGOption == "ZachariasWessolek_2007":
            WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray = vg_PTFs.ZachariasWessolek_2007(outputShp, VGOption, carbonConFactor, carbContent)
        
        elif VGOption == "Weynants_2009":
            # Has option to calculate Mualem-van Genuchten
            WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray, l_MvGArray, K_satArray = vg_PTFs.Weynants_2009(outputShp, VGOption, carbonConFactor, carbContent, MVGChoice)

        elif VGOption == "Dashtaki_2010_vg":
            WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray = vg_PTFs.Dashtaki_2010(outputShp, VGOption, carbonConFactor, carbContent)

        elif VGOption == "HodnettTomasella_2002":
            WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray = vg_PTFs.HodnettTomasella_2002(outputShp, VGOption, carbonConFactor, carbContent)

        else:
            log.error("Van Genuchten option not recognised: " + str(VGOption))
            sys.exit()
 
        # Write VG parameter results to output shapefile
        vanGenuchten.writeVGParams(outputShp, WC_residualArray, WC_satArray, alpha_VGArray, n_VGArray, m_VGArray)

        # Plot VG parameters
        vanGenuchten.plotVG(outputFolder, WC_residualArray,
                            WC_satArray, alpha_VGArray, n_VGArray,
                            m_VGArray, nameArray, fcVal, sicVal, pwpVal)

        ###############################################
        ### Calculate water content using VG params ###
        ###############################################

        # Calculate water content at default pressures
        WC_1kPaArray = []
        WC_3kPaArray = []
        WC_10kPaArray = []
        WC_33kPaArray = []
        WC_100kPaArray = []
        WC_200kPaArray = []
        WC_1000kPaArray = []
        WC_1500kPaArray = []

        for x in range(0, len(nameArray)):
            WC_1kPa = vanGenuchten.calcVGfxn(1.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_3kPa = vanGenuchten.calcVGfxn(3.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_10kPa = vanGenuchten.calcVGfxn(10.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_33kPa = vanGenuchten.calcVGfxn(33.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_100kPa = vanGenuchten.calcVGfxn(100.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_200kPa = vanGenuchten.calcVGfxn(200.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_1000kPa = vanGenuchten.calcVGfxn(1000.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])
            WC_1500kPa = vanGenuchten.calcVGfxn(1500.0, WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x])

            WC_1kPaArray.append(WC_1kPa)
            WC_3kPaArray.append(WC_3kPa)
            WC_10kPaArray.append(WC_10kPa)
            WC_33kPaArray.append(WC_33kPa)
            WC_100kPaArray.append(WC_100kPa)
            WC_200kPaArray.append(WC_200kPa)
            WC_1000kPaArray.append(WC_1000kPa)
            WC_1500kPaArray.append(WC_1500kPa)

        common.writeOutputWC(outputShp, WC_1kPaArray, WC_3kPaArray, WC_10kPaArray, WC_33kPaArray, WC_100kPaArray, WC_200kPaArray, WC_1000kPaArray, WC_1500kPaArray)

        # Write water content at user-input pressures

        # Initialise the pressure head array
        x = np.array(VGPressArray)
        vgPressures = x.astype(np.float)

        # For the headings
        headings = ['Name']

        for pressure in vgPressures:
            headName = 'WC_' + str(pressure) + "kPa"
            headings.append(headName)

        wcHeadings = headings[1:]

        # Initialise water content arrays
        wcArrays = []

        # Calculate soil moisture content at custom VG pressures
        for x in range(0, len(nameArray)):
            wcValues = vanGenuchten.calcPressuresVG(nameArray[x], WC_residualArray[x], WC_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x], vgPressures)
            wcArrays.append(wcValues)

        # Write to output CSV
        outCSV = os.path.join(outputFolder, 'WaterContent.csv')

        with open(outCSV, 'wb') as csv_file:
            writer = csv.writer(csv_file)
            writer.writerow(headings)

            for i in range(0, len(nameArray)):
                row = wcArrays[i]
                writer.writerow(row)

            msg = 'Output CSV with water content saved to: ' + str(outCSV)
            log.info(msg)

        csv_file.close()

        ##################################################
        ### Calculate water content at critical points ###
        ##################################################

        # Initialise water content arrays
        wc_satCalc = []
        wc_fcCalc = []
        wc_sicCalc = []
        wc_pwpCalc = []

        wc_DW = []
        wc_RAW = []
        wc_NRAW = []
        wc_PAW = []

        for i in range(0, len(nameArray)):
            wc_sat = vanGenuchten.calcVGfxn(0, WC_residualArray[i], WC_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i])
            wc_fc = vanGenuchten.calcVGfxn(float(fcVal), WC_residualArray[i], WC_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i])
            wc_sic = vanGenuchten.calcVGfxn(float(sicVal), WC_residualArray[i], WC_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i])
            wc_pwp = vanGenuchten.calcVGfxn(float(pwpVal), WC_residualArray[i], WC_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i])

            drainWater = wc_sat - wc_fc
            readilyAvailWater = wc_fc - wc_sic
            notRAW = wc_sic - wc_pwp
            PAW = wc_fc - wc_pwp

            checks_PTFs.checkNegValue("Drainable water", drainWater, nameArray[i])
            checks_PTFs.checkNegValue("Readily available water", readilyAvailWater, nameArray[i])
            checks_PTFs.checkNegValue("Not readily available water", notRAW, nameArray[i])
            checks_PTFs.checkNegValue("Not readily available water", PAW, nameArray[i])

            wc_satCalc.append(wc_sat)
            wc_fcCalc.append(wc_fc)
            wc_sicCalc.append(wc_sic)
            wc_pwpCalc.append(wc_pwp)
            wc_DW.append(drainWater)
            wc_RAW.append(readilyAvailWater)
            wc_NRAW.append(notRAW)
            wc_PAW.append(PAW)

        common.writeOutputCriticalWC(outputShp, wc_satCalc, wc_fcCalc, wc_sicCalc, wc_pwpCalc, wc_DW, wc_RAW, wc_NRAW, wc_PAW)

        ############################################
        ### Calculate using Mualem-van Genuchten ###
        ############################################

        if MVGChoice == True:
            if VGOption in ["Wosten_1999_top", "Wosten_1999_sub", "Weynants_2009"]:
                # Allow for calculation of MVG
                log.info("Calculating and plotting MVG")

                # Write l_MvGArray to outputShp
                arcpy.AddField_management(outputShp, "l_MvG", "DOUBLE", 10, 6)

                recordNum = 0
                with arcpy.da.UpdateCursor(outputShp, "l_MvG") as cursor:
                    for row in cursor:
                        row[0] = l_MvGArray[recordNum]

                        cursor.updateRow(row)
                        recordNum += 1

                # Plot MVG
                vanGenuchten.plotMVG(outputFolder, K_satArray, alpha_VGArray, n_VGArray, m_VGArray, l_MvGArray, WC_satArray, WC_residualArray, nameArray)

                # Calculate K at default pressures
                
                # Calculate at the pressures using the function
                K_1kPaArray = []
                K_3kPaArray = []
                K_10kPaArray = []
                K_33kPaArray = []
                K_100kPaArray = []
                K_200kPaArray = []
                K_1000kPaArray = []
                K_1500kPaArray = []

                for i in range(0, len(nameArray)):
                    K_1kPa = vanGenuchten.calcKhfxn(1.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_3kPa = vanGenuchten.calcKhfxn(3.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_10kPa = vanGenuchten.calcKhfxn(10.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_33kPa = vanGenuchten.calcKhfxn(33.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_100kPa = vanGenuchten.calcKhfxn(100.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_200kPa = vanGenuchten.calcKhfxn(200.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_1000kPa = vanGenuchten.calcKhfxn(1000.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])
                    K_1500kPa = vanGenuchten.calcKhfxn(1500.0, K_satArray[i], alpha_VGArray[i], n_VGArray[i], m_VGArray[i], l_MvGArray[i])

                    K_1kPaArray.append(K_1kPa)
                    K_3kPaArray.append(K_3kPa)
                    K_10kPaArray.append(K_10kPa)
                    K_33kPaArray.append(K_33kPa)
                    K_100kPaArray.append(K_100kPa)
                    K_200kPaArray.append(K_200kPa)
                    K_1000kPaArray.append(K_1000kPa)
                    K_1500kPaArray.append(K_1500kPa)

                # Write to the shapefile
                MVGFields = ["K_1kPa", "K_3kPa", "K_10kPa", "K_33kPa", "K_100kPa", "K_200kPa", "K_1000kPa", "K_1500kPa"]
                
                # Add fields
                for field in MVGFields:
                    arcpy.AddField_management(outputShp, field, "DOUBLE", 10, 6)

                recordNum = 0
                with arcpy.da.UpdateCursor(outputShp, MVGFields) as cursor:
                    for row in cursor:
                        row[0] = K_1kPaArray[recordNum]
                        row[1] = K_3kPaArray[recordNum]
                        row[2] = K_10kPaArray[recordNum]
                        row[3] = K_33kPaArray[recordNum]
                        row[4] = K_100kPaArray[recordNum]
                        row[5] = K_200kPaArray[recordNum]
                        row[6] = K_1000kPaArray[recordNum]
                        row[7] = K_1500kPaArray[recordNum]

                        cursor.updateRow(row)
                        recordNum += 1

                log.info("Unsaturated hydraulic conductivity at default pressures written to output shapefile")

                # Calculate K at custom pressures

                # Initialise the pressure head array
                x = np.array(VGPressArray)
                vgPressures = x.astype(np.float)

                # For the headings
                headings = ['Name']

                for pressure in vgPressures:
                    headName = 'K_' + str(pressure) + "kPa"
                    headings.append(headName)

                kHeadings = headings[1:]

                # Initialise K arrays
                kArrays = []

                # Calculate K content at custom VG pressures
                for x in range(0, len(nameArray)):
                    kValues = vanGenuchten.calcPressuresMVG(nameArray[x], K_satArray[x], alpha_VGArray[x], n_VGArray[x], m_VGArray[x], l_MvGArray[x], vgPressures)
                    kArrays.append(kValues)
                
                # Write to output CSV
                outCSV = os.path.join(outputFolder, 'K_MVG.csv')

                with open(outCSV, 'wb') as csv_file:
                    writer = csv.writer(csv_file)
                    writer.writerow(headings)

                    for i in range(0, len(nameArray)):
                        row = kArrays[i]
                        writer.writerow(row)

                    msg = 'Output CSV with unsaturated hydraulic conductivity saved to: ' + str(outCSV)
                    log.info(msg)

                csv_file.close()

            else:
                log.error("Selected PTF does not calculate Mualem-van Genuchten parameters")
                log.error("Please select a different PTF")
                sys.exit()

    except Exception:
        arcpy.AddError("van Genuchten function failed")
        raise

    finally:
        # Remove feature layers from memory
        try:
            for lyr in common.listFeatureLayers(locals()):
                arcpy.Delete_management(locals()[lyr])
                exec(lyr + ' = None') in locals()
        except Exception:
            pass
Beispiel #5
0
def function(outputFolder, inputShp, fieldFC, fieldPWP, fieldSat, RAWoption,
             RAWfrac, fieldCrit, RDchoice, rootingDepth):

    try:
        # Set temporary variables
        prefix = os.path.join(arcpy.env.scratchGDB, "moist_")

        tempSoils = prefix + "tempSoils"

        # Set output filename
        outputShp = os.path.join(outputFolder, "soilMoisture.shp")

        # Check fields are present in the input shapefile
        reqFields = ['OBJECTID', fieldFC, fieldPWP, fieldSat]

        if RAWoption == 'CriticalPoint':
            reqFields.append(fieldCrit)

        checkInputFields(reqFields, inputShp)

        # Copy the input shapefile to the output folder
        arcpy.CopyFeatures_management(inputShp, tempSoils)

        # Retrieve information from input shapefile
        record = []
        volFC = []
        volPWP = []
        volSat = []
        volCrit = []

        with arcpy.da.SearchCursor(tempSoils, reqFields) as searchCursor:
            for row in searchCursor:
                objectID = row[0]
                WC_FC = row[1]
                WC_PWP = row[2]
                WC_Sat = row[3]

                record.append(objectID)
                volFC.append(WC_FC)
                volPWP.append(WC_PWP)
                volSat.append(WC_Sat)

                if RAWoption == 'CriticalPoint':
                    WC_Crit = row[4]
                    volCrit.append(WC_Crit)

        volPAW = []
        volDW = []
        volTWC = []
        volRAW = []

        mmPAW = []
        mmDW = []
        mmTWC = []
        mmRAW = []

        for x in range(0, len(record)):

            # Calculate PAW
            PAW = volFC[x] - volPWP[x]

            if PAW < 0:
                log.warning('Negative PAW (vol) calculated for record ' +
                            str(record[x]))

            volPAW.append(PAW)

            # Calculate drainable water
            DW = volSat[x] - volFC[x]

            if DW < 0:
                log.warning(
                    'Negative drainable water (vol) calculated for record ' +
                    str(record[x]))

            volDW.append(DW)

            # Calculate total water content
            TWC = volSat[x] - volPWP[x]

            if TWC < 0:
                log.warning(
                    'Negative total water content (vol) calculated for record '
                    + str(record[x]))

            volTWC.append(TWC)

            if RAWoption == 'CriticalPoint':
                RAW = volFC[x] - volCrit[x]

                RAWfrac = RAW / float(PAW)

                if frac <= 0.2 or frac >= 0.8:
                    log.warning('Fraction of RAW to PAW is below 0.2 or 0.8')

                volRAW.append(RAW)

            elif RAWoption == 'Fraction':

                RAW = float(RAWfrac) * float(PAW)
                volRAW.append(RAW)

            if RDchoice == True:
                mm_PAW = PAW * float(rootingDepth)
                mm_DW = DW * float(rootingDepth)
                mm_TWC = TWC * float(rootingDepth)
                mm_RAW = RAW * float(rootingDepth)

                mmPAW.append(mm_PAW)
                mmDW.append(mm_DW)
                mmTWC.append(mm_TWC)
                mmRAW.append(mm_RAW)

        outFields = ['volPAW', 'volDW', 'volTWC', 'volRAW']

        # Write outputs to shapefile
        arcpy.AddField_management(tempSoils, "volPAW", "DOUBLE", 10, 6)
        arcpy.AddField_management(tempSoils, "volDW", "DOUBLE", 10, 6)
        arcpy.AddField_management(tempSoils, "volTWC", "DOUBLE", 10, 6)
        arcpy.AddField_management(tempSoils, "volRAW", "DOUBLE", 10, 6)

        if RDchoice == True:
            arcpy.AddField_management(tempSoils, "mmPAW", "DOUBLE", 10, 6)
            arcpy.AddField_management(tempSoils, "mmDW", "DOUBLE", 10, 6)
            arcpy.AddField_management(tempSoils, "mmTWC", "DOUBLE", 10, 6)
            arcpy.AddField_management(tempSoils, "mmRAW", "DOUBLE", 10, 6)

            outFields.append('mmPAW')
            outFields.append('mmDW')
            outFields.append('mmTWC')
            outFields.append('mmRAW')

        recordNum = 0
        with arcpy.da.UpdateCursor(tempSoils, outFields) as cursor:
            for row in cursor:
                row[0] = volPAW[recordNum]
                row[1] = volDW[recordNum]
                row[2] = volTWC[recordNum]
                row[3] = volRAW[recordNum]

                if RDchoice == True:
                    row[4] = mmPAW[recordNum]
                    row[5] = mmDW[recordNum]
                    row[6] = mmTWC[recordNum]
                    row[7] = mmRAW[recordNum]

                cursor.updateRow(row)
                recordNum += 1

        # Clean fields
        outFields.append('OBJECTID')
        common.CleanFields(tempSoils, outFields)

        arcpy.CopyFeatures_management(tempSoils, outputShp)

    except Exception:
        arcpy.AddError("Soil moisture function failed")
        raise

    finally:
        # Remove feature layers from memory
        try:
            for lyr in common.listFeatureLayers(locals()):
                arcpy.Delete_management(locals()[lyr])
                exec(lyr + ' = None') in locals()
        except Exception:
            pass