├── .gitignore
├── LICENSE
├── README.md
├── contributors
├── team_member_1
│ └── tm1_notebook.ipynb
└── team_member_2
│ └── tm2_notebook.ipynb
├── data
└── Antarctica_clustering
│ └── clustering[ 0. -72. 50. -68.5].pdf
├── environment.yml
├── notebooks
├── Antarctica_clustering.ipynb
├── images
│ ├── intro_figure.png
│ └── intro_figure_2.png
└── project_result_1.ipynb
└── scripts
├── Antarctica_kmeans_test1.ipynb
├── PlotPhotoHistograms.ipynb
├── Plotting_examples_file_location.ipynb
├── Plotting_tif_Images.ipynb
├── data_download.ipynb
├── get_hists.py
├── helper_tool.sh
└── photon_plotting.ipynb
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
106 | # Data files
107 | *.h5
108 | *.hdf
109 | *.hdf5
110 | *.nc
111 | *.tif
112 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2019, University of Washington Geohackweek
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Surface type clustering
2 |
3 | Unsupervised surface classification on ICESat-2's ATL03. Preliminary goals include correctly downloading and processing ATL03 data, curating the data for training and performing clustering on it to determine different surface types.
4 |
5 | # Team
6 |
7 | Brad Lipovsky, Yara Mohajerani, Kat Sejan, Susan Howard, Myung Sik Cho and Jordi Bolibar
8 |
9 | ## Files
10 |
11 | * `.gitignore`
12 |
Globally ignored files by `git` for the project.
13 | * `environment.yml`
14 |
`conda` environment description needed to run this project.
15 | * `README.md`
16 |
Description of the project. [Sample](https://geohackweek.github.io/wiki/github_project_management.html#project-guidelines)
17 |
18 | ## Folders
19 |
20 | ### `contributors`
21 | Each team member has it's own folder under contributors, where he/she can
22 | work on their contribution. Having a dedicated folder for one-self helps to
23 | prevent conflicts when merging with master.
24 |
25 | ### `notebooks`
26 | Notebooks that are considered delivered results for the project should go in
27 | here.
28 |
29 | ### `scripts`
30 | Helper utilities that are shared with the team
31 |
32 |
--------------------------------------------------------------------------------
/contributors/team_member_1/tm1_notebook.ipynb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/contributors/team_member_1/tm1_notebook.ipynb
--------------------------------------------------------------------------------
/contributors/team_member_2/tm2_notebook.ipynb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/contributors/team_member_2/tm2_notebook.ipynb
--------------------------------------------------------------------------------
/data/Antarctica_clustering/clustering[ 0. -72. 50. -68.5].pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/data/Antarctica_clustering/clustering[ 0. -72. 50. -68.5].pdf
--------------------------------------------------------------------------------
/environment.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/environment.yml
--------------------------------------------------------------------------------
/notebooks/images/intro_figure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/notebooks/images/intro_figure.png
--------------------------------------------------------------------------------
/notebooks/images/intro_figure_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/notebooks/images/intro_figure_2.png
--------------------------------------------------------------------------------
/notebooks/project_result_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "First test with new fork\n"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "import pandas as pd"
18 | ]
19 | },
20 | {
21 | "cell_type": "code",
22 | "execution_count": null,
23 | "metadata": {},
24 | "outputs": [],
25 | "source": []
26 | }
27 | ],
28 | "metadata": {
29 | "kernelspec": {
30 | "display_name": "",
31 | "name": ""
32 | },
33 | "language_info": {
34 | "codemirror_mode": {
35 | "name": "ipython",
36 | "version": 2
37 | },
38 | "file_extension": ".py",
39 | "mimetype": "text/x-python",
40 | "name": "python",
41 | "nbconvert_exporter": "python",
42 | "pygments_lexer": "ipython2",
43 | "version": "2.7.6"
44 | }
45 | },
46 | "nbformat": 4,
47 | "nbformat_minor": 4
48 | }
49 |
--------------------------------------------------------------------------------
/scripts/Antarctica_kmeans_test1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "
First full pipeline test on Antarctica
\n",
8 | ""
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": 54,
14 | "metadata": {},
15 | "outputs": [
16 | {
17 | "name": "stderr",
18 | "output_type": "stream",
19 | "text": [
20 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/proplot/config.py:1454: ProPlotWarning: Rebuilding font cache.\n"
21 | ]
22 | }
23 | ],
24 | "source": [
25 | "from icepyx import icesat2data as ipd\n",
26 | "import numpy as np\n",
27 | "import os\n",
28 | "import shutil\n",
29 | "import h5py\n",
30 | "import matplotlib.pyplot as plt\n",
31 | "import cartopy.crs as ccrs\n",
32 | "import sys\n",
33 | "import pyproj\n",
34 | "import proplot as plot\n",
35 | "\n",
36 | "%matplotlib widget"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": 4,
42 | "metadata": {},
43 | "outputs": [
44 | {
45 | "name": "stdin",
46 | "output_type": "stream",
47 | "text": [
48 | "Earthdata Login password: ··········\n"
49 | ]
50 | }
51 | ],
52 | "source": [
53 | "short_name = 'ATL06'\n",
54 | "spatial_extent = [31.5, -70.56, 33.73, -69.29]\n",
55 | "date_range = ['2020-03-30','2020-04-1']\n",
56 | "region_a = ipd.Icesat2Data(short_name, spatial_extent, date_range)\n",
57 | "\n",
58 | "username = \"JordiBN\"\n",
59 | "email = \"jordi.bolibar@univ-grenoble-alpes.fr\"\n",
60 | "\n",
61 | "region_a.earthdata_login(username,email)"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "#region_a.order_vars.avail()"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": 5,
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "region_a.order_vars.append(var_list=['count'])"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 6,
85 | "metadata": {},
86 | "outputs": [
87 | {
88 | "name": "stdout",
89 | "output_type": "stream",
90 | "text": [
91 | "Total number of data order requests is 1 for 1 granules.\n",
92 | "Data request 1 of 1 is submitting to NSIDC\n",
93 | "order ID: 5000000701699\n",
94 | "Initial status of your order request at NSIDC is: processing\n",
95 | "Your order status is still processing at NSIDC. Please continue waiting... this may take a few moments.\n",
96 | "Your order is: complete\n",
97 | "Beginning download of zipped output...\n",
98 | "Data request 5000000701699 of 1 order(s) is downloaded.\n",
99 | "Download complete\n"
100 | ]
101 | }
102 | ],
103 | "source": [
104 | "region_a.download_granules('/home/jovyan/surface_classification/data') "
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": 9,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "\n",
114 | "FILE_NAME = '/home/jovyan/data/processed_ATL06_20200330121520_00600712_003_01.h5'\n",
115 | "f = h5py.File(FILE_NAME, mode='r') \n",
116 | "\n",
117 | "count = f['gt1l/residual_histogram/count'][:] # has units of n_histograms, n_bins\n",
118 | "lat_mean = f['gt1l/residual_histogram/lat_mean'][:]\n",
119 | "lon_mean = f['gt1l/residual_histogram/lon_mean'][:]\n",
120 | "h_li = f['gt1l/land_ice_segments/h_li'][:]\n",
121 | "h_lat = f['gt1l/land_ice_segments/latitude'][:]\n",
122 | "h_lon = f['gt1l/land_ice_segments/longitude'][:]\n",
123 | "\n",
124 | "#latitude = f['/gt2r/heights/lat_ph']\n",
125 | "#longitude = f['/gt2r/heights/lon_ph']\n",
126 | "#height = f['gt2r/heights/h_ph']\n"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "\n",
134 | "Cropping the data far from surface in each histogram."
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": 8,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "data = count[:, 200:550]"
144 | ]
145 | },
146 | {
147 | "cell_type": "code",
148 | "execution_count": 52,
149 | "metadata": {},
150 | "outputs": [
151 | {
152 | "name": "stderr",
153 | "output_type": "stream",
154 | "text": [
155 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
156 | " \"\"\"Entry point for launching an IPython kernel.\n"
157 | ]
158 | },
159 | {
160 | "data": {
161 | "application/vnd.jupyter.widget-view+json": {
162 | "model_id": "775382cf22f340e0985523c5d679cd75",
163 | "version_major": 2,
164 | "version_minor": 0
165 | },
166 | "text/plain": [
167 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
168 | ]
169 | },
170 | "metadata": {},
171 | "output_type": "display_data"
172 | },
173 | {
174 | "name": "stderr",
175 | "output_type": "stream",
176 | "text": [
177 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:3: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.\n",
178 | " This is separate from the ipykernel package so we can avoid doing imports until\n"
179 | ]
180 | }
181 | ],
182 | "source": [
183 | "\n",
184 | "fig=plt.figure(figsize=(10,8))\n",
185 | "plt.title(\"Training data\")\n",
186 | "ax = fig.add_subplot(111)\n",
187 | "h = ax.imshow(np.transpose(data),vmin=0,vmax=30,cmap='inferno')\n",
188 | "plt.colorbar(h)\n",
189 | "plt.show()"
190 | ]
191 | },
192 | {
193 | "cell_type": "markdown",
194 | "metadata": {},
195 | "source": [
196 | "
Plot research area of the above file
"
197 | ]
198 | },
199 | {
200 | "cell_type": "markdown",
201 | "metadata": {},
202 | "source": [
203 | "** still needs track on this image"
204 | ]
205 | },
206 | {
207 | "cell_type": "code",
208 | "execution_count": 16,
209 | "metadata": {},
210 | "outputs": [],
211 | "source": [
212 | "data_root='/srv/tutorial-data/land_ice_applications/'"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": 17,
218 | "metadata": {},
219 | "outputs": [],
220 | "source": [
221 | "! cd ..; [ -d pointCollection ] || git clone https://www.github.com/smithB/pointCollection.git\n",
222 | "sys.path.append(os.path.join(os.getcwd(), '..'))\n",
223 | "import pointCollection as pc"
224 | ]
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | " Plotting track on map"
231 | ]
232 | },
233 | {
234 | "cell_type": "code",
235 | "execution_count": 108,
236 | "metadata": {},
237 | "outputs": [
238 | {
239 | "name": "stderr",
240 | "output_type": "stream",
241 | "text": [
242 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:8: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
243 | " \n"
244 | ]
245 | },
246 | {
247 | "data": {
248 | "application/vnd.jupyter.widget-view+json": {
249 | "model_id": "07f0f7123d1b4d1eb3488a75dbe43340",
250 | "version_major": 2,
251 | "version_minor": 0
252 | },
253 | "text/plain": [
254 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
255 | ]
256 | },
257 | "metadata": {},
258 | "output_type": "display_data"
259 | }
260 | ],
261 | "source": [
262 | "spatial_extent_ps = [spatial_extent[0], spatial_extent[2], spatial_extent[1], spatial_extent[3]]\n",
263 | "\n",
264 | "## we will want to set colorbar parameters based on the chosen variable\n",
265 | "vmin=0\n",
266 | "vmax=6\n",
267 | "ticks=np.arange(vmin,vmax+1,1)\n",
268 | "\n",
269 | "plt.figure(figsize=(8,8), dpi= 90)\n",
270 | "ax = plt.axes(projection=ccrs.SouthPolarStereo(central_longitude=0)) # choose polar sterographic for projection\n",
271 | "ax.coastlines(resolution='50m', color='black', linewidth=1)\n",
272 | "ax.set_extent(spatial_extent_ps, ccrs.PlateCarree())\n",
273 | "plt.plot(lon_mean,lat_mean,transform=ccrs.PlateCarree())\n",
274 | "plt.show()\n"
275 | ]
276 | },
277 | {
278 | "cell_type": "markdown",
279 | "metadata": {},
280 | "source": [
281 | "Plot comparing mean_lon and mean_lon from histrograms with beam lat and lon"
282 | ]
283 | },
284 | {
285 | "cell_type": "code",
286 | "execution_count": 103,
287 | "metadata": {},
288 | "outputs": [
289 | {
290 | "name": "stderr",
291 | "output_type": "stream",
292 | "text": [
293 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:1: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
294 | " \"\"\"Entry point for launching an IPython kernel.\n"
295 | ]
296 | },
297 | {
298 | "data": {
299 | "application/vnd.jupyter.widget-view+json": {
300 | "model_id": "e222d87d785241ba89721fe9d74e792d",
301 | "version_major": 2,
302 | "version_minor": 0
303 | },
304 | "text/plain": [
305 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
306 | ]
307 | },
308 | "metadata": {},
309 | "output_type": "display_data"
310 | },
311 | {
312 | "data": {
313 | "text/plain": [
314 | "[]"
315 | ]
316 | },
317 | "execution_count": 103,
318 | "metadata": {},
319 | "output_type": "execute_result"
320 | }
321 | ],
322 | "source": [
323 | "plt.figure()\n",
324 | "plt.plot(h_lon,h_lat,'ob' )\n",
325 | "plt.plot(lon_mean, lat_mean,'.r')"
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {},
331 | "source": [
332 | "Unsupervised learning of ATL06 residual histograms
"
333 | ]
334 | },
335 | {
336 | "cell_type": "code",
337 | "execution_count": 27,
338 | "metadata": {},
339 | "outputs": [],
340 | "source": [
341 | "from sklearn.cluster import KMeans"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": 99,
347 | "metadata": {},
348 | "outputs": [
349 | {
350 | "name": "stdout",
351 | "output_type": "stream",
352 | "text": [
353 | "Training data shape: (523, 350)\n",
354 | "\n",
355 | "Classified labels: [0 0 0 0 0 3 3 3 3 3 3 3 0 0 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0\n",
356 | " 0 0 3 0 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0\n",
357 | " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
358 | " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
359 | " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
360 | " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
361 | " 3 3 3 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 3 3 3 0 0 0 3 3 3 3 3 3 3 3 3 0 0 3\n",
362 | " 2 3 3 3 3 2 2 2 2 3 3 3 3 3 3 2 2 2 2 2 2 3 3 3 3 2 2 2 1 1 2 2 2 1 1 1 1\n",
363 | " 2 3 3 2 2 1 1 1 1 1 1 1 2 3 1 1 1 3 3 3 3 3 1 1 2 2 3 3 2 2 2 2 1 1 1 1 2\n",
364 | " 2 2 1 2 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1\n",
365 | " 1 2 2 1 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 3 3 3 3 3 3 3 3\n",
366 | " 0 3 3 3 3 3 3 3 3 3 3 0 3 0 3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 2 3 3 3 3 3 3 3\n",
367 | " 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 3 3 3 3 3 3 2 3 2 2 1 1 1 1 1 1 1 1\n",
368 | " 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n",
369 | " 1 1 1 1 1]\n",
370 | "\n",
371 | "K-means labels shape: (523,)\n"
372 | ]
373 | }
374 | ],
375 | "source": [
376 | "print(\"Training data shape: \" + str(data.shape))\n",
377 | "\n",
378 | "# Use int random_state in order to make centroid initialization deterministic\n",
379 | "kmeans = KMeans(n_clusters=4, random_state=1).fit(data)\n",
380 | "\n",
381 | "# Display classified labels\n",
382 | "print(\"\\nClassified labels: \" + str(kmeans.labels_))\n",
383 | "\n",
384 | "print(\"\\nK-means labels shape: \" + str(kmeans.labels_.shape))\n"
385 | ]
386 | },
387 | {
388 | "cell_type": "markdown",
389 | "metadata": {},
390 | "source": [
391 | "We plot the classified labels"
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": 100,
397 | "metadata": {},
398 | "outputs": [
399 | {
400 | "name": "stderr",
401 | "output_type": "stream",
402 | "text": [
403 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/proplot/ui.py:492: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
404 | " **kwargs\n"
405 | ]
406 | },
407 | {
408 | "data": {
409 | "application/vnd.jupyter.widget-view+json": {
410 | "model_id": "2012130aa8c54231807a0c92fddfb621",
411 | "version_major": 2,
412 | "version_minor": 0
413 | },
414 | "text/plain": [
415 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
416 | ]
417 | },
418 | "metadata": {},
419 | "output_type": "display_data"
420 | }
421 | ],
422 | "source": [
423 | "fig1, ax1 = plot.subplots(ncols=1, nrows=2, share=0, width=5, height=6)\n",
424 | "\n",
425 | "fig1.suptitle(\"Classified labels along transect\")\n",
426 | "\n",
427 | "ax1[0].set_ylabel('Histogram frequency')\n",
428 | "\n",
429 | "ax1.format(\n",
430 | " abc=True, abcloc='ul',\n",
431 | " ygridminor=True,\n",
432 | " ytickloc='both', yticklabelloc='left'\n",
433 | ")\n",
434 | "\n",
435 | "# Residual histograms\n",
436 | "ax1[0].imshow(np.transpose(data),vmin=0,vmax=30,cmap='inferno')\n",
437 | "ax1[0].colorbar(h)\n",
438 | "\n",
439 | "# Classified labels\n",
440 | "ax1[1].scatter(range(0,data.shape[0]), kmeans.labels_, c=kmeans.labels_, cmap='viridis')\n",
441 | "ax1[1].set_ylabel('Classification label')\n",
442 | "ax1[1].set_xlabel('Segments along track')\n",
443 | "plt.show()"
444 | ]
445 | },
446 | {
447 | "cell_type": "markdown",
448 | "metadata": {},
449 | "source": [
450 | "We display the labels on top of the raster map"
451 | ]
452 | },
453 | {
454 | "cell_type": "code",
455 | "execution_count": 109,
456 | "metadata": {},
457 | "outputs": [
458 | {
459 | "name": "stdout",
460 | "output_type": "stream",
461 | "text": [
462 | "[-70.56 -69.29 -69.29 -70.56 -70.56]\n",
463 | "[33.73 33.73 31.5 31.5 33.73]\n"
464 | ]
465 | },
466 | {
467 | "name": "stderr",
468 | "output_type": "stream",
469 | "text": [
470 | "/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:14: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
471 | " \n"
472 | ]
473 | },
474 | {
475 | "data": {
476 | "application/vnd.jupyter.widget-view+json": {
477 | "model_id": "43133013e344405eb337096ff52a22cf",
478 | "version_major": 2,
479 | "version_minor": 0
480 | },
481 | "text/plain": [
482 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
483 | ]
484 | },
485 | "metadata": {},
486 | "output_type": "display_data"
487 | },
488 | {
489 | "name": "stdout",
490 | "output_type": "stream",
491 | "text": [
492 | "{'cmap': 'gray', 'clim': [14000, 17000], 'extent': array([1114050., 1262050., 1773825., 1938825.]), 'origin': 'lower'}\n"
493 | ]
494 | },
495 | {
496 | "data": {
497 | "text/plain": [
498 | "Text(0.5, 1.0, 'Labeled transect')"
499 | ]
500 | },
501 | "execution_count": 109,
502 | "metadata": {},
503 | "output_type": "execute_result"
504 | }
505 | ],
506 | "source": [
507 | "spatial_extent = np.array(spatial_extent)\n",
508 | "lat=spatial_extent[[1, 3, 3, 1, 1]]\n",
509 | "lon=spatial_extent[[2, 2, 0, 0, 2]]\n",
510 | "print(lat)\n",
511 | "print(lon)\n",
512 | "# project the coordinates to Antarctic polar stereographic\n",
513 | "xy=np.array(pyproj.Proj(3031)(lon, lat))\n",
514 | "# get the bounds of the projected coordinates \n",
515 | "XR=[np.nanmin(xy[0,:]), np.nanmax(xy[0,:])]\n",
516 | "YR=[np.nanmin(xy[1,:]), np.nanmax(xy[1,:])]\n",
517 | "MOA=pc.grid.data().from_geotif(os.path.join(data_root, 'MOA','moa_2009_1km.tif'), bounds=[XR, YR])\n",
518 | "\n",
519 | "# show the mosaic:\n",
520 | "plt.figure()\n",
521 | "MOA.show(cmap='gray', clim=[14000, 17000])\n",
522 | "ax.stock_img()\n",
523 | "plt.plot(xy[0,:], xy[1,:])\n",
524 | "# This still needs to be fixed in order to properly display the transect on the map\n",
525 | "x_polar, y_polar=np.array(pyproj.Proj(3031)(lon_mean, lat_mean))\n",
526 | "plt.scatter(x_polar, y_polar, c=kmeans.labels_)\n",
527 | "plt.title('Labeled transect')"
528 | ]
529 | }
530 | ],
531 | "metadata": {
532 | "kernelspec": {
533 | "display_name": "Python 3",
534 | "language": "python",
535 | "name": "python3"
536 | },
537 | "language_info": {
538 | "codemirror_mode": {
539 | "name": "ipython",
540 | "version": 3
541 | },
542 | "file_extension": ".py",
543 | "mimetype": "text/x-python",
544 | "name": "python",
545 | "nbconvert_exporter": "python",
546 | "pygments_lexer": "ipython3",
547 | "version": "3.7.6"
548 | }
549 | },
550 | "nbformat": 4,
551 | "nbformat_minor": 4
552 | }
553 |
--------------------------------------------------------------------------------
/scripts/PlotPhotoHistograms.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 45,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from icepyx import icesat2data as ipd\n",
10 | "import numpy as np\n",
11 | "import os\n",
12 | "import shutil\n",
13 | "import h5py\n",
14 | "\n",
15 | "import matplotlib.pyplot as plt\n",
16 | "%matplotlib widget"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 3,
22 | "metadata": {},
23 | "outputs": [
24 | {
25 | "name": "stdin",
26 | "output_type": "stream",
27 | "text": [
28 | "Earthdata Login password: ········\n"
29 | ]
30 | }
31 | ],
32 | "source": [
33 | "short_name = 'ATL06'\n",
34 | "spatial_extent = [31.5, -70.56, 33.73, -69.29]\n",
35 | "date_range = ['2020-03-30','2020-04-1']\n",
36 | "region_a = ipd.Icesat2Data(short_name, spatial_extent, date_range)\n",
37 | "region_a.earthdata_login('therealbradlipovsky','brad_lipovsky@fas.harvard.edu')"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 19,
43 | "metadata": {
44 | "jupyter": {
45 | "source_hidden": true
46 | }
47 | },
48 | "outputs": [],
49 | "source": [
50 | "#region_a.order_vars.avail()"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 8,
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "region_a.order_vars.append(var_list=['count'])"
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": 9,
65 | "metadata": {},
66 | "outputs": [
67 | {
68 | "name": "stdout",
69 | "output_type": "stream",
70 | "text": [
71 | "Total number of data order requests is 1 for 1 granules.\n",
72 | "Data request 1 of 1 is submitting to NSIDC\n",
73 | "order ID: 5000000701069\n",
74 | "Initial status of your order request at NSIDC is: processing\n",
75 | "Your order status is still processing at NSIDC. Please continue waiting... this may take a few moments.\n",
76 | "Your order is: complete\n",
77 | "Beginning download of zipped output...\n",
78 | "Data request 5000000701069 of 1 order(s) is downloaded.\n",
79 | "Download complete\n"
80 | ]
81 | }
82 | ],
83 | "source": [
84 | "region_a.download_granules('/home/jovyan/data') "
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": 24,
90 | "metadata": {},
91 | "outputs": [],
92 | "source": [
93 | "\n",
94 | "FILE_NAME = 'data/processed_ATL06_20200330121520_00600712_003_01.h5'\n",
95 | "f = h5py.File(FILE_NAME, mode='r') \n",
96 | "\n",
97 | "count = f['gt1l/residual_histogram/count'] # has units of n_histograms, n_bins\n",
98 | "lat_mean = f['gt1l/residual_histogram/lat_mean']\n",
99 | "\n",
100 | "#latitude = f['/gt2r/heights/lat_ph']\n",
101 | "#longitude = f['/gt2r/heights/lon_ph']\n",
102 | "#height = f['gt2r/heights/h_ph']"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": 36,
108 | "metadata": {},
109 | "outputs": [],
110 | "source": [
111 | "data = np.transpose(np.array(count))"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": 56,
117 | "metadata": {},
118 | "outputs": [
119 | {
120 | "data": {
121 | "application/vnd.jupyter.widget-view+json": {
122 | "model_id": "10e03985839a4300998047ae87eb1560",
123 | "version_major": 2,
124 | "version_minor": 0
125 | },
126 | "text/plain": [
127 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
128 | ]
129 | },
130 | "metadata": {},
131 | "output_type": "display_data"
132 | }
133 | ],
134 | "source": [
135 | "\n",
136 | "fig=plt.figure(figsize=(10,8))\n",
137 | "ax = fig.add_subplot(111)\n",
138 | "h = ax.imshow(data,vmin=0,vmax=30,cmap='Reds')\n",
139 | "plt.colorbar(h)\n",
140 | "plt.show()"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": 35,
146 | "metadata": {},
147 | "outputs": [
148 | {
149 | "data": {
150 | "text/plain": [
151 | ""
152 | ]
153 | },
154 | "execution_count": 35,
155 | "metadata": {},
156 | "output_type": "execute_result"
157 | }
158 | ],
159 | "source": []
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "metadata": {},
165 | "outputs": [],
166 | "source": []
167 | }
168 | ],
169 | "metadata": {
170 | "kernelspec": {
171 | "display_name": "Python 3",
172 | "language": "python",
173 | "name": "python3"
174 | },
175 | "language_info": {
176 | "codemirror_mode": {
177 | "name": "ipython",
178 | "version": 3
179 | },
180 | "file_extension": ".py",
181 | "mimetype": "text/x-python",
182 | "name": "python",
183 | "nbconvert_exporter": "python",
184 | "pygments_lexer": "ipython3",
185 | "version": "3.7.6"
186 | }
187 | },
188 | "nbformat": 4,
189 | "nbformat_minor": 4
190 | }
191 |
--------------------------------------------------------------------------------
/scripts/Plotting_examples_file_location.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "A few examples of looking at location of interest and selected tracks
"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "load libraries"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": 1,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "from icepyx import icesat2data as ipd\n",
24 | "import numpy as np\n",
25 | "import os\n",
26 | "import shutil\n",
27 | "import h5py\n",
28 | "import cartopy.crs as ccrs\n",
29 | "import sys\n",
30 | "import matplotlib.pyplot as plt\n",
31 | "import pyproj\n",
32 | "%matplotlib widget"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "load file that has already been downloaded"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": 2,
45 | "metadata": {},
46 | "outputs": [],
47 | "source": [
48 | "\n",
49 | "FILE_NAME = '/home/jovyan/shared/data-showard/processed_ATL06_20200330121520_00600712_003_01.h5'\n",
50 | "f = h5py.File(FILE_NAME, mode='r') "
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {},
57 | "outputs": [
58 | {
59 | "name": "stdout",
60 | "output_type": "stream",
61 | "text": [
62 | "/ Group\n",
63 | "/METADATA Group\n"
64 | ]
65 | }
66 | ],
67 | "source": [
68 | "# Inspect file from the command line\n",
69 | "!h5ls -r /home/jovyan/shared/data-showard/processed_ATL06_20200330121520_00600712_003_01.h5"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "Pull out some variables to look at"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {},
83 | "outputs": [],
84 | "source": [
85 | "\n",
86 | "\n",
87 | "count = f['gt1l/residual_histogram/count'] # has units of n_histograms, n_bins\n",
88 | "lat_mean = f['gt1l/residual_histogram/lat_mean']\n",
89 | "lon_mean = f['gt1l/residual_histogram/lon_mean']\n",
90 | "h_li = f['gt1l/land_ice_segments/h_li']\n",
91 | "h_lat = f['gt1l/land_ice_segments/latitude']\n",
92 | "h_lon = f['gt1l/land_ice_segments/longitude']\n"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "Plot histogram count data usign method from PlotPhotoHistrograms.ipynb"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": null,
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "data = np.transpose(np.array(count))"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": null,
114 | "metadata": {},
115 | "outputs": [],
116 | "source": [
117 | "\n",
118 | "fig=plt.figure(figsize=(8,8))\n",
119 | "ax = fig.add_subplot(111)\n",
120 | "h = ax.imshow(data,vmin=0,vmax=30,cmap='Reds')\n",
121 | "plt.colorbar(h)\n",
122 | "plt.show()"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "Plot Search area on Moa image
"
130 | ]
131 | },
132 | {
133 | "cell_type": "markdown",
134 | "metadata": {},
135 | "source": [
136 | "** still needs track on this image"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": null,
142 | "metadata": {},
143 | "outputs": [],
144 | "source": [
145 | "data_root='/srv/tutorial-data/land_ice_applications/'"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {},
152 | "outputs": [],
153 | "source": [
154 | "! cd ..; [ -d pointCollection ] || git clone https://www.github.com/smithB/pointCollection.git\n",
155 | "sys.path.append(os.path.join(os.getcwd(), '..'))\n",
156 | "import pointCollection as pc"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "spatial_extent = np.array([25, -72.56, 40, -67])\n",
166 | "lat=spatial_extent[[1, 3, 3, 1, 1]]\n",
167 | "lon=spatial_extent[[2, 2, 0, 0, 2]]\n",
168 | "print(lat)\n",
169 | "print(lon)\n",
170 | "# project the coordinates to Antarctic polar stereographic\n",
171 | "xy=np.array(pyproj.Proj(3031)(lon, lat))\n",
172 | "# get the bounds of the projected coordinates \n",
173 | "XR=[np.nanmin(xy[0,:]), np.nanmax(xy[0,:])]\n",
174 | "YR=[np.nanmin(xy[1,:]), np.nanmax(xy[1,:])]\n",
175 | "MOA=pc.grid.data().from_geotif(os.path.join(data_root, 'MOA','moa_2009_1km.tif'), bounds=[XR, YR])\n",
176 | "\n",
177 | "# show the mosaic:\n",
178 | "plt.figure()\n",
179 | "MOA.show(cmap='gray', clim=[14000, 17000])\n",
180 | "plt.plot(xy[0,:], xy[1,:])\n",
181 | "plt.title(' Area used for search')"
182 | ]
183 | },
184 | {
185 | "cell_type": "markdown",
186 | "metadata": {},
187 | "source": [
188 | " A different way of plotting track on map"
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "metadata": {},
195 | "outputs": [],
196 | "source": [
197 | "\n",
198 | "\n",
199 | "## we will want to set colorbar parameters based on the chosen variable\n",
200 | "vmin=0\n",
201 | "vmax=6\n",
202 | "ticks=np.arange(vmin,vmax+1,1)\n",
203 | "\n",
204 | "plt.figure(figsize=(8,8), dpi= 90)\n",
205 | "ax = plt.axes(projection=ccrs.SouthPolarStereo(central_longitude=0)) # choose polar sterographic for projection\n",
206 | "ax.coastlines(resolution='50m', color='black', linewidth=1)\n",
207 | "ax.set_extent([25 , 40, -73, -67], ccrs.PlateCarree())\n",
208 | "plt.plot(lon_mean,lat_mean,transform=ccrs.PlateCarree())\n",
209 | "plt.show()\n"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "Plot comparing mean_lon and mean_lon from histrograms with beam lat and lon"
217 | ]
218 | },
219 | {
220 | "cell_type": "code",
221 | "execution_count": null,
222 | "metadata": {},
223 | "outputs": [],
224 | "source": [
225 | "plt.figure()\n",
226 | "plt.plot(h_lon,h_lat,'ob' )\n",
227 | "plt.plot(lon_mean, lat_mean,'.r')"
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "metadata": {},
234 | "outputs": [],
235 | "source": []
236 | }
237 | ],
238 | "metadata": {
239 | "kernelspec": {
240 | "display_name": "Python 3",
241 | "language": "python",
242 | "name": "python3"
243 | },
244 | "language_info": {
245 | "codemirror_mode": {
246 | "name": "ipython",
247 | "version": 3
248 | },
249 | "file_extension": ".py",
250 | "mimetype": "text/x-python",
251 | "name": "python",
252 | "nbconvert_exporter": "python",
253 | "pygments_lexer": "ipython3",
254 | "version": "3.7.6"
255 | }
256 | },
257 | "nbformat": 4,
258 | "nbformat_minor": 4
259 | }
260 |
--------------------------------------------------------------------------------
/scripts/get_hists.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | u"""
3 | get_hist.py
4 |
5 | Download user-requested histograms and save as numpy array.
6 | All strong beams are extracted and saved.
7 |
8 | History
9 | 06/16/2020 Written (Yara Mohajerani)
10 | """
11 | import os
12 | import sys
13 | import h5py
14 | import getopt
15 | import shutil
16 | import numpy as np
17 | from icepyx import icesat2data as ipd
18 |
19 | #-- help function
20 | def run_help():
21 | print("Commandline options:")
22 | print("Type '--HELP' or '-H' flag for help.")
23 | print("Type '--DIR=' or '-D:' flag to specify data directory.")
24 | print("Type '--EXTENT=' or '-E:' flag to specify data spatial extent.")
25 | print("Type '--DATE=' or '-T:' to specify data date range.")
26 | print("Type '--USER=' or '-U:' flag to specify EarthData username.")
27 | print("Type '--EMAIL=' or '-E:' flag to specify EarthData email.")
28 | print("Type '--noDownload' or '-N' flag to skip downloading data if it's already there.")
29 |
30 | #-- main function
31 | def main():
32 | #-- Read the system arguments listed after the program
33 | long_options=['HELP','DIR=','EXTENT=','DATE=','USER=','EMAIL=','noDownload']
34 | optlist,arglist = getopt.getopt(sys.argv[1:],'HD:E:T:U:E:N',long_options)
35 |
36 | #-- Set default settings
37 | ddir = '/home/jovyan/data'
38 | short_name = 'ATL06'
39 | spatial_extent = [31.5, -70.56, 33.73, -69.29]
40 | date_range = ['2020-03-30','2020-04-1']
41 | user = ''
42 | email = ''
43 | download = True
44 |
45 | #-- read commandline inputs
46 | for opt, arg in optlist:
47 | if opt in ("-H","--HELP"):
48 | run_help()
49 | sys.exit('Done.')
50 | elif opt in ("-D","--DIR"):
51 | ddir = os.path.expanduser(arg)
52 | elif opt in ("-E","--EXTENT"):
53 | spatial_extent = [float(i) for i in arg.replace('[','').replace(']','').split(',')]
54 | elif opt in ("-T","--DATE"):
55 | date_range = arg.replace('[','').replace(']','').replace("'","").split(',')
56 | elif opt in ("-U","--USER"):
57 | user = arg
58 | elif opt in ("-E","--EMAIL"):
59 | email = arg
60 | elif opt in ("N","--noDownload"):
61 | download = False
62 |
63 | if download:
64 | #-- login to earth data and get data
65 | region_a = ipd.Icesat2Data(short_name, spatial_extent, date_range)
66 | region_a.earthdata_login(user,email)
67 |
68 | #-- put data order
69 | region_a.order_vars.append(var_list=['count'])
70 | #-- download data
71 | region_a.download_granules(ddir)
72 |
73 | #-- Get list of files
74 | file_list = os.listdir(ddir)
75 | files = [f for f in file_list if f.endswith('.h5')]
76 |
77 | #-- Loop through files, read specified file, and save histogram as numpy array
78 | for f in files:
79 | print(f)
80 | #-- read specified file
81 | FILE_NAME = os.path.join(ddir,f)
82 | fid = h5py.File(FILE_NAME, mode='r')
83 |
84 | #-- determine which beam is the strong beam (left or right)
85 | if fid['gt1l'].attrs['atlas_beam_type'] == 'strong':
86 | strong_id = 'l'
87 | else:
88 | strong_id = 'r'
89 |
90 | #-- loop all three beam pairs and save all three
91 | for i in range(1,4):
92 | #-- read count
93 | count = fid['gt%i%s/residual_histogram/count'%(i,strong_id)][:]
94 | lat_mean = fid['gt%i%s/residual_histogram/lat_mean'%(i,strong_id)][:]
95 | lon_mean = fid['gt%i%s/residual_histogram/lon_mean'%(i,strong_id)][:]
96 | h_li = fid['gt%i%s/land_ice_segments/h_li'%(i,strong_id)][:]
97 | h_lat = fid['gt%i%s/land_ice_segments/latitude'%(i,strong_id)][:]
98 | h_lon = fid['gt%i%s/land_ice_segments/longitude'%(i,strong_id)][:]
99 |
100 | path_hist = os.path.join(ddir,'hist')
101 | if not os.path.exists(path_hist):
102 | os.makedirs(path_hist)
103 |
104 | path_lon = os.path.join(ddir,'lon')
105 | if not os.path.exists(path_lon):
106 | os.makedirs(path_lon)
107 |
108 | path_lat = os.path.join(ddir,'lat')
109 | if not os.path.exists(path_lat):
110 | os.makedirs(path_lat)
111 |
112 | #-- save numpy arrays
113 | np.save(os.path.join(path_hist, f.replace('.h5','_hist_gt%i%s.npy'%(i,strong_id))),count)
114 | np.save(os.path.join(path_lat,f.replace('.h5','_lat_mean_gt%i%s.npy'%(i,strong_id))),lat_mean)
115 | np.save(os.path.join(path_lon,f.replace('.h5','_lon_mean_gt%i%s.npy'%(i,strong_id))),lon_mean)
116 | np.save(os.path.join(ddir,f.replace('.h5','_h_li_gt%i%s.npy'%(i,strong_id))),h_li)
117 | np.save(os.path.join(ddir,f.replace('.h5','_h_lat_gt%i%s.npy'%(i,strong_id))),h_lat)
118 | np.save(os.path.join(ddir,f.replace('.h5','_h_lon_gt%i%s.npy'%(i,strong_id))),h_lon)
119 |
120 | #-- close hdf5 file
121 | fid.close()
122 |
123 | #-- run main program
124 | if __name__ == '__main__':
125 | main()
126 |
--------------------------------------------------------------------------------
/scripts/helper_tool.sh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICESAT-2HackWeek/surface_classification/4829efeb130a53e290e2c0db6cbb4fb602c66a88/scripts/helper_tool.sh
--------------------------------------------------------------------------------
/scripts/photon_plotting.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## ATL03 Open data and simple plot of pulse"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "This notebook is for pening data with hdf5 and simple visualisation of the photons per one pulse. Created for Unsupervised Surface Classification procject at Hackweek 2020"
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "**This file must be finished with plotting the correct variables, currently sigma_h is plotted**"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {},
27 | "source": [
28 | "List the downloaded data files and read in data from one of them."
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": 11,
34 | "metadata": {},
35 | "outputs": [],
36 | "source": [
37 | "import h5py\n",
38 | "import numpy as np\n",
39 | "from pathlib import Path\n",
40 | "import pyproj\n",
41 | "%matplotlib inline"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": 4,
47 | "metadata": {},
48 | "outputs": [],
49 | "source": [
50 | "#Here specify path to data \n",
51 | "data_home = Path('/home/jovyan/unsupervised_project/download/')"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": 5,
57 | "metadata": {},
58 | "outputs": [
59 | {
60 | "name": "stdout",
61 | "output_type": "stream",
62 | "text": [
63 | "[PosixPath('/home/jovyan/unsupervised_project/download/processed_ATL03_20190525195203_08790305_003_01.h5'), PosixPath('/home/jovyan/unsupervised_project/download/processed_ATL03_20190529194342_09400305_003_01.h5')]\n"
64 | ]
65 | }
66 | ],
67 | "source": [
68 | "files = list(data_home.glob('*.h5'))\n",
69 | "print(files) #list files in directory"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "To investigate the structure of the file we can vie the dictionary:"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": 6,
82 | "metadata": {
83 | "scrolled": true
84 | },
85 | "outputs": [
86 | {
87 | "name": "stdout",
88 | "output_type": "stream",
89 | "text": [
90 | "/ Group\n",
91 | "/METADATA Group\n",
92 | "/METADATA/AcquisitionInformation Group\n",
93 | "/METADATA/AcquisitionInformation/lidar Group\n",
94 | "/METADATA/AcquisitionInformation/lidarDocument Group\n",
95 | "/METADATA/AcquisitionInformation/platform Group\n",
96 | "/METADATA/AcquisitionInformation/platformDocument Group\n",
97 | "/METADATA/DataQuality Group\n",
98 | "/METADATA/DataQuality/CompletenessOmission Group\n",
99 | "/METADATA/DataQuality/DomainConsistency Group\n",
100 | "/METADATA/DatasetIdentification Group\n",
101 | "/METADATA/Extent Group\n",
102 | "/METADATA/Lineage Group\n",
103 | "/METADATA/Lineage/ANC01 Group\n",
104 | "/METADATA/Lineage/ANC03 Group\n",
105 | "/METADATA/Lineage/ANC04 Group\n",
106 | "/METADATA/Lineage/ANC05 Group\n",
107 | "/METADATA/Lineage/ANC06-01 Group\n",
108 | "/METADATA/Lineage/ANC06-02 Group\n",
109 | "/METADATA/Lineage/ANC06-03 Group\n",
110 | "/METADATA/Lineage/ANC07 Group\n",
111 | "/METADATA/Lineage/ANC08 Group\n",
112 | "/METADATA/Lineage/ANC11 Group\n",
113 | "/METADATA/Lineage/ANC12-01 Group\n",
114 | "/METADATA/Lineage/ANC12-02 Group\n",
115 | "/METADATA/Lineage/ANC19 Group\n",
116 | "/METADATA/Lineage/ANC22 Group\n",
117 | "/METADATA/Lineage/ANC23 Group\n",
118 | "/METADATA/Lineage/ANC25-03 Group\n",
119 | "/METADATA/Lineage/ANC26-03 Group\n",
120 | "/METADATA/Lineage/ANC28 Group\n",
121 | "/METADATA/Lineage/ANC29 Group\n",
122 | "/METADATA/Lineage/ANC36-03 Group\n",
123 | "/METADATA/Lineage/ANC38-03 Group\n",
124 | "/METADATA/Lineage/ANC41 Group\n",
125 | "/METADATA/Lineage/ATL02 Group\n",
126 | "/METADATA/Lineage/Control Group\n",
127 | "/METADATA/ProcessStep Group\n",
128 | "/METADATA/ProcessStep/Browse Group\n",
129 | "/METADATA/ProcessStep/Metadata Group\n",
130 | "/METADATA/ProcessStep/PGE Group\n",
131 | "/METADATA/ProcessStep/QA Group\n",
132 | "/METADATA/ProductSpecificationDocument Group\n",
133 | "/METADATA/QADatasetIdentification Group\n",
134 | "/METADATA/SeriesIdentification Group\n",
135 | "/ancillary_data Group\n",
136 | "/ancillary_data/atlas_sdp_gps_epoch Dataset {1}\n",
137 | "/ancillary_data/data_end_utc Dataset {1}\n",
138 | "/ancillary_data/data_start_utc Dataset {1}\n",
139 | "/ancillary_data/end_delta_time Dataset {1}\n",
140 | "/ancillary_data/granule_end_utc Dataset {1}\n",
141 | "/ancillary_data/granule_start_utc Dataset {1}\n",
142 | "/ancillary_data/start_delta_time Dataset {1}\n",
143 | "/gt1l Group\n",
144 | "/gt1l/geolocation Group\n",
145 | "/gt1l/geolocation/sigma_h Dataset {3294/Inf}\n",
146 | "/gt1l/geolocation/sigma_lat Dataset {3294/Inf}\n",
147 | "/gt1l/geolocation/sigma_lon Dataset {3294/Inf}\n",
148 | "/gt1l/geolocation/surf_type Dataset {3294/Inf, 5}\n",
149 | "/gt1r Group\n",
150 | "/gt1r/geolocation Group\n",
151 | "/gt1r/geolocation/sigma_h Dataset {3322/Inf}\n",
152 | "/gt1r/geolocation/sigma_lat Dataset {3322/Inf}\n",
153 | "/gt1r/geolocation/sigma_lon Dataset {3322/Inf}\n",
154 | "/gt1r/geolocation/surf_type Dataset {3322/Inf, 5}\n",
155 | "/gt2l Group\n",
156 | "/gt2l/geolocation Group\n",
157 | "/gt2l/geolocation/sigma_h Dataset {4305/Inf}\n",
158 | "/gt2l/geolocation/sigma_lat Dataset {4305/Inf}\n",
159 | "/gt2l/geolocation/sigma_lon Dataset {4305/Inf}\n",
160 | "/gt2l/geolocation/surf_type Dataset {4305/Inf, 5}\n",
161 | "/gt2r Group\n",
162 | "/gt2r/geolocation Group\n",
163 | "/gt2r/geolocation/sigma_h Dataset {4332/Inf}\n",
164 | "/gt2r/geolocation/sigma_lat Dataset {4332/Inf}\n",
165 | "/gt2r/geolocation/sigma_lon Dataset {4332/Inf}\n",
166 | "/gt2r/geolocation/surf_type Dataset {4332/Inf, 5}\n",
167 | "/gt3l Group\n",
168 | "/gt3l/geolocation Group\n",
169 | "/gt3l/geolocation/sigma_h Dataset {5316/Inf}\n",
170 | "/gt3l/geolocation/sigma_lat Dataset {5316/Inf}\n",
171 | "/gt3l/geolocation/sigma_lon Dataset {5316/Inf}\n",
172 | "/gt3l/geolocation/surf_type Dataset {5316/Inf, 5}\n",
173 | "/gt3r Group\n",
174 | "/gt3r/geolocation Group\n",
175 | "/gt3r/geolocation/sigma_h Dataset {5345/Inf}\n",
176 | "/gt3r/geolocation/sigma_lat Dataset {5345/Inf}\n",
177 | "/gt3r/geolocation/sigma_lon Dataset {5345/Inf}\n",
178 | "/gt3r/geolocation/surf_type Dataset {5345/Inf, 5}\n",
179 | "/orbit_info Group\n",
180 | "/orbit_info/sc_orient Dataset {1/Inf}\n",
181 | "/orbit_info/sc_orient_time Dataset {1/Inf}\n"
182 | ]
183 | }
184 | ],
185 | "source": [
186 | "!h5ls -r {files[0]} "
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "Create a reader to read in the data, extract variables and save them per track in seperate files:"
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": 7,
199 | "metadata": {},
200 | "outputs": [],
201 | "source": [
202 | "def transform_coord(proj1, proj2, x, y):\n",
203 | " \"\"\"Transform coordinates from proj1 to proj2 (EPSG num).\n",
204 | "\n",
205 | " Example EPSG projections:\n",
206 | " Geodetic (lon/lat): 4326\n",
207 | " Polar Stereo AnIS (x/y): 3031\n",
208 | " Polar Stereo GrIS (x/y): 3413\n",
209 | " \"\"\"\n",
210 | " # Set full EPSG projection strings\n",
211 | " proj1 = pyproj.Proj(\"+init=EPSG:\"+str(proj1))\n",
212 | " proj2 = pyproj.Proj(\"+init=EPSG:\"+str(proj2))\n",
213 | " return pyproj.transform(proj1, proj2, x, y) # convert\n",
214 | "\n",
215 | "\n",
216 | "\n",
217 | "def read_atl03(fname, outdir='data'):\n",
218 | " \"\"\"Read one ATL03 file and output 6 reduced files. \n",
219 | " \n",
220 | " Extract variables of interest and separate the ATL03 file \n",
221 | " into each beam (ground track) and ascending/descending orbits.\n",
222 | " \"\"\"\n",
223 | "\n",
224 | " # Each beam is a group\n",
225 | " group = ['/gt1l', '/gt1r', '/gt2l', '/gt2r', '/gt3l', '/gt3r']\n",
226 | "\n",
227 | " # Loop trough beams\n",
228 | " for k, g in enumerate(group):\n",
229 | " \n",
230 | " #-----------------------------------#\n",
231 | " # Read in data for a single beam #\n",
232 | " #-----------------------------------#\n",
233 | " \n",
234 | " data = {}\n",
235 | " \n",
236 | " try:\n",
237 | " # Load vars into memory (include as many as you want)\n",
238 | " with h5py.File(fname, 'r') as fi:\n",
239 | " \n",
240 | " data['lat'] = fi[g+'/geolocation/sigma_lat'][:]\n",
241 | " data['lon'] = fi[g+'/geolocation/sigma_lon'][:]\n",
242 | " data['height'] = fi[g+'/geolocation/sigma_h'][:]\n",
243 | " data['surf_type'] = fi[g+'/geolocation/surf_type'][:]\n",
244 | "\n",
245 | " \n",
246 | " \n",
247 | " except:\n",
248 | " print('skeeping group:', g)\n",
249 | " print('in file:', fname)\n",
250 | " continue\n",
251 | " \n",
252 | " #-----------------------#\n",
253 | " # Convert Coordinates #\n",
254 | " #-----------------------#\n",
255 | " \n",
256 | " # Geodetic lon/lat -> Polar Stereo x/y\n",
257 | " x, y = transform_coord(4326, 3031, data['lon'], data['lat'])\n",
258 | " \n",
259 | " data['x'] = x\n",
260 | " data['y'] = y\n",
261 | " \n",
262 | " \n",
263 | " #-----------------------#\n",
264 | " # Save selected data #\n",
265 | " #-----------------------#\n",
266 | " \n",
267 | " # Define output dir and file\n",
268 | " outdir = Path(outdir) \n",
269 | " fname = Path(fname)\n",
270 | " outdir.mkdir(exist_ok=True)\n",
271 | " outfile = outdir / fname.name.replace('.h5', '_' + g[1:] + '.h5')\n",
272 | " \n",
273 | " # Save variables\n",
274 | " with h5py.File(outfile, 'w') as fo:\n",
275 | " for k, v in data.items(): fo[k] = v\n",
276 | " print('out ->', outfile)\n",
277 | " \n",
278 | " \n",
279 | " "
280 | ]
281 | },
282 | {
283 | "cell_type": "code",
284 | "execution_count": 8,
285 | "metadata": {},
286 | "outputs": [],
287 | "source": [
288 | "#Here specify outdir \n",
289 | "outdir = Path('/home/jovyan/unsupervised_project/data/')\n",
290 | "\n",
291 | "outdir.mkdir(exist_ok=True)"
292 | ]
293 | },
294 | {
295 | "cell_type": "markdown",
296 | "metadata": {},
297 | "source": [
298 | "Run the reader:"
299 | ]
300 | },
301 | {
302 | "cell_type": "code",
303 | "execution_count": 12,
304 | "metadata": {},
305 | "outputs": [
306 | {
307 | "name": "stdout",
308 | "output_type": "stream",
309 | "text": [
310 | "running in parallel (8 jobs) ...\n"
311 | ]
312 | },
313 | {
314 | "name": "stderr",
315 | "output_type": "stream",
316 | "text": [
317 | "[Parallel(n_jobs=8)]: Using backend LokyBackend with 8 concurrent workers.\n",
318 | "[Parallel(n_jobs=8)]: Done 2 out of 2 | elapsed: 1.7s remaining: 0.0s\n",
319 | "[Parallel(n_jobs=8)]: Done 2 out of 2 | elapsed: 1.7s finished\n"
320 | ]
321 | }
322 | ],
323 | "source": [
324 | "njobs = 8\n",
325 | "\n",
326 | "if njobs == 1:\n",
327 | " print('running in serial ...')\n",
328 | " [read_atl03(f, outdir) for f in files]\n",
329 | "\n",
330 | "else:\n",
331 | " print('running in parallel (%d jobs) ...' % njobs)\n",
332 | " from joblib import Parallel, delayed\n",
333 | " Parallel(n_jobs=njobs, verbose=5)(delayed(read_atl03)(f, outdir) for f in files)\n",
334 | "\n"
335 | ]
336 | },
337 | {
338 | "cell_type": "markdown",
339 | "metadata": {},
340 | "source": [
341 | "Checking created files:"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": 13,
347 | "metadata": {},
348 | "outputs": [
349 | {
350 | "name": "stdout",
351 | "output_type": "stream",
352 | "text": [
353 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190525195203_08790305_003_01_gt2r.h5\n",
354 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190529194342_09400305_003_01_gt2r.h5\n",
355 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190525195203_08790305_003_01_gt2l.h5\n",
356 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190529194342_09400305_003_01_gt2l.h5\n",
357 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190525195203_08790305_003_01_gt3r.h5\n",
358 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190525195203_08790305_003_01_gt1l.h5\n",
359 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190529194342_09400305_003_01_gt1l.h5\n",
360 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190529194342_09400305_003_01_gt3r.h5\n",
361 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190525195203_08790305_003_01_gt3l.h5\n",
362 | "/home/jovyan/unsupervised_project/data/processed_ATL03_20190529194342_09400305_003_01_gt1r.h5\n",
363 | "Total number of files: 12\n"
364 | ]
365 | }
366 | ],
367 | "source": [
368 | "#outfiles = !ls {outdir}/*.h5\n",
369 | "outfiles = list(outdir.glob('*.h5'))\n",
370 | "\n",
371 | "for f in outfiles[:10]: print(f)\n",
372 | "print('Total number of files:', len(outfiles))"
373 | ]
374 | },
375 | {
376 | "cell_type": "markdown",
377 | "metadata": {},
378 | "source": [
379 | "Let's check if the expected variables are in the file, and how many measurements we have."
380 | ]
381 | },
382 | {
383 | "cell_type": "code",
384 | "execution_count": 14,
385 | "metadata": {},
386 | "outputs": [
387 | {
388 | "name": "stdout",
389 | "output_type": "stream",
390 | "text": [
391 | "/ Group\n",
392 | "/height Dataset {4332}\n",
393 | "/lat Dataset {4332}\n",
394 | "/lon Dataset {4332}\n",
395 | "/surf_type Dataset {4332, 5}\n",
396 | "/x Dataset {4332}\n",
397 | "/y Dataset {4332}\n"
398 | ]
399 | }
400 | ],
401 | "source": [
402 | "!h5ls -r {outfiles[0]}"
403 | ]
404 | },
405 | {
406 | "cell_type": "markdown",
407 | "metadata": {},
408 | "source": [
409 | "## Reading one of the files and plotting sigma"
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": 61,
415 | "metadata": {},
416 | "outputs": [],
417 | "source": [
418 | "def read_atl03_track(fname):\n",
419 | " \n",
420 | " import pandas as pd\n",
421 | " data = pd.DataFrame()\n",
422 | " \n",
423 | " with h5py.File(fname, 'r') as fi:\n",
424 | " \n",
425 | " data['x'] = fi['x'][:]\n",
426 | " data['y'] = fi['y'][:]\n",
427 | " data['height'] = fi['height'][:]\n",
428 | " return data"
429 | ]
430 | },
431 | {
432 | "cell_type": "code",
433 | "execution_count": 62,
434 | "metadata": {},
435 | "outputs": [
436 | {
437 | "name": "stdout",
438 | "output_type": "stream",
439 | "text": [
440 | " x y height\n",
441 | "0 25.122796 1.236743e+07 0.3\n",
442 | "1 25.128029 1.236743e+07 0.3\n",
443 | "2 25.133261 1.236743e+07 0.3\n",
444 | "3 25.138490 1.236743e+07 0.3\n",
445 | "4 25.143719 1.236743e+07 0.3\n",
446 | "... ... ... ...\n",
447 | "4327 38.687569 1.236743e+07 0.3\n",
448 | "4328 38.688267 1.236743e+07 0.3\n",
449 | "4329 38.688967 1.236743e+07 0.3\n",
450 | "4330 38.689690 1.236743e+07 0.3\n",
451 | "4331 38.690387 1.236743e+07 0.3\n",
452 | "\n",
453 | "[4332 rows x 3 columns]\n"
454 | ]
455 | }
456 | ],
457 | "source": [
458 | "import pandas as pd\n",
459 | "\n",
460 | "file = list(outdir.glob('*.h5'))[0]\n",
461 | "\n",
462 | "data = read_atl03_track(file)\n",
463 | "\n",
464 | "print(data)"
465 | ]
466 | },
467 | {
468 | "cell_type": "markdown",
469 | "metadata": {},
470 | "source": [
471 | "Plotting the data:"
472 | ]
473 | },
474 | {
475 | "cell_type": "code",
476 | "execution_count": 63,
477 | "metadata": {},
478 | "outputs": [
479 | {
480 | "data": {
481 | "text/plain": [
482 | ""
483 | ]
484 | },
485 | "execution_count": 63,
486 | "metadata": {},
487 | "output_type": "execute_result"
488 | },
489 | {
490 | "data": {
491 | "image/png": "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\n",
492 | "text/plain": [
493 | ""
494 | ]
495 | },
496 | "metadata": {
497 | "needs_background": "light"
498 | },
499 | "output_type": "display_data"
500 | }
501 | ],
502 | "source": [
503 | "data.plot(x='x', y='y', kind='scatter', c='height', s=1, cmap='inferno')"
504 | ]
505 | },
506 | {
507 | "cell_type": "markdown",
508 | "metadata": {},
509 | "source": [
510 | "clearly I have downloaded the wrong parameter here, instead of the photon point cloud I have height"
511 | ]
512 | },
513 | {
514 | "cell_type": "code",
515 | "execution_count": null,
516 | "metadata": {},
517 | "outputs": [],
518 | "source": []
519 | }
520 | ],
521 | "metadata": {
522 | "kernelspec": {
523 | "display_name": "Python 3",
524 | "language": "python",
525 | "name": "python3"
526 | },
527 | "language_info": {
528 | "codemirror_mode": {
529 | "name": "ipython",
530 | "version": 3
531 | },
532 | "file_extension": ".py",
533 | "mimetype": "text/x-python",
534 | "name": "python",
535 | "nbconvert_exporter": "python",
536 | "pygments_lexer": "ipython3",
537 | "version": "3.7.6"
538 | }
539 | },
540 | "nbformat": 4,
541 | "nbformat_minor": 4
542 | }
543 |
--------------------------------------------------------------------------------