Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the note_taking capacity #66

Merged
merged 11 commits into from
Jul 12, 2023
264 changes: 261 additions & 3 deletions docs/notebook/AVISO.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@
"attachments": {},
"cell_type": "markdown",
"id": "256affe3",
"metadata": {},
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## Loading data\n",
"\n",
Expand Down Expand Up @@ -311,6 +317,10 @@
"execution_count": null,
"id": "124718ad",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
Expand Down Expand Up @@ -347,6 +357,10 @@
"execution_count": null,
"id": "6d8ee9cc",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
Expand All @@ -371,6 +385,10 @@
"execution_count": null,
"id": "25f862a7",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
Expand All @@ -393,6 +411,10 @@
"execution_count": null,
"id": "0e0fc0c8",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
Expand All @@ -412,7 +434,13 @@
"attachments": {},
"cell_type": "markdown",
"id": "c7046590",
"metadata": {},
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Voila!"
]
Expand All @@ -422,6 +450,10 @@
"execution_count": null,
"id": "5338b2f2",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
Expand All @@ -444,6 +476,232 @@
"source": [
"**Fig.2** The trajectories of particles advected by AVISO-derived surface velocity field."
]
},
{
"cell_type": "markdown",
"id": "072f7015-6e4e-473e-85e3-ba15388963b9",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## Advanced use of `Particle`\n",
"\n",
"In this subsection, we are going to demonstrate how to access the analytical trajectories of particles. We are also going to demonstrate the flexibility of Particle release.\n",
"\n",
"Most of the notebooks release particles at the same time. We are going to do it differently this time. They are going to be released at 64W and 55S and 64S. Crucially, all of the particles are released at a different time."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b1a404b2-c59c-4d1a-87be-a49230639ebe",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"N = 777\n",
"t_earliest = sd.utils.convert_time(\"1970-01-01\")\n",
"t_final = sd.utils.convert_time(\"1970-02-01\")\n",
"t_latest = sd.utils.convert_time(\"1970-03-03\") # damn you, February.\n",
"t = np.linspace(t_earliest, t_latest, N)\n",
"\n",
"number_of_loop = 6.18\n",
"# y = -65.0+np.abs(10-np.linspace(0,number_of_loop*20,N)%20)\n",
"y = -59.5 + 4.5 * np.sin(number_of_loop * np.linspace(-3.14, 3.14, N))\n",
"x = np.ones(N) * (-64.0)\n",
"z = -np.ones(N)"
]
},
{
"cell_type": "markdown",
"id": "19c51858-ecf6-4229-adf9-0c6051d00405",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"To better demonstrate, here is a plot showing the release pattern of the particle. The time is referenced against the final time of the simulation. Note that every single particle will be released at a different time and there are going to be both forward and backward particles in the same simulation.\n",
"\n",
"This is as if there is a ship is commuting in drake passage while releasing particles."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1f5c63f8-6074-41d7-b0f6-513ee484e89a",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"plt.plot(t, y, \"o\", markersize=1)\n",
"plt.xticks(\n",
" [t_earliest, t_final - 15 * 86400, t_final, t_final + 15 * 86400, t_latest],\n",
" [\"-31 days\", \"-15 days\", \"0\", \"+15 days\", \"+31 days\"],\n",
")\n",
"plt.ylabel(\"Latitude\")\n",
"plt.title(\"Latitude of particles released at 64W\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "c4c7c3de-7c11-428e-b342-c854cc38e4ed",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"**Fig.3** Pattern of particle release. Time is relative to the final time."
]
},
{
"cell_type": "markdown",
"id": "2b5e335f-198a-4ba1-b3ff-85f5cc39d31b",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"The only difference in preparation between this one and the previous simulation is that we have `save_raw = True`. This means the particles will record all the necessary informations to reconstruct the analytical trajectory."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e329dca7-f916-4b08-89da-e99264f2aa76",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
"source": [
"p = sd.Particle(\n",
" x=x,\n",
" y=y,\n",
" z=z,\n",
" t=t,\n",
" data=bathtub,\n",
" uname=\"u\",\n",
" vname=\"v\",\n",
" wname=None,\n",
" callback=interested_in,\n",
" save_raw=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "1ef2b1d9-eceb-4418-9911-683116a8beb1",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"No tricks need to be played while execution."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eedf2bfd-5e4c-4387-b1d1-c7d81ed209f8",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
"source": [
"%%time\n",
"p.to_next_stop(t_final)"
]
},
{
"cell_type": "markdown",
"id": "850b27c8-5bcd-4d5e-bba0-5b88a380cf2b",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"When `save_raw = True` is selected, the `Particle` object records location and velocity information everytime velocity is updated. The following plot is plotted from longitude and latitudes of particles crossing cell walls. Each trajectory is colored based on the time of release, Purple is the earliest, red is the latest (furthest into the future)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0d6a4387-b10e-489c-a527-47d54b3f101f",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": [
"hide-input"
]
},
"outputs": [],
"source": [
"plt.figure(figsize=(9, 16))\n",
"ax = plt.axes(projection=ccrs.PlateCarree())\n",
"rainbow = plt.get_cmap(\"rainbow\")\n",
"for i in range(0, N):\n",
" color = rainbow(t[i] / 2 / t_final)\n",
" ax.plot([x[i]] + p.xxlist[i], [y[i]] + p.yylist[i], color=color, lw=0.2)\n",
"ax.coastlines()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "80a5ee7e-4791-46cb-9635-2084c262449d",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"**Fig.4** Trajectory of particles released at different time. Warm color are particles released after the final time, and cold colors are those released before the final time."
]
}
],
"metadata": {
Expand All @@ -463,7 +721,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
"version": "3.11.3"
}
},
"nbformat": 4,
Expand Down
45 changes: 0 additions & 45 deletions seaduck/eulerian.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,51 +501,6 @@ def get_f_node_weight(self):
"""Find weight for the corner points interpolation."""
return weight_f_node(self.rx, self.ry)

