Skip to content

Commit ca34fac

Browse files
committed
Merge branch 'development' of github.com:ICESat2-SlideRule/sliderule-python into development
2 parents ab6cfd3 + 150f2b1 commit ca34fac

9 files changed

Lines changed: 81 additions & 55 deletions

File tree

examples/arcticdem_strip_boundaries.ipynb

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
{
3535
"cell_type": "code",
3636
"execution_count": null,
37-
"id": "8ac0d0cc-a65d-4368-baa9-7d5dfb4936a7",
37+
"id": "78db0877-2ba9-4e8f-ba2e-a07e4de491ca",
3838
"metadata": {},
3939
"outputs": [],
4040
"source": [
@@ -71,7 +71,6 @@
7171
" \"len\": 40.0,\n",
7272
" \"res\": 120.0,\n",
7373
" \"maxi\": 5,\n",
74-
" \"cycle\": 15,\n",
7574
" \"rgt\": 658,\n",
7675
" \"time_start\":'2020-01-01',\n",
7776
" \"time_end\":'2021-01-01',\n",
@@ -82,14 +81,15 @@
8281
{
8382
"cell_type": "code",
8483
"execution_count": null,
85-
"id": "970e0770-abe9-4e2a-b1af-bc6e330fb566",
86-
"metadata": {},
84+
"id": "b815e8d8-c71a-4305-8649-fa4e95b64325",
85+
"metadata": {
86+
"tags": []
87+
},
8788
"outputs": [],
8889
"source": [
8990
"#\n",
9091
"# Set DEM of Interest\n",
9192
"#\n",
92-
"id = 17\n",
9393
"gdf.attrs['file_directory']"
9494
]
9595
},
@@ -143,8 +143,11 @@
143143
"#\n",
144144
"# Get Boundaries for each Raster\n",
145145
"#\n",
146+
"p0 = 132\n",
147+
"p1 = 148\n",
146148
"raster_of_interest = {}\n",
147-
"for i in gdf.attrs['file_directory']:\n",
149+
"for i in list(gdf.attrs['file_directory'].keys())[p0:p1]:\n",
150+
" print(\"Retrieving raster info for:\", gdf.attrs['file_directory'][i])\n",
148151
" rlist = getBB(gdf.attrs['file_directory'][i])\n",
149152
" raster_of_interest[\"dem\"+str(i)] = sliderule.toregion(rlist)"
150153
]
@@ -168,39 +171,36 @@
168171
" else:\n",
169172
" return None\n",
170173
"sampled_data = gdf[gdf['strips.time'].notnull()]\n",
171-
"for i in gdf.attrs['file_directory']:\n",
174+
"for i in list(gdf.attrs['file_directory'].keys())[p0:p1]:\n",
172175
" sampled_data[\"dem\"+str(i)] = sampled_data.apply(lambda x: getValue(x, i), axis=1)"
173176
]
174177
},
175178
{
176179
"cell_type": "code",
177180
"execution_count": null,
178-
"id": "24e1c0c3-b4e5-4bcd-af34-26bfa6885c91",
181+
"id": "f23a3827-93b6-47cb-9842-8f8269e0a871",
179182
"metadata": {},
180183
"outputs": [],
181184
"source": [
182-
"\n",
183-
"#\n",
184-
"# Create Boundaries for Region and Raster\n",
185-
"#\n",
186-
"\n",
187185
"#\n",
188-
"# Plot\n",
186+
"# Plot Overlays of Boundaries and Returns\n",
189187
"#\n",
190188
"fig = plt.figure(num=None, figsize=(24, 24))\n",
191189
"region_lons = [p[\"lon\"] for p in region_of_interest[\"poly\"]]\n",
192190
"region_lats = [p[\"lat\"] for p in region_of_interest[\"poly\"]]\n",
193191
"ax = {}\n",
194-
"for i in gdf.attrs['file_directory']:\n",
192+
"k = 0\n",
193+
"for i in list(gdf.attrs['file_directory'].keys())[p0:p1]:\n",
195194
" raster_lons = [p[\"lon\"] for p in raster_of_interest[\"dem\"+str(i)][\"poly\"]]\n",
196195
" raster_lats = [p[\"lat\"] for p in raster_of_interest[\"dem\"+str(i)][\"poly\"]]\n",
197196
" plot_data = sampled_data[sampled_data[\"dem\"+str(i)].notnull()]\n",
198197
" plot_data = sampled_data[sampled_data[\"dem\"+str(i)] > -9990]\n",
199-
" ax[i] = plt.subplot(5,4,i+1)\n",
200-
" gdf.plot(ax=ax[i], column='h_mean', color='y', markersize=0.5)\n",
201-
" plot_data.plot(ax=ax[i], column='h_mean', color='b', markersize=0.5)\n",
202-
" ax[i].plot(region_lons, region_lats, linewidth=1.5, color='r', zorder=2)\n",
203-
" ax[i].plot(raster_lons, raster_lats, linewidth=1.5, color='g', zorder=2)\n",
198+
" ax[k] = plt.subplot(5,4,k+1)\n",
199+
" gdf.plot(ax=ax[k], column='h_mean', color='y', markersize=0.5)\n",
200+
" plot_data.plot(ax=ax[k], column='h_mean', color='b', markersize=0.5)\n",
201+
" ax[k].plot(region_lons, region_lats, linewidth=1.5, color='r', zorder=2)\n",
202+
" ax[k].plot(raster_lons, raster_lats, linewidth=1.5, color='g', zorder=2)\n",
203+
" k += 1\n",
204204
"plt.tight_layout()"
205205
]
206206
},
@@ -218,7 +218,7 @@
218218
"######################\n",
219219
"# Select DEM File ID #\n",
220220
"######################\n",
221-
"file_id = 5\n",
221+
"file_id = list(gdf.attrs['file_directory'].keys())[p0]\n",
222222
"\n",
223223
"# Setup Plot\n",
224224
"fig,ax = plt.subplots(num=None, figsize=(10, 8))\n",

