ngiab-data-preprocess 4.0.5__py3-none-any.whl → 4.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import sqlite3
4
4
  from datetime import datetime
5
5
  from pathlib import Path
6
6
  import shutil
7
+ import requests
7
8
 
8
9
  import pandas
9
10
  import s3fs
@@ -309,18 +310,37 @@ def create_em_realization(cat_id: str, start_time: datetime, end_time: datetime)
309
310
  create_partitions(paths)
310
311
 
311
312
 
312
- def create_realization(cat_id: str, start_time: datetime, end_time: datetime, use_nwm_gw: bool = False):
313
+ def create_realization(
314
+ cat_id: str,
315
+ start_time: datetime,
316
+ end_time: datetime,
317
+ use_nwm_gw: bool = False,
318
+ gage_id: str = None,
319
+ ):
313
320
  paths = file_paths(cat_id)
314
321
 
315
- # get approximate groundwater levels from nwm output
316
322
  template_path = paths.template_cfe_nowpm_realization_config
317
-
323
+
324
+ if gage_id is not None:
325
+ # try and download s3:communityhydrofabric/hydrofabrics/community/gage_parameters/gage_id
326
+ # if it doesn't exist, use the default
327
+ try:
328
+ url = f"https://communityhydrofabric.s3.us-east-1.amazonaws.com/hydrofabrics/community/gage_parameters/{gage_id}.json"
329
+
330
+ new_template = requests.get(url).json()
331
+ template_path = paths.config_dir / "calibrated_params.json"
332
+ with open(template_path, "w") as f:
333
+ json.dump(new_template, f)
334
+ except Exception as e:
335
+ logger.warning(f"Failed to download gage parameters")
336
+
318
337
  conf_df = get_model_attributes(paths.geopackage_path)
319
338
 
320
339
  if use_nwm_gw:
321
340
  gw_levels = get_approximate_gw_storage(paths, start_time)
322
341
  else:
323
342
  gw_levels = dict()
343
+
324
344
  make_cfe_config(conf_df, paths, gw_levels)
325
345
 
326
346
  make_noahowp_config(paths.config_dir, conf_df, start_time, end_time)
