Source code for emc2.simulator.main

import numpy as np
from .subcolumn import set_convective_sub_col_frac, set_precip_sub_col_frac
from .subcolumn import set_stratiform_sub_col_frac, set_q_n
from .lidar_moments import calc_lidar_moments, calc_LDR_and_ext, calc_total_alpha_beta
from .radar_moments import calc_radar_moments, calc_total_reflectivity
from .attenuation import calc_radar_Ze_min
from .classification import lidar_classify_phase, lidar_emulate_cosp_phase, radar_classify_phase


[docs] def make_simulated_data(model, instrument, N_columns, do_classify=False, unstack_dims=False, skip_subcol_gen=False, finalize_fields=False, calc_spectral_width=True, subcol_gen_only=False, **kwargs): """ This procedure will make all of the subcolumns and simulated data for each model column. NOTE: When starting a parallel task (in microphysics approach), it is recommended to wrap the top-level python script calling the EMC^2 processing ('lines_of_code') with the following command (just below the 'import' statements): .. code-block:: python if __name__ == “__main__”: lines_of_code Parameters ---------- model: :func:`emc2.core.Model` The model to make the simulated parameters for. instrument: :func:`emc2.core.Instrument` The instrument to make the simulated parameters for. N_columns: int or None The number of subcolumns to generate. Set to None to automatically detect from LES 4D data. do_classify: bool run hydrometeor classification routines when True. unstack_dims: bool True - unstack the time, lat, and lon dimensions after processing in cases of regional model output. skip_subcol_gen: bool True - skip the subcolumn generator (e.g., in case subcolumn were already generated). finalize_fields: bool True - set absolute 0 values in"sub_col"-containing fields to np.nan enabling analysis and visualization. calc_spectral_width: bool If False, skips spectral width calculations since these are not always needed for an application and are the most computationally expensive. Default is True. subcol_gen_only: bool If True, only returns mass and number distributed among subcolumns and skips moment calculations Additional keyword arguments are passed into :func:`emc2.simulator.calc_lidar_moments` or :func:`emc2.simulator.calc_radar_moments` Returns ------- model: :func:`emc2.core.Model` The model with all of the simulated parameters generated. """ print("## Creating subcolumns...") hydrometeor_classes = model.conv_frac_names.keys() if 'use_rad_logic' in kwargs.keys(): use_rad_logic = kwargs['use_rad_logic'] del kwargs['use_rad_logic'] else: use_rad_logic = True if 'OD_from_sfc' in kwargs.keys(): OD_from_sfc = kwargs['OD_from_sfc'] del kwargs['OD_from_sfc'] else: OD_from_sfc = instrument.OD_from_sfc if 'parallel' in kwargs.keys(): parallel = kwargs['parallel'] del kwargs['parallel'] else: parallel = True if 'chunk' in kwargs.keys(): chunk = kwargs['chunk'] del kwargs['chunk'] else: chunk = None if 'convert_zeros_to_nan' in kwargs.keys(): convert_zeros_to_nan = kwargs['convert_zeros_to_nan'] del kwargs['convert_zeros_to_nan'] else: convert_zeros_to_nan = False if 'mask_height_rng' in kwargs.keys(): mask_height_rng = kwargs['mask_height_rng'] del kwargs['mask_height_rng'] else: mask_height_rng = None if 'hyd_types' in kwargs.keys(): hyd_types = kwargs['hyd_types'] del kwargs['hyd_types'] else: hyd_types = None if 'mie_for_ice' in kwargs.keys(): mie_for_ice = {"conv": kwargs['mie_for_ice'], "strat": kwargs['mie_for_ice']} del kwargs['mie_for_ice'] else: if use_rad_logic: mie_for_ice = {"conv": False, "strat": False} else: mie_for_ice = {"conv": False, "strat": True} # use True for strat (micro), False for conv (rad) if 'use_empiric_calc' in kwargs.keys(): use_empiric_calc = kwargs['use_empiric_calc'] del kwargs['use_empiric_calc'] else: use_empiric_calc = False if skip_subcol_gen: print('Skipping subcolumn generator (make sure subcolumns were already generated).') else: if model.process_conv: for hyd_type in hydrometeor_classes: model = set_convective_sub_col_frac( model, hyd_type, N_columns=N_columns, use_rad_logic=use_rad_logic) else: print("No convective processing for %s" % model.model_name) # Subcolumn Generator model = set_stratiform_sub_col_frac( model, use_rad_logic=use_rad_logic, N_columns=N_columns, parallel=parallel, chunk=chunk) precip_types = list(hydrometeor_classes) if "cl" in precip_types: precip_types.remove("cl") if "ci" in precip_types: precip_types.remove("ci") model = set_precip_sub_col_frac( model, is_conv=False, use_rad_logic=use_rad_logic, parallel=parallel, chunk=chunk, precip_types=precip_types) if model.process_conv: model = set_precip_sub_col_frac( model, is_conv=True, use_rad_logic=use_rad_logic, parallel=parallel, chunk=chunk) for hyd_type in hydrometeor_classes: if hyd_type != 'cl': model = set_q_n( model, hyd_type, is_conv=False, qc_flag=False, use_rad_logic=use_rad_logic, parallel=parallel, chunk=chunk) if model.process_conv: model = set_q_n( model, hyd_type, is_conv=True, qc_flag=False, use_rad_logic=use_rad_logic, parallel=parallel, chunk=chunk) else: model = set_q_n( model, hyd_type, is_conv=False, qc_flag=True, use_rad_logic=use_rad_logic, parallel=parallel, chunk=chunk) if model.process_conv: model = set_q_n( model, hyd_type, is_conv=True, qc_flag=False, use_rad_logic=use_rad_logic, parallel=parallel, chunk=chunk) # Skip moment calculations and return only subcolumn-distributed q and N, else continue to simulator if subcol_gen_only: print("User chose to return only subcolumn generation and skip moment calculations") else: # Radar Simulator if instrument.instrument_class.lower() == "radar": print("Generating radar moments...") if 'reg_rng' in kwargs.keys(): ref_rng = kwargs['ref_rng'] del kwargs['ref_rng'] else: ref_rng = 1000 model = calc_radar_moments( instrument, model, False, OD_from_sfc=OD_from_sfc, hyd_types=hyd_types, parallel=parallel, chunk=chunk, mie_for_ice=mie_for_ice["strat"], use_rad_logic=use_rad_logic, use_empiric_calc=use_empiric_calc, calc_spectral_width=calc_spectral_width,**kwargs) if model.process_conv: model = calc_radar_moments( instrument, model, True, OD_from_sfc=OD_from_sfc, hyd_types=hyd_types, parallel=parallel, chunk=chunk, mie_for_ice=mie_for_ice["conv"], use_rad_logic=use_rad_logic, use_empiric_calc=use_empiric_calc, calc_spectral_width=calc_spectral_width,**kwargs) model = calc_radar_Ze_min(instrument, model, ref_rng) model = calc_total_reflectivity(model, detect_mask=True) if do_classify is True: model = radar_classify_phase( instrument, model, mask_height_rng=mask_height_rng, convert_zeros_to_nan=convert_zeros_to_nan) # Lidar Simulator elif instrument.instrument_class.lower() == "lidar": print("Generating lidar moments...") if 'ext_OD' in kwargs.keys(): ext_OD = kwargs['ext_OD'] del kwargs['ext_OD'] else: ext_OD = instrument.ext_OD if 'eta' in kwargs.keys(): eta = kwargs['eta'] del kwargs['eta'] else: eta = instrument.eta model = calc_lidar_moments( instrument, model, False, OD_from_sfc=OD_from_sfc, hyd_types=hyd_types, parallel=parallel, eta=eta, chunk=chunk, mie_for_ice=mie_for_ice["strat"], use_rad_logic=use_rad_logic, use_empiric_calc=use_empiric_calc, **kwargs) if model.process_conv: model = calc_lidar_moments( instrument, model, True, OD_from_sfc=OD_from_sfc, hyd_types=hyd_types, parallel=parallel, eta=eta, chunk=chunk, mie_for_ice=mie_for_ice["conv"], use_rad_logic=use_rad_logic, use_empiric_calc=use_empiric_calc, **kwargs) model = calc_total_alpha_beta(model, OD_from_sfc=OD_from_sfc, eta=eta) model = calc_LDR_and_ext(model, ext_OD=ext_OD, OD_from_sfc=OD_from_sfc, hyd_types=hyd_types) if do_classify is True: model = lidar_classify_phase( instrument, model, convert_zeros_to_nan=convert_zeros_to_nan) model = lidar_emulate_cosp_phase( instrument, model, eta=eta, OD_from_sfc=OD_from_sfc, convert_zeros_to_nan=convert_zeros_to_nan, hyd_types=hyd_types) else: raise ValueError("Currently, only lidars and radars are supported as instruments.") if finalize_fields: model.finalize_subcol_fields() # Unstack dims in case of regional model output (typically done at the end of all EMC^2 processing) if np.logical_and(model.stacked_time_dim is not None, unstack_dims): print("Unstacking the %s dimension (time, lat, and lon dimensions)" % model.stacked_time_dim) model.unstack_time_lat_lon() return model