def _get_lon_lat(self): # pragma: no cover
"""Return the lat-lon value based on relative coordinate.

This method only work if the dataset has readiness['h'] == 'oceanparcel'.
"""
px, py = self.get_px_py()
w = self.get_f_node_weight()
lon = np.einsum("nj,nj->n", w, px.T)
lat = np.einsum("nj,nj->n", w, py.T)
return lon, lat

def _get_needed(
self, var_name, knw, required=None, prefetched=None, **kwarg
): # pragma: no cover
if required is None:
required = self.ocedata._ds[var_name].dims
ind = self.fatten(knw, required=required, **kwarg)
if len(ind) != len(self.ocedata._ds[var_name].dims):
raise IndexError(
"Dimension mismatch. "
"Please check if the Position objects "
"have all the dimensions needed"
)
if prefetched is None:
return smart_read(self.ocedata[var_name], ind)
else:
return prefetched[ind]

def _get_masked(self, knw, cuvwg="C", **kwarg): # pragma: no cover
ind = self.fatten(knw, four_d=True, **kwarg)
if self.it is not None:
ind = ind[1:]
if len(ind) != len(self.ocedata._ds["maskC"].dims):
raise IndexError(
"Dimension mismatch. "
"Please check if the Position objects "
"have all the dimensions needed"
)
return get_masked(self.ocedata, ind, cuvwg=cuvwg)

def _find_pk4d(self, knw, cuvwg="C"): # pragma: no cover
masked = self._get_masked(knw, cuvwg=cuvwg)
pk4d = find_pk_4d(masked, inheritance=knw.inheritance)
return pk4d

def _register_interpolation_input(
self, var_name, knw, prefetched=None, prefetch_prefix=None
):
Expand Down
Loading