Esempio n. 1
0
def l6qc(cf, ds5):
    ds6 = qcio.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
    qcutils.UpdateGlobalAttributes(cf, ds6, "L6")
    # parse the control file
    qcrp.ParseL6ControlFile(cf, ds6)
    # check to see if we have any imports
    qcgf.ImportSeries(cf, ds6)
    # check units
    qcutils.CheckUnits(ds6, "Fc", "umol/m2/s", convert_units=True)
    ## filter Fc for night time and ustar threshold, write to ds as "ER"
    #result = qcrp.GetERFromFc(cf,ds6)
    #if result==0: return
    # apply the turbulence filter (if requested)
    qcck.ApplyTurbulenceFilter(cf, ds6)
    qcrp.GetERFromFc2(cf, ds6)
    # estimate ER using SOLO
    qcrp.ERUsingSOLO(cf, ds6)
    # estimate ER using FFNET
    qcrp.ERUsingFFNET(cf, ds6)
    # estimate ER using Lloyd-Taylor
    qcrp.ERUsingLloydTaylor(cf, ds6)
    # estimate ER using Lasslop et al
    qcrp.ERUsingLasslop(cf, ds6)
    # merge the estimates of ER with the observations
    qcts.MergeSeriesUsingDict(ds6, merge_order="standard")
    # calculate NEE from Fc and ER
    qcrp.CalculateNEE(cf, ds6)
    # calculate NEP from NEE
    qcrp.CalculateNEP(cf, ds6)
    # calculate ET from Fe
    qcrp.CalculateET(ds6)
    # partition NEE into GPP and ER
    qcrp.PartitionNEE(cf, ds6)
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds6)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds6)
    # do the L6 summary
    qcrp.L6_summary(cf, ds6)

    return ds6
Esempio n. 2
0
def l6qc(cf,ds5):
    ds6 = qcio.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
    qcutils.UpdateGlobalAttributes(cf,ds6,"L6")
    # parse the control file
    qcrp.ParseL6ControlFile(cf,ds6)
    # check to see if we have any imports
    qcgf.ImportSeries(cf,ds6)
    # check units
    qcutils.CheckUnits(ds6,"Fc","umol/m2/s",convert_units=True)
    ## filter Fc for night time and ustar threshold, write to ds as "ER"
    #result = qcrp.GetERFromFc(cf,ds6)
    #if result==0: return
    # apply the turbulence filter (if requested)
    qcck.ApplyTurbulenceFilter(cf,ds6)
    qcrp.GetERFromFc2(cf,ds6)
    # estimate ER using SOLO
    qcrp.ERUsingSOLO(cf,ds6)
    # estimate ER using FFNET
    qcrp.ERUsingFFNET(cf,ds6)
    # estimate ER using Lloyd-Taylor
    qcrp.ERUsingLloydTaylor(cf,ds6)
    # estimate ER using Lasslop et al
    qcrp.ERUsingLasslop(cf,ds6)
    # merge the estimates of ER with the observations
    qcts.MergeSeriesUsingDict(ds6,merge_order="standard")
    # calculate NEE from Fc and ER
    qcrp.CalculateNEE(cf,ds6)
    # calculate NEP from NEE
    qcrp.CalculateNEP(cf,ds6)
    # calculate ET from Fe
    qcrp.CalculateET(ds6)
    # partition NEE into GPP and ER
    qcrp.PartitionNEE(cf,ds6)
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds6)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds6)
    # do the L6 summary
    qcrp.L6_summary(cf,ds6)

    return ds6
Esempio n. 3
0
def l5qc(cf, ds4):
    ds5 = qcio.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
    qcutils.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
    qcgf.ImportSeries(cf, ds5)
    # re-apply the quality control checks (range, diurnal and rules)
    qcck.do_qcchecks(cf, ds5)
    # now do the flux gap filling methods
    label_list = qcutils.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
        qcgf.GapFillParseControlFile(cf, ds5, label, ds_alt)
    # *** start of the section that does the gap filling of the fluxes ***
    # apply the turbulence filter (if requested)
    qcck.ApplyTurbulenceFilter(cf, ds5)
    # fill short gaps using interpolation
    qcgf.GapFillUsingInterpolation(cf, ds5)
    # do the gap filling using SOLO
    qcgfSOLO.GapFillUsingSOLO(cf, ds4, ds5)
    if ds5.returncodes["solo"] == "quit":
        return ds5
    # gap fill using marginal distribution sampling
    qcgfMDS.GapFillFluxUsingMDS(cf, ds5)
    # gap fill using climatology
    qcgf.GapFillFromClimatology(ds5)
    # merge the gap filled drivers into a single series
    qcts.MergeSeriesUsingDict(ds5, merge_order="standard")
    # calculate Monin-Obukhov length
    qcts.CalculateMoninObukhovLength(ds5)
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds5)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds5)

    return ds5
