Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let's get all the changes we've done so far on the main branch. Are we ready? #35

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7210ee8
Add first pass at an environment specification
mfisher87 Sep 28, 2023
d6425a6
Remove DATA_VERSION conditionals
mfisher87 Sep 28, 2023
997b547
Add gdal and geopandas to env
mfisher87 Sep 28, 2023
27200b6
Replace relative paths with absolute paths
mfisher87 Sep 29, 2023
62a68ba
Add dateutil, pillow deps
mfisher87 Sep 29, 2023
c169cc9
Document running update_data.py
mfisher87 Sep 29, 2023
7fa1dac
Stub out mypy config
mfisher87 Sep 29, 2023
0c65836
Add warning about memory footprint to docs
mfisher87 Sep 29, 2023
db8a21e
Narrow scope of some imports
mfisher87 Sep 29, 2023
163d5c7
Replace all relative paths ("../") with absolute paths
mfisher87 Sep 29, 2023
706a78f
Write database to optional external location
mfisher87 Sep 29, 2023
fcda0ad
Create parent directory of melt picklefile if it doesn't exist
mfisher87 Sep 29, 2023
51fa2be
Lock environment
mfisher87 Sep 29, 2023
647ff44
Create parent dir for gap-filled pickle
mfisher87 Sep 29, 2023
65b773f
WIP operations doc
mfisher87 Sep 29, 2023
baee844
WIP documentation enhancements
mfisher87 Sep 30, 2023
014d9f7
Ensure `gdal.Open` receives strings for filepaths
mfisher87 Oct 2, 2023
037b5f3
Document Tb directory won't contain `.bin` files anymore
mfisher87 Oct 2, 2023
64c573b
Download NSIDC-0080 v2 with `earthaccess`
mfisher87 Oct 2, 2023
bb7af78
Read from NSIDC-0080v2 NetCDF files
mfisher87 Oct 3, 2023
3051567
Fixed nan assertion failures
encassano Nov 8, 2023
3d79679
Fixed nan assertion failures
encassano Nov 9, 2023
3fb8a38
Added verbiage in operation.md to address non-bash users`
encassano Nov 9, 2023
4744eaf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 9, 2023
50f9fb9
Fixing deprecated usages of old numpy dtypes.
mmacferrin Dec 12, 2023
ea0d2ac
Minor bug fixes and improved comments.
mmacferrin Dec 13, 2023
2076a10
Updated "update_data.py" to use work with nsidc-0080 v2 data (from v1…
mmacferrin Dec 14, 2023
fb65820
Expand the documentation of processing steps in the operation.md manual.
mmacferrin Dec 14, 2023
2fe965d
Added an optional parameter to limit & filter the download of Tb brig…
mmacferrin Dec 14, 2023
c79cf46
Ignore .nc and .bin files in the Tb/nsidc-0080 folder. These are to b…
mmacferrin Dec 14, 2023
1f9c68c
Fixed a typo in Region 7 name ("Amundsen Bellinghausen" --> "Amundsen…
mmacferrin Dec 15, 2023
7a39152
Removed deprecated "numpy.product" call, replaced with call to "numpy…
mmacferrin Dec 15, 2023
659587f
Fixed runtime bug in previous update to "update_data.py" that was cau…
mmacferrin Dec 15, 2023
6b911ed
Uncommenting the code that downloaded the latest files from NSDIC in …
mmacferrin Dec 17, 2023
aa3edaa
Quick bug fix (mis-named variable).
mmacferrin Dec 17, 2023
13a7ed8
Flipped a parameter to *not* make it use symlinks when copying everyt…
mmacferrin Dec 18, 2023
1e21d83
Merge branch 'main' into matt-is-back
mfisher87 Jul 19, 2024
f069e9a
Add continuous integration workflow
mfisher87 Jul 19, 2024
2b417c7
Make PR template collapsible
mfisher87 Jul 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<!-- Thank you for opening a PR! Please conform to the checklist below. If your PR is
not completely ready yet, please open a "draft" PR. -->

## PR checklist
<details><summary>PR checklist</summary>

- [ ] Has a descriptive title
- [ ] Has a descriptive body
- [ ] Includes a link to any issues closed by this PR, e.g. `Closes #5`.
- [ ] Passes checks (to auto-fix a pre-commit.ci failure, add a comment
containing "pre-commit.ci autofix")

