예제 #1
0
def l5qc(main_gui, cf, ds4):
    ds5 = pfp_io.copy_datastructure(cf, ds4)
    # ds5 will be empty (logical false) if an error occurs in copy_datastructure
    # return from this routine if this is the case
    if not ds5:
        return ds5
    # set some attributes for this level
    pfp_utils.UpdateGlobalAttributes(cf, ds5, "L5")
    # parse the control file for information on how the user wants to do the gap filling
    l5_info = pfp_gf.ParseL5ControlFile(cf, ds5)
    if ds5.returncodes["value"] != 0:
        return ds5
    # check to see if we have any imports
    pfp_gf.ImportSeries(cf, ds5)
    # re-apply the quality control checks (range, diurnal and rules)
    pfp_ck.do_qcchecks(cf, ds5)
    pfp_gf.CheckL5Drivers(ds5, l5_info)
    if ds5.returncodes["value"] != 0:
        return ds5
    # now do the flux gap filling methods
    # *** start of the section that does the gap filling of the fluxes ***
    pfp_gf.CheckGapLengths(cf, ds5, l5_info)
    if ds5.returncodes["value"] != 0:
        return ds5
    # apply the turbulence filter (if requested)
    pfp_ck.ApplyTurbulenceFilter(cf, ds5, l5_info)
    # fill short gaps using interpolation
    pfp_gf.GapFillUsingInterpolation(cf, ds5)
    # gap fill using marginal distribution sampling
    if "GapFillUsingMDS" in l5_info:
        pfp_gfMDS.GapFillUsingMDS(ds5, l5_info, "GapFillUsingMDS")
    # do the gap filling using SOLO
    if "GapFillUsingSOLO" in l5_info:
        pfp_gfSOLO.GapFillUsingSOLO(main_gui, ds5, l5_info, "GapFillUsingSOLO")
        if ds5.returncodes["value"] != 0:
            return ds5
    # fill long gaps using SOLO
    if "GapFillLongSOLO" in l5_info:
        pfp_gfSOLO.GapFillUsingSOLO(main_gui, ds5, l5_info, "GapFillLongSOLO")
        if ds5.returncodes["value"] != 0:
            return ds5
    # merge the gap filled drivers into a single series
    pfp_ts.MergeSeriesUsingDict(ds5, l5_info, merge_order="standard")
    # check that all targets were gap filled
    pfp_gf.CheckL5Targets(ds5, l5_info)
    if ds5.returncodes["value"] != 0:
        return ds5
    # calculate Monin-Obukhov length
    pfp_ts.CalculateMoninObukhovLength(ds5)
    # write the percentage of good data as a variable attribute
    pfp_utils.get_coverage_individual(ds5)
    # write the percentage of good data for groups
    pfp_utils.get_coverage_groups(ds5)
    # remove intermediate series from the data structure
    pfp_ts.RemoveIntermediateSeries(ds5, l5_info)

    return ds5
예제 #2
0
def l4qc(main_gui, cf, ds3):
    ds4 = pfp_io.copy_datastructure(cf, ds3)
    # ds4 will be empty (logical false) if an error occurs in copy_datastructure
    # return from this routine if this is the case
    if not ds4:
        return ds4
    # set some attributes for this level
    pfp_utils.UpdateGlobalAttributes(cf, ds4, "L4")
    # check to see if we have any imports
    pfp_gf.ImportSeries(cf, ds4)
    # re-apply the quality control checks (range, diurnal and rules)
    pfp_ck.do_qcchecks(cf, ds4)
    # now do the meteorological driver gap filling
    # parse the control file for information on how the user wants to do the gap filling
    l4_info = pfp_gf.ParseL4ControlFile(cf, ds4)
    if ds4.returncodes["value"] != 0:
        return ds4
    # *** start of the section that does the gap filling of the drivers ***
    # read the alternate data files
    ds_alt = pfp_gf.ReadAlternateFiles(ds4, l4_info)
    # fill short gaps using interpolation
    pfp_gf.GapFillUsingInterpolation(cf, ds4)
    # gap fill using climatology
    if "GapFillFromClimatology" in l4_info:
        pfp_gf.GapFillFromClimatology(ds4, l4_info, "GapFillFromClimatology")
    # do the gap filling using the ACCESS output
    if "GapFillFromAlternate" in l4_info:
        pfp_gfALT.GapFillFromAlternate(main_gui, ds4, ds_alt, l4_info, "GapFillFromAlternate")
        if ds4.returncodes["value"] != 0:
            return ds4
    # merge the first group of gap filled drivers into a single series
    pfp_ts.MergeSeriesUsingDict(ds4, l4_info, merge_order="prerequisite")
    # re-calculate the ground heat flux but only if requested in control file
    opt = pfp_utils.get_keyvaluefromcf(cf,["Options"], "CorrectFgForStorage", default="No", mode="quiet")
    if opt.lower() != "no":
        pfp_ts.CorrectFgForStorage(cf, ds4, Fg_out='Fg', Fg_in='Fg_Av', Ts_in='Ts', Sws_in='Sws')
    # re-calculate the net radiation
    pfp_ts.CalculateNetRadiation(cf, ds4, Fn_out='Fn', Fsd_in='Fsd', Fsu_in='Fsu', Fld_in='Fld', Flu_in='Flu')
    # re-calculate the available energy
    pfp_ts.CalculateAvailableEnergy(ds4, Fa_out='Fa', Fn_in='Fn', Fg_in='Fg')
    # merge the second group of gap filled drivers into a single series
    pfp_ts.MergeSeriesUsingDict(ds4, l4_info, merge_order="standard")
    # re-calculate the water vapour concentrations
    pfp_ts.CalculateHumiditiesAfterGapFill(ds4, l4_info)
    # re-calculate the meteorological variables
    pfp_ts.CalculateMeteorologicalVariables(ds4, l4_info)
    # check for any missing data
    pfp_utils.get_missingingapfilledseries(ds4, l4_info)
    # write the percentage of good data as a variable attribute
    pfp_utils.get_coverage_individual(ds4)
    # write the percentage of good data for groups
    pfp_utils.get_coverage_groups(ds4)
    # remove intermediate series from the data structure
    pfp_ts.RemoveIntermediateSeries(ds4, l4_info)

    return ds4