Esempio n. 4
0
def l5qc(cf,ds4):
    ds5 = qcio.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
    qcutils.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
    qcgf.ImportSeries(cf,ds5)
    # re-apply the quality control checks (range, diurnal and rules)
    qcck.do_qcchecks(cf,ds5)
    # now do the flux gap filling methods
    label_list = qcutils.get_label_list_from_cf(cf)
    for ThisOne in label_list:
        # parse the control file for information on how the user wants to do the gap filling
        qcgf.GapFillParseControlFile(cf,ds5,ThisOne,ds_alt)
    # *** start of the section that does the gap filling of the fluxes ***
    # apply the turbulence filter (if requested)
    qcck.ApplyTurbulenceFilter(cf,ds5)
    # fill short gaps using interpolation
    #qcgf.GapFillUsingInterpolation(cf,ds5)
    # do the gap filling using SOLO
    qcgf.GapFillUsingSOLO(cf,ds4,ds5)
    if ds5.returncodes["solo"]=="quit": return ds5
    ## gap fill using marginal distribution sampling
    #qcgf.GapFillFluxUsingMDS(cf,ds5)
    ## gap fill using ratios
    #qcgf.GapFillFluxFromDayRatio(cf,ds5)
    # gap fill using climatology
    qcgf.GapFillFromClimatology(ds5)
    # merge the gap filled drivers into a single series
    qcts.MergeSeriesUsingDict(ds5,merge_order="standard")
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds5)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds5)

    return ds5
Esempio n. 5
0
def l6qc(cf,ds5):
    ds6 = qcio.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
    qcutils.UpdateGlobalAttributes(cf,ds6,"L6")
    # parse the control file
    qcrp.ParseL6ControlFile(cf,ds6)
    # check to see if we have any imports
    qcgf.ImportSeries(cf,ds6)
    # filter Fc for night time and ustar threshold, write to ds as "Fre"
    #qcrp.GetFreIndicator(cf,ds6)
    qcrp.GetFreFromFc(cf,ds6)
    # estimate Reco using SOLO
    qcrp.FreUsingSOLO(cf,ds6)
    # estimate Reco using FFNET
    qcrp.FreUsingFFNET(cf,ds6)
    # estimate Reco using Lloyd-Taylor
    qcrp.FreUsingLloydTaylor(cf,ds6)
    # estimate Reco using Lasslop et al
    qcrp.FreUsingLasslop(cf,ds6)
    # merge the estimates of Reco with the observations
    qcts.MergeSeriesUsingDict(ds6,merge_order="standard")
    # calculate NEE from Fc and Fre
    qcrp.CalculateNEE(cf,ds6)
    # calculate NEP from NEE
    qcrp.CalculateNEP(cf,ds6)
    # calculate ET from Fe
    qcrp.CalculateET(ds6)
    # partition NEE into GPP and Reco
    qcrp.PartitionNEE(cf,ds6)
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds6)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds6)
    # do the L6 summary
    qcrp.L6_summary(cf,ds6)

    return ds6
