Coverage for wrainfo/clutter.py: 88%
49 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-18 12:40 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-18 12:40 +0000
1"""Clutter detection module."""
3# WRaINfo, Is a software to process FURUNO weather radar data.
4#
5# Copyright (c) 2022, FernLab (GFZ Potsdam, fernlab@gfz-potsdam.de)
6#
7# This software was developed within the context of the RaINfo ("Potential use of
8# high resolution weather data in agriculture") project of FernLab funded by
9# the Impulse and Networking Fund of the Helmholtz Association.
10#
11# Licensed under the Apache License, Version 2.0 (the "License");
12# you may not use this file except in compliance with the License.
13#
14# You may obtain a copy of the License at
15# http://www.apache.org/licenses/LICENSE-2.0
16#
17# Unless required by applicable law or agreed to in writing, software
18# distributed under the License is distributed on an "AS IS" BASIS,
19# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20# See the License for the specific language governing permissions and
21# limitations under the License.
23# imports
24# -------
26import logging
27import xarray as xr
28import wradlib as wrl
29import numpy as np
30from wrainfo.reader import read_single_file
33# fuzzy echo classification based on wRadlib
34# -------------------------------------------
36def fuzzy_echo_classification(ds, cmap, dims=["azimuth", "range"]):
37 """Fuzzy echo classification and clutter identification based on polarimetric variables.
39 Parameters
40 ----------
41 ds : xarray.Dataset
42 cmap : xarray.DataArray
43 processed clutter map
44 dims : list
45 dimension of the dataset
47 Returns
48 -------
49 : xarray.Dataset
50 xarray.Dataset with a clutter map.
51 """
52 trpz_default = {"zdr": [0.7, 1.0, 9999, 9999],
53 "rho": [0.1, 0.15, 9999, 9999],
54 "phi": [15, 20, 10000, 10000],
55 "dop": [-0.2, -0.1, 0.1, 0.2],
56 "map": [1, 1, 9999, 9999],
57 "rho2": [-9999, -9999, 0.95, 0.98],
58 "dr": [-20, -12, 9999, 9999],
59 "cpa": [0.6, 0.9, 9999, 9999], }
61 weights = {"zdr": 0.4,
62 "rho": 0.4,
63 "rho2": 0.4,
64 "phi": 0.1,
65 "dop": 0.1,
66 "map": 0.5}
68 dat = dict(rho=ds.RHOHV.values,
69 phi=ds.PHIDP.values,
70 ref=ds.DBZH.values,
71 rho2=ds.RHOHV.values,
72 dop=ds.VRAD.values,
73 zdr=ds.ZDR.values,
74 map=cmap.values)
76 clmap, nanmask = wrl.clutter.classify_echo_fuzzy(dat,
77 weights=weights,
78 trpz=trpz_default,
79 thresh=0.5)
81 ds = ds.assign(dict(FUZZ=(dims, clmap)))
83 return ds
86# remove clutter
87# --------------
89def dbzh_no_clutter(ds, dims=["azimuth", "range"]):
90 """Set DBZH values, where clutter were identified, to NaN-values.
92 Parameters
93 ----------
94 ds : xarray.Dataset
95 dims : list
96 dimensions of the dataset
98 Returns
99 -------
100 : xarray.Dataset
101 xarray.Dataset with removed clutter.
102 """
103 dbzh_no_clutter = ds.DBZH.where(ds.FUZZ == False) # noqa E712
105 dbzh_no_clutter_attrs = {"standard_name": "radar_equivalent_reflectivity_factor_h",
106 "long_name": "Equivalent reflectivity factor H",
107 "unit": "dBZ", }
109 ds["DBZH_no_clutter"] = xr.DataArray(dbzh_no_clutter,
110 dims=dims,
111 attrs=dbzh_no_clutter_attrs)
113 return ds
116def create_clutter_map_sequential(files, threshold=0, grp="dataset1", status=False, logger=logging.getLogger()):
117 """Create a clutter map sequential in order to not overload the working memory.
119 Parameters
120 ----------
121 files : list
122 threshold : integer
123 threshold of the reflectivity
124 status : bool
125 percent of progress
127 Returns
128 -------
129 : xarray.Dataset
130 xarray.Dataset with clutter values.
131 """
132 file_count = 0
133 elapsed = 0
134 logger.info("Processing " + str(len(files)) + " files sequentially.")
135 file = files[0]
136 sum_dbzh_values = None
138 for file in files:
139 try:
140 # read furuno files
141 data = read_single_file(file=file, grp=grp)
143 except Exception:
144 # except errors if a file could not read
145 logger.warning("Could not load file:' " + file + "'.")
146 continue
148 # create a data array of reflectivity values
149 if sum_dbzh_values is None:
150 sum_dbzh_values = data.DBZH[0, :, :].values
152 else:
153 values = data.DBZH[0, :, :].values
155 # extract only correct values without NaN values
156 good = ~np.isnan(values)
157 sum_dbzh_values[good] += data.DBZH[0, :, :].values[good]
159 file_count += 1
161 new = round(20 * file_count / len(files), 0)
163 if status:
164 if new > elapsed:
165 elapsed = new
166 print(str(elapsed * 5) + "% done")
168 logger.info("Creating boolean clutter map.")
169 sum_dbzh_bool = sum_dbzh_values > threshold
171 # set attributes for the new data array
172 sum_dbzh_values_attrs = {"standard_name": "radar_equivalent_reflectivity_factor_h",
173 "long_name": "Equivalent reflectivity factor H",
174 "unit": "dBZ", }
176 # create dataset
177 logger.info("Creating arrays.")
178 data["DBZH_sum_values"] = xr.DataArray(sum_dbzh_values,
179 dims=["azimuth", "range"],
180 attrs=sum_dbzh_values_attrs)
182 data["DBZH_sum_bool"] = xr.DataArray(sum_dbzh_bool,
183 dims=["azimuth", "range"],
184 attrs=sum_dbzh_values_attrs)
186 # delete all other moments in the dataset except for clutter map
187 variables = ['DBZH_sum_bool', 'DBZH_sum_values']
188 cmap = data[variables]
190 return cmap