sliderule/gedi.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@
5151
# default GEDI standard data product version
5252
DEFAULT_GEDI_SDP_VERSION = '2'
5353

54-
# gps-based epoch for delta times
55-
GEDI_SDP_EPOCH = datetime.datetime(2018, 1, 1)
56-
5754
# gedi parameters
5855
ALL_BEAMS = -1
5956

@@ -64,7 +61,7 @@
6461
#
6562
# Dictionary to GeoDataFrame
6663
#
67-
def __todataframe(columns, delta_time_key="delta_time", lon_key="longitude", lat_key="latitude", **kwargs):
64+
def __todataframe(columns, time_key="time", lon_key="longitude", lat_key="latitude", **kwargs):
6865

6966
# Latch Start Time
7067
tstart = time.perf_counter()
@@ -78,9 +75,7 @@ def __todataframe(columns, delta_time_key="delta_time", lon_key="longitude", lat
7875
return sliderule.emptyframe(**kwargs)
7976

8077
# Generate Time Column
81-
delta_time = (columns[delta_time_key]*1e9).astype('timedelta64[ns]')
82-
gedi_sdp_epoch = numpy.datetime64(GEDI_SDP_EPOCH)
83-
columns['time'] = geopandas.pd.to_datetime(gedi_sdp_epoch + delta_time)
78+
columns['time'] = columns[time_key].astype('datetime64[ns]')
8479

8580
# Generate Geometry Column
8681
geometry = geopandas.points_from_xy(columns[lon_key], columns[lat_key])

sliderule/icesat2.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@
8888
P = { '5': 0, '10': 1, '15': 2, '20': 3, '25': 4, '30': 5, '35': 6, '40': 7, '45': 8, '50': 9,
8989
'55': 10, '60': 11, '65': 12, '70': 13, '75': 14, '80': 15, '85': 16, '90': 17, '95': 18 }
9090

91-
# gps-based epoch for delta times
92-
ATLAS_SDP_EPOCH = datetime.datetime(2018, 1, 1)
93-
9491
###############################################################################
9592
# LOCAL FUNCTIONS
9693
###############################################################################
@@ -142,7 +139,7 @@ def __calcspot(sc_orient, track, pair):
142139
#
143140
# Dictionary to GeoDataFrame
144141
#
145-
def __todataframe(columns, delta_time_key="delta_time", lon_key="lon", lat_key="lat", **kwargs):
142+
def __todataframe(columns, time_key="time", lon_key="lon", lat_key="lat", **kwargs):
146143

147144
# Latch Start Time
148145
tstart = time.perf_counter()
@@ -156,9 +153,7 @@ def __todataframe(columns, delta_time_key="delta_time", lon_key="lon", lat_key="
156153
return sliderule.emptyframe(**kwargs)
157154

158155
# Generate Time Column
159-
delta_time = (columns[delta_time_key]*1e9).astype('timedelta64[ns]')
160-
atlas_sdp_epoch = numpy.datetime64(ATLAS_SDP_EPOCH)
161-
columns['time'] = geopandas.pd.to_datetime(atlas_sdp_epoch + delta_time)
156+
columns['time'] = columns[time_key].astype('datetime64[ns]')
162157

163158
# Generate Geometry Column
164159
geometry = geopandas.points_from_xy(columns[lon_key], columns[lat_key])

sliderule/sliderule.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
"BITFIELD": { "fmt": 'x', "size": 0, "nptype": numpy.byte }, # unsupported
120120
"FLOAT": { "fmt": 'f', "size": 4, "nptype": numpy.single },
121121
"DOUBLE": { "fmt": 'd', "size": 8, "nptype": numpy.double },
122-
"TIME8": { "fmt": 'Q', "size": 8, "nptype": numpy.byte },
122+
"TIME8": { "fmt": 'q', "size": 8, "nptype": numpy.int64 }, # numpy.datetime64
123123
"STRING": { "fmt": 's', "size": 1, "nptype": numpy.byte }
124124
}
125125

@@ -917,7 +917,7 @@ def authenticate (ps_organization, ps_username=None, ps_password=None):
917917
#
918918
# gps2utc
919919
#
920-
def gps2utc (gps_time, as_str=True, epoch=gps_epoch):
920+
def gps2utc (gps_time, as_str=True):
921921
'''
922922
Convert a GPS based time returned from SlideRule into a UTC time.
923923
@@ -927,8 +927,6 @@ def gps2utc (gps_time, as_str=True, epoch=gps_epoch):
927927
number of seconds since GPS epoch (January 6, 1980)
928928
as_str: bool
929929
if True, returns the time as a string; if False, returns the time as datatime object
930-
epoch: datetime
931-
the epoch used in the conversion, defaults to GPS epoch (Jan 6, 1980)
932930
933931
Returns
934932
-------
@@ -941,15 +939,11 @@ def gps2utc (gps_time, as_str=True, epoch=gps_epoch):
941939
>>> sliderule.gps2utc(1235331234)
942940
'2019-02-27 19:34:03'
943941
'''
944-
gps_time = epoch + timedelta(seconds=gps_time)
945-
tai_time = gps_time + timedelta(seconds=19)
946-
tai_timestamp = (tai_time - tai_epoch).total_seconds()
947-
utc_timestamp = datetime.utcfromtimestamp(tai_timestamp)
942+
rsps = source("time", {"time": gps_time, "input": "GPS", "output": "DATE"})
948943
if as_str:
949-
return str(utc_timestamp)
944+
return rsps["time"]
950945
else:
951-
return utc_timestamp
952-
946+
return datetime.strptime(rsps["time"], '%Y-%m-%dT%H:%M:%SZ')
953947
#
954948
# get_definition
955949
#

tests/test_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def test_definition(self, domain, organization):
118118
"rectype": "atl06rec.elevation",
119119
}
120120
d = sliderule.source("definition", rqst)
121-
assert d["delta_time"]["offset"] == 256
121+
assert d["time"]["offset"] == 192
122122