예제 #3
0
def l6qc(main_gui, cf, ds5):
    ds6 = pfp_io.copy_datastructure(cf, ds5)
    # ds6 will be empty (logical false) if an error occurs in copy_datastructure
    # return from this routine if this is the case
    if not ds6:
        return ds6
    # set some attributes for this level
    pfp_utils.UpdateGlobalAttributes(cf, ds6, "L6")
    # parse the control file
    l6_info = pfp_rp.ParseL6ControlFile(cf, ds6)
    # check to see if we have any imports
    pfp_gf.ImportSeries(cf, ds6)
    # check units of Fc
    Fc_list = [label for label in ds6.series.keys() if label[0:2] == "Fc"]
    pfp_utils.CheckUnits(ds6, Fc_list, "umol/m2/s", convert_units=True)
    # get ER from the observed Fc
    pfp_rp.GetERFromFc(cf, ds6)
    # return code will be non-zero if turbulance filter not applied to CO2 flux
    if ds6.returncodes["value"] != 0:
        return ds6
    # estimate ER using SOLO
    if "ERUsingSOLO" in l6_info:
        pfp_rp.ERUsingSOLO(main_gui, ds6, l6_info, "ERUsingSOLO")
        if ds6.returncodes["value"] != 0:
            return ds6
    # estimate ER using FFNET
    #pfp_rp.ERUsingFFNET(cf, ds6, l6_info)
    # estimate ER using Lloyd-Taylor
    pfp_rp.ERUsingLloydTaylor(cf, ds6, l6_info)
    # estimate ER using Lasslop et al
    pfp_rp.ERUsingLasslop(ds6, l6_info)
    # merge the estimates of ER with the observations
    pfp_ts.MergeSeriesUsingDict(ds6, l6_info, merge_order="standard")
    # calculate NEE from Fc and ER
    pfp_rp.CalculateNEE(cf, ds6, l6_info)
    # calculate NEP from NEE
    pfp_rp.CalculateNEP(cf, ds6)
    # calculate ET from Fe
    pfp_rp.CalculateET(ds6)
    # partition NEE into GPP and ER
    pfp_rp.PartitionNEE(ds6, l6_info)
    # write the percentage of good data as a variable attribute
    pfp_utils.get_coverage_individual(ds6)
    # write the percentage of good data for groups
    pfp_utils.get_coverage_groups(ds6)
    # remove intermediate series from the data structure
    pfp_ts.RemoveIntermediateSeries(ds6, l6_info)
    # do the L6 summary
    pfp_rp.L6_summary(cf, ds6)

    return ds6
예제 #4
0
def l5qc(cf, ds4):
    ds5 = pfp_io.copy_datastructure(cf, ds4)
    # ds4 will be empty (logical false) if an error occurs in copy_datastructure
    # return from this routine if this is the case
    if not ds5:
        return ds5
    # set some attributes for this level
    pfp_utils.UpdateGlobalAttributes(cf, ds5, "L5")
    ds5.cf = cf
    # create a dictionary to hold the gap filling data
    ds_alt = {}
    # check to see if we have any imports
    pfp_gf.ImportSeries(cf, ds5)
    # re-apply the quality control checks (range, diurnal and rules)
    pfp_ck.do_qcchecks(cf, ds5)
    # now do the flux gap filling methods
    label_list = pfp_utils.get_label_list_from_cf(cf)
    for label in label_list:
        # parse the control file for information on how the user wants to do the gap filling
        pfp_gf.GapFillParseControlFile(cf, ds5, label, ds_alt)
    # *** start of the section that does the gap filling of the fluxes ***
    # apply the turbulence filter (if requested)
    pfp_ck.ApplyTurbulenceFilter(cf, ds5)
    # fill short gaps using interpolation
    pfp_gf.GapFillUsingInterpolation(cf, ds5)
    # do the gap filling using SOLO
    pfp_gfSOLO.GapFillUsingSOLO(cf, ds4, ds5)
    if ds5.returncodes["solo"] == "quit":
        return ds5
    # gap fill using marginal distribution sampling
    pfp_gfMDS.GapFillFluxUsingMDS(cf, ds5)
    # gap fill using climatology
    pfp_gf.GapFillFromClimatology(ds5)
    # merge the gap filled drivers into a single series
    pfp_ts.MergeSeriesUsingDict(ds5, merge_order="standard")
    # calculate Monin-Obukhov length
    pfp_ts.CalculateMoninObukhovLength(ds5)
    # write the percentage of good data as a variable attribute
    pfp_utils.get_coverage_individual(ds5)
    # write the percentage of good data for groups
    pfp_utils.get_coverage_groups(ds5)

    return ds5