</details>
64 changes: 64 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Continuous Integration

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
# Many color libraries just need this to be set to any value, but at least
# one distinguishes color depth, where "3" -> "256-bit color".
FORCE_COLOR: 3

defaults:
run:
# Enables steps to see the micromamba environment:
shell: bash -leo pipefail {0}


jobs:
checks:
name: Check Python ${{ matrix.python-version }} on ${{ matrix.runs-on }}
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
python-version: ["3.8"]
runs-on:
- ubuntu-latest
- macos-latest
# - windows-latest

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: mamba-org/setup-micromamba@v1
with:
micromamba-version: '1.5.6-0' # any version from https://github.com/mamba-org/micromamba-releases
environment-file: environment.yml
init-shell: >-
bash
powershell
cache-environment: true
post-cleanup: 'all'

- name: Type-check package
run: mypy

# - name: Test package
# run: >-
# python -m pytest -ra --cov --cov-report=xml --cov-report=term
# --durations=20

# - name: Upload coverage report
# uses: codecov/[email protected]
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
2 changes: 2 additions & 0 deletions Tb/nsidc-0080/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*
# Except this file
!.gitignore
*.nc
*.bin
30 changes: 14 additions & 16 deletions antarctica_today/compute_mean_climatology.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def compute_daily_climatology_pixel_averages(
# Generate an empty MxNxT array with
average_melt_array = numpy.zeros(
(melt_array.shape[0], melt_array.shape[1], len(baseline_filler_dt_list)),
dtype=numpy.float,
dtype=float,
)

# Now, compute the average odds (0-1) of melt on any given day for any given pixel, over the baseline period.
Expand All @@ -123,7 +123,7 @@ def compute_daily_climatology_pixel_averages(
((dt.month == bdt.month) and (dt.day == bdt.day))
for dt in dt_list_melt_season
],
dtype=numpy.bool,
dtype=bool,
)
# # print ("\t", [dt for i,dt in enumerate(dt_list_melt_season) if bdt_day_mask[i]])
# if numpy.count_nonzero(bdt_day_mask) == 0:
Expand Down Expand Up @@ -286,9 +286,7 @@ def create_baseline_climatology_tif(
num_years = int((end_date - start_date).days / 365.25)
# print(num_years)

annual_sum_grids = numpy.empty(
model_array.shape[0:2] + (num_years,), dtype=numpy.int
)
annual_sum_grids = numpy.empty(model_array.shape[0:2] + (num_years,), dtype=int)

if gap_filled:
model_melt_days = model_array
Expand All @@ -308,7 +306,7 @@ def create_baseline_climatology_tif(
# print(i, dt1, dt2)

dates_mask = numpy.array(
[(dt >= dt1) & (dt <= dt2) for dt in datetimes], dtype=numpy.bool
[(dt >= dt1) & (dt <= dt2) for dt in datetimes], dtype=bool
)

# dt1_i = datetimes.index(dt1)
Expand All @@ -320,8 +318,8 @@ def create_baseline_climatology_tif(
annual_std_array = numpy.std(annual_sum_grids, axis=2, dtype=numpy.float32)

if round_to_integers:
annual_mean_array = numpy.array(numpy.round(annual_mean_array), dtype=numpy.int)
annual_std_array = numpy.array(numpy.round(annual_std_array), dtype=numpy.int)
annual_mean_array = numpy.array(numpy.round(annual_mean_array), dtype=int)
annual_std_array = numpy.array(numpy.round(annual_std_array), dtype=int)

annual_mean_array[(ice_mask == 0)] = -1
annual_std_array[(ice_mask == 0)] = -1
Expand Down Expand Up @@ -382,7 +380,7 @@ def create_partial_year_melt_anomaly_tif(
((dt >= first_dt_of_present_melt_season) and (dt <= current_datetime))
for dt in dt_list
],
dtype=numpy.bool,
dtype=bool,
)
dts_masked = [dt for dt, mask_val in zip(dt_list, dt_mask) if mask_val]

Expand Down Expand Up @@ -492,7 +490,7 @@ def read_annual_melt_anomaly_tif(
if verbose:
print("Reading", anomaly_tif)

ds = gdal.Open(anomaly_tif, gdal.GA_ReadOnly)
ds = gdal.Open(str(anomaly_tif), gdal.GA_ReadOnly)
if ds is None:
return None

Expand All @@ -514,7 +512,7 @@ def get_baseline_climatology_array(fname=None, gap_filled=True):
fname = base + "_gap_filled" + ext

if os.path.exists(fname):
ds = gdal.Open(fname, gdal.GA_ReadOnly)
ds = gdal.Open(str(fname), gdal.GA_ReadOnly)
if ds is None:
raise FileNotFoundError("Could not open {0}".format(fname))
array = ds.GetRasterBand(1).ReadAsArray()
Expand Down Expand Up @@ -592,7 +590,7 @@ def create_annual_melt_sum_tif(

dates_mask = numpy.array(
[((dt >= start_date) and (dt <= end_date)) for dt in dt_list],
dtype=numpy.bool,
dtype=bool,
)

# Skip any years for which there is no data.
Expand All @@ -602,13 +600,13 @@ def create_annual_melt_sum_tif(
if gap_filled:
# First add the floating-point values
melt_array_year = numpy.sum(
melt_array[:, :, dates_mask], axis=2, dtype=numpy.float
melt_array[:, :, dates_mask], axis=2, dtype=float
)
# Round to integers
melt_array_year = numpy.array(melt_array_year.round(), dtype=numpy.int)
melt_array_year = numpy.array(melt_array_year.round(), dtype=int)
else:
melt_array_year = numpy.sum(
(melt_array[:, :, dates_mask] == 2), axis=2, dtype=numpy.int
(melt_array[:, :, dates_mask] == 2), axis=2, dtype=int
)

melt_array_year[ice_mask == 0] = -1
Expand Down Expand Up @@ -838,7 +836,7 @@ def _get_regional_tif_masks(tifname=antarctic_regions_tif):
Regions will be 1..7. masks will each be an MxN array of (0,1) values.
"""
# Read the ice mask tif, return the array.
regions_ds = gdal.Open(tifname, gdal.GA_ReadOnly)
regions_ds = gdal.Open(str(tifname), gdal.GA_ReadOnly)
region_array = regions_ds.GetRasterBand(1).ReadAsArray()
ndv = regions_ds.GetRasterBand(1).GetNoDataValue()
unique_vals = [val for val in numpy.unique(region_array) if val != ndv]
Expand Down
Empty file.
10 changes: 10 additions & 0 deletions antarctica_today/constants/grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import Final

# If you are using Arctic data or some other grid, change the DEFAULT_GRID_SHAPE below,
# or just use the optional parameter when you call it.
#
# * For Antarctica, (rows, cols) = (332,316)
# * For Arctic, (rows, cols) = (448, 304)
#
# Source: https://nsidc.org/data/polar-stereo/ps_grids.html
DEFAULT_GRID_SHAPE: Final = (332, 316)
37 changes: 37 additions & 0 deletions antarctica_today/constants/paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os
from pathlib import Path
from typing import Final

_this_dir: Final = Path(__file__).parent

# The directory containing the main Python package:
PACKAGE_DIR: Final = _this_dir.parent

# The root of the Git repository (directory containing `.git`)
REPO_DIR: Final = PACKAGE_DIR.parent

# New data directories:
# - Keep data included in the repo separate from runtime data. We don't want to require
# a specific directory structure that may not work on every computer. For example, on
# NSIDC VMs, we have limited direct storage, and need to use mounts to access larger
# storage devices.
# - Use environment variables to enable override; in this case I think we only need one
# for the root storage directory. Default to an in-repo storage location so if the
# envvars are not populated, system pollution doesn't occur.
# - Migrate more things iteratively :)
_default_storage_dir = REPO_DIR
STORAGE_DIR: Final = Path(
os.environ.get("ANTARCTICA_TODAY_STORAGE_DIR", _default_storage_dir)
)
DATA_DATABASE_DIR: Final = STORAGE_DIR / "database"
# DATA_OUTPUT_DIR: Final = STORAGE_DIR / "output"

# Legacy data directories
DATA_DIR: Final = REPO_DIR / "data"
DATA_QGIS_DIR: Final = REPO_DIR / "qgis"
DATA_TB_DIR: Final = REPO_DIR / "Tb"
DATA_PLOTS_DIR: Final = REPO_DIR / "plots"
DATA_BASELINE_DATASETS_DIR: Final = REPO_DIR / "baseline_datasets"


# TODO: Bring tb_file_data.py into constants
Loading
Loading