From cdd9f7bfca95740295d724cd61c0ca122b86b90a Mon Sep 17 00:00:00 2001 From: sarahwilson523 Date: Fri, 22 May 2026 16:27:03 -0600 Subject: [PATCH 1/7] scaffolding and output updates --- tutorials/fundamentals/3_authorization.ipynb | 10 ++- tutorials/fundamentals/4_seismic_data.ipynb | 66 +++++++++++++------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/tutorials/fundamentals/3_authorization.ipynb b/tutorials/fundamentals/3_authorization.ipynb index 986056d..f1524cf 100644 --- a/tutorials/fundamentals/3_authorization.ipynb +++ b/tutorials/fundamentals/3_authorization.ipynb @@ -7,11 +7,15 @@ "source": [ "# Getting a Token to Access EarthScope Services\n", "\n", - "EarthScope currently offers data through web services and, in the future, direct access to seismic and geodetic data in the cloud. In this module, we'll learn how to request an authorization token for downloading or accessing data from EarthScope.\n", + "The NSF National Geophysical Facility currently offers data through web services and, in the future, direct access to seismic and geodetic data in the cloud. In this module, we'll learn how to request an authorization token for downloading or accessing data directly from EarthScope. \n", + "\n", + "```{note}\n", + "An access token is not required to access data using obspy.\n", + "```\n", "\n", "## Getting an EarthScope Token\n", "\n", - "EarthScope's funders require tracking data usage. To this end, EarthScope issues a token to access resources. Tokens are tied to your EarthScope account (which you used to log into GeoLab). Tokens are generated using either the EarthScope SDK (Software Development Kit) or CLI (Command Line Interface). Both packages are installed in GeoLab. The simplest way to generate a token is to use the EarthScope CLI. Copy and paste `es login` into a terminal, then follow the instructions to get a token.\n", + "The NSF requires EarthScope tracking data usage. To this end, EarthScope issues a token to access resources. Tokens are tied to your EarthScope account (which you used to log into GeoLab). Tokens are generated using either the EarthScope SDK (Software Development Kit) or CLI (Command Line Interface). Both packages are installed in GeoLab. The simplest way to generate a token is to use the EarthScope CLI. **Copy and paste `es login` into a terminal, then open the link to get a token.**\n", "\n", "```bash\n", "es login\n", @@ -121,7 +125,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.5" + "version": "3.12.5" } }, "nbformat": 4, diff --git a/tutorials/fundamentals/4_seismic_data.ipynb b/tutorials/fundamentals/4_seismic_data.ipynb index 443f18b..820f841 100644 --- a/tutorials/fundamentals/4_seismic_data.ipynb +++ b/tutorials/fundamentals/4_seismic_data.ipynb @@ -15,7 +15,7 @@ "source": [ "This section details how to get seismic data from EarthScope. This section requires a working knowledge of Python. You should have an understanding of data types and string formatting, creating file paths and file naming, web requests, and creating Python functions. In addition to Python, you should have an understanding of miniSEED data distributed through the International Federation of Digital Seismograph Networks (FDSN). \n", "\n", - "The notebook material is informational and is useful for completing the seismic and geodetic exercises." + "**This notebook assumes you have already run the `es login` command to obtain an access token.** You can learn more about the login flow and authentication tokens in the authorization notebook." ] }, { @@ -25,15 +25,18 @@ "source": [ "## Getting Seismic Data from EarthScope\n", "\n", - "Seismic data is available through third party packages such as [obspy](https://docs.obspy.org/) or through EarthScope's `dataselect` web service.\n", - "\n", - "![](images/Web_Services_Data_Flow.png)\n", + "Seismic data is available through EarthScope's `dataselect` web service, or through third party packages such as [`obspy`](https://docs.obspy.org/) (which use dataselect under the hood).\n", "\n", "Currently, the simplest way to access EarthScope's seismic data is to use a third party package such as obspy. If you want to work directly with miniSEED files, EarthScope's dataselect service supports selecting sorting event data and returns data in the miniSEED format. \n", "\n", - "![](images/cloud_native_data_access.png)\n", + "```{note}\n", + "Because GeoLab runs in the same AWS region as the data is stored in, `dataselect` routes the data to GeoLab without any egress from the cloud. You can follow these same instructions to run `dataselect` and `obspy` on your local machine, but they are _significantly faster_ when run on cloud resources in AWS US-east-2, such as GeoLab. \n", + "```\n", + "\n", + "At the end of this notebook, we also provide an overview of how data is stored in AWS S3 and an example of how to access data from a public S3 bucket. The NSF NGF does not currently have data available in this format, but many other data providers do (e.g., [NCEDC](https://ncedc.org/) and [SCEDC](https://scedc.caltech.edu/). The NSF NGF plans to offer public S3 bucket access in the future and will update this tutorial and our documentation when it is available. \n", "\n", - "In the future, data will be available from EarthScopes cloud services hosted in Amazon's S3 storage service. We provide an overview of how data is stored in S3 and an example of how to access data from a public S3 bucket. " + "Until NSF NGF data is available in public buckets, it can be accessed directly from EarthScope's AWS S3 storage service. This advanced approach is not covered in this tutorial, but you can learn more about the S3 direct access program by visiting the [SDK docs](https://docs.earthscope.org/sdk/s3-direct-access-tutorial).\n", + "\n" ] }, { @@ -45,27 +48,36 @@ "\n", "Obspy is a Python framework (or package) for processing seismic data. It provides parsers for common file formats, clients to access data centers and seismological signal processing routines which allow the manipulation of seismological time series.\n", "\n", - "We'll start by importing modules from the obspy package. It's not necessary to import the entire package, just the function from the module, e.g., obspy.clients.fdsn. Next we create a client that connects to EarthScope's services and send a query based on start and end time, and the minimum magnitude of an event.\n", + "We'll start by importing modules from the obspy package. It's not necessary to import the entire package, just the function from the module, e.g., obspy.clients.fdsn. Next we create a client that connects to EarthScope's services and send a query based on start and end time, and the minimum magnitude of an event. The data is returned in a catalog, which is a list-like container for events. \n", "\n", - "```python\n", + "An example of instantiating a client and retrieving data is below. To learn more about working with `obspy`, see the documentation and tutorials on their [web site].(https://docs.obspy.org/) \n", + "\n", + "Note, a token is not required to access data using obspy. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b317fb6-f98e-4ce3-b8f5-38a4ef89d88a", + "metadata": {}, + "outputs": [], + "source": [ "from obspy.clients.fdsn import Client\n", "from obspy.clients.fdsn.header import URL_MAPPINGS\n", "from obspy import UTCDateTime\n", "import warnings\n", - "import cartopy\n", "\n", "warnings.filterwarnings('ignore')\n", "warnings.simplefilter('ignore')\n", "\n", - "# creates a client that connects to the IRIS data center\n", + "# creates a client that connects to the IRIS (NGF) data center\n", "client = Client(\"IRIS\")\n", "\n", "starttime = UTCDateTime(\"2020-01-01\")\n", "endtime = UTCDateTime(\"2025-12-31\")\n", "catalog = client.get_events(starttime=starttime, endtime=endtime, minmagnitude=7)\n", - "```\n", "\n", - "The data is returned in a catalog, which is a list-like container for events. To learn more about working with obspy, see the documentation and tutorials on the obspy [web site](chttps://docs.obspy.org/) " + "print(catalog)" ] }, { @@ -93,7 +105,9 @@ "\n", "To download a file, we can use the `requests` package to send the HTTP request to the dataselect web service. As discussed in the previous section, the request must include an authorization token using the `get_token` function.\n", "\n", - "The `download_data` function requires the query parameters required by the FDSN Web Service specification, and where to write the data. The function does several things. First, it requests an authorization token. Next, it creates a file name for the data. Finally, it sends the request to dataselect and writes the data to a file in a directory." + "The `download_data` function requires the query parameters required by the FDSN Web Service specification, and where to write the data. The function does several things. First, it requests an authorization token. Next, it creates a file name for the data. Finally, it sends the request to dataselect and writes the data to a file in a directory.\n", + "\n", + "**Note, you'll need an authentication token to successfully run the cell below. See the Authorization Notebook for instructions.**" ] }, { @@ -108,7 +122,7 @@ "from datetime import datetime\n", "from earthscope_sdk import EarthScopeClient\n", "\n", - "# SAGE archive\n", + "# NSF NGF Seismic Archive\n", "URL = \"http://service.iris.edu/fdsnws/dataselect/1/query?\"\n", "\n", "# function to get authorization token \n", @@ -165,6 +179,14 @@ "download_data(params, data_directory)\n" ] }, + { + "cell_type": "markdown", + "id": "00592210-5c7f-413e-adef-5f2370a010b8", + "metadata": {}, + "source": [ + "The function above will copy data into a location specified by the variable `data_directory`. Check in your filetree: you should have a new directory called `miniseed_data` with one `.mseed` file in it. " + ] + }, { "cell_type": "markdown", "id": "729eab32", @@ -182,13 +204,13 @@ "\n", "> s3:ncedc-pds/continuous_waveforms/BK/2022/2022.231/MERC.BK.HNZ.00.D.2022.231\n", "\n", - "- s3 - service name\n", - "- ncedc-pds - bucket name\n", - "- continuous_waveforms - prefix\n", - "- BK - (prefix) seismic network name \n", - "- 2022 - (prefix) year \n", - "- 2022.231 - (prefix) year and day of year\n", - "- MERC.BK.HNZ.00.D.2022.231 - (key) station.network.channel.location.year.day of year\n", + "- `s3` - service name\n", + "- `ncedc-pds` - bucket name\n", + "- `continuous_waveforms` - prefix\n", + "- `BK` - (prefix) seismic network name \n", + "- `2022` - (prefix) year \n", + "- `2022.231` - (prefix) year and day of year\n", + "- `MERC.BK.HNZ.00.D.2022.231` - (key) station.network.channel.location.year.day of year\n", "\n", "Similar to a web service file URL, the ARN is used to request data." ] @@ -273,7 +295,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.5" + "version": "3.12.12" } }, "nbformat": 4, From 2c062206125da2ebdefbfb3286a84cf51217c094 Mon Sep 17 00:00:00 2001 From: sarahwilson523 Date: Wed, 27 May 2026 11:21:16 -0600 Subject: [PATCH 2/7] rename fundamentals -> foundations --- .../0_project_overview.ipynb | 0 .../{fundamentals => foundations}/1_git_intro.ipynb | 0 .../2_package_management.ipynb | 0 .../3_authorization.ipynb | 0 .../4_seismic_data.ipynb | 0 .../5_seismic_exercise.ipynb | 0 .../6_geodetic_data.ipynb | 0 .../7_geodetic_exercise.ipynb | 0 .../{fundamentals => foundations}/8_wrap_up.ipynb | 0 .../images/Web_Services_Data_Flow.png | Bin .../images/cloud_native_data_access.png | Bin .../images/github_push.png | Bin .../{fundamentals => foundations}/images/login.png | Bin .../images/menubar.png | Bin .../images/project_work_flow.png | Bin .../images/toolbar.png | Bin .../images/workspace.png | Bin .../questions/authorization.json | 0 .../questions/branches.json | 0 .../questions/create_clone.json | 0 .../questions/push_pull.json | 0 .../questions/working_with_files.json | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename tutorials/{fundamentals => foundations}/0_project_overview.ipynb (100%) rename tutorials/{fundamentals => foundations}/1_git_intro.ipynb (100%) rename tutorials/{fundamentals => foundations}/2_package_management.ipynb (100%) rename tutorials/{fundamentals => foundations}/3_authorization.ipynb (100%) rename tutorials/{fundamentals => foundations}/4_seismic_data.ipynb (100%) rename tutorials/{fundamentals => foundations}/5_seismic_exercise.ipynb (100%) rename tutorials/{fundamentals => foundations}/6_geodetic_data.ipynb (100%) rename tutorials/{fundamentals => foundations}/7_geodetic_exercise.ipynb (100%) rename tutorials/{fundamentals => foundations}/8_wrap_up.ipynb (100%) rename tutorials/{fundamentals => foundations}/images/Web_Services_Data_Flow.png (100%) rename tutorials/{fundamentals => foundations}/images/cloud_native_data_access.png (100%) rename tutorials/{fundamentals => foundations}/images/github_push.png (100%) rename tutorials/{fundamentals => foundations}/images/login.png (100%) rename tutorials/{fundamentals => foundations}/images/menubar.png (100%) rename tutorials/{fundamentals => foundations}/images/project_work_flow.png (100%) rename tutorials/{fundamentals => foundations}/images/toolbar.png (100%) rename tutorials/{fundamentals => foundations}/images/workspace.png (100%) rename tutorials/{fundamentals => foundations}/questions/authorization.json (100%) rename tutorials/{fundamentals => foundations}/questions/branches.json (100%) rename tutorials/{fundamentals => foundations}/questions/create_clone.json (100%) rename tutorials/{fundamentals => foundations}/questions/push_pull.json (100%) rename tutorials/{fundamentals => foundations}/questions/working_with_files.json (100%) diff --git a/tutorials/fundamentals/0_project_overview.ipynb b/tutorials/foundations/0_project_overview.ipynb similarity index 100% rename from tutorials/fundamentals/0_project_overview.ipynb rename to tutorials/foundations/0_project_overview.ipynb diff --git a/tutorials/fundamentals/1_git_intro.ipynb b/tutorials/foundations/1_git_intro.ipynb similarity index 100% rename from tutorials/fundamentals/1_git_intro.ipynb rename to tutorials/foundations/1_git_intro.ipynb diff --git a/tutorials/fundamentals/2_package_management.ipynb b/tutorials/foundations/2_package_management.ipynb similarity index 100% rename from tutorials/fundamentals/2_package_management.ipynb rename to tutorials/foundations/2_package_management.ipynb diff --git a/tutorials/fundamentals/3_authorization.ipynb b/tutorials/foundations/3_authorization.ipynb similarity index 100% rename from tutorials/fundamentals/3_authorization.ipynb rename to tutorials/foundations/3_authorization.ipynb diff --git a/tutorials/fundamentals/4_seismic_data.ipynb b/tutorials/foundations/4_seismic_data.ipynb similarity index 100% rename from tutorials/fundamentals/4_seismic_data.ipynb rename to tutorials/foundations/4_seismic_data.ipynb diff --git a/tutorials/fundamentals/5_seismic_exercise.ipynb b/tutorials/foundations/5_seismic_exercise.ipynb similarity index 100% rename from tutorials/fundamentals/5_seismic_exercise.ipynb rename to tutorials/foundations/5_seismic_exercise.ipynb diff --git a/tutorials/fundamentals/6_geodetic_data.ipynb b/tutorials/foundations/6_geodetic_data.ipynb similarity index 100% rename from tutorials/fundamentals/6_geodetic_data.ipynb rename to tutorials/foundations/6_geodetic_data.ipynb diff --git a/tutorials/fundamentals/7_geodetic_exercise.ipynb b/tutorials/foundations/7_geodetic_exercise.ipynb similarity index 100% rename from tutorials/fundamentals/7_geodetic_exercise.ipynb rename to tutorials/foundations/7_geodetic_exercise.ipynb diff --git a/tutorials/fundamentals/8_wrap_up.ipynb b/tutorials/foundations/8_wrap_up.ipynb similarity index 100% rename from tutorials/fundamentals/8_wrap_up.ipynb rename to tutorials/foundations/8_wrap_up.ipynb diff --git a/tutorials/fundamentals/images/Web_Services_Data_Flow.png b/tutorials/foundations/images/Web_Services_Data_Flow.png similarity index 100% rename from tutorials/fundamentals/images/Web_Services_Data_Flow.png rename to tutorials/foundations/images/Web_Services_Data_Flow.png diff --git a/tutorials/fundamentals/images/cloud_native_data_access.png b/tutorials/foundations/images/cloud_native_data_access.png similarity index 100% rename from tutorials/fundamentals/images/cloud_native_data_access.png rename to tutorials/foundations/images/cloud_native_data_access.png diff --git a/tutorials/fundamentals/images/github_push.png b/tutorials/foundations/images/github_push.png similarity index 100% rename from tutorials/fundamentals/images/github_push.png rename to tutorials/foundations/images/github_push.png diff --git a/tutorials/fundamentals/images/login.png b/tutorials/foundations/images/login.png similarity index 100% rename from tutorials/fundamentals/images/login.png rename to tutorials/foundations/images/login.png diff --git a/tutorials/fundamentals/images/menubar.png b/tutorials/foundations/images/menubar.png similarity index 100% rename from tutorials/fundamentals/images/menubar.png rename to tutorials/foundations/images/menubar.png diff --git a/tutorials/fundamentals/images/project_work_flow.png b/tutorials/foundations/images/project_work_flow.png similarity index 100% rename from tutorials/fundamentals/images/project_work_flow.png rename to tutorials/foundations/images/project_work_flow.png diff --git a/tutorials/fundamentals/images/toolbar.png b/tutorials/foundations/images/toolbar.png similarity index 100% rename from tutorials/fundamentals/images/toolbar.png rename to tutorials/foundations/images/toolbar.png diff --git a/tutorials/fundamentals/images/workspace.png b/tutorials/foundations/images/workspace.png similarity index 100% rename from tutorials/fundamentals/images/workspace.png rename to tutorials/foundations/images/workspace.png diff --git a/tutorials/fundamentals/questions/authorization.json b/tutorials/foundations/questions/authorization.json similarity index 100% rename from tutorials/fundamentals/questions/authorization.json rename to tutorials/foundations/questions/authorization.json diff --git a/tutorials/fundamentals/questions/branches.json b/tutorials/foundations/questions/branches.json similarity index 100% rename from tutorials/fundamentals/questions/branches.json rename to tutorials/foundations/questions/branches.json diff --git a/tutorials/fundamentals/questions/create_clone.json b/tutorials/foundations/questions/create_clone.json similarity index 100% rename from tutorials/fundamentals/questions/create_clone.json rename to tutorials/foundations/questions/create_clone.json diff --git a/tutorials/fundamentals/questions/push_pull.json b/tutorials/foundations/questions/push_pull.json similarity index 100% rename from tutorials/fundamentals/questions/push_pull.json rename to tutorials/foundations/questions/push_pull.json diff --git a/tutorials/fundamentals/questions/working_with_files.json b/tutorials/foundations/questions/working_with_files.json similarity index 100% rename from tutorials/fundamentals/questions/working_with_files.json rename to tutorials/foundations/questions/working_with_files.json From 3576f1c2c900a034ea502d1271a25383e1de1301 Mon Sep 17 00:00:00 2001 From: sarahwilson523 Date: Wed, 27 May 2026 11:29:18 -0600 Subject: [PATCH 3/7] move intro, git, env to moodle; renumber notebooks --- tutorials/.DS_Store | Bin 0 -> 6148 bytes .../foundations/0_project_overview.ipynb | 101 ---- ...horization.ipynb => 1_authorization.ipynb} | 0 tutorials/foundations/1_git_intro.ipynb | 463 ------------------ .../foundations/2_package_management.ipynb | 186 ------- ...ata.ipynb => 2_seismic_data_example.ipynb} | 0 ...xercise.ipynb => 3_seismic_exercise.ipynb} | 0 ...ta.ipynb => 4_geodetic_data_example.ipynb} | 0 ...ercise.ipynb => 5_geodetic_exercise.ipynb} | 0 tutorials/foundations/8_wrap_up.ipynb | 59 --- tutorials/foundations/README.md | 5 + 11 files changed, 5 insertions(+), 809 deletions(-) create mode 100644 tutorials/.DS_Store delete mode 100644 tutorials/foundations/0_project_overview.ipynb rename tutorials/foundations/{3_authorization.ipynb => 1_authorization.ipynb} (100%) delete mode 100644 tutorials/foundations/1_git_intro.ipynb delete mode 100644 tutorials/foundations/2_package_management.ipynb rename tutorials/foundations/{4_seismic_data.ipynb => 2_seismic_data_example.ipynb} (100%) rename tutorials/foundations/{5_seismic_exercise.ipynb => 3_seismic_exercise.ipynb} (100%) rename tutorials/foundations/{6_geodetic_data.ipynb => 4_geodetic_data_example.ipynb} (100%) rename tutorials/foundations/{7_geodetic_exercise.ipynb => 5_geodetic_exercise.ipynb} (100%) delete mode 100644 tutorials/foundations/8_wrap_up.ipynb create mode 100644 tutorials/foundations/README.md diff --git a/tutorials/.DS_Store b/tutorials/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..da32fbcc93428a36621d16da073a654cc8da497f GIT binary patch literal 6148 zcmeHKPfrs;6n_Inwp3(+7BOhj*oz6Mtx?c;a48r=JV022C4gnO-PV<5rtWU3NJ#nx z^y&xj1DJUAq8~tyUOo5)ym-bpf0lpMqejfWWajtg&3iNRew&%u0RU2LRto?+0BBe^ zCi<}Yh46k}I;2ZkdJu^iqY4&;-~t2M;T;=d24V*OH3sJiNnlZC?m#cwAr%g9e=REB?;UZUqfB-g~>@xj~rEe<5AniJmjPTCbMU*3BoZ zWrkMR42qV&%3Di}d3K~*_Ok1=%6fW+(a>_KY&ToBbQcLtH_$P8i-g^c4$d0 zS=PsPcdr(1-p)^CZ{+XnO=Ncqg-L8oO-}CZCACcM`rXCyrng1eOOYH9JkW&nD~#Y3 zDhH{%m2H(0`4pw}RoA1Wl6|SO{pSYs!J*;7^k62F896_CVQB1PSs%8o%4Xf?i=AN} z^NU{7DeD6PraV_+bisGFG1XG&JP%Fx1$GUc2v~Hgj}J{tI}P+n9~#7<4}8a=t99S4 z&ev*z6PAwXD}1(!&pdB|1#ajvy0Ru_51p+!T4OjPU%`BXcLmFiA0T$blvXU?w`kod z?yP&3?RfLF$ik3qm0Zk%uUt%NHmr(E>$!X1C5y?NaYbr6CnT(SOa*Iq6gG`e}vPw3H zMV`v|uIM9QQsXHg0V)R{dE4}<$7mgGk^gb`)7nzmXsOehK)mjlftZ0m#sEJbvRF78 z3fmIJ(SenC0w5;PEChA_v%q7r3JryAiP(ceWGJExCF+SmWH{Qh%Fj^PmMFu4h?#L5 zH8W8!6e4CvdsesuF(k%y%s|Y*aR$0&Q|I^pecZ#pdH){|id!)QF$4b<10*qP&hlrw zx?4Mv<9BTq%LW!M+^;QBgkYtvW1;Y?cod5e?8|Zm(NNfyh!&LiM?laJS1|*Bm4Tlt Cq~cTn literal 0 HcmV?d00001 diff --git a/tutorials/foundations/0_project_overview.ipynb b/tutorials/foundations/0_project_overview.ipynb deleted file mode 100644 index 6918df9..0000000 --- a/tutorials/foundations/0_project_overview.ipynb +++ /dev/null @@ -1,101 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a2e2e354-9dcf-4af5-84d8-51142b01f1b2", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "# Project Overview\n", - "\n", - "This project demonstrates a typical project workflow in GeoLab. The objective is to instruct how to download data from EarthScope web services, and how to access data in the cloud. The difference between the two methods is that web services are file download services. In contrast, cloud services stream data directly to memory, which is more efficient and enables processing more data.\n", - "\n", - "This exercise covers:\n", - "\n", - "- how to initialize a project using git\n", - "- how to create a Python environment and manage packages\n", - "- explains how to get an EarthScope token to access data\n", - "- how to download seismic and geodetic data using EarthScope web services\n", - "- how access seismic and geodetic data in the cloud\n", - " \n", - "A section can include quizzes, working in the terminal, or a coding exercise. The project map below shows how the sections correspond to notebooks.\n", - "\n", - "![](images/project_work_flow.png)\n", - "\n", - "## Using Git\n", - "\n", - "Git is used to store and track code changes. We strongly recommend that you start a project by creating a git repository. First, by creating a git repository, you can rollback any changes made in your code. For example, adding a new feature. If it fails to work, you can revert your changes to the point where the code was working. Git also enables the creation of branches, which let you add new features without disrupting working code. If you create a GitHub account, you can keep a copy of the repository online and share it with others. There are many benefits to using git to manage project code.\n", - "\n", - "The notebook covers the basics of creating a git repository and managing code.\n", - "\n", - "## Python Environments and Package Management\n", - "\n", - "Creating a Python environment for a project is a best practice. Environments determine the version of Python used and the software packages available for a project. GeoLab's default environment contains many packages useful for scientific computing. However, you may want to add a package, and this module explains how to add packages and the basics of managing a Python environment.\n", - "\n", - "## Getting Authorization to Access EarthScope Services\n", - "\n", - "To download or access EarthScope SAGE and GAGE data, you will need an EarthScope account. Tracking data usage is a requirement of EarthScope's funding. Usage is tracked by a issuing an 0Auth token. You can request a token using EarthScope's CLI (Command Line Interface) or programmatically with EarthScope's SDK (Software Development Kit). This section demonstrates both methods for requesting a token.\n", - "\n", - "In the future, EarthScope will provide access to data in AWS S3 buckets. Direct data access is briefly discussed and will be expanded when the service becomes available.\n", - "\n", - "## Getting Seismic Data\n", - "\n", - "This task demonstrates how to download files from SAGE and GAGE web services using Python. How to formulate a request with the correct parameters and authorization is shown. In addition, this section demonstrates how to access data from an AWS S3 bucket that does not require authorization.\n", - "\n", - "## Seismic Data Exercise\n", - "\n", - "Using the skills from the previous notebook. You will complete a Python script that will download data from EarthScope web services.\n", - "\n", - "## Getting Geodetic Data\n", - "\n", - "This notebook demonstrates how to get cloud native seismic and geodetic data using the `boto3` Python and the EarthScope SDK. This section demonstrates how to access data from an AWS S3 bucket without authorization, and how the EarthScope SDK manages authorization.\n", - "\n", - "## Geodetic Data Exercise\n", - "\n", - "Using the skills from the previous notebook. You will complete a Python script that pull seismic and geodetic data from the cloud." - ] - }, - { - "cell_type": "markdown", - "id": "d3c7e78d-5791-4c1a-a59c-8af6467921a7", - "metadata": {}, - "source": [ - "## [Next >](./1_git_intro.ipynb)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1d28597e-bba5-4d3b-aa4a-98524e741a31", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/foundations/3_authorization.ipynb b/tutorials/foundations/1_authorization.ipynb similarity index 100% rename from tutorials/foundations/3_authorization.ipynb rename to tutorials/foundations/1_authorization.ipynb diff --git a/tutorials/foundations/1_git_intro.ipynb b/tutorials/foundations/1_git_intro.ipynb deleted file mode 100644 index 9ac3deb..0000000 --- a/tutorials/foundations/1_git_intro.ipynb +++ /dev/null @@ -1,463 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "b6d2d667", - "metadata": {}, - "source": [ - "# Intro to Git \n", - "\n", - "## Keeping track of code\n", - "\n", - "Git is a free and open-source distributed version control system (VCS). Software developers use it to track changes to their code over time, enabling collaboration and efficient management of project versions. Think of it as a sophisticated \"undo\" button and a way to manage different versions of files, which is especially useful when multiple people are working on the same project. You can also use git to save your work outside of GeoLab.\n", - "\n", - "## Installation\n", - "\n", - "GeoLab includes the git client. However, to check if git is installed on a computer, use the version flag, which returns the version of git.\n", - "\n", - "```\n", - "git --version\n", - "```\n", - "\n", - "## Setting up Git\n", - "\n", - "Git is a distributed system, meaning you can have a version of code on your computer and access it through a Git service provider. By configuring git with your user name and email, you'll be able to make changes on the remote copy of your code. To configure git in GeoLab, use the following commands in the terminal.\n", - "\n", - "```\n", - "git config --global user.name \n", - "git config --global user.email \n", - "```\n", - "\n", - "## How Git Works\n", - "\n", - "Git manages changes to your projects. It uses repositories, which contain all your project files and their complete history. Git keeps track of every modification you make, allowing you to save different versions of your work in a branch and merge changes back into the main project. You can collaborate with others by sharing your project online with a remote repository. You can get feedback through pull requests from other project users and maintainers, and integrate their contributions seamlessly. Git keeps track of changes and lets you collaborate with other project users, making it easier to manage and improve your projects without losing any work.\n", - "\n", - "## Getting Started with Git\n", - "\n", - "There are two ways to start using git. The first way is to `clone` or copy a repository from a online git hosting, such as GitLab or GitHub. Cloning a repository copies all the files, code and tracking data, from an online resource to your computer. \n", - "\n", - "The second method is to create a local git repository on your computer. You can create a remote repository in GitHub or GitLab and copy, or `push`, the local repository into the online, or `remote`, repository.\n", - "\n", - "We'll start with cloning a repository, and follow with creating a local repository." - ] - }, - { - "cell_type": "markdown", - "id": "55f11155", - "metadata": {}, - "source": [ - "## Cloning a Repository\n", - "\n", - "Cloning repositories enables us to collaborate on projects with other developers. Cloning a repository creates a complete local copy, including all branches and commit history. You can make changes to the project and push your changes back to the remote repository for others to review and merge. To clone the remote repository, use the following command.\n", - "\n", - "```\n", - "git clone \n", - "```\n", - "\n", - "There are two types of repository URLs used when cloning a project.\n", - "\n", - "- HTTPS URL: Commonly used for cloning and pushing code.\n", - "\n", - "> Example: https://github.com/username/repository.git\n", - "\n", - "- SSH URL: More secure and used for authentication without entering a username or password.\n", - "\n", - "> Example: git@github.com:username/repository.git\n", - "\n", - "`git clone` copies the main branch by default. If you want to clone a specific branch of the repository, you can use the -b option.\n", - "\n", - "```\n", - "git clone -b \n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "e05eb452", - "metadata": {}, - "source": [ - "## Creating a Repository\n", - "\n", - "Let's create a repository in GeoLab. Open a terminal, and go to your home directory.\n", - "\n", - "```\n", - "cd ~\n", - "```\n", - "\n", - "Create a new directory named `my_repo` and then use the `cd` command to switch to it.\n", - "\n", - "```\n", - "mkdir my_repo\n", - "cd my_repo\n", - "```\n", - "\n", - "To create a new repository, use the `init` command. The repository has a hidden directory, `.git`, which contains the files for tracking and managing changes to the repository.\n", - "\n", - "```\n", - "git init\n", - "```\n", - "\n", - "If we want to check if there are changes to repository, use the `status` command.\n", - "\n", - "```\n", - "git status\n", - "```\n", - "\n", - "This shows the status of all the files in the repository. Since the repository is empty, git will respond with:\n", - "\n", - "```\n", - "On branch main\n", - "\n", - "No commits yet\n", - "\n", - "nothing to commit (create/copy files and use \"git add\" to track)\n", - "```\n", - "\n", - "## Adding Files\n", - "\n", - "Let's add a Markdown and Python file and add them to the repository.\n", - "\n", - "```\n", - "echo \"# My Repository\" > README.md\n", - "echo \"print(\"Hello GeoLab!\") > hello.py\n", - "```\n", - "\n", - "Although the files are in the directory, git isn't tracking them. When you modify an existing file, create a new file, or delete a file in your working directory, Git considers changes as \"untracked\" or \"modified.\" The `git add` command adds changes from the working directory to the staging area, also known as the index. Think of the staging are as an web shopping cart. The staging area acts as a temporary holding area where you can carefully select which changes you want to include when want to save or make a snapshot of the repository. To add all the changes to the staging area, follow the `git add` command with a period, e.g.:\n", - "\n", - "```\n", - "git add .\n", - "```\n", - "\n", - "You can also add specific files:\n", - "\n", - "`README.md` and `hello.py` files are added to the repository. You can also add single files by their name. \n", - "\n", - "```\n", - "git add hello.py\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "492a41d8", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "## Committing Files\n", - "\n", - "Committing files takes a snapshot of your code at that moment. That means you can always go back to that point. Use the `commit` command to create a snapshot. The `-m` flag adds a message about the change.\n", - "\n", - "```\n", - "git commit -m \"first commit\"\n", - "```\n", - "\n", - "You can see all your commits with the `log` command. A commit hash references each commit.\n", - "\n", - "```\n", - "git log\n", - "\n", - "commit 10814a1c1cd6d8696ccc1a98eb65720ec95607c1 (HEAD -> main)\n", - "Author: spara-earthscope \n", - "Date: Mon Jul 7 21:29:56 2025 -0600\n", - "\n", - " first commit\n", - "```\n", - "\n", - "We've create a repository snapshot with the two files. Let's see what happens when you delete a file with the `git rm` command which removes the file from staging. We want to update our snapshot with `git commit` and check the commit with `git log`.\n", - "\n", - "```\n", - "git rm --cached hello.py\n", - "git commit -m 'deleted hello.py from staging'\n", - "git log\n", - "```\n", - "\n", - "commit 77f2e485703918f938a285f5aac012ab0899d1bf\n", - "Author: spara-earthscope \n", - "Date: Mon Jul 7 21:26:11 2025 -0600\n", - "\n", - " deleted hello.py from staging\n", - "```\n", - "\n", - "At this point you have two snapshots of your code. The first snapshot contains the README.md and hello.py files. The second and current snapshot contains only the README.md file." - ] - }, - { - "cell_type": "markdown", - "id": "e6f3604e", - "metadata": {}, - "source": [ - "## Push\n", - "\n", - "Sometimes you want to save or share your work outside of GeoLab. You can save or publish your code to GitHub by creating a new GitHub repository with these [instructions](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository). \n", - "\n", - "Don't initialize the repository with README, license, or gitignore files to avoid errors or conflicts when pushing your code. \n", - "\n", - "![](images/github_push.png)\n", - "\n", - "GitHub provides the remote repository URL when the remote repository is available. Copy the URL. In your terminal, go to the project directory and set the alias for the remote repository as `origin`.\n", - "\n", - "```\n", - "git remote add origin REMOTE-URL\n", - "```\n", - "\n", - "Verify the remote URL:\n", - "\n", - "```\n", - "git remote -v\n", - "```\n", - "\n", - "To push your project and changes to GitHub:\n", - "\n", - "```\n", - "git push -u origin main\n", - "\n", - "```\n", - "\n", - "Refresh the browser window to see the files you've pushed to the repository." - ] - }, - { - "cell_type": "markdown", - "id": "dacbf116", - "metadata": {}, - "source": [ - "## Pull\n", - "\n", - "If the GitHub repository has been updated, the `git pull` command updates the local version of a repository from a remote repository on GitHub with the changes. It does two things.\n", - "\n", - "- Updates the current local working branch (currently checked out branch)\n", - "- Updates the remote tracking branches for all other branches.\n", - "\n", - "`git pull` fetches (`git fetch`) new commits and merges (`git merge`) these into your local branch. In addition, the remote repository is set (`git remote -v`), then it will pull from the remote branch.\n", - "\n", - "```\n", - "git pull \n", - "```\n", - "\n", - "If the remote repository, or `origin`, is not set, use:\n", - "\n", - "```\n", - "git pull origin \n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "1ac3da09", - "metadata": {}, - "source": [ - "## Summary\n", - "\n", - "Git manages your code by saving snapshots of the project at various points. You can revert changes to previous versions of the project code. A typical git work flow looks like this:\n", - "\n", - "1. Clone a repository from GitHub or GitLab, or initialize a new repository for a project on your computer.\n", - "2. [Optional] Create a branch for project changes and to preserve the main, or primary branch.\n", - "3. Edit or add files to the repository.\n", - "4. Use the `git add` command to stage the files to save in the repository.\n", - "5. Save a snapshot of the changes with `git commit`. Committing saves the code at that point and lets you go back to if if needed.\n", - "6. `git commit` saves the snapshot on your computer. If you want to publish changes to the remote repository on GitHub or GitLab, use the `git push` command.\n", - "7. Use the `git merge` if you want to update the remote main branch with your changes. If you are working on the main branch, this isn't necessary and a `push` will merge your changes to main.\n", - "\n", - "Repeat the `add` => `commit` => `push` cycle when you've made a changes to the repository. It can prevent loss of work and let you recover changes throughout the project's life cycle." - ] - }, - { - "cell_type": "markdown", - "id": "1a533357", - "metadata": {}, - "source": [ - "## More Git Resources\n", - "\n", - "Want to learn more about git?\n", - "\n", - "- Git basics in [GitHub](https://docs.github.com/en/get-started/start-your-journey/hello-world)\n", - "- If you want to understand how to collaborate with others, [Git Flow](https://docs.github.com/en/get-started/using-github/github-flow) provides an overview.\n", - "- A deep dive into git with the [Git Pro Book](https://git-scm.com/book/en/v2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e123d2df", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "6687320f", - "metadata": {}, - "source": [ - "## Exercise\n", - "\n", - "Using the information above, complete the exercise.\n", - "\n", - "1. In the terminal, make a directory called `first_project` and change to that directory.\n", - "\n", - " ```\n", - " mkdir first_project\n", - " cd first_project\n", - " ```\n", - " \n", - "2. Create a project by initializing git.\n", - "\n", - "3. Create a README file.\n", - "\n", - " ```\n", - " echo \"# First GeoLab Project\" > README.md\n", - " ```\n", - " \n", - "4. Add the README to the repository.\n", - "\n", - "5. Look at the status of the repository.\n", - "\n", - "6. Commit the README to the repository.\n", - "\n", - "7. Look at the repository log. What is in the log?\n", - "\n", - "In the next section, we'll learn about Python package managers and environments." - ] - }, - { - "cell_type": "markdown", - "id": "b2cf015d", - "metadata": {}, - "source": [ - "# OPTIONAL: Additional Git Commands \n", - "\n", - "## Fixing Mistakes\n", - "\n", - "Git lets you fix mistakes by reverting commits. There are three ways to fix a mistake.\n", - "\n", - "1. `Checkout` is a safe option because you can view a version without changing any other versions and return to the current version. To check out a commit, the first eight to ten characters of the hash are sufficient for uniqueness. \n", - "\n", - "```\n", - "git checkout 10814a1c\n", - "git checkout main\n", - "```\n", - "\n", - "2. `Revert` changes commits. For example, if we want to change a commit using `revert`, it opens a [vim](https://github.com/vim/vim) editor. To save the change, add a new message, then type `:wq`. Revert does not delete a commit; it creates a new commit that shows that the commit was changed.\n", - "\n", - "```\n", - "git revert 10814a1c\n", - "git log\n", - "\n", - "commit 8aa48904a09d826118569227bfaa34fb7a1ff2e7 (HEAD -> main)\n", - "Author: spara-earthscope \n", - "Date: Mon Jul 7 23:06:13 2025 -0600\n", - "\n", - " Revert \"update README\"\n", - "\n", - " This reverts commit 10814a1c1cd6d8696ccc1a98eb65720ec95607c1.\n", - "\n", - " Removed change to README\n", - "```\n", - "3. `Reset` deletes commits from a certain point, e.g.:\n", - "\n", - "```\n", - "git reset 10814a1c\n", - "```\n", - "\n", - "All commits after and including 2aa211 will be deleted and recovered.\n", - "\n", - "## Branches\n", - "\n", - "When you initialize a git repository, it starts at the main branch. The main branch is typically the stable branch, i.e., the branch with working code that you can share. If we want to add a new feature without changing the published code, we add a branch, like this:\n", - "\n", - "```\n", - "git branch new_feature\n", - "```\n", - "\n", - "You can see all the branches in a repository by:\n", - "\n", - "```\n", - "git branch\n", - "```\n", - "\n", - "or by:\n", - "\n", - "```\n", - "git branch -a\n", - "```\n", - "\n", - "It shows `main` and `new_feature` branches. The branch with an asterisk, `*`, is the current branch. To switch to the `new_feature` use the `checkout` command, e.g.:\n", - "\n", - "```\n", - "git checkout new_feature\n", - "```\n", - "\n", - "Note that you can also use `checkout` to create a new branch:\n", - "\n", - "```\n", - "git checkout -b new_feature\n", - "```\n", - "\n", - "You can safely delete a branch if it has been merged into main or another branch.\n", - "\n", - "```\n", - "git branch -d new_feature\n", - "```\n", - "\n", - "To `delete` an unmerged branch, use the force option:\n", - "\n", - "```\n", - "git branch -D new_feature\n", - "```\n", - "\n", - "## Merging Branches\n", - "\n", - "If the new_feature branch is complete, we can merge it into the main branch. First, check out the main branch, then merge the new_feature branch.\n", - "\n", - "\n", - "```\n", - "git checkout main\n", - "git merge new_feature.\n", - "```\n", - "\n", - "If you encounter conflicts, ensure you have updated the branch to be merged by adding and committing the code.\n", - "\n", - "```\n", - "git add .\n", - "git commit -m 'updating code'\n", - "```\n" - ] - }, - { - "cell_type": "markdown", - "id": "9e475784-2c57-42c4-992f-50b7ef392297", - "metadata": {}, - "source": [ - "## [< Previous](./0_project_overview.ipynb)             [Next >](./2_package_management.ipynb)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "geolab", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.14.0" - }, - "toc": { - "base_numbering": 0 - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/foundations/2_package_management.ipynb b/tutorials/foundations/2_package_management.ipynb deleted file mode 100644 index 0e5192a..0000000 --- a/tutorials/foundations/2_package_management.ipynb +++ /dev/null @@ -1,186 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "7495572e", - "metadata": {}, - "source": [ - "# Python Environments and Package Management\n", - "\n", - "Python packages are collections of modules that provide additional functionality and tools to Python programs. These packages can contain functions, classes, and variables that are designed to perform specific tasks, ranging from data manipulation and scientific computing to web development and machine learning. Developers can leverage pre-written, tested code to save time and reduce the potential for errors.\n", - "\n", - "Python package managers are tools for installing, updating, configuring, and removing Python packages. Package managers handle dependencies and ensure that software projects have the necessary libraries and supporting packages to run correctly. They fetch and install packages, simplifying the process of integrating external libraries into projects.\n", - "\n", - "## Pip and Conda\n", - "\n", - "[Pip](https://github.com/pypa/pip) and [conda](https://docs.conda.io/en/latest/) are popular package managers. Pip is the default package manager for Python and is commonly used because of its integration with PyPI (Python Package Index), a third-party repository for Python packages. Conda is a package manager that comes with the [Anaconda distribution](https://www.anaconda.com/docs/getting-started/anaconda/main). Conda can handle packages from various languages and is useful in data science and scientific computing because it can manage non-Python dependencies and complex binary packages. Pip is sufficient for pure Python projects, but conda provides additional functionality and ease of use for more complex environments, making it a preferred choice for many data scientists and researchers.\n", - "\n", - "GeoLab is based on the [PanGeo](https://github.com/pangeo-data/pangeo-docker-images) computing environment and uses conda as the package manager. \n", - "\n", - "## Virtual Environments\n", - "\n", - "Virtual environments are a best practice and an integral part of Python development because they provide isolated environments for project development. Isolation ensures that the dependencies of one project do not conflict with those of another. Developers can manage project-specific dependencies effectively and avoid potential conflicts between package versions. The result is an easy-to-manage, clean, and organized development environment.\n", - "\n", - "To list the virtual environments in GeoLab, type the following command in the terminal.\n", - "\n", - "```\n", - "conda env list\n", - "```\n", - "\n", - "The environment with an asterisk is the current environment. To list the installed packages, type:\n", - "\n", - "```\n", - "conda list\n", - "```\n", - "\n", - "The list has four columns: Name, Version, Build, and Channel. The Channel is the repository for a package. If you scroll through the list, [conda-forge](https://conda-forge.org/) is the predominant channel, and [ PyPI or the Python Package Index](https://pypi.org/) is occasionally listed. You can install packages from PyPI in a conda environment, and in general, it will work with the existing dependencies. \n", - "\n", - "To use or activate a specific environment, for example, `notebook`, use the activate command.\n", - "\n", - "```\n", - "conda activate notebook\n", - "```\n", - "\n", - "To leave an environment, use the `deactivate` command \n", - "\n", - "```\n", - "conda deactivate\n", - "```\n", - "\n", - "### Creating Environments\n", - "\n", - "You can create an environment with the `conda create` command (try `env-new` for an environment name).\n", - "\n", - "```\n", - "conda create --name \n", - "```\n", - "\n", - "You can also clone the base environment if you want to keep the existing packages and install additional packages.\n", - "\n", - "```\n", - "conda create --name env-clone --clone notebook\n", - "```\n", - "\n", - "More information about creating and managing environments is available in the [documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html). Don't forget to activate the environment after creating it.\n", - "\n", - "### Installing Packages\n", - "\n", - "To install Python packages with conda, type (try [`tqdm`](https://anaconda.org/channels/anaconda/packages/tqdm/overview) a python progress meter):\n", - "\n", - "```\n", - "conda install \n", - "```\n", - "\n", - "This command installs packages from anaconda.org. If you want to install packages from conda-forge, which has the latest version, add the channel parameter. Either syntax shown below installs a package from a channel.\n", - "\n", - "```\n", - "conda install --channel conda-forge \n", - "conda install conda-forge::\n", - "```\n", - "\n", - "You can also specify package versions, including Python. For example, a package may require Python 3.10.\n", - "\n", - "```\n", - "conda install conda-forge:python=3.10\n", - "```\n", - "\n", - "You can also install packages with pip (try [`pytube`](https://pypi.org/project/pytube/) a YouTube video downloading package).\n", - "\n", - "```\n", - "pip install \n", - "```\n", - "\n", - "GeoLab instances are ephemeral. That means if you install a package in the terminal, it will not be there the next time you open a stopped GeoLab. The best practice for installing packages is to install them in a notebook with a [magic command](https://ipython.readthedocs.io/en/stable/interactive/magics.html).\n", - "\n", - "```\n", - "%pip install \n", - "%conda install \n", - "```\n", - "\n", - "Alternatively, you can create a custom environment or clone the base environment and install the required packages. The custom environment will persist and can be reused. In this example, we will clone the default environment and add a beautifulsoup package for parsing web pages. We can list packages and see beautifulsoup4 and bs4 are installed.\n", - "\n", - "```\n", - "conda create --name myenv --clone notebook\n", - "conda activate myenv\n", - "conda install bs4\n", - "conda list\n", - "```\n", - "\n", - "If you leave GeoLab, `myenv` will persist, along with the added packages.\n", - "\n", - "\n", - "## Summary\n", - "\n", - "Python projects use libraries of software, or packages. Building packages with different versions of Python can introduce dependencies on a Python version and other packages as well. Virtual environments manage dependencies by creating a repeatable working space. Conda, the Python package manager, takes this one step further and checks for dependencies and finds, or solves, for packages without dependency issues.\n", - "\n", - "Conda can install many common packages, however, there are also geoscience packages distributed through the Python Package Index (PyPI). These packages can be installed in a conda environment.\n", - "\n", - "These are the common commands to manage a python environment.\n", - "\n", - "1. List the conda environments with `conda env list`.\n", - "2. Create conda environment with `conda create` environment_name.\n", - "3. Use the environment you created with `conda activate` environment_name.\n", - "4. Add conda packages with `conda install` package_name or from the CondaForge repository, `conda install --channel conda-forge` package_name.\n", - "5. Add packages from PyPI with `pip install` package_name.\n", - "6. To leave an environment use `conda deactivate`.\n", - "\n", - "## Exercise\n", - "\n", - "For this exercise, we will create an environment and add packages. Follow these instructions and type the commands in the terminal.\n", - "\n", - "1. In the terminal, change into the geolab directory and create an environment called `first_project`.\n", - "\n", - " ```\n", - " conda create --name first-project --clone base\n", - " ```\n", - "\n", - "3. List the environments; you should see `first_project` in the list.\n", - "\n", - " ```\n", - " conda list\n", - " ```\n", - "\n", - "4. Activate the `first_project` environment.\n", - "\n", - " ```\n", - " conda activate first_project\n", - " ```\n", - "\n", - "5. List the packages; it should have the same packages as the base environment.\n", - "\n", - " ```\n", - " conda list\n", - " ```" - ] - }, - { - "cell_type": "markdown", - "id": "b87b0908-0428-4673-b2ea-645073191d0a", - "metadata": {}, - "source": [ - "## [< Previous](./1_git_intro.ipynb)             [Next >](./3_authorization.ipynb)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/foundations/4_seismic_data.ipynb b/tutorials/foundations/2_seismic_data_example.ipynb similarity index 100% rename from tutorials/foundations/4_seismic_data.ipynb rename to tutorials/foundations/2_seismic_data_example.ipynb diff --git a/tutorials/foundations/5_seismic_exercise.ipynb b/tutorials/foundations/3_seismic_exercise.ipynb similarity index 100% rename from tutorials/foundations/5_seismic_exercise.ipynb rename to tutorials/foundations/3_seismic_exercise.ipynb diff --git a/tutorials/foundations/6_geodetic_data.ipynb b/tutorials/foundations/4_geodetic_data_example.ipynb similarity index 100% rename from tutorials/foundations/6_geodetic_data.ipynb rename to tutorials/foundations/4_geodetic_data_example.ipynb diff --git a/tutorials/foundations/7_geodetic_exercise.ipynb b/tutorials/foundations/5_geodetic_exercise.ipynb similarity index 100% rename from tutorials/foundations/7_geodetic_exercise.ipynb rename to tutorials/foundations/5_geodetic_exercise.ipynb diff --git a/tutorials/foundations/8_wrap_up.ipynb b/tutorials/foundations/8_wrap_up.ipynb deleted file mode 100644 index a0e7129..0000000 --- a/tutorials/foundations/8_wrap_up.ipynb +++ /dev/null @@ -1,59 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3154392e-b584-445c-a6cb-b9dfed447a7f", - "metadata": {}, - "source": [ - "# Putting It All Together\n", - "\n", - "This project covers how to create a project in GeoLab. It's best practice to structure your project using git for several reasons. First, git tracks your code and saves it at different states. It enables you to roll back to working code. Second, you can create branches to test new features. Finally, you can publish and share your project code by publishing it to a public repository, such as GitHub.\n", - "\n", - "GeoLab is a Python environment that contains many tools for geoscience. However, it's another best practice to create a project-specific virtual environment. GeoLab uses conda as a package manager, and you can clone the base GeoLab virtual environment and add project-specific packages as needed. Conda creates virtual environments and resolves package dependencies and conflicts, ensuring that projects can be deployed on a variety of platforms.\n", - "\n", - "You will need an EarthScope account to access GeoLab. Once in GeoLab, accessing EarthScope data requires an authorization token, which can be requested with the EarthScope CLI or programmatically with the EarthScope SDK. The token enables requesting data from EarthScope.\n", - "\n", - "There are several ways to acquire data from EarthScope. Data is available through web services and through cloud services. The primary distinction between web and cloud services is that web services are used to download data as files in GeoLab. In addition to the computer I/O overhead of writing a file, there is additional overhead to read files for processing and analysis. In contrast, cloud services stream data directly to memory, where it is immediately available for processing and analysis.\n", - "\n", - "The future of GeoLab and EarthScope data distribution is cloud services. Web services will remain available as EarthScope makes more data available through the cloud." - ] - }, - { - "cell_type": "markdown", - "id": "2a7a6216-0058-40ca-9586-448c71a4c6d4", - "metadata": {}, - "source": [ - "## [< Previous](./7_cloud_native_exercise.ipynb)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d626393-6414-4f45-b275-f84b090b7cdd", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.5" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/foundations/README.md b/tutorials/foundations/README.md new file mode 100644 index 0000000..4393ea7 --- /dev/null +++ b/tutorials/foundations/README.md @@ -0,0 +1,5 @@ +The notebook tutorials in this directory are designed to be used in conjunction with the Cloud Foundations self-paced online course, but can also be used as standalone examples. + +They provide instructions for how to generate EarthScope data access credentials, and examples for accessing NSF NGF data from GeoLab. + +You can enroll in Cloud Foundations at course.earthscope.org . \ No newline at end of file From 60367d62413ad1e5dc716856b1b94cfbd6072303 Mon Sep 17 00:00:00 2001 From: sarahwilson523 Date: Wed, 27 May 2026 11:40:28 -0600 Subject: [PATCH 4/7] remove rinex data from seismic exercise --- tutorials/foundations/3_seismic_exercise.ipynb | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/tutorials/foundations/3_seismic_exercise.ipynb b/tutorials/foundations/3_seismic_exercise.ipynb index 5550dcb..43d40a7 100644 --- a/tutorials/foundations/3_seismic_exercise.ipynb +++ b/tutorials/foundations/3_seismic_exercise.ipynb @@ -94,7 +94,7 @@ " return ____\n", "\n", "\n", - "# ---------- Download a file from EarthScope's web services ----------\n", + "# ---------- Create a function to download a file from EarthScope's web services ----------\n", "# --------------------------------------------------------------------\n", "def download_data(url, data_directory, params={}): # params is an optional query parameter\n", " \"\"\"\n", @@ -145,7 +145,7 @@ " print(f\"failure: {r.status_code}, {r.reason}\")\n", " return None\n", "\n", - "# Download a miniSEED file for an event\n", + "# Describe the parameters for a miniSEED file for an event\n", "# \n", "params = {\"net\" : 'IU',\n", " \"sta\" : 'ANMO',\n", @@ -154,17 +154,8 @@ " \"start\": '2010-02-27T06:30:00',\n", " \"end\": '2010-02-27T10:30:00'}\n", "\n", - "# Try the parameterized request\n", - "download_data(____, DATA_DIR, ___)\n", - "\n", - "# Download a RINEX file\n", - "year = 2025\n", - "day = 1\n", - "station = 'p034'\n", - "doy = '%03d'.format(day)\n", - "compression = 'd.Z' # or \".Z\" / \"\" depending on the archive\n", - "url = create_url(year, ____, station, compression)\n", - "download_data(url, ____)" + "# Use the function you created above to execute the parameterized request\n", + "download_data(____, DATA_DIR, ___)\n" ] }, { From 47b6a99ed337716de0a64b51b81440906497eff9 Mon Sep 17 00:00:00 2001 From: sarahwilson523 Date: Wed, 27 May 2026 14:07:38 -0600 Subject: [PATCH 5/7] typo in README --- tutorials/foundations/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/foundations/README.md b/tutorials/foundations/README.md index 4393ea7..77432c1 100644 --- a/tutorials/foundations/README.md +++ b/tutorials/foundations/README.md @@ -2,4 +2,4 @@ The notebook tutorials in this directory are designed to be used in conjunction They provide instructions for how to generate EarthScope data access credentials, and examples for accessing NSF NGF data from GeoLab. -You can enroll in Cloud Foundations at course.earthscope.org . \ No newline at end of file +You can enroll in Cloud Foundations at courses.earthscope.org . \ No newline at end of file From caaa70726bef8a0d97e6d5872f49ce3c96dd9b9e Mon Sep 17 00:00:00 2001 From: spara-earthscope Date: Wed, 27 May 2026 14:24:57 -0600 Subject: [PATCH 6/7] updated es_sdk download examples for es_sk-1.4 --- .../foundations/4_geodetic_data_example.ipynb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tutorials/foundations/4_geodetic_data_example.ipynb b/tutorials/foundations/4_geodetic_data_example.ipynb index 493f949..47ea91c 100644 --- a/tutorials/foundations/4_geodetic_data_example.ipynb +++ b/tutorials/foundations/4_geodetic_data_example.ipynb @@ -79,18 +79,19 @@ "source": [ "import datetime as dt\n", "import pandas as pd\n", - "from earthscope_sdk import EarthScopeClient\n", + "import pyarrow as pa\n", + "from earthscope_sdk import AsyncEarthScopeClient\n", "\n", - "es = EarthScopeClient()\n", + "es = AsyncEarthScopeClient()\n", "\n", "# Request 30 hours of data (1 day + 3 hour arcs on either side)\n", - "arrow_table = es.data.gnss_observations(\n", + "table = await es.data.gnss_observations(\n", " start_datetime=dt.datetime(2025, 7, 20, 21),\n", " end_datetime=dt.datetime(2025, 7, 22, 3),\n", " station_name=\"AC60\",\n", ").fetch()\n", "\n", - "df = arrow_table.to_pandas()\n", + "df = table.to_pandas()\n", "df" ] }, @@ -109,9 +110,9 @@ "metadata": {}, "outputs": [], "source": [ - "arrow_table = es.data.gnss_observations(\n", - " start_datetime=dt.datetime(2025, 7, 20),\n", - " end_datetime=dt.datetime(2025, 9, 20),\n", + "table = await es.data.gnss_observations(\n", + " start_datetime=dt.datetime(2025, 7, 20, 21),\n", + " end_datetime=dt.datetime(2025, 7, 22, 3),\n", " station_name=\"AC60\",\n", " session_name=\"A\",\n", " system=\"G\",\n", @@ -119,7 +120,7 @@ " satellite=\"7\",\n", " field=\"snr\",\n", ").fetch()\n", - "df = arrow_table.to_pandas()\n", + "df = table.to_pandas()\n", "df.sort_values(by=\"timestamp\")\n", "df" ] From 4a1bb9dd223bfd37ef12f8df3447e71925ace42a Mon Sep 17 00:00:00 2001 From: sarahwilson523 Date: Wed, 27 May 2026 16:55:22 -0600 Subject: [PATCH 7/7] NGF language update --- .../foundations/3_seismic_exercise.ipynb | 18 ++++++++--------- .../foundations/4_geodetic_data_example.ipynb | 20 ++++++++----------- .../foundations/5_geodetic_exercise.ipynb | 17 ++++++++-------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/tutorials/foundations/3_seismic_exercise.ipynb b/tutorials/foundations/3_seismic_exercise.ipynb index 43d40a7..299b29f 100644 --- a/tutorials/foundations/3_seismic_exercise.ipynb +++ b/tutorials/foundations/3_seismic_exercise.ipynb @@ -21,7 +21,7 @@ "source": [ "## Exercise A: Download miniSEED files from dataselect\n", "\n", - "This exercise is a script for downloading seismic data from EarthScope in the miniSEED file format. All the functions are covered in the previous `4_seismic.ipynb` notebook. The download function builds a SAGE web service request. Fill in the blanks to complete the script. Download earthquake event data by the query parameters for the SAGE web service. You can use the example in the previous notebook or use another event and station. \n", + "This exercise is a script for downloading seismic data from EarthScope in the miniSEED file format. All the functions are covered in the previous `2_seismic_data_example.ipynb` notebook. The download function builds a web service request. Fill in the blanks to complete the script. Download earthquake event data by the query parameters for the web service. You can use the example in the previous notebook or use another event and station. \n", "\n", "If the script is correctly completed you will have a new directory called `/data` containing a miniSEED file." ] @@ -66,8 +66,8 @@ "client = ____\n", "\n", "\n", - "# Fill this with the service endpoint for SAGE data\n", - "SAGE_URL = ____\n", + "# Fill this with the service endpoint for NSF NGF Seismic data\n", + "URL = ____\n", "\n", "DATA_DIR = Path(\"./data\")\n", "DATA_DIR.mkdir(parents=True, exist_ok=True)\n", @@ -94,11 +94,11 @@ " return ____\n", "\n", "\n", - "# ---------- Create a function to download a file from EarthScope's web services ----------\n", + "# ---------- Define a function to download a file from EarthScope's web services ----------\n", "# --------------------------------------------------------------------\n", "def download_data(url, data_directory, params={}): # params is an optional query parameter\n", " \"\"\"\n", - " Sends GET with query parameters to the SAGE web service and saves the response \n", + " Sends GET with query parameters to the NSF NGF web service and saves the response \n", " body to a file. Expected params include: net, sta, loc, cha, start (ISO), end (ISO), etc.\n", " \"\"\"\n", " # get authorization token\n", @@ -227,8 +227,8 @@ "# ---------- Create an EarthScope client to get token ----------\n", "client = EarthScopeClient()\n", "\n", - "# Fill this with the service endpoint for SAGE data\n", - "SAGE_URL = \"http://service.iris.edu/fdsnws/dataselect/1/query?\"\n", + "# Fill this with the service endpoint for NSF NGF Seismic data\n", + "URL = \"http://service.iris.edu/fdsnws/dataselect/1/query?\"\n", "\n", "# create a directory for rinex data\n", "DATA_DIR = \"./data\"\n", @@ -253,7 +253,7 @@ " return {\"authorization\": f\"Bearer {token}\"}\n", "\n", "\n", - "# ---------- Download a file from EarthScope's web services ----------\n", + "# ---------- Define a function to download a file from EarthScope's web services ----------\n", "# --------------------------------------------------------------------\n", "def download_data(url, data_directory, params={}):\n", " \"\"\"\n", @@ -308,7 +308,7 @@ " \"end\": '2010-02-27T10:30:00'}\n", "\n", "# Try the parameterized request\n", - "download_data(SAGE_URL, DATA_DIR, params)\n", + "download_data(URL, DATA_DIR, params)\n", "\n", "```" ] diff --git a/tutorials/foundations/4_geodetic_data_example.ipynb b/tutorials/foundations/4_geodetic_data_example.ipynb index 47ea91c..ff35af3 100644 --- a/tutorials/foundations/4_geodetic_data_example.ipynb +++ b/tutorials/foundations/4_geodetic_data_example.ipynb @@ -23,13 +23,9 @@ "id": "98ab6e5a", "metadata": {}, "source": [ - "## Getting Geodetic Data from EarthScope\n", + "## Getting Geodetic Data from the NSF NGF Archive\n", "\n", - "![](images/cloud_native_data_access.png)\n", - "\n", - "The recommended method to access EarthScope's geodetic data is to use the [EarthScope SDK](). The SDK supports requesting just the GNSS observations data you need instead of a single RINEX file. It reduces the size of data and returns the data in Apache [arrow](https://arrow.apache.org/), which is a memory efficient format that can used by analytic data formats such as Pandas [dataframes](https://pandas.pydata.org/). In the future other GNSS data types will be added to the SDK.\n", - "\n", - "![](images/Web_Services_Data_Flow.png)\n", + "The recommended method to access the NSF NGF's geodetic data is to use the [EarthScope SDK](). The SDK supports requesting just the GNSS observations data you need instead of a single RINEX file. It reduces the size of data and returns the data in Apache [arrow](https://arrow.apache.org/), which is a memory efficient format that can used by analytic data formats such as Pandas [dataframes](https://pandas.pydata.org/). In the future other GNSS data types will be added to the SDK.\n", "\n", "In addition to GNSS observations, EarthScope distributes RINEX files and other GNSS data such as navigation and meteorological data. These data can be downloaded as files in their respective formats. An example for downloading files is provided below." ] @@ -138,15 +134,15 @@ "id": "525448ca", "metadata": {}, "source": [ - "## Downloading Geodetic Data from GAGE\n", + "## Downloading Geodetic Data from the NSF NGF Archive\n", "\n", - "The GAGE archive holds many types of data ranging from GPS/GNSS data to borehole strain data. We will focus on GPS/GNSS data. Each type of data has API interfaces specific to the data. Unlike dataselect, the API calls return information about data or processed data. The collected data is distributed by a file server and can be programmatically downloaded if you know the URL to the file.\n", + "The NSF NGF archive holds many types of data ranging from GPS/GNSS data to borehole strain data. We will focus on GPS/GNSS data. Each type of data has API interfaces specific to the data. Unlike dataselect, the API calls return information about data or processed data. The collected data is distributed by a file server and can be programmatically downloaded if you know the URL to the file.\n", "\n", - "In this example, we will download GNSS data in RINEX. GAGE data is located on a file server and data cab be downloaded with a properly formatted URL. The script downloads the stations by providing the parameters that make up the URL to the data. \n", + "In this example, we will download GNSS data in RINEX. Geodetic data is located on a file server and data cab be downloaded with a properly formatted URL. The script downloads the stations by providing the parameters that make up the URL to the data. \n", "\n", "### Downloading RINEX files\n", "\n", - "The GAGE base URL for gnss data in RINEX is `https://gage-data.earthscope.org/archive/gnss/rinex/obs/`. \n", + "The base URL for gnss data in RINEX is `https://gage-data.earthscope.org/archive/gnss/rinex/obs/`. \n", "\n", "Files are organized by year and the day of the year, e.g., `/2025/001/`. File names use this pattern: \n", "\n", @@ -161,7 +157,7 @@ "\n", "> Note: files ending with `d.Z` are [hatanaka compressed files](https://www.unavco.org/data/gps-gnss/hatanaka/hatanaka.html) and files ending with `o.Z` are not hatanaka compressed. Hatanaka compressed files are much smaller but require software to read the data.\n", "\n", - "The same method for downloading SAGE data can be used to download GAGE data once URL is properly constructed." + "The same method for downloading seismic data can be used to download geodetic data once URL is properly constructed." ] }, { @@ -189,7 +185,7 @@ " \n", " return token\n", "\n", - "# function to download data from GAGE archive\n", + "# define a function to download data from the NSF NGF archive\n", "def download_file(url, data_directory):\n", " \n", " # get authorization Bearer token\n", diff --git a/tutorials/foundations/5_geodetic_exercise.ipynb b/tutorials/foundations/5_geodetic_exercise.ipynb index 5da029d..062466a 100644 --- a/tutorials/foundations/5_geodetic_exercise.ipynb +++ b/tutorials/foundations/5_geodetic_exercise.ipynb @@ -84,8 +84,8 @@ "client = ____\n", "\n", "\n", - "# Fill this with the service endpoint for GAGE data\n", - "GAGE_URL = ____\n", + "# Fill this with the service endpoint for NSF NGF data\n", + "URL = ____\n", "\n", "DATA_DIR = Path(\"./data\")\n", "DATA_DIR.mkdir(parents=True, exist_ok=True)\n", @@ -112,11 +112,11 @@ " return ____\n", "\n", "\n", - "# ---------- Download a file from EarthScope's web services ----------\n", + "# ---------- Define a function to download a file from EarthScope's web services ----------\n", "# --------------------------------------------------------------------\n", "def download_data(url, data_directory): # params is an optional query parameter\n", " \"\"\"\n", - " Sends GET request to GAGE web service by construcing the URL to the RINEX file.\n", + " Sends GET request to web service by construcing the URL to the RINEX file.\n", " \"\"\"\n", " # get authorization token\n", " token = get_token()\n", @@ -149,7 +149,7 @@ " return None\n", "\n", "\n", - "# ---------- Creates URL to download data from the EarthScope GAGE web service ----------\n", + "# ---------- Create URL to download data from the EarthScope web service ----------\n", "# ---------------------------------------------------------------------------------------\n", "def create_url(year, day, station, compression):\n", " \"\"\"\n", @@ -162,11 +162,10 @@ "\n", " file_path = \"/\".join([str(year), doy])\n", " file_name = \"\".join([\"/\", station, doy, \"0.\", two_digit_year, compression])\n", - " url = \"\".join([GAGE_URL, file_path, file_name])\n", + " url = \"\".join([URL, file_path, file_name])\n", " return url\n", "\n", - "# Download a RINEX file\n", - "#\n", + "# Execute the functions above to download a RINEX file\n", "year = 2025\n", "day = 1\n", "station = 'p034'\n", @@ -236,7 +235,7 @@ "client = EarthScopeClient()\n", "\n", "# Fill this with the service endpoint for SAGE data\n", - "GAGE_URL = \"https://gage-data.earthscope.org/archive/gnss/rinex/obs/?\"\n", + "URL = \"https://gage-data.earthscope.org/archive/gnss/rinex/obs/?\"\n", "\n", "# create a directory for RINEX data\n", "DATA_DIR = \"./data\"\n",