예제 #5
0
def l4qc(cf, ds3):

    # !!! code here to use existing L4 file
    # logic
    # if the L4 doesn't exist
    #  - create ds4 by using copy.deepcopy(ds3)
    # if the L4 does exist and the "UseExistingL4File" option is False
    #  - create ds4 by using copy.deepcopy(ds3)
    # if the L4 does exist and the "UseExistingL4File" option is True
    #  - read the contents of the L4 netCDF file
    #  - check the start and end dates of the L3 and L4 data
    #     - if these are the same then tell the user there is nothing to do
    #  - copy the L3 data to the L4 data structure
    #  - replace the L3 data with the L4 data
    #ds4 = copy.deepcopy(ds3)
    ds4 = pfp_io.copy_datastructure(cf, ds3)
    # ds4 will be empty (logical false) if an error occurs in copy_datastructure
    # return from this routine if this is the case
    if not ds4: return ds4
    # set some attributes for this level
    pfp_utils.UpdateGlobalAttributes(cf, ds4, "L4")
    ds4.cf = cf
    ## calculate the available energy
    #if "Fa" not in ds4.series.keys():
    #pfp_ts.CalculateAvailableEnergy(ds4,Fa_out='Fa',Fn_in='Fn',Fg_in='Fg')
    # create a dictionary to hold the gap filling data
    ds_alt = {}
    # check to see if we have any imports
    pfp_gf.ImportSeries(cf, ds4)
    # re-apply the quality control checks (range, diurnal and rules)
    pfp_ck.do_qcchecks(cf, ds4)
    # now do the meteorological driver gap filling
    for ThisOne in cf["Drivers"].keys():
        if ThisOne not in ds4.series.keys():
            logger.warning("Series " + ThisOne + " not in data structure")
            continue
        # parse the control file for information on how the user wants to do the gap filling
        pfp_gf.GapFillParseControlFile(cf, ds4, ThisOne, ds_alt)
    # *** start of the section that does the gap filling of the drivers ***
    # fill short gaps using interpolation
    pfp_gf.GapFillUsingInterpolation(cf, ds4)
    # gap fill using climatology
    pfp_gf.GapFillFromClimatology(ds4)
    # do the gap filling using the ACCESS output
    pfp_gfALT.GapFillFromAlternate(cf, ds4, ds_alt)
    if ds4.returncodes["alternate"] == "quit": return ds4
    # gap fill using SOLO
    pfp_gfSOLO.GapFillUsingSOLO(cf, ds3, ds4)
    if ds4.returncodes["solo"] == "quit": return ds4
    # merge the first group of gap filled drivers into a single series
    pfp_ts.MergeSeriesUsingDict(ds4, merge_order="prerequisite")
    # re-calculate the ground heat flux but only if requested in control file
    opt = pfp_utils.get_keyvaluefromcf(cf, ["Options"],
                                       "CorrectFgForStorage",
                                       default="No",
                                       mode="quiet")
    if opt.lower() != "no":
        pfp_ts.CorrectFgForStorage(cf,
                                   ds4,
                                   Fg_out='Fg',
                                   Fg_in='Fg_Av',
                                   Ts_in='Ts',
                                   Sws_in='Sws')
    # re-calculate the net radiation
    pfp_ts.CalculateNetRadiation(cf,
                                 ds4,
                                 Fn_out='Fn',
                                 Fsd_in='Fsd',
                                 Fsu_in='Fsu',
                                 Fld_in='Fld',
                                 Flu_in='Flu')
    # re-calculate the available energy
    pfp_ts.CalculateAvailableEnergy(ds4, Fa_out='Fa', Fn_in='Fn', Fg_in='Fg')
    # merge the second group of gap filled drivers into a single series
    pfp_ts.MergeSeriesUsingDict(ds4, merge_order="standard")
    # re-calculate the water vapour concentrations
    pfp_ts.CalculateHumiditiesAfterGapFill(ds4)
    # re-calculate the meteorological variables
    pfp_ts.CalculateMeteorologicalVariables(ds4)
    # the Tumba rhumba
    pfp_ts.CalculateComponentsFromWsWd(ds4)
    # check for any missing data
    pfp_utils.get_missingingapfilledseries(ds4)
    # write the percentage of good data as a variable attribute
    pfp_utils.get_coverage_individual(ds4)
    # write the percentage of good data for groups
    pfp_utils.get_coverage_groups(ds4)

    return ds4