├── .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 | --------------------------------------------------------------------------------