Skip to content
Snippets Groups Projects
inst_eddies.py.in 5.54 KiB
Newer Older
#!/usr/bin/env python3

GUEZ Lionel's avatar
GUEZ Lionel committed
"""This script creates the directory {SHPC_dir}/Slice_{my_slice},
containing a time slice of instantaneous eddies. If
{SHPC_dir}/Slice_{my_slice} already exists then it is replaced.
Lionel GUEZ's avatar
Lionel GUEZ committed

"""
Lionel GUEZ's avatar
Lionel GUEZ committed

import shutil
import nco
import os
import subprocess
import shapefile
Lionel GUEZ's avatar
Lionel GUEZ committed
import time
import csv
GUEZ Lionel's avatar
GUEZ Lionel committed

def process_1_file(
    bbox,
    nco_instance,
    nc_file,
    inst_eddies_exe,
    d,
    my_slice,
    writer,
    config_nml_string,
GUEZ Lionel's avatar
GUEZ Lionel committed
):
    t0 = time.perf_counter()

    if bbox:
        xmin, xmax, ymin, ymax = bbox

        try:
GUEZ Lionel's avatar
GUEZ Lionel committed
            nco_instance.ncks(
                nc_file,
                output="cropped.nc",
GUEZ Lionel's avatar
GUEZ Lionel committed
                options=[
                    f"--dimension=longitude,{xmin},{xmax}",
                    f"--dimension=latitude,{ymin},{ymax}",
                ],
            )
        except nco.NCOException as err:
            print(err.stdout)
            raise

        nc_file = "cropped.nc"
    nco_instance.ncpdq(nc_file, output="unpacked.nc", options=["--unpack"])
    t1 = time.perf_counter()
    elapsed_NCO = t1 - t0
    t0 = t1
GUEZ Lionel's avatar
GUEZ Lionel committed
    subprocess.run(
        [inst_eddies_exe, SHPC_dir, "unpacked.nc"],
GUEZ Lionel's avatar
GUEZ Lionel committed
        check=True,
        input=f"&dates_nml date = {d}, slice = {my_slice}/\n"
        + config_nml_string
GUEZ Lionel's avatar
GUEZ Lionel committed
        + f"&input_ssh_nml periodic = {periodic}/\n",
GUEZ Lionel's avatar
GUEZ Lionel committed
        text=True,
    )
    elapsed_Fortran = time.perf_counter() - t0
    writer.writerow([d, elapsed_NCO, elapsed_Fortran])


def loop_inst_eddies(
    SHPC_dir, files, bbox, config_nml_string, d, my_slice, periodic
):
Lionel GUEZ's avatar
Lionel GUEZ committed
    """`files` is an iterator of file paths. The first file must exist,
    others can be missing. bbox is a tuple of four real numbers. `d`
    is a date index (integer value) for the first date. my_slice is
    the slice index (integer value) in the SHPC.
Lionel GUEZ's avatar
Lionel GUEZ committed

    """

    inst_eddies_exe = "@CMAKE_CURRENT_BINARY_DIR@/inst_eddies"

    if not os.access(inst_eddies_exe, os.X_OK):
GUEZ Lionel's avatar
GUEZ Lionel committed
        sys.exit(
            "inst_eddies.loop_inst_eddies:"
            + inst_eddies_exe
            + " not found or not executable"
        )

    nco_instance = nco.Nco()

    if os.access(f"{SHPC_dir}/Slice_{my_slice}", os.F_OK):
        shutil.rmtree(f"{SHPC_dir}/Slice_{my_slice}")
    for orient in ["Cyclones", "Anticyclones"]:
        os.makedirs(f"{SHPC_dir}/Slice_{my_slice}/{orient}")
GUEZ Lionel's avatar
GUEZ Lionel committed
    perf_report = open(
        f"{SHPC_dir}/Slice_{my_slice}/perf_report.csv", "w", newline=""
GUEZ Lionel's avatar
GUEZ Lionel committed
    )
    writer = csv.writer(perf_report, lineterminator="\n")
    writer.writerow(["", "s", "s"])  # units
    writer.writerow(["date", "elapsed NCO", "elapsed Fortran"])  # long names
