diff --git a/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC index bfb5c74a3ad..33ca4018636 100755 --- a/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC +++ b/dev/jobs/JGLOBAL_ATMOS_ANALYSIS_CALC @@ -15,7 +15,7 @@ export DO_CALC_ANALYSIS=${DO_CALC_ANALYSIS:-"YES"} GDATE=$(date --utc +%Y%m%d%H -d "${PDY} ${cyc} - ${assim_freq} hours") export gPDY=${GDATE:0:8} export gcyc=${GDATE:8:2} -export GDUMP="gdas" +GDUMP="${RUN/gfs/gdas}" export GDUMP_ENS="enkf${GDUMP}" export OPREFIX="${rCDUMP}.t${cyc}z." @@ -31,6 +31,11 @@ YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ COMIN_ATMOS_RESTART:COM_ATMOS_RESTART_TMPL +if [[ "${RUN}" == "gcdas" ]]; then + YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ + COMIN_CHEM_ANALYSIS:COM_CHEM_ANALYSIS_TMPL +fi + RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ COMIN_OBS_PREV:COM_OBS_TMPL \ COMIN_ATMOS_HISTORY_PREV:COM_ATMOS_HISTORY_TMPL diff --git a/dev/parm/config/gcafs/config.aeroanlgenb b/dev/parm/config/gcafs/config.aeroanlgenb index 87353213761..8b656a7c4d2 100644 --- a/dev/parm/config/gcafs/config.aeroanlgenb +++ b/dev/parm/config/gcafs/config.aeroanlgenb @@ -16,7 +16,7 @@ export aero_diffusion_horiz_len=300e3 export aero_diffusion_fixed_val=20.0 export npx_clim_b=97 export npy_clim_b=97 -export aero_diagb_weight=0.9 +export aero_diagb_weight=1.0 export aero_staticb_rescaling_factor=2.0 export aero_diagb_n_halo=4 export aero_diagb_n_neighbors=16 diff --git a/dev/parm/config/gcafs/config.anal b/dev/parm/config/gcafs/config.anal new file mode 120000 index 00000000000..3066ff0bdad --- /dev/null +++ b/dev/parm/config/gcafs/config.anal @@ -0,0 +1 @@ +../gfs/config.anal \ No newline at end of file diff --git a/dev/parm/config/gcafs/config.analcalc b/dev/parm/config/gcafs/config.analcalc new file mode 120000 index 00000000000..e6de2d248bb --- /dev/null +++ b/dev/parm/config/gcafs/config.analcalc @@ -0,0 +1 @@ +../gfs/config.analcalc \ No newline at end of file diff --git a/dev/parm/config/gcafs/config.base.j2 b/dev/parm/config/gcafs/config.base.j2 index c091f269c62..825bc66cb2b 100644 --- a/dev/parm/config/gcafs/config.base.j2 +++ b/dev/parm/config/gcafs/config.base.j2 @@ -381,6 +381,8 @@ export SMOOTH_ENKF="NO" export l4densvar=".true." export lwrite4danl=".true." export DO_CALC_INCREMENT="NO" +export USE_BUILD_GSINFO="NO" +export BUILD_GSINFO_DIR="${PARMgfs}/gsinfo" # Early-cycle EnKF parameters export NMEM_ENS_GFS="{{ NMEM_ENS_GFS }}" diff --git a/dev/parm/config/gcafs/config.resources b/dev/parm/config/gcafs/config.resources index f5b412cffd0..4962aba0875 100644 --- a/dev/parm/config/gcafs/config.resources +++ b/dev/parm/config/gcafs/config.resources @@ -680,7 +680,7 @@ case ${step} in "anal") - if [[ "${RUN}" = *gdas ]]; then + if [[ "${RUN}" = *gdas || "${RUN}" = gcdas ]]; then walltime="01:20:00" case ${CASE} in "C1152" | "C768") diff --git a/dev/parm/config/gcafs/config.upp b/dev/parm/config/gcafs/config.upp deleted file mode 120000 index e97b0ea3710..00000000000 --- a/dev/parm/config/gcafs/config.upp +++ /dev/null @@ -1 +0,0 @@ -../gfs/config.upp \ No newline at end of file diff --git a/dev/parm/config/gcafs/config.upp b/dev/parm/config/gcafs/config.upp new file mode 100644 index 00000000000..ec7180612b9 --- /dev/null +++ b/dev/parm/config/gcafs/config.upp @@ -0,0 +1,16 @@ +#! /usr/bin/env bash + +########## config.upp ########## +# UPP specific + +echo "BEGIN: config.upp" + +# Get task specific resources +. "${EXPDIR}/config.resources" upp + +export UPP_CONFIG="${PARMgfs}/post/upp_gcafs.yaml" + +# No. of forecast hours to process in a single job +export NFHRS_PER_GROUP=3 + +echo "END: config.upp" diff --git a/dev/scripts/exglobal_atmos_analysis_calc.sh b/dev/scripts/exglobal_atmos_analysis_calc.sh index 8b09c06c2cf..0ce814e624c 100755 --- a/dev/scripts/exglobal_atmos_analysis_calc.sh +++ b/dev/scripts/exglobal_atmos_analysis_calc.sh @@ -51,8 +51,11 @@ export CHGRESNCEXEC=${CHGRESNCEXEC:-"${EXECgfs}/enkf_chgres_recenter_nc.x"} export CHGRESINCEXEC=${CHGRESINCEXEC:-"${EXECgfs}/interp_inc.x"} export NTHREADS_CHGRES=${NTHREADS_CHGRES:-1} CALCINCPY=${CALCINCPY:-"${USHgfs}/calcinc_gfs.py"} -CALCANLPY=${CALCANLPY:-"${USHgfs}/calcanl_gfs.py"} - +if [[ "${RUN}" == "gcdas" ]]; then + CALCANLPY=${CALCANLPY:-"${USHgfs}/calcanl_gcafs.py"} +else + CALCANLPY=${CALCANLPY:-"${USHgfs}/calcanl_gfs.py"} +fi DOGAUSFCANL=${DOGAUSFCANL-"NO"} GAUSFCANLSH=${GAUSFCANLSH:-"${USHgfs}/gaussian_sfcanl.sh"} export GAUSFCANLEXE=${GAUSFCANLEXE:-"${EXECgfs}/gaussian_sfcanl.x"} @@ -78,6 +81,9 @@ ATMANL=${ATMANL:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}analysis.atm.a006.nc"} # Increment files ATMINC=${ATMINC:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.atm.i006.nc"} DTFANL=${DTFANL:-"${COMOUT_ATMOS_ANALYSIS}/${APREFIX}increment.dtf.i006.nc"} +if [[ "${RUN}" == "gcdas" ]]; then + AEROINC=${AEROINC:-"${COMIN_CHEM_ANALYSIS}/${APREFIX}aeroinc.nc"} +fi # Set script / GSI control parameters DOHYBVAR=${DOHYBVAR:-"NO"} @@ -118,6 +124,11 @@ if [[ "${DO_CALC_ANALYSIS}" == "YES" ]]; then # link analysis and increment files ${NLN} "${ATMANL}" siganl ${NLN} "${ATMINC}" siginc.nc + + if [[ "${RUN}" == "gcdas" ]]; then + ${NLN} "${AEROINC}" aeroinc.nc + fi + if [[ "${DOHYBVAR}" == "YES" && "${l4densvar}" == ".true." && "${lwrite4danl}" == ".true." ]]; then ${NLN} "${ATMA03}" siga03 ${NLN} "${ATMI03}" sigi03.nc diff --git a/dev/workflow/applications/gcafs_cycled.py b/dev/workflow/applications/gcafs_cycled.py index 7a96b0437aa..01c6568b2be 100644 --- a/dev/workflow/applications/gcafs_cycled.py +++ b/dev/workflow/applications/gcafs_cycled.py @@ -136,6 +136,7 @@ def _get_app_configs(self, run): if options['do_aero_anl']: configs += ['aeroanlgenb', 'aeroanlinit', 'aeroanlvar', 'aeroanlfinal'] configs += ['prep'] + configs += ['analcalc'] if options['do_anlstat']: configs += ['anlstat'] @@ -204,6 +205,8 @@ def get_task_names(self): task_names[run] += ['aeroanlgenb'] task_names[run] += ['aeroanlinit', 'aeroanlvar', 'aeroanlfinal'] task_names[run] += ['prep'] + task_names[run] += ['analcalc'] + task_names[run] += ['atmanlupp', 'atmanlprod'] if options['do_anlstat']: task_names[run] += ['anlstat'] diff --git a/dev/workflow/rocoto/gcafs_tasks.py b/dev/workflow/rocoto/gcafs_tasks.py index 4aaf7f21d43..dc19040409d 100644 --- a/dev/workflow/rocoto/gcafs_tasks.py +++ b/dev/workflow/rocoto/gcafs_tasks.py @@ -534,6 +534,34 @@ def aeroanlfinal(self): return task + def analcalc(self): + + deps = [] + dep_dict = {'type': 'task', 'name': f'{self.run}_offlineanl'} + deps.append(rocoto.add_dependency(dep_dict)) + dep_dict = {'type': 'task', 'name': f'{self.run}_sfcanl'} + deps.append(rocoto.add_dependency(dep_dict)) + dep_dict = {'type': 'task', 'name': f'{self.run}_aeroanlfinal'} + deps.append(rocoto.add_dependency(dep_dict)) + dependencies = rocoto.create_dependency(dep_condition='and', dep=deps) + + resources = self.get_resource('analcalc') + task_name = f'{self.run}_analcalc' + task_dict = {'task_name': task_name, + 'resources': resources, + 'dependency': dependencies, + 'envars': self.envars, + 'cycledef': self.run.replace('enkf', ''), + 'command': f'{self.HOMEgfs}/dev/job_cards/rocoto/analcalc.sh', + 'job_name': f'{self.pslot}_{task_name}_@H', + 'log': f'{self.rotdir}/logs/@Y@m@d@H/{task_name}.log', + 'maxtries': '&MAXTRIES;' + } + + task = rocoto.create_task(task_dict) + + return task + def aerosol_init(self): """ Create a task for aerosol initialization. @@ -848,18 +876,12 @@ def atmanlupp(self): for key, value in postenvar_dict.items(): postenvars.append(rocoto.create_envar(name=key, value=str(value))) - atm_anl_path = self._template_to_rocoto_cycstring(self._base["COM_ATMOS_ANALYSIS_TMPL"]) deps = [] - data = f'{atm_anl_path}/{self.run}.t@Hz.analysis.atm.a006.nc' - dep_dict = {'type': 'data', 'data': data, 'age': 120} - deps.append(rocoto.add_dependency(dep_dict)) - data = f'{atm_anl_path}/{self.run}.t@Hz.analysis.sfc.a006.nc' - dep_dict = {'type': 'data', 'data': data, 'age': 120} - deps.append(rocoto.add_dependency(dep_dict)) - data = f'{atm_anl_path}/{self.run}.t@Hz.analysis.done.txt' - dep_dict = {'type': 'data', 'data': data, 'age': 60} + dep_dict = {'type': 'task', 'name': f'{self.run}_analcalc'} deps.append(rocoto.add_dependency(dep_dict)) + dependencies = rocoto.create_dependency(dep=deps, dep_condition='and') + resources = self.get_resource('upp') task_name = f'{self.run}_atmanlupp' task_dict = {'task_name': task_name, diff --git a/parm/archive/master_gcdas.yaml.j2 b/parm/archive/master_gcdas.yaml.j2 index 32814f4aeb3..ed694b9c4c3 100644 --- a/parm/archive/master_gcdas.yaml.j2 +++ b/parm/archive/master_gcdas.yaml.j2 @@ -19,6 +19,28 @@ datasets: {% for itile in range(1,7) %} - "{{ COMIN_CHEM_ANALYSIS | relpath(ROTDIR) }}/aeroinc.{{ cycle_YMD }}.{{ cycle_HH }}0000.fv_tracer.res.tile{{ itile }}.nc" {% endfor %} + # Analysis Master GRIB2 data + - "{{ COMIN_ATMOS_MASTER | relpath(ROTDIR) }}/{{ head }}master.analysis.grib2" + - "{{ COMIN_ATMOS_MASTER | relpath(ROTDIR) }}/{{ head }}master.analysis.grib2.idx" + + # Analysis GRIB2 (sub-sampled) data + - "{{ COMIN_ATMOS_GRIB_0p25 | relpath(ROTDIR) }}/{{ head }}pres_a.0p25.analysis.grib2" + - "{{ COMIN_ATMOS_GRIB_0p25 | relpath(ROTDIR) }}/{{ head }}pres_a.0p25.analysis.grib2.idx" + - "{{ COMIN_ATMOS_GRIB_0p50 | relpath(ROTDIR) }}/{{ head }}pres_a.0p50.analysis.grib2" + - "{{ COMIN_ATMOS_GRIB_0p50 | relpath(ROTDIR) }}/{{ head }}pres_a.0p50.analysis.grib2.idx" + - "{{ COMIN_ATMOS_GRIB_1p00 | relpath(ROTDIR) }}/{{ head }}pres_a.1p00.analysis.grib2" + - "{{ COMIN_ATMOS_GRIB_1p00 | relpath(ROTDIR) }}/{{ head }}pres_a.1p00.analysis.grib2.idx" + # temporarily disable pres_b products archiving. + #- "{{ COMIN_ATMOS_GRIB_0p25 | relpath(ROTDIR) }}/{{ head }}pres_b.0p25.analysis.grib2" + #- "{{ COMIN_ATMOS_GRIB_0p25 | relpath(ROTDIR) }}/{{ head }}pres_b.0p25.analysis.grib2.idx" + #- "{{ COMIN_ATMOS_GRIB_0p25 | relpath(ROTDIR) }}/{{ head }}pres_b.0p50.analysis.grib2" + #- "{{ COMIN_ATMOS_GRIB_0p25 | relpath(ROTDIR) }}/{{ head }}pres_b.0p50.analysis.grib2.idx" + #- "{{ COMIN_ATMOS_GRIB_1p00 | relpath(ROTDIR) }}/{{ head }}pres_b.1p00.analysis.grib2" + #- "{{ COMIN_ATMOS_GRIB_1p00 | relpath(ROTDIR) }}/{{ head }}pres_b.1p00.analysis.grib2.idx" + + # Analysis netCDF (raw) data + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.atm.a006.nc" + - "{{ COMIN_ATMOS_ANALYSIS | relpath(ROTDIR) }}/{{ head }}analysis.sfc.a006.nc" {% endif %} {% if DO_PREP_OBS_AERO %} - "{{ COMIN_OBS | relpath(ROTDIR) }}/{{ head }}aeroobs" @@ -65,6 +87,7 @@ datasets: - "{{ COMIN_ATMOS_RESTART | relpath(ROTDIR) }}/{{ r_prefix }}.coupler.res" - "{{ COMIN_ATMOS_RESTART | relpath(ROTDIR) }}/{{ r_prefix }}.fv_core.res.nc" {% endfor %} + # Archive the EXPDIR if requested {% if archive_expdir %} {% filter indent(width=4) %} diff --git a/parm/post/itag.jinja b/parm/post/itag.jinja index 07aa41f8da3..1cf40c0e639 100644 --- a/parm/post/itag.jinja +++ b/parm/post/itag.jinja @@ -12,5 +12,6 @@ kpo = {{ po | length }}, po = {{ po | join(', ') }}, rdaod = {{ rdaod | to_f90bool }} + nasa_on = {{ nasa_on | to_f90bool }} / diff --git a/parm/post/upp_gcafs.yaml b/parm/post/upp_gcafs.yaml new file mode 100644 index 00000000000..8e131c7d283 --- /dev/null +++ b/parm/post/upp_gcafs.yaml @@ -0,0 +1,37 @@ +upp: + config: + grib_version: "grib2" + ioform: "netcdfpara" + po: [1000.,975.,950.,925.,900.,875.,850.,825.,800.,775.,750.,725.,700.,675.,650.,625.,600.,575.,550.,525.,500.,475.,450.,425.,400.,375.,350.,325.,300.,275.,250.,225.,200.,175.,150.,125.,100.,70.,50.,40.,30.,20.,15.,10.,7.,5.,3.,2.,1.,0.7,0.4,0.2,0.1,0.07,0.04,0.02,0.01] + rdaod: False + nasa_on: False + fix_data: + mkdir: + - "{{ DATA }}" + copy: + - ["{{ 'g2tmpl_ROOT' | getenv }}/share/params_grib2_tbl_new", "{{ DATA }}/params_grib2_tbl_new"] + - ["{{ PARMgfs }}/post/nam_micro_lookup.dat", "{{ DATA }}/eta_micro_lookup.dat"] + - ["{{ EXECgfs }}/upp.x", "{{ DATA }}/"] + - ["{{ PARMgfs }}/post/itag.jinja", "{{ DATA }}/"] + - ["{{ PARMgfs }}/post/optics_luts_DUST_nasa.dat", "{{ DATA }}/optics_luts_DUST_nasa.dat"] + - ["{{ PARMgfs }}/post/optics_luts_NITR_nasa.dat", "{{ DATA }}/optics_luts_NITR_nasa.dat"] + - ["{{ PARMgfs }}/post/optics_luts_SALT_nasa.dat", "{{ DATA }}/optics_luts_SALT_nasa.dat"] + - ["{{ PARMgfs }}/post/optics_luts_SOOT_nasa.dat", "{{ DATA }}/optics_luts_SOOT_nasa.dat"] + - ["{{ PARMgfs }}/post/optics_luts_SUSO_nasa.dat", "{{ DATA }}/optics_luts_SUSO_nasa.dat"] + - ["{{ PARMgfs }}/post/optics_luts_WASO_nasa.dat", "{{ DATA }}/optics_luts_WASO_nasa.dat"] + +analysis: + config: + rdaod: False + nasa_on: True + NET: GFS # upp doesn't work with GCAFS,set to GFS instead + data_in: + copy: + - ["{{ PARMgfs }}/post/gcafs/postxconfig-NT-gcafs.txt", "{{ DATA }}/postxconfig-NT.txt"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.analysis.atm.a006.nc", "{{ DATA }}/{{ atmos_filename }}"] + - ["{{ COMIN_ATMOS_ANALYSIS }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.analysis.sfc.a006.nc", "{{ DATA }}/{{ flux_filename }}"] + data_out: + copy: + - ["{{ DATA }}/GFSPRS.GrbF00", "{{ COMOUT_ATMOS_MASTER }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.master.analysis.grib2"] + - ["{{ DATA }}/GFSPRS.GrbF00.idx", "{{ COMOUT_ATMOS_MASTER }}/{{ RUN }}.t{{ current_cycle | strftime('%H') }}z.master.analysis.grib2.idx"] + diff --git a/ush/calcanl_gcafs.py b/ush/calcanl_gcafs.py new file mode 100755 index 00000000000..a0a1e2a9aee --- /dev/null +++ b/ush/calcanl_gcafs.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# calcanl_gcafs.py +# script to run executables to produce netCDF analysis +# on GCAFS gaussian grid for downstream users +# based on calcanl_gfs.py +import os +import datetime +from wxflow import FileHandler +from netCDF4 import Dataset, num2date +import numpy as np + +python2fortran_bool = {True: '.true.', False: '.false.'} + + +# function to calculate analysis from two increment files and background +def calcanl_gcafs(RunDir, ComOut, APrefix): + print('calcanl_gcafs beginning at: ', datetime.datetime.utcnow()) + # add aerosol increments to background aerosol fields + # add meteorological increments to background meteorological fields + + # analysis increment is already assumed to be + # at the GCAFS C384 equivalent Gaussian resolution + + # define path variables + inc_file = os.path.join(RunDir, 'siginc.nc') + anl_file = os.path.join(RunDir, 'siganl') + ges_file = os.path.join(RunDir, 'sigf06') + + # add meteorological increments to background meteorological fields + metvars = [['spfh', 'sphum'], + ['tmp', 'T'], + ['ugrd', 'u'], + ['vgrd', 'v'], + ['dpres', 'delp'], + ['delz', 'delz'], + ['o3mr', 'o3mr'], + ['clwmr', 'liq_wat']] + + with Dataset(inc_file, mode='r') as incfile, Dataset(ges_file, mode='r') as gesfile, Dataset(anl_file, mode='a') as anlfile: + # loop over meteorological variables and add increments to background + for ioname, incname in metvars: + print(f"Adding increment to background for variable: {ioname}") + bkg = gesfile.variables[ioname][:] + increment = incfile.variables[incname + '_inc'][:] + anl = bkg + np.flip(increment, axis=1) + + anlfile.variables[ioname][:] = anl[:] + + # handle pressfc as a special case + print("Adding increment to background for variable: pressfc") + # read bk attribute and compute ps_inc from delp_inc + bk = gesfile.ncattrs() + if 'bk' in bk: + bk = gesfile.getncattr('bk') + else: + # try to find bk as a variable if not an attribute + bk = gesfile.variables['bk'][:] + + pressfc = gesfile.variables['pressfc'][:] + delp_inc = incfile.variables['delp_inc'][:] + + # compute surface pressure increment + ps_inc = delp_inc[-1] / (bk[-1] - bk[-2]) + + # add increment to background surface pressure + pressfc_anl = pressfc + np.flip(ps_inc, axis=0) + anlfile.variables['pressfc'][:] = pressfc_anl[:] + + # add aerosol increments to background aerosol fields + aerovars = [['so4', 'mass_fraction_of_sulfate_in_air'], + ['bc1', 'mass_fraction_of_hydrophobic_black_carbon_in_air'], + ['bc2', 'mass_fraction_of_hydrophilic_black_carbon_in_air'], + ['oc1', 'mass_fraction_of_hydrophobic_organic_carbon_in_air'], + ['oc2', 'mass_fraction_of_hydrophilic_organic_carbon_in_air'], + ['dust1', 'mass_fraction_of_dust001_in_air'], + ['dust2', 'mass_fraction_of_dust002_in_air'], + ['dust3', 'mass_fraction_of_dust003_in_air'], + ['dust4', 'mass_fraction_of_dust004_in_air'], + ['dust5', 'mass_fraction_of_dust005_in_air'], + ['seas1', ''], # no seas1 increment + ['seas2', 'mass_fraction_of_sea_salt001_in_air'], + ['seas3', 'mass_fraction_of_sea_salt002_in_air'], + ['seas4', 'mass_fraction_of_sea_salt003_in_air'], + ['seas5', 'mass_fraction_of_sea_salt004_in_air'] + ] + + inc_file = os.path.join(RunDir, 'aeroinc.nc') + with Dataset(inc_file, mode='r') as incfile, Dataset(ges_file, mode='r') as gesfile, Dataset(anl_file, mode='a') as anlfile: + for ioname, incname in aerovars: + print(f"Adding increment to background for variable: {ioname}") + bkg = gesfile.variables[ioname][:] + # no seas1 increment + if ioname == 'seas1': + anl = bkg + else: + increment = incfile.variables[incname][:] + # reordering the dimensions of increment (latitude, longitude, levels) to macth background (time, levs, lat, lon) + increment_reshape = np.transpose(increment, (2, 0, 1)) + anl = bkg + increment_reshape[np.newaxis, :, :, :] + + anlfile.variables[ioname][:] = anl[:] + # update time (from 6 to 0) and time units in anlfile so UPP can create anl variables + time = gesfile.variables['time'] + time_val = time[:] + time_units = time.units + time_calendar = getattr(time, "calendar", "standard") + cycle_time = num2date(time_val, units=time_units, calendar=time_calendar) + time_units_new = f"hours since {cycle_time[0]}" + anlfile.variables['time'][:] = 0.0 + anlfile.variables['time'].setncattr("units", time_units_new) + + print('calcanl_gcafs successfully completed at: ', datetime.datetime.utcnow()) + + +# run the function if this script is called from the command line +if __name__ == '__main__': + ComOut = os.getenv('COMOUT_ATMOS_ANALYSIS', './') + APrefix = os.getenv('APREFIX', '') + RunDir = os.getenv('DATA', './') + + calcanl_gcafs(RunDir, ComOut, APrefix)