123123
def test_version(self, domain, organization):
124124
icesat2.init(domain, organization=organization)

tests/test_arcticdem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_nearestneighbour(self, domain, asset, organization):
3232
"samples": {"mosaic": {"asset": "arcticdem-mosaic"}} }
3333
gdf = icesat2.atl06p(parms, asset=asset, resources=[resource])
3434
assert len(gdf) == 964
35-
assert len(gdf.keys()) == 20
35+
assert len(gdf.keys()) == 19
3636
assert gdf["rgt"][0] == 1160
3737
assert gdf["cycle"][0] == 2
3838
assert gdf['segment_id'].describe()["min"] == 405240
@@ -54,7 +54,7 @@ def test_zonal_stats(self, domain, asset, organization):
5454
"samples": {"mosaic": {"asset": "arcticdem-mosaic", "radius": 10.0, "zonal_stats": True}} }
5555
gdf = icesat2.atl06p(parms, asset=asset, resources=[resource])
5656
assert len(gdf) == 964
57-
assert len(gdf.keys()) == 27
57+
assert len(gdf.keys()) == 26
5858
assert gdf["rgt"][0] == 1160
5959
assert gdf["cycle"][0] == 2
6060
assert gdf['segment_id'].describe()["min"] == 405240

tests/test_client.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ def test_seturl_empty(self):
1313
with pytest.raises(TypeError, match=('url')):
1414
sliderule.set_url()
1515