@@ -317,15 +317,33 @@ def subset_table_by_vpu(table: str, vpu: str, hydrofabric: Path, subset_gpkg_nam
317
317
  sql_query = f"SELECT * FROM '{table}' WHERE vpuid IN ({','.join(vpus)})"
318
318
  contents = source_db.execute(sql_query).fetchall()
319
319
 
320
+ if table == "network":
321
+ # Look for the network entry that has a toid not in the flowpath or nexus tables
322
+ network_toids = [x[2] for x in contents]
323
+ print(f"Network toids: {len(network_toids)}")
324
+ sql = "SELECT id FROM flowpaths"
325
+ flowpath_ids = [x[0] for x in dest_db.execute(sql).fetchall()]
326
+ print(f"Flowpath ids: {len(flowpath_ids)}")
327
+ sql = "SELECT id FROM nexus"
328
+ nexus_ids = [x[0] for x in dest_db.execute(sql).fetchall()]
329
+ print(f"Nexus ids: {len(nexus_ids)}")
330
+ bad_ids = set(network_toids) - set(flowpath_ids + nexus_ids)
331
+ print(bad_ids)
332
+ print(f"Removing {len(bad_ids)} network entries that are not in flowpaths or nexuses")
333
+ # id column is second after fid
334
+ contents = [x for x in contents if x[1] not in bad_ids]
335
+
320
336
  insert_data(dest_db, table, contents)
321
337
 
338
+
322
339
  if table in get_feature_tables(file_paths.conus_hydrofabric):
323
340
  fids = [str(x[0]) for x in contents]
324
341
  copy_rTree_tables(table, fids, source_db, dest_db)
325
342
 
326
343
  dest_db.commit()
327
344
  source_db.close()
328
- dest_db.close()
345
+ dest_db.close()
346
+
329
347
 
330
348
  def subset_table(table: str, ids: List[str], hydrofabric: Path, subset_gpkg_name: Path) -> None:
331
349
  """
data_processing/subset.py CHANGED
@@ -22,13 +22,16 @@ subset_tables = [
22
22
  "flowpath-attributes-ml",
23
23
  "flowpaths",
24
24
  "hydrolocations",
25
- "network",
26
25
  "nexus",
27
26
  "pois", # requires flowpaths
28
27
  "lakes", # requires pois
28
+ "network",
29
29
  ]
30
30
 
31
- def create_subset_gpkg(ids: Union[List[str],str], hydrofabric: Path, output_gpkg_path: Path, is_vpu: bool = False) -> Path:
31
+
32
+ def create_subset_gpkg(
33
+ ids: Union[List[str], str], hydrofabric: Path, output_gpkg_path: Path, is_vpu: bool = False
34
+ ) -> Path:
32
35
  # ids is a list of nexus and wb ids, or a single vpu id
33
36
  if not isinstance(ids, list):
34
37
  ids = [ids]
@@ -42,12 +45,13 @@ def create_subset_gpkg(ids: Union[List[str],str], hydrofabric: Path, output_gpkg
42
45
  for table in subset_tables:
43
46
  if is_vpu:
44
47
  subset_table_by_vpu(table, ids[0], hydrofabric, output_gpkg_path)
45
- else:
48
+ else:
46
49
  subset_table(table, ids, hydrofabric, output_gpkg_path)
47
50
 
48
51
  add_triggers_to_gpkg(output_gpkg_path)
49
52
  update_geopackage_metadata(output_gpkg_path)
50
53
 
54
+
51
55
  def subset_vpu(vpu_id: str, output_gpkg_path: Path, hydrofabric: Path = file_paths.conus_hydrofabric):
52
56
 
53
57
  if output_gpkg_path.exists():
@@ -77,6 +81,7 @@ def subset(
77
81
  logger.info(f"Subset complete for {len(upstream_ids)} features (catchments + nexuses)")
78
82
  logger.debug(f"Subset complete for {upstream_ids} catchments")
79
83
 
84
+
80
85
  def move_files_to_config_dir(subset_output_dir: str) -> None:
81
86
  config_dir = subset_output_dir / "config"
82
87
  config_dir.mkdir(parents=True, exist_ok=True)
@@ -169,13 +169,20 @@ def main() -> None:
169
169
 
170
170
  if args.realization:
171
171
  logging.info(f"Creating realization from {args.start_date} to {args.end_date}...")
172
+ gage_id = None
173
+ if args.gage:
174
+ gage_id = args.input_feature
172
175
  if args.empirical_model:
173
176
  create_em_realization(
174
177
  output_folder, start_time=args.start_date, end_time=args.end_date
175
178
  )
176
179
  else:
177
180
  create_realization(
178
- output_folder, start_time=args.start_date, end_time=args.end_date, use_nwm_gw=args.nwm_gw
181
+ output_folder,
182
+ start_time=args.start_date,
183
+ end_time=args.end_date,
184
+ use_nwm_gw=args.nwm_gw,
185
+ gage_id=gage_id,
179
186
  )
180
187
  logging.info("Realization creation complete.")
181
188
 
@@ -198,7 +205,7 @@ def main() -> None:
198
205
  except:
199
206
  logging.error("Docker is not running, please start Docker and try again.")
200
207
  try:
201
- #command = f'docker run --rm -it -v "{str(paths.subset_dir)}:/ngen/ngen/data" joshcu/ngiab /ngen/ngen/data/ auto {num_partitions} local'
208
+ # command = f'docker run --rm -it -v "{str(paths.subset_dir)}:/ngen/ngen/data" joshcu/ngiab /ngen/ngen/data/ auto {num_partitions} local'
202
209
  command = f'docker run --rm -it -v "{str(paths.subset_dir)}:/ngen/ngen/data" awiciroh/ciroh-ngen-image:latest /ngen/ngen/data/ auto {num_partitions} local'
203
210
  subprocess.run(command, shell=True)
204
211
  logging.info("Next Gen run complete.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngiab_data_preprocess
3
- Version: 4.0.5
3
+ Version: 4.1.1
4
4
  Summary: Graphical Tools for creating Next Gen Water model input data.
5
5
  Author-email: Josh Cunningham <jcunningham8@ua.edu>
6
6
  Project-URL: Homepage, https://github.com/CIROH-UA/NGIAB_data_preprocess
@@ -8,11 +8,11 @@ Project-URL: Issues, https://github.com/CIROH-UA/NGIAB_data_preprocess/issues
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
- Requires-Python: <3.13,>=3.10
11
+ Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: pyogrio==0.7.2
15
- Requires-Dist: pyproj==3.6.1
14
+ Requires-Dist: pyogrio>=0.7.2
15
+ Requires-Dist: pyproj>=3.6.1
16
16
  Requires-Dist: Flask==3.0.2
17
17
  Requires-Dist: geopandas>=1.0.0
18
18
  Requires-Dist: requests==2.32.2
@@ -20,19 +20,20 @@ Requires-Dist: igraph==0.11.4
20
20
  Requires-Dist: s3fs==2024.3.1
21
21
  Requires-Dist: xarray==2024.2.0
22
22
  Requires-Dist: zarr==2.17.1
23
- Requires-Dist: netCDF4==1.6.5
23
+ Requires-Dist: netCDF4>=1.6.5
24
24
  Requires-Dist: dask==2024.4.1
25
25
  Requires-Dist: dask[distributed]==2024.4.1
26
26
  Requires-Dist: black==24.3.0
27
27
  Requires-Dist: isort==5.13.2
28
28
  Requires-Dist: h5netcdf==1.3.0
29
29
  Requires-Dist: exactextract==0.2.0
30
- Requires-Dist: numpy==1.26.4
30
+ Requires-Dist: numpy>=1.26.4
31
31
  Requires-Dist: tqdm==4.66.4
32
32
  Requires-Dist: rich==13.7.1
33
33
  Requires-Dist: colorama==0.4.6
34
34
  Requires-Dist: bokeh==3.5.1
35
35
  Requires-Dist: boto3
36
+ Requires-Dist: numcodecs<0.16.0
36
37
  Provides-Extra: eval
37
38
  Requires-Dist: ngiab_eval; extra == "eval"
38
39
  Provides-Extra: plot
@@ -85,6 +86,41 @@ For automatic interactive visualisation, please run [NGIAB](https://github.com/C
85
86
  * This tool is officially supported on macOS or Ubuntu (tested on 22.04 & 24.04). To use it on Windows, please install [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
86
87
 
87
88
  ## Installation and Running
89
+ It is highly recommended to use [Astral UV](https://docs.astral.sh/uv/) to install and run this tool. It works similarly to pip and conda, and I would also recommend you use it for other python projects as it is so useful.
90
+
91
+ ```bash
92
+ # Install UV
93
+ curl -LsSf https://astral.sh/uv/install.sh | sh
94
+ # It can be installed via pip if that fails
95
+ # pip install uv
96
+
97
+ # Create a virtual environment in the current directory
98
+ uv venv
99
+
100
+ # Install the tool in the virtual environment
101
+ uv pip install ngiab_data_preprocess
102
+
103
+ # To run the cli
104
+ uv run cli --help
105
+
106
+ # To run the map
107
+ uv run map_app
108
+ ```
109
+
110
+ UV automatically detects any virtual environments in the current directory and will use them when you use `uv run`.
111
+
112
+ ### Running without install
113
+ This package supports pipx and uvx which means you can run the tool without installing it. No virtual environment needed, just UV.
114
+ ```bash
115
+ # run this from anywhere
116
+ uvx --from ngiab_data_preprocess cli --help
117
+ # for the map
118
+ uvx --from ngiab_data_preprocess map_app
119
+ ```
120
+
121
+ ## For legacy pip installation
122
+ <details>
123
+ <summary>Click here to expand</summary>
88
124
 
89
125
  ```bash
90
126
  # If you're installing this on jupyterhub / 2i2c you HAVE TO DEACTIVATE THE CONDA ENV
@@ -102,8 +138,7 @@ pip install 'ngiab_data_preprocess'
102
138
  python -m map_app
103
139
  # CLI instructions at the bottom of the README
104
140
  ```
105
-
106
- The first time you run this command, it will download the hydrofabric from Lynker Spatial. If you already have it, place `conus_nextgen.gpkg` into `~/.ngiab/hydrofabric/v2.2/`.
141
+ </details>
107
142
 
108
143
  ## Development Installation
109
144
 
@@ -117,24 +152,23 @@ To install and run the tool, follow these steps:
117
152
  git clone https://github.com/CIROH-UA/NGIAB_data_preprocess
118
153
  cd NGIAB_data_preprocess
119
154
  ```
120
- 2. Create a virtual environment and activate it:
155
+ 2. Create a virtual environment:
121
156
  ```bash
122
- python3 -m venv env
123
- source env/bin/activate
157
+ uv venv
124
158
  ```
125
159
  3. Install the tool:
126
160
  ```bash
127
- pip install -e .
161
+ uv pip install -e .
128
162
  ```
129
163
  4. Run the map app:
130
164
  ```bash
131
- python -m map_app
165
+ uv run map_app
132
166
  ```
133
167
  </details>
134
168
 
135
169
  ## Usage
136
170
 
137
- Running the command `python -m map_app` will open the app in a new browser tab.
171
+ Running the command `uv run map_app` will open the app in a new browser tab.
138
172
 
139
173
  To use the tool:
140
174
  1. Select the catchment you're interested in on the map.
@@ -1,12 +1,12 @@
1
- data_processing/create_realization.py,sha256=qsUXNxPgXkQ26PSTl7arXXQ3Ea6d31Y2mVTGSMopcpo,14268
1
+ data_processing/create_realization.py,sha256=AxUDVSORjwd6IAImZpgDr8GRHKSUQF8emQi1ikfIno4,14899
2
2
  data_processing/dataset_utils.py,sha256=4qmRmK3qMWPkiWZHXhXv3c-ISbtOwr7QhciEl2ok6Ao,7314
3
3
  data_processing/datasets.py,sha256=kAtTKj2yQINUSzI0vX-kuXMPVeQBtZVfGkfpPh6Qi_0,3528
4
4
  data_processing/file_paths.py,sha256=Cp3BxbO6sD50464ciTshjb3Z0vTvL0ZeSbOJgNdOqQ0,4698
5
5
  data_processing/forcings.py,sha256=6Q9fSXa67OrXg_r9li0K9widsclN2DQUp1-oUH2tZwo,19208
6
- data_processing/gpkg_utils.py,sha256=oVUutZWTKm2_1xAVSuMgMUc_9OwJHNNHZWkqH7uE6yA,19403
6
+ data_processing/gpkg_utils.py,sha256=SdniJrwhta7fPchVSCliuThPENgcs0m9Elx615yttAU,20248
7
7
  data_processing/graph_utils.py,sha256=TsCSZmQ8SPm5F2YzDKv32BxdzaHlPrC6UijZxUJbZvI,7966
8
8
  data_processing/s3fs_utils.py,sha256=WoqqwxkHpv0Qq4I5f5-gUZBCFtVQ68ehXbdOjWRKTDQ,2752
9
- data_processing/subset.py,sha256=8bNkiOWZcmOrHo6MXQceMulbEnXitbD1NUTgIbOaJmQ,2920
9
+ data_processing/subset.py,sha256=WklS0CT5O4oz29fhTT46NmSOe_EFMCC93gLeg6nQ88I,2914
10
10
  data_sources/cfe-nowpm-realization-template.json,sha256=8an6q1drWD8wU1ocvdPab-GvZDvlQ-0di_-NommH3QI,3528
11
11
  data_sources/cfe-template.ini,sha256=6e5-usqjWtm3MWVvtm8CTeZTJJMxO1ZswkOXq0L9mnc,2033
12
12
  data_sources/em-catchment-template.yml,sha256=M08ixazEUHYI2PNavtI0xPZeSzcQ9bg2g0XzNT-8_u4,292
@@ -32,13 +32,13 @@ map_app/static/resources/light-style.json,sha256=DaE52qKpAkjiWSKY_z7LxreqA2rW4Zy
32
32
  map_app/static/resources/loading.gif,sha256=ggdkZf1AD7rSwIpSJwfiIqANgmVV1WHlxGuKxQKv7uY,72191
33
33
  map_app/static/resources/screenshot.jpg,sha256=Ia358aX-OHM9BP4B8lX05cLnguF2fHUIimno9bnFLYw,253730
34
34
  map_app/templates/index.html,sha256=ITRzQEYn15sFN4qRACjaNj5muhalOeP9n_IwcdsIlUs,6631
35
- ngiab_data_cli/__main__.py,sha256=_m0bhAXdyLeZBuh03PKNXlJ6BUJnZDR-xZIbFyRH8iE,10164
35
+ ngiab_data_cli/__main__.py,sha256=X_imHhWo2RBTJzJ9bUwEcAnAtZSyjKJXB60dBxea6ck,10361
36
36
  ngiab_data_cli/arguments.py,sha256=7ptImy8tLM1XvjfDr13tZszkjGVtenXo0KqllJeE3Mw,4372
37
37
  ngiab_data_cli/custom_logging.py,sha256=iS2XozaxudcxQj17qAsrCgbVK9LJAYAPmarJuVWJo1k,1280
38
38
  ngiab_data_cli/forcing_cli.py,sha256=lkcqWDk5H8IPyGv0DwLIZMQldqTUXpfwSX0C_RIuIJ8,3890
39
- ngiab_data_preprocess-4.0.5.dist-info/licenses/LICENSE,sha256=6dMSprwwnsRzEm02mEDbKHD9dUbL8bPIt9Vhrhb0Ulk,1081
40
- ngiab_data_preprocess-4.0.5.dist-info/METADATA,sha256=RkqbXcc3Ac-4qJvLCn-qiCnUV2DCFfoSpp-QdZcuCWw,9433
41
- ngiab_data_preprocess-4.0.5.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
42
- ngiab_data_preprocess-4.0.5.dist-info/entry_points.txt,sha256=spwlhKEJ3ZnNETQsJGeTjD7Vwy8O_zGHb9GdX8ACCtw,128
43
- ngiab_data_preprocess-4.0.5.dist-info/top_level.txt,sha256=CjhYAUZrdveR2fOK6rxffU09VIN2IuPD7hk4V3l3pV0,52
44
- ngiab_data_preprocess-4.0.5.dist-info/RECORD,,
39
+ ngiab_data_preprocess-4.1.1.dist-info/licenses/LICENSE,sha256=6dMSprwwnsRzEm02mEDbKHD9dUbL8bPIt9Vhrhb0Ulk,1081
40
+ ngiab_data_preprocess-4.1.1.dist-info/METADATA,sha256=-LH19uwmvO9AB0NBtN4JECrQrwSLVZUXKtoSVqaNoWA,10310
41
+ ngiab_data_preprocess-4.1.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
42
+ ngiab_data_preprocess-4.1.1.dist-info/entry_points.txt,sha256=spwlhKEJ3ZnNETQsJGeTjD7Vwy8O_zGHb9GdX8ACCtw,128
43
+ ngiab_data_preprocess-4.1.1.dist-info/top_level.txt,sha256=CjhYAUZrdveR2fOK6rxffU09VIN2IuPD7hk4V3l3pV0,52
44
+ ngiab_data_preprocess-4.1.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.1)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5