• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ssec / polar2grid / 3971687213

pending completion
3971687213

Pull #583

github

GitHub
Merge 05b59b898 into e4fa254de
Pull Request #583: Add basic AWIPS debug tiles helper script

0 of 72 new or added lines in 1 file covered. (0.0%)

4364 of 5170 relevant lines covered (84.41%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/polar2grid/utils/create_awips_debug_tiles.py
1
#!/usr/bin/env python3
2
# encoding: utf-8
3
# Copyright (C) 2022 Space Science and Engineering Center (SSEC),
4
# University of Wisconsin-Madison.
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
#
19
# This file is part of the polar2grid software package. Polar2grid takes
20
# satellite observation data, remaps it, and writes it to a file format for
21
# input into another program.
22
# Documentation: http://www.ssec.wisc.edu/software/polar2grid/
NEW
23
"""Helper script for generating debug AWIPS Tiled files for verifying AWIPS client behavior."""
×
NEW
24
import contextlib
×
NEW
25
import os
×
NEW
26
import sys
×
NEW
27
import tempfile
×
NEW
28
from datetime import datetime
×
29

NEW
30
import dask.array as da
×
NEW
31
import numpy as np
×
NEW
32
import satpy
×
NEW
33
import xarray as xr
×
NEW
34
import yaml
×
NEW
35
from pyresample import create_area_def
×
NEW
36
from satpy import Scene
×
37

NEW
38
from polar2grid.utils.config import add_polar2grid_config_paths
×
39

NEW
40
SCALE_FACTOR = 0.25
×
NEW
41
ADD_OFFSET = 2000.0
×
42

43

NEW
44
def main():
×
NEW
45
    from argparse import ArgumentParser
×
46

NEW
47
    parser = ArgumentParser(description="Create single AWIPS tile example file for debugging")
×
NEW
48
    parser.add_argument(
×
49
        "physical_element_prefix", help="Name of the product in AWIPS. No spaces or special characters allowed."
50
    )
NEW
51
    parser.add_argument(
×
52
        "--units", default="1", help="CF-compatible units. Will be converted if necessary to AWIPS-compatible units."
53
    )
NEW
54
    parser.add_argument(
×
55
        "--idtype", default="uint16", help="Numpy data type of the data created and then stored in the NetCDF file."
56
    )
NEW
57
    parser.add_argument(
×
58
        "--odtype", default="int16", help="Numpy data type of the data created and then stored in the NetCDF file."
59
    )
NEW
60
    parser.add_argument(
×
61
        "--ounsigned",
62
        action="store_true",
63
        help="Whether or not to include the special 'Unsigned' flag in the NetCDF file. No effect if odtype "
64
        "isn't signed.",
65
    )
NEW
66
    args = parser.parse_args()
×
67

NEW
68
    add_polar2grid_config_paths()
×
69

NEW
70
    start_time = datetime.utcnow()
×
NEW
71
    idtype_str = args.idtype
×
NEW
72
    idtype = getattr(np, idtype_str)
×
NEW
73
    odtype_str = args.odtype
×
NEW
74
    set_unsigned = args.ounsigned
×
NEW
75
    set_unsigned_str = "U" if set_unsigned else ""
×
NEW
76
    units = args.units
×
NEW
77
    physical_element = (
×
78
        args.physical_element_prefix.replace(" ", "-") + f"-{units}-{idtype_str}-{set_unsigned_str}{odtype_str}"
79
    )
80

NEW
81
    data = _gradient_data(dtype=idtype)
×
NEW
82
    area = create_area_def(
×
83
        "fakelcc",
84
        {"proj": "lcc", "lon_0": -95.0, "lat_0": 25, "lat_1": 25},
85
        shape=data.shape,
86
        resolution=(10000.0, 10000.0),
87
        center=(0, 0),
88
    )
NEW
89
    data_arr = xr.DataArray(
×
90
        data,
91
        attrs={
92
            "platform_name": "P2G-DEBUG",
93
            "sensor": "P2G-INST",
94
            "name": physical_element,
95
            "start_time": start_time,
96
            "units": units,
97
            "area": area,
98
            "valid_range": _valid_range_for_idtype(idtype),
99
        },
100
        dims=("y", "x"),
101
    )
NEW
102
    scn = Scene()
×
NEW
103
    scn[physical_element] = data_arr
×
104

NEW
105
    os.environ["ORGANIZATION"] = "P2G_DEBUG_ORG"
×
NEW
106
    with add_fake_awips_template(physical_element, odtype_str, set_unsigned):
×
NEW
107
        scn.save_datasets(
×
108
            writer="awips_tiled",
109
            sector_id="LCC",
110
            tile_count=(4, 4),
111
            source_name="SSEC",
112
        )
113

114

NEW
115
@contextlib.contextmanager
×
NEW
116
def add_fake_awips_template(product_name, odtype_str, set_unsigned):
×
NEW
117
    with tempfile.TemporaryDirectory(prefix="p2g_awips_debug_") as tdir:
×
NEW
118
        writers_dir = os.path.join(tdir, "writers")
×
NEW
119
        os.makedirs(writers_dir)
×
NEW
120
        yaml_filename = os.path.join(writers_dir, "awips_tiled.yaml")
×
NEW
121
        with open(yaml_filename, "w") as yaml_file:
×
NEW
122
            var_config = {
×
123
                "name": product_name,
124
                "var_name": "data",
125
                "attributes": {
126
                    "physical_element": {"value": "{name}"},
127
                    "units": {},
128
                },
129
                "encoding": {
130
                    "dtype": odtype_str,
131
                    # "scale_factor": SCALE_FACTOR,
132
                    # "add_offset": ADD_OFFSET,
133
                    # "_FillValue": 10,
134
                },
135
            }
NEW
136
            if set_unsigned:
×
NEW
137
                var_config["encoding"]["_Unsigned"] = "true"
×
NEW
138
            yaml.dump(
×
139
                {
140
                    "templates": {
141
                        "polar": {
142
                            "variables": {
143
                                "my_fake_var": var_config,
144
                            },
145
                        },
146
                    },
147
                },
148
                yaml_file,
149
            )
150

NEW
151
        with satpy.config.set(config_path=[tdir] + satpy.config.get("config_path")):
×
NEW
152
            yield
×
153

154

NEW
155
def _valid_range_for_idtype(dtype):
×
NEW
156
    min_val = np.iinfo(dtype).min
×
NEW
157
    max_val = np.iinfo(dtype).max
×
NEW
158
    return [min_val, max_val]
×
159

160

NEW
161
def _gradient_data(dtype):
×
NEW
162
    num_rows = 300
×
NEW
163
    num_cols = 100
×
NEW
164
    min_val, max_val = _valid_range_for_idtype(dtype)
×
NEW
165
    unscaled_min = min_val * SCALE_FACTOR + ADD_OFFSET
×
NEW
166
    unscaled_max = max_val * SCALE_FACTOR + ADD_OFFSET
×
NEW
167
    data = np.repeat(np.linspace(unscaled_min, unscaled_max, num_cols)[np.newaxis, :], num_rows, axis=0)
×
NEW
168
    half_row = num_rows // 2
×
NEW
169
    half_col = num_cols // 2
×
NEW
170
    data[half_row - 5 : half_row + 5, half_col - 5 : half_col + 5] = np.nan
×
NEW
171
    return da.from_array(data)
×
172

173

NEW
174
if __name__ == "__main__":
×
NEW
175
    sys.exit(main())
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc