diff --git a/buildbucket/buildbucket_environment.yaml b/buildbucket/buildbucket_environment.yaml index 84bcd1d2badf8ab4b7a5015b69ee88ba9f184086..d2231fa7952630a315ba9ed523350ef306b9d5a7 100644 --- a/buildbucket/buildbucket_environment.yaml +++ b/buildbucket/buildbucket_environment.yaml @@ -15,4 +15,16 @@ dependencies: - scipy - setuptools - xarray - - zarr \ No newline at end of file + - zarr + # satpy dependencies: + - configobj + - pykdtree + - pyresample + - trollsift + - trollimage + - shapely + - pip: + - git+https://github.com/deeplycloudy/lmatools.git@minvaluegrids + - git+https://github.com/deeplycloudy/stormdrain.git + - git+https://github.com/deeplycloudy/glmtools.git@master + - git+https://github.com/pytroll/satpy.git@master \ No newline at end of file diff --git a/buildbucket/package.sh b/buildbucket/package.sh index cffb35e89c680bee049c73ab5649537099ea57c3..4250d496a9aa818a403dcc15e6b61f1027278fb5 100755 --- a/buildbucket/package.sh +++ b/buildbucket/package.sh @@ -25,9 +25,6 @@ fi pkg_name=cspp-geo-gridded-glm-${version} DIST=${DIST:-"/dock"} -LMATOOLS_REF=${LMATOOLS_REF:-"minvaluegrids"} -GLMTOOLS_REF=${GLMTOOLS_REF:-"master"} -GLMTOOLS_REPOS=${GLMTOOLS_REPOS:-"https://github.com/deeplycloudy/glmtools.git"} GGLM_REPOS=${GGLM_REPOS:-"https://gitlab.ssec.wisc.edu/cspp_geo/cspp-geo-gridded-glm.git"} GGLM_REF=${GGLM_REF:-"master"} MINIFY_TARBALL=${MINIFY_TARBALL:-1} @@ -53,20 +50,11 @@ which python conda info -a conda list --export echo "Version specified: ${version}" -echo "lmatools reference: ${LMATOOLS_REF}" -echo "glmtools reference: ${GLMTOOLS_REF}" # Turn on command printing here because we don't need all of the `conda` # internal bash commands to pollute our output set -x -# Install glmtools and related packages -# All dependencies should have been built with the buildbucket -# Careful: Could result in missing dependencies but we want reproducibility -pip install --no-deps git+https://github.com/deeplycloudy/lmatools.git@${LMATOOLS_REF} -pip install --no-deps git+https://github.com/deeplycloudy/stormdrain.git -pip install --no-deps git+${GLMTOOLS_REPOS}@${GLMTOOLS_REF} - # get the current packages files # if the caller mounted the repository already then use that GGLM_DIR="/work/cspp-geo-gridded-glm/gridded_glm" @@ -76,19 +64,20 @@ fi # Build a tarball version of the current conda environment # TODO: Add conda cleanup commands similar to what Polar2Grid uses to save space -conda_tb=conda_lmatools-${LMATOOLS_REF}_glmtools-${GLMTOOLS_REF}.tar.gz +conda_tb=conda_gglm.tar.gz conda clean -ay # remove unnecessary things from conda environment conda pack --n-threads $(nproc) -n build -o ${conda_tb} # Build up our package directory mkdir -p ${pkg_name} cd ${pkg_name} -mkdir -p bin opt/conda +mkdir -p bin libexec/python_runtime # Copy package scripts/data to package directory cp $GGLM_DIR/PACKAGE_README.md ./README.md cp $GGLM_DIR/bin/* ./bin/ +cp $GGLM_DIR/libexec/* ./libexec/ # Untar the tarball so we can put things where we want -tar -xz -C ./opt/conda -f ../${conda_tb} +tar -xz -C ./libexec/python_runtime -f ../${conda_tb} # Go back to original work directory cd .. diff --git a/gridded_glm/PACKAGE_README.md b/gridded_glm/PACKAGE_README.md index c04e3534941e05fc15aa6e571f9ccc3dfe096a21..98db29de7c9c4b2e606e2437f945df413773fb4d 100644 --- a/gridded_glm/PACKAGE_README.md +++ b/gridded_glm/PACKAGE_README.md @@ -1,3 +1,21 @@ # CSPP Geo Gridded GLM -TODO \ No newline at end of file +USAGE + +The following scripts are located in the `bin/` directory. + +cspp-geo-gglm-trio-picker.sh + +A simple wrapper around cspp-geo-gglm-minute-gridder.sh that takes a single input file and: +1) determines if it is the last file in a minute +2) if so, finds all files from that minute and passes them to cspp-geo-gglm-minute-gridder.sh +3) creates both grids and tiles for that minute + +cspp-geo-gglm-minute-gridder.sh + +This script creates one minute grids from any number of input files. + + +cspp-geo-gglm-make-grids.sh + +A wrapper for the `make_GLM_grids.py` "kitchen sink" example script provided by glmtools. \ No newline at end of file diff --git a/gridded_glm/bin/make_glm_grids.sh b/gridded_glm/bin/cspp-geo-gglm-make-grids.sh similarity index 92% rename from gridded_glm/bin/make_glm_grids.sh rename to gridded_glm/bin/cspp-geo-gglm-make-grids.sh index d844d9197a15fcb15ebdbecaf3d3fced13ed9cf7..f0e536213b20577bc44266cb9de0fc83076db11f 100755 --- a/gridded_glm/bin/make_glm_grids.sh +++ b/gridded_glm/bin/cspp-geo-gglm-make-grids.sh @@ -26,7 +26,7 @@ if [ -z "$CSPP_GEO_GGLM_HOME" ]; then fi # Setup necessary environments -source $CSPP_GEO_GGLM_HOME/bin/env.sh +source $CSPP_GEO_GGLM_HOME/libexec/env.sh # Call the python module to do the processing, passing all arguments -python3 $CSPP_GEO_GGLM_HOME/bin/_make_glm_grids.py "$@" +python3 $CSPP_GEO_GGLM_HOME/libexec/_make_glm_grids.py "$@" diff --git a/gridded_glm/bin/cspp-geo-gglm-minute-gridder.sh b/gridded_glm/bin/cspp-geo-gglm-minute-gridder.sh new file mode 100755 index 0000000000000000000000000000000000000000..f554eecea91d3c94d8b2d5c4edbfe48b65a22ad7 --- /dev/null +++ b/gridded_glm/bin/cspp-geo-gglm-minute-gridder.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# encoding: utf-8 +# Copyright (C) 2019 Space Science and Engineering Center (SSEC), +# University of Wisconsin-Madison. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This file is part of the CSPP Geo Gridded GLM software package. CSPP Geo +# Gridded GLM takes GOES GLM Level 2 LCFA files and grids them to the ABI +# fixed grid. It does this using the open source glmtools python package by +# Eric Bruning. + +if [ -z "$CSPP_GEO_GGLM_HOME" ]; then + export CSPP_GEO_GGLM_HOME="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" +fi + +# Setup necessary environments +source $CSPP_GEO_GGLM_HOME/libexec/env.sh + +# Call the python module to do the processing, passing all arguments +python3 $CSPP_GEO_GGLM_HOME/libexec/_minute_gridder.py "$@" diff --git a/gridded_glm/bin/cspp-geo-gglm-trio-picker.sh b/gridded_glm/bin/cspp-geo-gglm-trio-picker.sh new file mode 100755 index 0000000000000000000000000000000000000000..034851efa97cfe85e4b638b4f7ec737238486f67 --- /dev/null +++ b/gridded_glm/bin/cspp-geo-gglm-trio-picker.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# encoding: utf-8 + +if [ -z "$CSPP_GEO_GGLM_HOME" ]; then + export CSPP_GEO_GGLM_HOME="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" +fi + +# Setup necessary environments +source $CSPP_GEO_GGLM_HOME/libexec/env.sh + +# Call the python module to do the processing, passing all arguments +python3 $CSPP_GEO_GGLM_HOME/libexec/_glm_trio_picker.py "$@" diff --git a/gridded_glm/libexec/_glm_trio_picker.py b/gridded_glm/libexec/_glm_trio_picker.py new file mode 100644 index 0000000000000000000000000000000000000000..01fcde73cc21b5479755c5d9adeb20c83911d328 --- /dev/null +++ b/gridded_glm/libexec/_glm_trio_picker.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +import sys +import os +from glob import glob +from datetime import datetime +import subprocess +from glmtools.io.glm import parse_glm_filename + +if __name__ == '__main__': + # FIXME: handle args better if this goes beyond my testing + _, glmfile = sys.argv + +# bad (start of period) +# glmfile = '/scratch/nickb/cspp-geo-grb-1.0/output/product/OR_GLM-L2-LCFA_G16_s20210131854000_e20210131854204_c20210131854225.nc' + +# good (end of period) +# glmfile = '/scratch/nickb/cspp-geo-grb-1.0/output/product/OR_GLM-L2-LCFA_G16_s20210131854400_e20210131855004_c20210131855027.nc' +# glmfile = '/data/users/nickb/cspp-geo-gridded-glm/testing/2020-11-05/CLASS/OR_GLM-L2-LCFA_G16_s20203101529400_e20203101530004_c20203101530021.nc' + + # check that glmfile is actually a GLM file + glminfo = parse_glm_filename(os.path.basename(glmfile)) + filename_starts = glminfo[3] + filename_ends = glminfo[4] + + # if this isn't the last file of the minute, exit + if filename_starts.second != 40: + print("This is not the last GLM file from this minute. Exiting.") + exit(0) + + # if this is the last file of the minute, grab all files of the minute (three) + # example trio: + # OR_GLM-L2-LCFA_G16_s20203101529000_e20203101529205_c20203101529215.nc + # OR_GLM-L2-LCFA_G16_s20203101529200_e20203101529405_c20203101529430.nc + # OR_GLM-L2-LCFA_G16_s20203101529400_e20203101530004_c20203101530021.nc + globstring = "{}_{}_{}_s{}*".format(glminfo[0], glminfo[1], glminfo[2], glminfo[3].strftime("%Y%j%H%M")) + fileglob = glob(os.path.join(os.path.dirname(glmfile), globstring)) + print("Gridding {} files".format(len(fileglob))) + + # and run gridded glm a'la: + # minute_gridder.sh \ + # --goes-position auto --goes-sector full \ + # --create-tiles \ + # ./2020-11-05/CLASS/OR_GLM-L2-LCFA_G16_s20203101529000_e20203101529205_c20203101529215.nc \ + # ./2020-11-05/CLASS/OR_GLM-L2-LCFA_G16_s20203101529200_e20203101529405_c20203101529430.nc \ + # ./2020-11-05/CLASS/OR_GLM-L2-LCFA_G16_s20203101529400_e20203101530004_c20203101530021.nc + subprocess.run(["cspp-geo-gglm-minute-gridder.sh", + "--goes-position", "auto", + "--goes-sector", "full", + "--create-tiles", + fileglob[0], fileglob[1], fileglob[2]] + ) diff --git a/gridded_glm/bin/_make_glm_grids.py b/gridded_glm/libexec/_make_glm_grids.py similarity index 100% rename from gridded_glm/bin/_make_glm_grids.py rename to gridded_glm/libexec/_make_glm_grids.py diff --git a/gridded_glm/libexec/_minute_gridder.py b/gridded_glm/libexec/_minute_gridder.py new file mode 100644 index 0000000000000000000000000000000000000000..4b4709055d40849f64fd8912291a63c1358f2aab --- /dev/null +++ b/gridded_glm/libexec/_minute_gridder.py @@ -0,0 +1,287 @@ +#!/usr/bin/env python3 +# Based on https://github.com/deeplycloudy/glmtools/blob/master/examples/grid/make_GLM_grids.py + +parse_desc = """Grid the past X minutes of GLM flash data, given a single input file. +""" + +import numpy as np +from datetime import datetime, timedelta +import os +import sys +import tempfile +import shutil +import atexit +from glob import glob +#from multiprocessing import freeze_support # https://docs.python.org/2/library/multiprocessing.html#multiprocessing.freeze_support +from functools import partial +from lmatools.grid.make_grids import write_cf_netcdf_latlon, write_cf_netcdf_noproj, write_cf_netcdf_fixedgrid +from lmatools.grid.make_grids import dlonlat_at_grid_center, grid_h5flashfiles +from glmtools.grid.make_grids import grid_GLM_flashes +from glmtools.io.glm import parse_glm_filename +from lmatools.grid.fixed import get_GOESR_grid, get_GOESR_coordsys + +import logging + +log = logging.getLogger(__name__) + +def create_parser(): + import argparse + parser = argparse.ArgumentParser(description=parse_desc) + parser.add_argument('-v', '--verbose', dest='verbosity', action="count", default=0, + help='each occurrence increases verbosity 1 level through ERROR-WARNING-INFO-DEBUG (default INFO)') + parser.add_argument('-l', '--log', dest="log_fn", default=None, + help="specify the log filename") + # from Requirements: "Output is Gridded GLM in the native glmtools NetCDF4 format, with a user option to produce AWIPS-compatible NetCDF tiles as described below" + parser.add_argument('-o', '--output-dir', metavar='output directory', + default=os.getcwd()) + parser.add_argument('--goes-sector', default="full", + help="One of [full|conus|meso]. " + "Requires goes_position. If sector is " + "meso, ctr_lon and ctr_lat are interpreted as " + "the ctr_x and ctr_y of the fixed grid") + parser.add_argument('--goes-position', default="auto", + help="One of [east|west|test|auto]. " + "Requires '--goes-sector'.") + parser.add_argument("-t", "--create-tiles", default=False, action='store_true', + help="create AWIPS-compatible tiles") # FIXME: improve this help text + parser.add_argument('--ctr-lat', metavar='latitude', + type=float, help='center latitude (required for meso)') + parser.add_argument('--ctr-lon', metavar='longitude', + type=float, help='center longitude (required for meso)') + # from Requirements: "Input is one or more GLM LCFA (L2+) files in mission standard format (nominally three 20-second input files)" + parser.add_argument(dest='filenames', metavar='filename', nargs='+') + return parser + +""" +old arguments for reference + +FIXME: remove this whole comment once everything is working + + parser.add_argument('--dx', metavar='km', + default=10.0, type=float, + help='approximate east-west grid spacing') + parser.add_argument('--dy', metavar='km', + default=10.0, type=float, + help='approximate north-south grid spacing') + parser.add_argument('--dt', metavar='seconds', + default=60.0, type=float, + help='frame duration') + parser.add_argument('--width', metavar='distance in km', + default=400.0, + type=float, help='total width of the grid') + parser.add_argument('--height', metavar='distance in km', + default=400.0, + type=float, help='total height of the grid') + parser.add_argument('--nevents', metavar='minimum events per flash', + type=int, dest='min_events', default=1, + help='minimum number of events per flash') + parser.add_argument('--ngroups', metavar='minimum groups per flash', + type=int, dest='min_groups', default=1, + help='minimum number of groups per flash') + parser.add_argument('--subdivide-grid', metavar='sqrt(number of subgrids)', + type=int, default=1, + help="subdivide the grid this many times along " + "each dimension") +""" + + +def get_resolution(args): + closest_resln = 2.0 # hardcoding resolution to 2.0 for now. see nearest_resolution in make_glm_grids for how we could expose this if we change our minds. + resln = '{0:4.1f}km'.format(closest_resln).replace(' ', '') + return resln + + +# if provided "auto" position, we determine the sensor from the filename +def get_goes_position(filenames): + if all("_G16_" in f for f in filenames): + return "east" + if all("_G17_" in f for f in filenames): + return "west" + + # we require that all files are from the same sensor and raise an exception if not + raise ValueError("position 'auto' but could not determine position - did you provide a mix of satellites?") + + +def get_start_end(filenames, start_time=None, end_time=None): + """Compute start and end time of data based on filenames.""" + base_filenames = [os.path.basename(p) for p in filenames] + + filename_infos = [parse_glm_filename(f) for f in base_filenames] + # opsenv, algorithm, platform, start, end, created = parse_glm_filename(f) + filename_starts = [info[3] for info in filename_infos] + filename_ends = [info[4] for info in filename_infos] + start_time = min(filename_starts) + + # Used to use max(filename_ends), but on 27 Oct 2020, the filename + # ends started to report the time of the last event in the file, + # causing a slight leakage (usually less than a second) into the + # next minute. This caused two minutes of grids to be produced for every + # three twenty second files passed to this script. + # Instead, we now assume every LCFA file is 20 s long, beginning with + # the start time. No doubt in the future we will see filenames that no + # longer start on an even minute boundary. + end_time = max(filename_starts) + timedelta(0, 20) + + if start_time is None or end_time is None: + raise ValueError("Could not determine start/end time") + + return start_time, end_time + + +def grid_setup(args, work_dir=os.getcwd()): + # When passed None for the minimum event or group counts, the gridder will skip + # the check, saving a bit of time. + min_events = None + min_groups = None + + try: + start_time, end_time = get_start_end(args.filenames) + except ValueError: + log.error("Non-standard filenames provided, use --start and --end to specify data times.") + raise + + base_date = datetime(start_time.year, start_time.month, start_time.day) + proj_name = 'geos' + + outputpath = os.path.join(work_dir, "{dataset_name}") # GLMTools expects a template in addition to the path + + if args.goes_position == "auto": + goes_position = get_goes_position(args.filenames) + else: + goes_position = args.goes_position + + resln = get_resolution(args) + view = get_GOESR_grid(position=goes_position, + view=args.goes_sector, + resolution=resln) + nadir_lon = view['nadir_lon'] + dx = dy = view['resolution'] + nx, ny = view['pixelsEW'], view['pixelsNS'] + geofixcs, grs80lla = get_GOESR_coordsys(sat_lon_nadir=nadir_lon) + + if 'centerEW' in view: + x_ctr, y_ctr = view['centerEW'], view['centerNS'] + elif args.goes_sector == 'meso': + # use ctr_lon, ctr_lat to get the center of the mesoscale FOV + x_ctr, y_ctr, z_ctr = geofixcs.fromECEF( + *grs80lla.toECEF(args.ctr_lon, args.ctr_lat, 0.0)) + else: + # FIXME: is it possible to get here? if so, what should happen? + raise RuntimeError + + # Need to use +1 here to convert to xedge, yedge expected by gridder + # instead of the pixel centroids that will result in the final image + nx += 1 + ny += 1 + x_bnd = (np.arange(nx, dtype='float') - (nx) / 2.0) * dx + x_ctr + 0.5 * dx + y_bnd = (np.arange(ny, dtype='float') - (ny) / 2.0) * dy + y_ctr + 0.5 * dy + log.debug(("initial x,y_ctr", x_ctr, y_ctr)) + log.debug(("initial x,y_bnd", x_bnd.shape, y_bnd.shape)) + x_bnd = np.asarray([x_bnd.min(), x_bnd.max()]) + y_bnd = np.asarray([y_bnd.min(), y_bnd.max()]) + + geofixcs, grs80lla = get_GOESR_coordsys(sat_lon_nadir=nadir_lon) + ctr_lon, ctr_lat, ctr_alt = grs80lla.fromECEF( + *geofixcs.toECEF(x_ctr, y_ctr, 0.0)) + fixed_grid = geofixcs + log.debug((x_bnd, y_bnd, dx, dy, nx, ny)) + + output_writer = partial(write_cf_netcdf_fixedgrid, nadir_lon=nadir_lon) + + gridder = grid_GLM_flashes + output_filename_prefix = 'GLM' + grid_kwargs = dict(proj_name=proj_name, + base_date=base_date, do_3d=False, + dx=dx, dy=dy, frame_interval=60.0, + x_bnd=x_bnd, y_bnd=y_bnd, + ctr_lat=ctr_lat, ctr_lon=ctr_lon, outpath=outputpath, + min_points_per_flash=min_events, + output_writer=output_writer, subdivide=1, # subdivide the grid this many times along each dimension + output_filename_prefix=output_filename_prefix, + output_kwargs={'scale_and_offset': False}, + spatial_scale_factor=1.0) + + #if args.fixed_grid: + # grid_kwargs['fixed_grid'] = True + # grid_kwargs['nadir_lon'] = nadir_lon + # if args.split_events: + grid_kwargs['clip_events'] = True + if min_groups is not None: + grid_kwargs['min_groups_per_flash'] = min_groups + grid_kwargs['energy_grids'] = ('total_energy',) + if (proj_name == 'pixel_grid') or (proj_name == 'geos'): + grid_kwargs['pixel_coords'] = fixed_grid + grid_kwargs['ellipse_rev'] = -1 # -1 (default) = infer from date in each GLM file + return gridder, args.filenames, start_time, end_time, grid_kwargs + + +if __name__ == '__main__': +# freeze_support() # nb. I don't think this is needed as we're not making windows execs at this time + parser = create_parser() + args = parser.parse_args() + + # Configure logging + levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG] + logging.basicConfig(level=levels[min(3, args.verbosity)], filename=args.log_fn) + if levels[min(3, args.verbosity)] > logging.DEBUG: + import warnings + warnings.filterwarnings("ignore") + log.info("Starting GLM Gridding") + log.debug("Starting script with: %s", sys.argv) + + # set up output dir + os.makedirs(args.output_dir, exist_ok=True) + + # set up temporary dir + tempdir_path = tempfile.mkdtemp(suffix=None, prefix="tmp-glm-grids-", dir=os.getcwd()) + log.info("working in: {}".format(tempdir_path)) + # clean our temporary dir on exit + atexit.register(shutil.rmtree, tempdir_path) + + # do the gridding + gridder, glm_filenames, start_time, end_time, grid_kwargs = grid_setup(args, work_dir=tempdir_path) + gridder(glm_filenames, start_time, end_time, **grid_kwargs) + + # pick up gridded files from the tempdir + # output looks like: OR_GLM-L2-GLMC-M3_G17_s20202691559400_e20202691600400_c20210120141010.nc + log.debug("gridded files in {}".format(tempdir_path)) + gridded_path = os.path.join(tempdir_path, 'OR_GLM-L2-GLM?-M?_G??_s*_e*_c*.nc') + log.debug(gridded_path) + gridded_files = glob(gridded_path) + log.debug(gridded_files) + + # (optionally) do tiling + if args.create_tiles: + from satpy import Scene + for gridded_file in gridded_files: + log.info("TILING: {}".format(gridded_files)) + scn = Scene(reader='glm_l2', filenames=[gridded_file]) # n.b. satpy requires a list of filenames + scn.load([ + 'DQF', + 'flash_extent_density', + 'minimum_flash_area', + 'total_energy', + ]) + + scn.save_datasets(writer='awips_tiled', + template='glm_l2_radf', + sector_id="GOES_EAST", # sector_id becomes an attribute in the output files and may be another legacy kind of thing. I'm not sure how much is is actually used here. + source_name="", # You could probably make source_name an empty string. I think it is required by the writer for legacy reasons but isn't actually used for the glm output + base_dir=tempdir_path, # base_dir is the output directory. I think blank is the same as current directory. + tile_size=(506, 904), # tile_size is set to the size of the GLMF sample tiles we were given and should match the full disk ABI tiles which is what they wanted + check_categories=False) # check_categories is there because of that issue I mentioned where DQF is all valid all the time so there is no way to detect empty tiles unless we ignore the "category" products + + + # pick up output files from the tempdir + # output looks like: OR_GLM-L2-GLMC-M3_G17_T03_20200925160040.nc + log.debug("files in {}".format(tempdir_path)) + log.debug(os.listdir(tempdir_path)) + log.debug("moving output to {}".format(args.output_dir)) + tiled_path = os.path.join(tempdir_path, 'OR_GLM-L2-GLM?-M?_G??_T??_*.nc') + tiled_files = glob(tiled_path) + for f in tiled_files: + shutil.move(f, os.path.join(args.output_dir, os.path.basename(f))) + for f in gridded_files: + shutil.move(f, os.path.join(args.output_dir, os.path.basename(f))) + + # tempdir cleans itself up via atexit, above \ No newline at end of file diff --git a/gridded_glm/bin/env.sh b/gridded_glm/libexec/env.sh similarity index 93% rename from gridded_glm/bin/env.sh rename to gridded_glm/libexec/env.sh index 0bcdaa0e140715af486ca32e37b107afd35a6a7a..6ee195beffbd127147741e83f85e70aebb6dc23e 100644 --- a/gridded_glm/bin/env.sh +++ b/gridded_glm/libexec/env.sh @@ -28,4 +28,4 @@ fi unset PYTHONPATH unset LD_LIBRARY_PATH -export PATH=$PATH:$CSPP_GEO_GGLM_HOME/bin:$CSPP_GEO_GGLM_HOME/opt/conda/bin \ No newline at end of file +export PATH=$CSPP_GEO_GGLM_HOME/bin:$CSPP_GEO_GGLM_HOME/libexec/python_runtime/bin:$PATH \ No newline at end of file