Esempio n. 6
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 = qcio.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    
    qcutils.UpdateGlobalAttributes(cf,ds4,"L4")
    ds4.cf = cf
    # calculate the available energy
    if "Fa" not in ds4.series.keys():
        qcts.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
    qcgf.ImportSeries(cf,ds4)
    # re-apply the quality control checks (range, diurnal and rules)
    qcck.do_qcchecks(cf,ds4)
    # now do the meteorological driver gap filling
    for ThisOne in cf["Drivers"].keys():
        if ThisOne not in ds4.series.keys(): log.error("Series "+ThisOne+" not in data structure"); continue
        # parse the control file for information on how the user wants to do the gap filling
        qcgf.GapFillParseControlFile(cf,ds4,ThisOne,ds_alt)
    # *** start of the section that does the gap filling of the drivers ***
    # fill short gaps using interpolation
    qcgf.GapFillUsingInterpolation(cf,ds4)
    # gap fill using climatology
    qcgf.GapFillFromClimatology(ds4)
    # do the gap filling using the ACCESS output
    qcgf.GapFillFromAlternate(cf,ds4,ds_alt)
    if ds4.returncodes["alternate"]=="quit": return ds4
    # gap fill using SOLO
    qcgf.GapFillUsingSOLO(cf,ds3,ds4)
    if ds4.returncodes["solo"]=="quit": return ds4
    # merge the first group of gap filled drivers into a single series
    qcts.MergeSeriesUsingDict(ds4,merge_order="prerequisite")
    # re-calculate the ground heat flux but only if requested in control file
    opt = qcutils.get_keyvaluefromcf(cf,["Options"],"CorrectFgForStorage",default="No",mode="quiet")
    if opt.lower()!="no":
        qcts.CorrectFgForStorage(cf,ds4,Fg_out='Fg',Fg_in='Fg_Av',Ts_in='Ts',Sws_in='Sws')
    # re-calculate the net radiation
    qcts.CalculateNetRadiation(cf,ds4,Fn_out='Fn',Fsd_in='Fsd',Fsu_in='Fsu',Fld_in='Fld',Flu_in='Flu')
    # re-calculate the available energy
    qcts.CalculateAvailableEnergy(ds4,Fa_out='Fa',Fn_in='Fn',Fg_in='Fg')
    # merge the second group of gap filled drivers into a single series
    qcts.MergeSeriesUsingDict(ds4,merge_order="standard")
    # re-calculate the water vapour concentrations
    qcts.CalculateHumiditiesAfterGapFill(ds4)
    # re-calculate the meteorological variables
    qcts.CalculateMeteorologicalVariables(ds4)
    # the Tumba rhumba
    qcts.CalculateComponentsFromWsWd(ds4)
    # check for any missing data
    qcutils.get_missingingapfilledseries(ds4)
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds4)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds4)

    return ds4
Esempio n. 7
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 = qcio.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
    qcutils.UpdateGlobalAttributes(cf, ds4, "L4")
    ds4.cf = cf
    # calculate the available energy
    if "Fa" not in ds4.series.keys():
        qcts.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
    qcgf.ImportSeries(cf, ds4)
    # re-apply the quality control checks (range, diurnal and rules)
    qcck.do_qcchecks(cf, ds4)
    # now do the meteorological driver gap filling
    for ThisOne in cf["Drivers"].keys():
        if ThisOne not in ds4.series.keys():
            log.error("Series " + ThisOne + " not in data structure")
            continue
        # parse the control file for information on how the user wants to do the gap filling
        qcgf.GapFillParseControlFile(cf, ds4, ThisOne, ds_alt)
    # *** start of the section that does the gap filling of the drivers ***
    # fill short gaps using interpolation
    qcgf.GapFillUsingInterpolation(cf, ds4)
    # gap fill using climatology
    qcgf.GapFillFromClimatology(ds4)
    # do the gap filling using the ACCESS output
    qcgf.GapFillFromAlternate(cf, ds4, ds_alt)
    if ds4.returncodes["alternate"] == "quit": return ds4
    # gap fill using SOLO
    qcgf.GapFillUsingSOLO(cf, ds3, ds4)
    if ds4.returncodes["solo"] == "quit": return ds4
    # merge the first group of gap filled drivers into a single series
    qcts.MergeSeriesUsingDict(ds4, merge_order="prerequisite")
    # re-calculate the ground heat flux but only if requested in control file
    opt = qcutils.get_keyvaluefromcf(cf, ["Options"],
                                     "CorrectFgForStorage",
                                     default="No",
                                     mode="quiet")
    if opt.lower() != "no":
        qcts.CorrectFgForStorage(cf,
                                 ds4,
                                 Fg_out='Fg',
                                 Fg_in='Fg_Av',
                                 Ts_in='Ts',
                                 Sws_in='Sws')
    # re-calculate the net radiation
    qcts.CalculateNetRadiation(cf,
                               ds4,
                               Fn_out='Fn',
                               Fsd_in='Fsd',
                               Fsu_in='Fsu',
                               Fld_in='Fld',
                               Flu_in='Flu')
    # re-calculate the available energy
    qcts.CalculateAvailableEnergy(ds4, Fa_out='Fa', Fn_in='Fn', Fg_in='Fg')
    # merge the second group of gap filled drivers into a single series
    qcts.MergeSeriesUsingDict(ds4, merge_order="standard")
    # re-calculate the water vapour concentrations
    qcts.CalculateHumiditiesAfterGapFill(ds4)
    # re-calculate the meteorological variables
    qcts.CalculateMeteorologicalVariables(ds4)
    # the Tumba rhumba
    qcts.CalculateComponentsFromWsWd(ds4)
    # check for any missing data
    qcutils.get_missingingapfilledseries(ds4)
    # write the percentage of good data as a variable attribute
    qcutils.get_coverage_individual(ds4)
    # write the percentage of good data for groups
    qcutils.get_coverage_groups(ds4)

    return ds4