Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
fa6b297
support for download mirror
Oct 30, 2024
56ced89
trace (.collected): write hash + timestamp
Oct 30, 2024
81c7b4d
export native without warp; working import; WIP test
Apr 2, 2025
9514dba
support metadata pairs when exporting mosaic using modis_window
Apr 25, 2025
c71a54b
only create non-required tiles (do not collect data)
Apr 27, 2025
0f1dc7e
collect all tiles if not specified which are required
Apr 27, 2025
93c9e2b
handle empty H5 archives
Apr 27, 2025
8a01f41
more handling of empty H5 (smooth, window)
Apr 28, 2025
438be6f
fixes uses before assignment
Apr 28, 2025
9f7c304
check raw dates only after reading from raw file
Apr 28, 2025
de8cd5d
minor bugs in refectoring
Apr 28, 2025
3baaec6
supports VIIRS VNP13A2
Jul 6, 2025
3172c21
correct string slicing for .h5 in locating metadata xml
Jul 6, 2025
d1008eb
correctly sets the value range
Jul 8, 2025
3d3e879
add utilities to work in .h5 archive
Jul 8, 2025
c339327
reports check summary
Jul 8, 2025
8ce055c
validates the supplied min-max (both inclusive)
Jul 8, 2025
29fd04d
adds test data
Sep 6, 2025
f334f6e
tweaks pre-allocatoin in modis_collect, new CLI integration tests +fixes
Sep 16, 2025
8949c45
Merge branch 'support-for-viirs-vnp13a2' into sgrid-export-import
Sep 16, 2025
48587ca
fixes unit tests for introducing HDFHandler.HandleCollection
Sep 16, 2025
75e4985
Merge branch 'download-collect-from-local-mirror' into sgrid-export-i…
Sep 16, 2025
47e4593
fixes tests and apply again correct string slicing for .h5
Sep 16, 2025
44aca3f
Updates CI Python versions
Sep 16, 2025
4d16128
no need for ubuntugis ppa repo, right?
Sep 16, 2025
1141a03
migrated to pyproject.toml
Sep 16, 2025
374fca1
do not fail fast
Sep 16, 2025
49711e8
install pytest and pytest-cov
Sep 16, 2025
9251755
get whittaker going
Sep 17, 2025
49c270a
use python -m pip
Sep 17, 2025
febb814
test import modape.whittaker
Sep 17, 2025
738e4f0
check for whittaker in modape
Sep 17, 2025
dd02d8c
cascaded import modape => whittaker
Sep 17, 2025
74eada4
list members in modape
Sep 17, 2025
37ba57d
much like my dev setup
Sep 17, 2025
7b6e272
don't forget pytest + pytest-cov
Sep 17, 2025
3d7914e
sudo python -m pip
Sep 17, 2025
c51cede
pandas < 2
Sep 17, 2025
0aaef69
get _gdal_array going
Sep 17, 2025
714a5bf
gdal: no cache, force reinstall
Sep 17, 2025
225f479
install wheel
Sep 17, 2025
69187a4
CI support only for Python 3.10 and 3.11
Sep 17, 2025
031a125
less is more?
Sep 18, 2025
c614596
parameterizes the interleaving
Sep 21, 2025
599d9a9
Handles empty archives (dates, rawdates)
Sep 21, 2025
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
37 changes: 29 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ on:

jobs:
build_and_test:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -23,12 +24,32 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: install dependencies
run: |
sudo add-apt-repository ppa:ubuntugis/ppa
sudo apt-get update && sudo apt-get install -y libgdal-dev
pip install cython numpy
sudo apt-get update && sudo apt-get install -y \
libgdal-dev build-essential swig \
python3-dev python3-pip \
&& cd /usr/local/bin \
&& ln -s $(readlink -f $(which python3)) python \
&& cd /bin \
&& ln -s $(readlink -f $(which python3)) python \
&& rm -rf /var/lib/apt/lists/*
sudo python -m pip install --upgrade pip
sudo python -m pip install pytest pytest-cov cython "numpy<2" "pandas<2"
sudo python -m pip install "setuptools~=57.5.0" wheel
- name: build gdal
run: pip install gdal==$(gdal-config --version)
run: |
sudo python -m pip uninstall gdal --break-system-packages \
&& python -m pip install "numpy<2" --break-system-packages \
&& sudo python -m pip install \
--no-build-isolation --no-cache-dir --force-reinstall \
gdal==$(gdal-config --version) \
--global-option=build_ext --global-option="-I/usr/include/gdal" \
--break-system-packages
- name: build
run: pip install $GITHUB_WORKSPACE
run: |
cd $GITHUB_WORKSPACE \
&& sudo python -m pip install pytest pytest-cov \
&& sudo python -m pip install -e .[dev] --break-system-packages
- name: test
run: python $GITHUB_WORKSPACE/setup.py test
run: |
cd $GITHUB_WORKSPACE \
&& sudo python -m pytest
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,5 @@ wsmtk.cred.pkl
wsmtk.key.pkl

docenv/*

.vscode/
96 changes: 74 additions & 22 deletions modape/constants.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,109 @@
"""Constants for modape"""

import re
from typing import Any

from osgeo import gdal

REGEX_PATTERNS = {
"product": re.compile(r"^M[O|Y]D\d{2}\w{1}\d{1}"),
"product": re.compile(r"^(?:VNP|M[O|Y|X]D)\d{2}\w{1}\d{1}"),
"version": re.compile(r".+\.(\d{3})\..+"),
"tile": re.compile(r"h\d+v\d+"),
"date": re.compile(r".+A(\d{7}).+"),
"processing_timestamp": re.compile(r".+(\d{13}).+"),
"AquaTerra": re.compile(r"^M[Y|O]D\d{2}.+"),
"AquaTerra": re.compile(r"^M[O|Y|X]D\d{2}.+"),
"Aqua": re.compile(r"^MYD\d{2}.+"),
"Terra": re.compile(r"^MYD\d{2}.+"),
"VIM": re.compile(r"^M[Y|O|X]D13.+"),
"VIM": re.compile(r"^(?:VNP|M[O|Y|X]D)13.+"),
"LST": re.compile(r"^M[Y|O]D11.+"),
"VIMLST": re.compile(r"^M[Y|O]D[11|13].+"),
"VIMLST": re.compile(r"^(?:VNP|M[O|Y|X]D)[11|13].+"),
}

VAM_PRODUCT_CODES = dict(zip(["VIM", "VEM", "LTD", "LTN"], ["NDVI", "EVI", "LST_Day", "LST_Night"]))

PRODUCT_SRS_DICT: dict[str, dict[str, Any]] = {
"VNP13A2": {
"ProjectionWKT": """\
PROJCRS["unnamed",
BASEGEOGCRS["Unknown datum based upon the custom spheroid",
DATUM["Not specified (based on custom spheroid)",
ELLIPSOID["Custom spheroid",6371007.181,0,
LENGTHUNIT["metre",1,
ID["EPSG",9001]]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433,
ID["EPSG",9122]]]],
CONVERSION["unnamed",
METHOD["Sinusoidal"],
PARAMETER["Longitude of natural origin",0,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["False easting",0,
LENGTHUNIT["Meter",1],
ID["EPSG",8806]],
PARAMETER["False northing",0,
LENGTHUNIT["Meter",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["easting",east,
ORDER[1],
LENGTHUNIT["Meter",1]],
AXIS["northing",north,
ORDER[2],
LENGTHUNIT["Meter",1]]]""",
"AxisMapping": "1,2",
"PixelSize": tuple([xy * 926.6254330558334 for xy in [1, -1]]),
"Origin": {"h": dict(index=18, offset=0), "v": dict(index=9, offset=0)},
}
}

VAM_PRODUCT_CODES = dict(
zip(["VIM", "VEM", "LTD", "LTN"],
["NDVI", "EVI", "LST_Day", "LST_Night"])
)
# Mapping for <NASA Product>_<VAM Subdataset> to physical encoding of the data: value range, nodata
PRODUCT_SDS_DICT: dict[str, dict[str, int | list[int]]] = {
"VNP13A2_NDVI": {
"Name": "//HDFEOS/GRIDS/VIIRS_Grid_16Day_VI_1km/Data_Fields/1_km_16_days_NDVI",
"DataType": gdal.GDT_Int16,
"ValueRange": (-10000, 10000),
"NoDataValue": (-15000, -13000),
"Size": (1200, 1200),
"BlockSize": (1200, 1),
}
}

TEMPORAL_DICT = {
"MXD13":{
"VNP13": {
"temporalresolution": 8,
"tshift": 8,
"mux": "VNP",
"min_date": "2012017",
},
"MOD13":{
"MXD13": {
"temporalresolution": 8,
"tshift": 8,
"min_date": "2002185",
},
"MOD13": {
"temporalresolution": 16,
"tshift": 8,
"mux": "MXD",
},
"MYD13":{
"MYD13": {
"temporalresolution": 16,
"tshift": 8,
"mux": "MXD",
},
"MOD11":{
"MOD11": {
"temporalresolution": 8,
"tshift": 4,
},
"MYD11":{
"MYD11": {
"temporalresolution": 8,
"tshift": 4,
},
}

LST_NAME_LUD = {
"LTD": {
"MOD": "TDT",
"MYD": "TDA"
},
"LTN": {
"MOD": "TNT",
"MYD": "TNA"
},
"LTD": {"MOD": "TDT", "MYD": "TDA"},
"LTN": {"MOD": "TNT", "MYD": "TNA"},
}

TEMPINT_LABELS = {
Expand All @@ -61,5 +113,5 @@

DATE_LABELS = {
5: dict(zip([3, 8, 13, 18, 23, 28], ["p1", "p2", "p3", "p4", "p5", "p6"])),
10: dict(zip([5, 15, 25], ["d1", "d2", "d3"]))
10: dict(zip([5, 15, 25], ["d1", "d2", "d3"])),
}
Loading