16-
def test_gps2utc(self):
17-
utc = sliderule.gps2utc(1235331234)
18-
assert utc == '2019-02-27 19:34:03'
16+
def test_gps2utc(self, domain, organization):
17+
sliderule.init(domain, organization=organization)
18+
utc = sliderule.gps2utc(1235331234000)
19+
assert utc == '2019-02-27T19:33:36Z'
1920

2021
@pytest.mark.network
2122
class TestRemote:

tests/test_geojson.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
@pytest.mark.network
1212
class TestGeoJson:
13-
def test_atl06(self, domain, asset, organization):
13+
def test_atl03(self, domain, asset, organization):
1414
icesat2.init(domain, organization=organization)
1515
for testfile in ["data/grandmesa.geojson", "data/grandmesa.shp"]:
1616
region = sliderule.toregion(os.path.join(TESTDIR, testfile))

tests/test_parquet.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import pytest
44
from pathlib import Path
5+
import numpy
56
import os
67
import os.path
78
import sliderule
@@ -26,7 +27,7 @@ def test_atl06(self, domain, asset, organization):
2627
"output": { "path": "testfile1.parquet", "format": "parquet", "open_on_complete": True } }
2728
gdf = icesat2.atl06p(parms, asset=asset, resources=[resource])
2829
assert len(gdf) == 964
29-
assert len(gdf.keys()) == 17
30+
assert len(gdf.keys()) == 16
3031
assert gdf["rgt"][0] == 1160
3132
assert gdf["cycle"][0] == 2
3233
assert gdf['segment_id'].describe()["min"] == 405240
@@ -48,9 +49,49 @@ def test_atl03(self, domain, asset, organization):
4849
"output": { "path": "testfile2.parquet", "format": "parquet", "open_on_complete": True } }
4950
gdf = icesat2.atl03sp(parms, asset=asset, resources=[resource])
5051
assert len(gdf) == 194696
51-
assert len(gdf.keys()) == 18
52+
assert len(gdf.keys()) == 17
5253
assert gdf["rgt"][0] == 1160
5354
assert gdf["cycle"][0] == 2
5455
assert gdf['segment_id'].describe()["min"] == 405240
5556
assert gdf['segment_id'].describe()["max"] == 405915
5657
os.remove("testfile2.parquet")
58+
59+
def test_atl06_index(self, domain, asset, organization):
60+
icesat2.init(domain, organization=organization)
61+
resource = "ATL03_20181017222812_02950102_005_01.h5"
62+
region = sliderule.toregion(os.path.join(TESTDIR, "data/grandmesa.geojson"))
63+
parms = {
64+
"poly": region["poly"],
65+
"raster": region["raster"],
66+
"srt": icesat2.SRT_LAND,
67+
"cnf": icesat2.CNF_SURFACE_HIGH,
68+
"ats": 10.0,
69+
"cnt": 10,
70+
"len": 40.0,
71+
"res": 20.0,
72+
"output": { "path": "testfile3.parquet", "format": "parquet", "open_on_complete": True } }
73+
gdf = icesat2.atl06p(parms, asset=asset, resources=[resource])
74+
assert len(gdf) == 275
75+
assert gdf.index.values.min() == numpy.datetime64('2018-10-17T22:31:35.330187264')
76+
assert gdf.index.values.max() == numpy.datetime64('2018-10-17T22:31:37.693747456')
77+
os.remove("testfile3.parquet")
78+
79+
def test_atl03_index(self, domain, asset, organization):
80+
icesat2.init(domain, organization=organization)
81+
resource = "ATL03_20181017222812_02950102_005_01.h5"
82+
region = sliderule.toregion(os.path.join(TESTDIR, "data/grandmesa.geojson"))
83+
parms = {
84+
"poly": region["poly"],
85+
"raster": region["raster"],
86+
"srt": icesat2.SRT_LAND,
87+
"cnf": icesat2.CNF_SURFACE_HIGH,
88+
"ats": 10.0,
89+
"cnt": 10,
90+
"len": 40.0,
91+
"res": 20.0,
92+
"output": { "path": "testfile4.parquet", "format": "parquet", "open_on_complete": True } }
93+
gdf = icesat2.atl03sp(parms, asset=asset, resources=[resource])
94+
assert len(gdf) == 21029
95+
assert gdf.index.values.min() == numpy.datetime64('2018-10-17T22:31:35.330047488')
96+
assert gdf.index.values.max() == numpy.datetime64('2018-10-17T22:31:37.695347456')
97+
os.remove("testfile4.parquet")

0 commit comments

Comments
 (0)