def main(cfg):
    """Execute the program.

    Argument cfg, containing directory paths, preprocessed input dataset
    filenames and user-defined options, is passed by ESMValTool preprocessor.
    """
    provlog = ProvenanceLogger(cfg)
    lorenz = lorenz_cycle
    comp = computations
    logger.info('Entering the diagnostic tool')
    # Load paths
    wdir_up = cfg['work_dir']
    pdir_up = cfg['plot_dir']
    input_data = cfg['input_data'].values()
    logger.info('Work directory: %s \n', wdir_up)
    logger.info('Plot directory: %s \n', pdir_up)
    plotsmod = plot_script
    data = e.Datasets(cfg)
    logger.debug(data)
    models = data.get_info_list('dataset')
    model_names = list(set(models))
    model_names.sort()
    logger.info(model_names)
    varnames = data.get_info_list('short_name')
    curr_vars = list(set(varnames))
    logger.debug(curr_vars)
    # load user-defined options
    lsm = str(cfg['lsm'])
    wat = str(cfg['wat'])
    lec = str(cfg['lec'])
    entr = str(cfg['entr'])
    met = str(cfg['met'])
    flags = [wat, lec, entr, met]
    # Initialize multi-model arrays
    modnum = len(model_names)
    te_all = np.zeros(modnum)
    toab_all = np.zeros([modnum, 2])
    toab_oc_all = np.zeros(modnum)
    toab_la_all = np.zeros(modnum)
    atmb_all = np.zeros([modnum, 2])
    atmb_oc_all = np.zeros(modnum)
    atmb_la_all = np.zeros(modnum)
    surb_all = np.zeros([modnum, 2])
    surb_oc_all = np.zeros(modnum)
    surb_la_all = np.zeros(modnum)
    wmb_all = np.zeros([modnum, 2])
    wmb_oc_all = np.zeros(modnum)
    wmb_la_all = np.zeros(modnum)
    latent_all = np.zeros([modnum, 2])
    latent_oc_all = np.zeros(modnum)
    latent_la_all = np.zeros(modnum)
    baroc_eff_all = np.zeros(modnum)
    lec_all = np.zeros([modnum, 2])
    horzentr_all = np.zeros([modnum, 2])
    vertentr_all = np.zeros([modnum, 2])
    matentr_all = np.zeros([modnum, 2])
    irrevers_all = np.zeros(modnum)
    diffentr_all = np.zeros([modnum, 2])
    logger.info("Entering main loop\n")
    i_m = 0
    for model in model_names:
        # Load paths to individual models output and plotting directories
        wdir = os.path.join(wdir_up, model)
        pdir = os.path.join(pdir_up, model)
        os.makedirs(wdir)
        os.makedirs(pdir)
        aux_file = wdir + '/aux.nc'
        te_ymm_file, te_gmean_constant, te_file = mkthe.init_mkthe_te(
            model, wdir, input_data)
        te_all[i_m] = te_gmean_constant
        logger.info('Computing energy budgets\n')
        in_list, eb_gmean, eb_file, toab_ymm_file = comp.budgets(
            model, wdir, aux_file, input_data)
        prov_rec = provenance_meta.get_prov_map(
            ['TOA energy budgets', model],
            [in_list[4], in_list[6], in_list[7]])
        provlog.log(eb_file[0], prov_rec)
        prov_rec = provenance_meta.get_prov_map(
            ['atmospheric energy budgets', model], [
                in_list[0], in_list[1], in_list[2], in_list[3], in_list[4],
                in_list[5], in_list[6], in_list[7], in_list[8]
            ])
        provlog.log(eb_file[1], prov_rec)
        prov_rec = provenance_meta.get_prov_map(
            ['surface energy budgets', model], [
                in_list[0], in_list[1], in_list[2], in_list[3], in_list[5],
                in_list[7]
            ])
        provlog.log(eb_file[2], prov_rec)
        toab_all[i_m, 0] = np.nanmean(eb_gmean[0])
        toab_all[i_m, 1] = np.nanstd(eb_gmean[0])
        atmb_all[i_m, 0] = np.nanmean(eb_gmean[1])
        atmb_all[i_m, 1] = np.nanstd(eb_gmean[1])
        surb_all[i_m, 0] = np.nanmean(eb_gmean[2])
        surb_all[i_m, 1] = np.nanstd(eb_gmean[2])
        logger.info('Global mean emission temperature: %s\n',
                    te_gmean_constant)
        logger.info('TOA energy budget: %s\n', toab_all[i_m, 0])
        logger.info('Atmospheric energy budget: %s\n', atmb_all[i_m, 0])
        logger.info('Surface energy budget: %s\n', surb_all[i_m, 0])
        logger.info('Done\n')
        baroc_eff_all[i_m] = comp.baroceff(model, wdir, aux_file,
                                           toab_ymm_file, te_ymm_file)
        logger.info('Baroclinic efficiency (Lucarini et al., 2011): %s\n',
                    baroc_eff_all[i_m])
        logger.info('Running the plotting module for the budgets\n')
        plotsmod.balances(cfg, wdir_up, pdir,
                          [eb_file[0], eb_file[1], eb_file[2]],
                          ['toab', 'atmb', 'surb'], model)
        logger.info('Done\n')
        # Water mass budget
        if wat == 'True':
            (wm_file,
             wmb_all[i_m, 0],
             wmb_all[i_m, 1],
             latent_all[i_m, 0],
             latent_all[i_m, 1]) = compute_water_mass_budget(
                 cfg, wdir_up, pdir, model, wdir, input_data, flags, aux_file)
        if lsm == 'True':
            sftlf_fx = e.select_metadata(input_data,
                                         short_name='sftlf',
                                         dataset=model)[0]['filename']
            logger.info('Computing energy budgets over land and oceans\n')
            toab_oc_all[i_m], toab_la_all[i_m] = compute_land_ocean(
                model, wdir, eb_file[0], sftlf_fx, 'toab')
            atmb_oc_all[i_m], atmb_la_all[i_m] = compute_land_ocean(
                model, wdir, eb_file[1], sftlf_fx, 'atmb')
            surb_oc_all[i_m], surb_la_all[i_m] = compute_land_ocean(
                model, wdir, eb_file[2], sftlf_fx, 'surb')
            if wat == 'True':
                logger.info('Computing water mass and latent energy'
                            ' budgets over land and oceans\n')
                wmb_oc_all[i_m], wmb_la_all[i_m] = compute_land_ocean(
                    model, wdir, wm_file[0], sftlf_fx, 'wmb')
                latent_oc_all[i_m], latent_la_all[i_m] = compute_land_ocean(
                    model, wdir, wm_file[1], sftlf_fx, 'latent')
            logger.info('Done\n')
        if lec == 'True':
            logger.info('Computation of the Lorenz Energy '
                        'Cycle (year by year)\n')
            _, _ = mkthe.init_mkthe_lec(model, wdir, input_data)
            lect = lorenz.preproc_lec(model, wdir, pdir, input_data)
            lec_all[i_m, 0] = np.nanmean(lect)
            lec_all[i_m, 1] = np.nanstd(lect)
            logger.info(
                'Intensity of the annual mean Lorenz Energy '
                'Cycle: %s\n', lec_all[i_m, 0])
            logger.info('Done\n')
        else:
            lect = np.repeat(2.0, len(eb_gmean[0]))
            lec_all[i_m, 0] = 2.0
            lec_all[i_m, 1] = 0.2
        if entr == 'True':
            if met in {'1', '3'}:
                logger.info('Computation of the material entropy production '
                            'with the indirect method\n')
                indentr_list = [te_file, eb_file[0]]
                horz_mn, vert_mn, horzentr_file, vertentr_file = comp.indentr(
                    model, wdir, indentr_list, input_data, aux_file,
                    eb_gmean[0])
                listind = [horzentr_file, vertentr_file]
                provenance_meta.meta_indentr(cfg, model, input_data, listind)
                horzentr_all[i_m, 0] = np.nanmean(horz_mn)
                horzentr_all[i_m, 1] = np.nanstd(horz_mn)
                vertentr_all[i_m, 0] = np.nanmean(vert_mn)
                vertentr_all[i_m, 1] = np.nanstd(vert_mn)
                logger.info(
                    'Horizontal component of the material entropy '
                    'production: %s\n', horzentr_all[i_m, 0])
                logger.info(
                    'Vertical component of the material entropy '
                    'production: %s\n', vertentr_all[i_m, 0])
                logger.info('Done\n')
                logger.info('Running the plotting module for the material '
                            'entropy production (indirect method)\n')
                plotsmod.entropy(pdir, vertentr_file, 'sver',
                                 'Vertical entropy production', model)
                logger.info('Done\n')
            if met in {'2', '3'}:
                matentr, irrevers, entr_list = comp.direntr(
                    logger, model, wdir, input_data, aux_file, te_file, lect,
                    flags)
                provenance_meta.meta_direntr(cfg, model, input_data, entr_list)
                matentr_all[i_m, 0] = matentr
                if met in {'3'}:
                    diffentr = (float(np.nanmean(vert_mn)) +
                                float(np.nanmean(horz_mn)) - matentr)
                    logger.info('Difference between the two '
                                'methods: %s\n', diffentr)
                    diffentr_all[i_m, 0] = diffentr
                logger.info('Degree of irreversibility of the '
                            'system: %s\n', irrevers)
                irrevers_all[i_m] = irrevers
                logger.info('Running the plotting module for the material '
                            'entropy production (direct method)\n')
                plotsmod.init_plotentr(model, pdir, entr_list)
                logger.info('Done\n')
            os.remove(te_file)
        os.remove(te_ymm_file)
        logger.info('Done for model: %s \n', model)
        i_m = i_m + 1
    logger.info('I will now start multi-model plots')
    logger.info('Meridional heat transports\n')
    plotsmod.plot_mm_transp(model_names, wdir_up, pdir_up)
    logger.info('Scatter plots')
    summary_varlist = [
        atmb_all, baroc_eff_all, horzentr_all, lec_all, matentr_all, te_all,
        toab_all, vertentr_all
    ]
    plotsmod.plot_mm_summaryscat(pdir_up, summary_varlist)
    logger.info('Scatter plots for inter-annual variability of'
                ' some quantities')
    eb_list = [toab_all, atmb_all, surb_all]
    plotsmod.plot_mm_ebscatter(pdir_up, eb_list)
    logger.info("The diagnostic has finished. Now closing...\n")