Lionel GUEZ's avatar
Lionel GUEZ committed

    # Short names (without blanks):
    writer.writerow(["date", "elapsed_NCO", "elapsed_Fortran"])
    # First file is out of the loop because it must be present:
    nc_file = next(files)
    print("inst_eddies.loop_inst_eddies: Date:", d)
GUEZ Lionel's avatar
GUEZ Lionel committed
    print("inst_eddies.loop_inst_eddies: Input file:", nc_file, flush=True)
    process_1_file(
        bbox,
        nco_instance,
        nc_file,
        inst_eddies_exe,
        d,
        my_slice,
        writer,
        config_nml_string,
GUEZ Lionel's avatar
GUEZ Lionel committed
    )
    for nc_file in files:
Lionel GUEZ's avatar
Lionel GUEZ committed
        print("inst_eddies.loop_inst_eddies: Date:", d)
GUEZ Lionel's avatar
GUEZ Lionel committed
        print("inst_eddies.loop_inst_eddies: Input file:", nc_file, flush=True)

        if os.access(nc_file, os.F_OK):
GUEZ Lionel's avatar
GUEZ Lionel committed
            process_1_file(
                bbox,
                nco_instance,
                nc_file,
                inst_eddies_exe,
                d,
                my_slice,
                writer,
                config_nml_string,
GUEZ Lionel's avatar
GUEZ Lionel committed
            )
Lionel GUEZ's avatar
Lionel GUEZ committed
            print("inst_eddies.loop_inst_eddies: Missing file:", nc_file)
            for orient in ["Cyclones", "Anticyclones"]:
GUEZ Lionel's avatar
GUEZ Lionel committed
                with open(
                    f"{SHPC_dir}/Slice_{my_slice}/{orient}/ishape_last.txt", "a"
GUEZ Lionel's avatar
GUEZ Lionel committed
                ) as ishape_last, shapefile.Reader(
                    f"{SHPC_dir}/Slice_{my_slice}/{orient}/" "extremum"
GUEZ Lionel's avatar
GUEZ Lionel committed
                ) as shpr:
                    n_shapes = len(shpr)
                    ishape_last.write(str(n_shapes - 1) + "\n")

        d += 1

    perf_report.close()
    os.remove("unpacked.nc")
GUEZ Lionel's avatar
GUEZ Lionel committed

GUEZ Lionel's avatar
GUEZ Lionel committed
    if bbox:
        os.remove("cropped.nc")
    if my_slice == 0 and not os.access(f"{SHPC_dir}/n_slices.txt", os.F_OK):
        with open(f"{SHPC_dir}/n_slices.txt", "w") as f:
GUEZ Lionel's avatar
GUEZ Lionel committed
            f.write("1\n")

if __name__ == "__main__":
Lionel GUEZ's avatar
Lionel GUEZ committed
    import argparse
GUEZ Lionel's avatar
GUEZ Lionel committed

    argparser = argparse.ArgumentParser()
    argparser.add_argument("SHPC_dir")
GUEZ Lionel's avatar
GUEZ Lionel committed
    argparser.add_argument(
        "file",
        nargs="+",
        help="NetCDF file containing SSH and velocity " "at a single date",
    )
    argparser.add_argument(
        "-b",
        "--bbox",
        nargs=4,
        type=float,
        metavar=("xmin", "xmax", "ymin", "ymax"),
    )
    args = argparser.parse_args()

    if not os.access(args.file[0], os.F_OK):
        sys.exit(args.file[0] + " not found")

    if os.access("inst_eddies_nml.txt", os.R_OK):
        print("Will use inst_eddies_nml.txt.")
    else:
        sys.exit('"inst_eddies_nml.txt" not found -- Aborting')

    with open("inst_eddies_nml.txt") as f_obj:
        config_nml_string = f_obj.read()

Lionel GUEZ's avatar
Lionel GUEZ committed
    d = input("Enter first date index (integer value): ")
    d = int(d)
    my_slice = input("Enter slice index (integer value): ")
    my_slice = int(my_slice)
    periodic = input("periodic (t/f)? ")
    loop_inst_eddies(
        args.SHPC_dir,
        iter(args.file),
        args.bbox,
        config_nml_string,
        d,
        my_slice,
        periodic,