Esempio n. 2
0
def balances(cfg, wdir, plotpath, filena, name, model):
    """Plot everything related to energy and water mass budgets.

    This method provides climatological annal mean maps of TOA, atmospheric
    and surface energy budgets, time series of annual mean anomalies in the
    two hemispheres and meridional sections of meridional enthalpy
    transports. Scatter plots of oceanic vs. atmospheric meridional
    enthalpy transports are also provided.

    Arguments:
    - wdir: the working directory;
    - plotpath: the path where the plot has to be saved;
    - filena: the files containing input fields;
    - name: the name of the variable associated with the input field;
    - model: the name of the model to be analysed;
    """
    cdo = Cdo()
    provlog = ProvenanceLogger(cfg)
    nsub = len(filena)
    pdir = plotpath
    plotentname = pdir + '/{}_heat_transp.png'.format(model)
    plotwmbname = pdir + '/{}_wmb_transp.png'.format(model)
    plotlatname = pdir + '/{}_latent_transp.png'.format(model)

    # timesery = np.zeros([nsub, 2])
    dims, ndims, tmean, zmean, timeser = global_averages(nsub, filena, name)
    transp_mean = np.zeros([nsub, ndims[1]])
    lat_maxm = np.zeros([nsub, 2, len(dims[3])])
    tr_maxm = np.zeros([nsub, 2, len(dims[3])])
    lim = [55, 55, 25]
    for i_f in np.arange(nsub):
        transp = transport(zmean[i_f, :, :], timeser[i_f, :, 0], dims[1])
        transp_mean[i_f, :], list_peak = transports_preproc(
            dims[1], ndims[3], lim[i_f], transp)
        lat_maxm[i_f, :, :] = list_peak[0]
        tr_maxm[i_f, :, :] = list_peak[1]
    if nsub == 3:
        ext_name = [
            'TOA Energy Budget', 'Atmospheric Energy Budget',
            'Surface Energy Budget'
        ]
        transpty = (-6E15, 6E15)
        coords = [dims[0], dims[1]]
        plot_climap_eb(model, pdir, coords, tmean, ext_name)
        fig = plt.figure()
        strings = ['Meridional heat transports', 'Latitude [deg]', '[W]']
        lats = dims[1]
        for i in np.arange(nsub):
            filename = filena[i] + '.nc'
            if name[i] == 'toab':
                nameout = 'total'
            elif name[i] == 'atmb':
                nameout = 'atmos'
            elif name[i] == 'surb':
                nameout = 'ocean'
            nc_f = wdir + '/{}_transp_mean_{}.nc'.format(nameout, model)
            removeif(nc_f)
            lat_model = 'lat_{}'.format(model)
            pr_output(transp_mean[i, :], filename, nc_f, nameout, lat_model)
            name_model = '{}_{}'.format(nameout, model)
            cdo.chname('{},{}'.format(nameout, name_model),
                       input=nc_f,
                       output='aux.nc')
            move('aux.nc', nc_f)
            cdo.chname('lat,{}'.format(lat_model), input=nc_f, output='aux.nc')
            move('aux.nc', nc_f)
            attr = ['{} meridional enthalpy transports'.format(nameout), model]
            provrec = provenance_meta.get_prov_transp(attr, filename,
                                                      plotentname)
            provlog.log(nc_f, provrec)
            plot_1m_transp(lats, transp_mean[i, :], transpty, strings)
        plt.grid()
        plt.savefig(plotentname)
        plt.close(fig)
        plot_1m_scatter(model, pdir, lat_maxm, tr_maxm)
    elif nsub == 2:
        ext_name = ['Water mass budget', 'Latent heat budget']
        transpwy = (-2E9, 2E9)
        transply = (-6E15, 6E15)
        coords = [dims[0], dims[1]]
        plot_climap_wm(model, pdir, coords, tmean, ext_name, name)
        nc_f = wdir + '/{}_transp_mean_{}.nc'.format('wmb', model)
        removeif(nc_f)
        filena[0] = filena[0].split('.nc', 1)[0]
        filename = filena[0] + '.nc'
        pr_output(transp_mean[0, :], filename, nc_f, 'wmb', 'lat')
        attr = ['water mass transport', model]
        provrec = provenance_meta.get_prov_transp(attr, filename, plotwmbname)
        provlog.log(nc_f, provrec)
        nc_f = wdir + '/{}_transp_mean_{}.nc'.format('latent', model)
        removeif(nc_f)
        filena[1] = filena[1].split('.nc', 1)[0]
        filename = filena[1] + '.nc'
        pr_output(transp_mean[1, :], filename, nc_f, 'latent', 'lat')
        attr = ['latent energy transport', model]
        provrec = provenance_meta.get_prov_transp(attr, filename, plotlatname)
        provlog.log(nc_f, provrec)
        strings = ['Water mass transports', 'Latitude [deg]', '[kg*s-1]']
        fig = plt.figure()
        plot_1m_transp(dims[1], transp_mean[0, :], transpwy, strings)
        plt.grid()
        plt.savefig(plotwmbname)
        plt.close(fig)
        strings = ['Latent heat transports', 'Latitude [deg]', '[W]']
        fig = plt.figure()
        plot_1m_transp(dims[1], transp_mean[1, :], transply, strings)
        plt.grid()
        plt.savefig(plotlatname)
        plt.close(fig)
    for i_f in np.arange(nsub):
        fig = plt.figure()
        axi = plt.subplot(111)
        axi.plot(dims[3], timeser[i_f, :, 0], 'k', label='Global')
        axi.plot(dims[3], timeser[i_f, :, 1], 'r', label='SH')
        axi.plot(dims[3], timeser[i_f, :, 2], 'b', label='NH')
        plt.title('Annual mean {}'.format(ext_name[i_f]))
        plt.xlabel('Years')
        plt.ylabel('[W/m2]')
        axi.legend(loc='upper center',
                   bbox_to_anchor=(0.5, -0.07),
                   shadow=True,
                   ncol=3)
        plt.tight_layout()
        plt.grid()
        plt.savefig(pdir + '/{}_{}_timeser.png'.format(model, name[i_f]))
        plt.close(fig)