diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 0000000..1020e31 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,115 @@ + + + + + + + +Page not found (404) • harpTobac + + + + + + + + + + + +
+
+ + + + +
+
+ + +Content not found. Please use links in the navbar. + +
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/LICENSE.html b/docs/LICENSE.html new file mode 100644 index 0000000..825f5c4 --- /dev/null +++ b/docs/LICENSE.html @@ -0,0 +1,165 @@ + +Apache License • harpTobac + + +
+
+ + + +
+
+ + +
+ +

Version 2.0, January 2004 <http://www.apache.org/licenses/>

+
+

Terms and Conditions for use, reproduction, and distribution

+
+

1. Definitions

+

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

+

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

+

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

+

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

+

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

+

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

+

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

+

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

+

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

+

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

+
+
+ +

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

+
+
+

3. Grant of Patent License

+

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

+
+
+

4. Redistribution

+

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

+
  • +(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
  • +
  • +(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
  • +
  • +(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
  • +
  • +(d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
  • +

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

+
+
+

5. Submission of Contributions

+

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

+
+
+

6. Trademarks

+

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

+
+
+

7. Disclaimer of Warranty

+

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

+
+
+

8. Limitation of Liability

+

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

+
+
+

9. Accepting Warranty or Additional Liability

+

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

+

END OF TERMS AND CONDITIONS

+
+
+
+

APPENDIX: How to apply the Apache License to your work

+

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets [] replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

+
Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+ +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/articles/index.html b/docs/articles/index.html new file mode 100644 index 0000000..ffc64d0 --- /dev/null +++ b/docs/articles/index.html @@ -0,0 +1,88 @@ + +Articles • harpTobac + + +
+
+ + + +
+
+ + + +
+
+ + +
+ + + + + + + + diff --git a/docs/articles/tarcking_seviri_brightness_temp.html b/docs/articles/tarcking_seviri_brightness_temp.html new file mode 100644 index 0000000..9325c2b --- /dev/null +++ b/docs/articles/tarcking_seviri_brightness_temp.html @@ -0,0 +1,309 @@ + + + + + + + +Track satellite brightness temperature • harpTobac + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

Introduction +

+

The purpose of this article is to show how to read in data that harp +cannot natively deal with. In this case we will read in SEVIRI +brightness temperature data from a NetCDF file that lacks information +about the domain.

+ +
+
+

Attach the data file and define the domain +

+

The data are stored as example data with the harpTobac +package and can be accessed via the system.file() +function.

+
+file_name <- system.file(
+  "example_data/Spain_202205_SEVIRI_bt_all.nc",
+  package = "harpTobac"
+)
+nc <- nc_open(file_name)
+

Longitude and latitude are stored as 2d arrays, so let’s read them in +and then close the connection to the NetCDF file.

+
+lon <- ncvar_get(nc, "longitude")
+lat <- ncvar_get(nc, "latitude")
+nc_close(nc)
+

Now we need to establish the grid resolution. We can establish if the +data are on a regular grid, by checking if the mean difference between +each value is the same as the maximum.

+
+identical(apply(diff(lon), 1, mean), apply(diff(lon), 1, max))
+#> [1] TRUE
+identical(apply(diff(t(lat)), 1, mean), apply(diff(t(lat)), 1, max))
+#> [1] TRUE
+

Now that we have established that the data are on a regular grid, we +can extract the horizontal resolution.

+
+dx <- diff(lon)[1]
+dy <- diff(t(lat))[1]
+

Finally we need the centre point of the domain in order to properly +define the domain.

+
+centre_lon <- min(lon) + diff(range(lon)) / 2
+centre_lat <- min(lat) + diff(range(lat)) / 2
+

Now we can define the domain.

+
+dom <- define_domain(
+  centre_lon = centre_lon, 
+  centre_lat = centre_lat,
+  nxny       = dim(lon),
+  dxdy       = c(dx, dy),
+  proj       = "longlat"
+)
+
+plot(dom)
+

+

We also need to get the time data from the file. These are stored in +hours since the first date-time, but we want the data to be the actual +date times. harpIO has a, currently non exported function, that +can read the time data and convert them in date-times in UTC.

+
+valid_dttm <- unixtime_to_dttm(
+  harpIO:::get_time_nc(file_name, harpIO::netcdf_opts())$validdate
+)
+
+
+

Read the brightness temperature data +

+

The brightness temperature is stored in degrees C, which we will +convert to Kelvin. We will read in one time at a time and use the domain +e have just defined to put the data into a geofield, and subsequently a +geolist. We will do this with the help of lapply() and put +the data in a tibble (just a data frame with a nicer print method).

+
+library(tibble)
+nc <- nc_open(file_name)
+bt <- tibble(
+  valid_dttm = valid_dttm,
+  brightness_temp = geolist(
+    lapply(
+      seq_along(valid_dttm),
+      function(i) geofield(
+        ncvar_get(nc, "bt", start = c(1, 1, i), count = c(-1, -1, 1)) + 273.15,
+        domain = dom
+      )
+    )
+  )
+)
+nc_close(nc)
+

Finally the harpTobac functions require the data to be of +class harp_df and we can easily do that conversion with +as_harp_df()

+
+bt <- as_harp_df(bt)
+
+
+

Feature detection +

+

We will detect features using minimum brightness temperature +thresholds of 250, 240, 230 and 220 K.

+
+features <- detect_features_multithreshold(
+  bt, 
+  thresholds         = seq(250, 220, -10),
+  data_col           = brightness_temp,
+  target             = "min",
+  n_min_threshold    = 16, 
+  position_threshold = "weighted_diff"
+)
+

And plot the feature locations at each time.

+
+countries <- get_map(get_domain(bt$brightness_temp), polygon = FALSE)
+ggplot(features, aes(longitude, latitude)) +
+  geom_path(aes(x, y), countries, colour = "grey30") + 
+  geom_point(aes(colour = factor(threshold_value))) +
+  facet_wrap(~timestr) +
+  coord_equal(expand = FALSE) + 
+  theme_harp_map() + 
+  labs(colour = bquote(atop(Brightness~Temp, Threshold~"["*K*"]")))
+

+
+
+

Segmentation +

+

We will segment the data using a threshold of 250K.

+
+library(zeallot)
+c(segments, features) %<-% segment_2d(
+  features, 
+  bt, 
+  threshold = 250, 
+  data_col  = brightness_temp, 
+  target    = "min"
+)
+

And plot with the brightness temperature for some selected times.

+
+ggplot() + 
+  geom_georaster(
+    aes(geofield = brightness_temp), bt[13:16, ], 
+    upscale_factor = 4, upscale_method = "downsample"
+  ) +
+  geom_geocontour(
+    aes(geofield = segmentation_mask), segments[13:16, ],
+    colour = "red"
+  ) + 
+  geom_path(aes(x, y), countries, colour = "grey30") +
+  facet_wrap(~valid_dttm) +
+  scale_fill_viridis_c(direction = -1) +
+  coord_equal(expand = FALSE) +
+  theme_harp_map()
+

+
+
+

Cell tracks +

+

Now we can compute the cell tracks.

+
+tracks <- link_tracks(
+  features, 
+  bt, 
+  data_col        = brightness_temp, 
+  v_max           = 20, 
+  stubs           = 2,  
+  subnetwork_size = 100, 
+  adaptive_step   = 0.95, 
+  adaptive_stop   = 0.2
+)
+

And plot them, separately for each feature threshold.

+
+countries <- get_map(get_domain(bt$brightness_temp))
+ggplot(filter(tracks, cell > -1), aes(x, y)) + 
+  geom_polygon(aes(group = group), countries, fill = "grey", colour = "grey30") +
+  geom_path(
+    aes(group = factor(cell), colour = factor(threshold_value)),
+    arrow = arrow(type = "open", angle = 30, length = unit(0.1, "cm"))
+  ) +
+  facet_wrap(~paste0("Brightness temp >= ", threshold_value, "K")) +
+  labs(colour = bquote(atop(OLR~threshold, "["*W.m^{-2}*"]"))) +
+  coord_equal(expand = FALSE) + 
+  theme_harp_map()
+

+
+
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/define-domain-1.png b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/define-domain-1.png new file mode 100644 index 0000000..53115b7 Binary files /dev/null and b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/define-domain-1.png differ diff --git a/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-features-1.png b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-features-1.png new file mode 100644 index 0000000..66439e4 Binary files /dev/null and b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-features-1.png differ diff --git a/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-segments-1.png b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-segments-1.png new file mode 100644 index 0000000..51e6d18 Binary files /dev/null and b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-segments-1.png differ diff --git a/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-tracks-1.png b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-tracks-1.png new file mode 100644 index 0000000..32299e3 Binary files /dev/null and b/docs/articles/tarcking_seviri_brightness_temp_files/figure-html/plot-tracks-1.png differ diff --git a/docs/articles/tracking_model_OLR.html b/docs/articles/tracking_model_OLR.html new file mode 100644 index 0000000..756ab00 --- /dev/null +++ b/docs/articles/tracking_model_OLR.html @@ -0,0 +1,347 @@ + + + + + + + +Track OLR features • harpTobac + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

Introduction +

+

In this article, we show an example of tracking features in an +outgoing longwave radiation field from the NWP model MEPS. We are going +to make use of the harpIO package to load the data and the +ggplot2 package, together with some expansions from the +harpVis package to plot the data.

+ +
+
+

Loading the data +

+

First we need to load the data using read_forecast() +from the harpIO package. The data are downloaded from the open +data Thredds server at the Norwegian Meteorological Institute.

+

There are a few steps we need to go through to ensure we read the +data properly. First we’ll add the outgoing longwave parameter to the +parameter definitions so that read_forecast() knows what +parameter to extract. The data are also negative for outgoing radiation +so we multiply by -1

+
+my_params <- add_param_def(
+  "olr", 
+  netcdf = new_netcdf_param("toa_outgoing_longwave_flux"), 
+  func = function(x) x * -1
+)
+

Then we set the path and template for the file(s) to read, as well as +some information about the netcdf files.

+
+url       <- "https://thredds.met.no/thredds/dodsC/meps25epsarchive"
+template  <- "{YYYY}/{MM}/{DD}/{fcst_model}_sfc_{YYYY}{MM}{DD}T{HH}Z.ncml"
+file_opts <- netcdf_opts(
+  z_var = "top_of_atmosphere", ref_time_var = "forecast_reference_time"
+)
+

And now we can read the data…

+
+olr <- read_forecast(
+  dttm             = 2024052700,
+  fcst_model       = "meps_det",
+  parameter        = "olr",
+  lead_time        = seq(0, 23),
+  file_path        = url, 
+  file_template    = template, 
+  file_format      = "netcdf",
+  file_format_opts = file_opts,
+  param_defs       = my_params, 
+  return_data      = TRUE 
+)
+#> Reading https://thredds.met.no/thredds/dodsC/meps25epsarchive/2024/05/27/meps_det_sfc_20240527T00Z.ncml
+
+
+

Feature detction +

+

Feature detection is done using thresholds to identify contiguous +features in the field of interest at each time. This requires careful +selection of thresholds, so as a first step we will plot the OLR at each +time step.

+
+countries <- get_map(get_domain(olr$fcst), polygon = FALSE)
+ggplot() + 
+  geom_georaster(
+    aes(geofield = fcst), olr, 
+    upscale_factor = 8, upscale_method = "downsample"
+  ) + 
+  geom_path(aes(x, y), countries, colour = "grey30") +
+  facet_wrap(~valid_dttm) +
+  scale_fill_viridis_c(bquote(OLR~"["*W.m^{-2}*"]"), direction = -1) + 
+  coord_equal(expand = FALSE) +
+  theme_harp_map()
+

+

It looks like most of the interesting features are for OLR < ~180. +We can get a better idea by masking all values that are > 180, by +adding limits to the colour scale.

+
+countries <- get_map(get_domain(olr$fcst), polygon = FALSE)
+ggplot() + 
+  geom_georaster(
+    aes(geofield = fcst), olr, 
+    upscale_factor = 8, upscale_method = "downsample"
+  ) + 
+  geom_path(aes(x, y), countries, colour = "grey30") +
+  facet_wrap(~valid_dttm) +
+  scale_fill_viridis_c(
+    bquote(OLR~"["*W.m^{-2}*"]"), direction = -1, 
+    limits = c(NA, 180), na.value = "white"
+  ) + 
+  coord_equal(expand = FALSE) +
+  theme_harp_map()
+

+

Using this information we will use thresholds of 180, 160 and 140 in +the feature detection, setting the target to “min” since we want +features to be identified that are less than the thresholds. Features +are detected using detect_features_multithreshold() that is +a wrapper around tobac.feature_detection.feature_detection_multithreshold +from the original Python package. We will only detect features that are +at least 16 contiguous pixels in size, and use the “weighted_diff” +method to set the position of the features.

+
+features <- detect_features_multithreshold(
+  olr, 
+  thresholds         = c(180, 160, 140),
+  data_col           = fcst,
+  target             = "min",
+  n_min_threshold    = 16, 
+  position_threshold = "weighted_diff"
+)
+

We can now plot the feature locations for each threshold and +time.

+
+ggplot(features, aes(projection_x_coordinate, projection_y_coordinate)) +
+  geom_path(aes(x, y), countries, colour = "grey30") + 
+  geom_point(aes(colour = factor(threshold_value))) +
+  facet_wrap(~timestr) +
+  coord_equal(expand = FALSE) + 
+  theme_harp_map() + 
+  labs(colour = bquote(atop(OLR~Threshold,"["*W.m^{-2}*"]")))
+

+
+
+

Segmentation +

+

Having run the feature detection, the next step is to associate +regions with the identified features. This is done using +segment_2d() that is a wrapper around the tobac.segmentation.segmentation_2D +function from the original Python package. Here a single threshold is +needed, and we use the highest of the thresholds we used in the feature +detection. segment_2d returns a named list, but we can +destructure using the %<-% operator from the +zeallot package.

+
+library(zeallot)
+c(segments, features) %<-% segment_2d(
+  features, 
+  olr, 
+  threshold = 180, 
+  data_col  = fcst, 
+  target    = "min"
+)
+

segments is a data frame with a geolist coloumn +that contains fields with a mask identifying the areas that are +associated with each feature, while features is the same as +the output of the previous step, but with an extra column giving the +number of cells associated with each feature. The segment masks can be +overlayed on top of the original OLR data. Here we just show 4 +times.

+
+ggplot() + 
+  geom_georaster(
+    aes(geofield = fcst), olr[11:14, ], 
+    upscale_factor = 4, upscale_method = "downsample"
+  ) +
+  geom_geocontour(
+    aes(geofield = segmentation_mask), segments[11:14, ],
+    colour = "red"
+  ) + 
+  geom_path(aes(x, y), countries, colour = "grey30") +
+  facet_wrap(~valid_dttm) +
+  scale_fill_viridis_c(direction = -1) +
+  coord_equal(expand = FALSE) +
+  theme_harp_map()
+

+
+
+

Tracking +

+

With the features identified, the tracking algorithm attempts to link +these features in time to produce tracks. The tracking is computed with +the link_tracks() function that is a wrapper around tobac.tracking.linking_trackpy +from the original Python package.

+
+tracks <- link_tracks(
+  features, 
+  olr, 
+  data_col        = fcst, 
+  v_max           = 20, 
+  stubs           = 2,  
+  subnetwork_size = 100, 
+  adaptive_step   = 0.95, 
+  adaptive_stop   = 0.2
+)
+

Some of the arguments in the call to link_tracks() +require some experimentation, and are better explained in some of the tobac +examples.

+

The tracks for each of the identified cells can easily be plotted. +For all tracks throughout the period this can be done making sure to +remove untracked cells (these are labelled -1).

+
+library(dplyr)
+countries <- get_map(get_domain(olr$fcst))
+ggplot(filter(tracks, cell > -1), aes(x, y)) + 
+  geom_polygon(aes(group = group), countries, fill = "grey", colour = "grey30") +
+  geom_path(
+    aes(group = factor(cell), colour = factor(threshold_value)),
+    arrow = arrow(type = "open", angle = 30, length = unit(0.1, "cm"))
+  ) +
+  labs(colour = bquote(atop(OLR~threshold, "["*W.m^{-2}*"]"))) +
+  coord_equal(expand = FALSE) + 
+  theme_harp_map()
+

+

We could then plot some statistics, such as the distribution of the +lifetimes of individual cells.

+
+ggplot(
+  summarise(
+    filter(tracks, cell > -1),
+    lifetime = max(time_cell) / 3600, 
+    .by      = cell
+  )
+) +
+  geom_bar(aes(x = factor(lifetime)), fill = "steelblue") + 
+  labs(x = "Cell lifetime [h]")
+

+
+
+

Epilogue +

+

There are many analysis possibilities with these data. In addition +the harpTobac package gives you access to all of the +functionality of the Python tobac package via +tobac$<module name>$<function>.

+
+
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/articles/tracking_model_OLR_files/figure-html/olr-mask-plot-1.png b/docs/articles/tracking_model_OLR_files/figure-html/olr-mask-plot-1.png new file mode 100644 index 0000000..c7bdb3a Binary files /dev/null and b/docs/articles/tracking_model_OLR_files/figure-html/olr-mask-plot-1.png differ diff --git a/docs/articles/tracking_model_OLR_files/figure-html/olr-plot-1.png b/docs/articles/tracking_model_OLR_files/figure-html/olr-plot-1.png new file mode 100644 index 0000000..da54299 Binary files /dev/null and b/docs/articles/tracking_model_OLR_files/figure-html/olr-plot-1.png differ diff --git a/docs/articles/tracking_model_OLR_files/figure-html/plot-cell-lifetime-1.png b/docs/articles/tracking_model_OLR_files/figure-html/plot-cell-lifetime-1.png new file mode 100644 index 0000000..c878f50 Binary files /dev/null and b/docs/articles/tracking_model_OLR_files/figure-html/plot-cell-lifetime-1.png differ diff --git a/docs/articles/tracking_model_OLR_files/figure-html/plot-features-1.png b/docs/articles/tracking_model_OLR_files/figure-html/plot-features-1.png new file mode 100644 index 0000000..9d52dd9 Binary files /dev/null and b/docs/articles/tracking_model_OLR_files/figure-html/plot-features-1.png differ diff --git a/docs/articles/tracking_model_OLR_files/figure-html/plot-segment-mask-1.png b/docs/articles/tracking_model_OLR_files/figure-html/plot-segment-mask-1.png new file mode 100644 index 0000000..2026029 Binary files /dev/null and b/docs/articles/tracking_model_OLR_files/figure-html/plot-segment-mask-1.png differ diff --git a/docs/articles/tracking_model_OLR_files/figure-html/plot-tracks-1.png b/docs/articles/tracking_model_OLR_files/figure-html/plot-tracks-1.png new file mode 100644 index 0000000..332b6ab Binary files /dev/null and b/docs/articles/tracking_model_OLR_files/figure-html/plot-tracks-1.png differ diff --git a/docs/articles/tracking_seviri_brightness_temp.html b/docs/articles/tracking_seviri_brightness_temp.html new file mode 100644 index 0000000..ed6cadc --- /dev/null +++ b/docs/articles/tracking_seviri_brightness_temp.html @@ -0,0 +1,309 @@ + + + + + + + +Track satellite brightness temperature • harpTobac + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

Introduction +

+

The purpose of this article is to show how to read in data that harp +cannot natively deal with. In this case we will read in SEVIRI +brightness temperature data from a NetCDF file that lacks information +about the domain.

+ +
+
+

Attach the data file and define the domain +

+

The data are stored as example data with the harpTobac +package and can be accessed via the system.file() +function.

+
+file_name <- system.file(
+  "example_data/Spain_202205_SEVIRI_bt_all.nc",
+  package = "harpTobac"
+)
+nc <- nc_open(file_name)
+

Longitude and latitude are stored as 2d arrays, so let’s read them in +and then close the connection to the NetCDF file.

+
+lon <- ncvar_get(nc, "longitude")
+lat <- ncvar_get(nc, "latitude")
+nc_close(nc)
+

Now we need to establish the grid resolution. We can establish if the +data are on a regular grid, by checking if the mean difference between +each value is the same as the maximum.

+
+identical(apply(diff(lon), 1, mean), apply(diff(lon), 1, max))
+#> [1] TRUE
+identical(apply(diff(t(lat)), 1, mean), apply(diff(t(lat)), 1, max))
+#> [1] TRUE
+

Now that we have established that the data are on a regular grid, we +can extract the horizontal resolution.

+
+dx <- diff(lon)[1]
+dy <- diff(t(lat))[1]
+

Finally we need the centre point of the domain in order to properly +define the domain.

+
+centre_lon <- min(lon) + diff(range(lon)) / 2
+centre_lat <- min(lat) + diff(range(lat)) / 2
+

Now we can define the domain.

+
+dom <- define_domain(
+  centre_lon = centre_lon, 
+  centre_lat = centre_lat,
+  nxny       = dim(lon),
+  dxdy       = c(dx, dy),
+  proj       = "longlat"
+)
+
+plot(dom)
+

+

We also need to get the time data from the file. These are stored in +hours since the first date-time, but we want the data to be the actual +date times. harpIO has a, currently non exported function, that +can read the time data and convert them in date-times in UTC.

+
+valid_dttm <- unixtime_to_dttm(
+  harpIO:::get_time_nc(file_name, harpIO::netcdf_opts())$validdate
+)
+
+
+

Read the brightness temperature data +

+

The brightness temperature is stored in degrees C, which we will +convert to Kelvin. We will read in one time at a time and use the domain +e have just defined to put the data into a geofield, and subsequently a +geolist. We will do this with the help of lapply() and put +the data in a tibble (just a data frame with a nicer print method).

+
+library(tibble)
+nc <- nc_open(file_name)
+bt <- tibble(
+  valid_dttm = valid_dttm,
+  brightness_temp = geolist(
+    lapply(
+      seq_along(valid_dttm),
+      function(i) geofield(
+        ncvar_get(nc, "bt", start = c(1, 1, i), count = c(-1, -1, 1)) + 273.15,
+        domain = dom
+      )
+    )
+  )
+)
+nc_close(nc)
+

Finally the harpTobac functions require the data to be of +class harp_df and we can easily do that conversion with +as_harp_df()

+
+bt <- as_harp_df(bt)
+
+
+

Feature detection +

+

We will detect features using minimum brightness temperature +thresholds of 250, 240, 230 and 220 K.

+
+features <- detect_features_multithreshold(
+  bt, 
+  thresholds         = seq(250, 220, -10),
+  data_col           = brightness_temp,
+  target             = "min",
+  n_min_threshold    = 16, 
+  position_threshold = "weighted_diff"
+)
+

And plot the feature locations at each time.

+
+countries <- get_map(get_domain(bt$brightness_temp), polygon = FALSE)
+ggplot(features, aes(longitude, latitude)) +
+  geom_path(aes(x, y), countries, colour = "grey30") + 
+  geom_point(aes(colour = factor(threshold_value))) +
+  facet_wrap(~timestr) +
+  coord_equal(expand = FALSE) + 
+  theme_harp_map() + 
+  labs(colour = bquote(atop(Brightness~Temp, Threshold~"["*K*"]")))
+

+
+
+

Segmentation +

+

We will segment the data using a threshold of 250K.

+
+library(zeallot)
+c(segments, features) %<-% segment_2d(
+  features, 
+  bt, 
+  threshold = 250, 
+  data_col  = brightness_temp, 
+  target    = "min"
+)
+

And plot with the brightness temperature for some selected times.

+
+ggplot() + 
+  geom_georaster(
+    aes(geofield = brightness_temp), bt[13:16, ], 
+    upscale_factor = 4, upscale_method = "downsample"
+  ) +
+  geom_geocontour(
+    aes(geofield = segmentation_mask), segments[13:16, ],
+    colour = "red"
+  ) + 
+  geom_path(aes(x, y), countries, colour = "grey30") +
+  facet_wrap(~valid_dttm) +
+  scale_fill_viridis_c(direction = -1) +
+  coord_equal(expand = FALSE) +
+  theme_harp_map()
+

+
+
+

Cell tracks +

+

Now we can compute the cell tracks.

+
+tracks <- link_tracks(
+  features, 
+  bt, 
+  data_col        = brightness_temp, 
+  v_max           = 20, 
+  stubs           = 2,  
+  subnetwork_size = 100, 
+  adaptive_step   = 0.95, 
+  adaptive_stop   = 0.2
+)
+

And plot them, separately for each feature threshold.

+
+countries <- get_map(get_domain(bt$brightness_temp))
+ggplot(filter(tracks, cell > -1), aes(x, y)) + 
+  geom_polygon(aes(group = group), countries, fill = "grey", colour = "grey30") +
+  geom_path(
+    aes(group = factor(cell), colour = factor(threshold_value)),
+    arrow = arrow(type = "open", angle = 30, length = unit(0.1, "cm"))
+  ) +
+  facet_wrap(~paste0("Brightness temp >= ", threshold_value, "K")) +
+  labs(colour = bquote(atop(OLR~threshold, "["*W.m^{-2}*"]"))) +
+  coord_equal(expand = FALSE) + 
+  theme_harp_map()
+

+
+
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/articles/tracking_seviri_brightness_temp_files/figure-html/define-domain-1.png b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/define-domain-1.png new file mode 100644 index 0000000..53115b7 Binary files /dev/null and b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/define-domain-1.png differ diff --git a/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-features-1.png b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-features-1.png new file mode 100644 index 0000000..66439e4 Binary files /dev/null and b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-features-1.png differ diff --git a/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-segments-1.png b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-segments-1.png new file mode 100644 index 0000000..51e6d18 Binary files /dev/null and b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-segments-1.png differ diff --git a/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-tracks-1.png b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-tracks-1.png new file mode 100644 index 0000000..32299e3 Binary files /dev/null and b/docs/articles/tracking_seviri_brightness_temp_files/figure-html/plot-tracks-1.png differ diff --git a/docs/authors.html b/docs/authors.html new file mode 100644 index 0000000..3851f9b --- /dev/null +++ b/docs/authors.html @@ -0,0 +1,112 @@ + +Authors and Citation • harpTobac + + +
+
+ + + +
+
+
+ + + +
  • +

    Andrew Singleton. Author, maintainer. +

    +
  • +
  • +

    Juan-Jesus Gonzalez. Author. +

    +
  • +
+
+
+

Citation

+ Source: DESCRIPTION +
+
+ + +

Singleton A, Gonzalez J (2024). +harpTobac: harp bindings for the Python tobac package. +R package version 0.1.0, https://harphub.github.io/harpTobac/, https://github.com/harphub/harpTobac. +

+
@Manual{,
+  title = {harpTobac: harp bindings for the Python tobac package},
+  author = {Andrew Singleton and Juan-Jesus Gonzalez},
+  year = {2024},
+  note = {R package version 0.1.0, https://harphub.github.io/harpTobac/},
+  url = {https://github.com/harphub/harpTobac},
+}
+ +
+ +
+ + + +
+ + + + + + + + diff --git a/docs/bootstrap-toc.css b/docs/bootstrap-toc.css new file mode 100644 index 0000000..5a85941 --- /dev/null +++ b/docs/bootstrap-toc.css @@ -0,0 +1,60 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ + +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ + +/* All levels of nav */ +nav[data-toggle='toc'] .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; +} +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; +} +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; +} + +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} +nav[data-toggle='toc'] .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; +} +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 29px; +} +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; +} + +/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ +nav[data-toggle='toc'] .nav > .active > ul { + display: block; +} diff --git a/docs/bootstrap-toc.js b/docs/bootstrap-toc.js new file mode 100644 index 0000000..1cdd573 --- /dev/null +++ b/docs/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function() { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function(el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function(el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function(el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function() { + return $(''); + }, + + createChildNavList: function($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function(anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function(headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function(el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function(i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function(arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function(opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function() { + $('nav[data-toggle="toc"]').each(function(i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(); diff --git a/docs/docsearch.css b/docs/docsearch.css new file mode 100644 index 0000000..e5f1fe1 --- /dev/null +++ b/docs/docsearch.css @@ -0,0 +1,148 @@ +/* Docsearch -------------------------------------------------------------- */ +/* + Source: https://github.com/algolia/docsearch/ + License: MIT +*/ + +.algolia-autocomplete { + display: block; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1 +} + +.algolia-autocomplete .ds-dropdown-menu { + width: 100%; + min-width: none; + max-width: none; + padding: .75rem 0; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .1); + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); +} + +@media (min-width:768px) { + .algolia-autocomplete .ds-dropdown-menu { + width: 175% + } +} + +.algolia-autocomplete .ds-dropdown-menu::before { + display: none +} + +.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { + padding: 0; + background-color: rgb(255,255,255); + border: 0; + max-height: 80vh; +} + +.algolia-autocomplete .ds-dropdown-menu .ds-suggestions { + margin-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion { + padding: 0; + overflow: visible +} + +.algolia-autocomplete .algolia-docsearch-suggestion--category-header { + padding: .125rem 1rem; + margin-top: 0; + font-size: 1.3em; + font-weight: 500; + color: #00008B; + border-bottom: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--wrapper { + float: none; + padding-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { + float: none; + width: auto; + padding: 0; + text-align: left +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content { + float: none; + width: auto; + padding: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content::before { + display: none +} + +.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { + padding-top: .75rem; + margin-top: .75rem; + border-top: 1px solid rgba(0, 0, 0, .1) +} + +.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { + display: block; + padding: .1rem 1rem; + margin-bottom: 0.1; + font-size: 1.0em; + font-weight: 400 + /* display: none */ +} + +.algolia-autocomplete .algolia-docsearch-suggestion--title { + display: block; + padding: .25rem 1rem; + margin-bottom: 0; + font-size: 0.9em; + font-weight: 400 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--text { + padding: 0 1rem .5rem; + margin-top: -.25rem; + font-size: 0.8em; + font-weight: 400; + line-height: 1.25 +} + +.algolia-autocomplete .algolia-docsearch-footer { + width: 110px; + height: 20px; + z-index: 3; + margin-top: 10.66667px; + float: right; + font-size: 0; + line-height: 0; +} + +.algolia-autocomplete .algolia-docsearch-footer--logo { + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; + overflow: hidden; + text-indent: -9000px; + width: 100%; + height: 100%; + display: block; + transform: translate(-8px); +} + +.algolia-autocomplete .algolia-docsearch-suggestion--highlight { + color: #FF8C00; + background: rgba(232, 189, 54, 0.1) +} + + +.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { + box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) +} + +.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { + background-color: rgba(192, 192, 192, .15) +} diff --git a/docs/docsearch.js b/docs/docsearch.js new file mode 100644 index 0000000..b35504c --- /dev/null +++ b/docs/docsearch.js @@ -0,0 +1,85 @@ +$(function() { + + // register a handler to move the focus to the search bar + // upon pressing shift + "/" (i.e. "?") + $(document).on('keydown', function(e) { + if (e.shiftKey && e.keyCode == 191) { + e.preventDefault(); + $("#search-input").focus(); + } + }); + + $(document).ready(function() { + // do keyword highlighting + /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ + var mark = function() { + + var referrer = document.URL ; + var paramKey = "q" ; + + if (referrer.indexOf("?") !== -1) { + var qs = referrer.substr(referrer.indexOf('?') + 1); + var qs_noanchor = qs.split('#')[0]; + var qsa = qs_noanchor.split('&'); + var keyword = ""; + + for (var i = 0; i < qsa.length; i++) { + var currentParam = qsa[i].split('='); + + if (currentParam.length !== 2) { + continue; + } + + if (currentParam[0] == paramKey) { + keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); + } + } + + if (keyword !== "") { + $(".contents").unmark({ + done: function() { + $(".contents").mark(keyword); + } + }); + } + } + }; + + mark(); + }); +}); + +/* Search term highlighting ------------------------------*/ + +function matchedWords(hit) { + var words = []; + + var hierarchy = hit._highlightResult.hierarchy; + // loop to fetch from lvl0, lvl1, etc. + for (var idx in hierarchy) { + words = words.concat(hierarchy[idx].matchedWords); + } + + var content = hit._highlightResult.content; + if (content) { + words = words.concat(content.matchedWords); + } + + // return unique words + var words_uniq = [...new Set(words)]; + return words_uniq; +} + +function updateHitURL(hit) { + + var words = matchedWords(hit); + var url = ""; + + if (hit.anchor) { + url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; + } else { + url = hit.url + '?q=' + escape(words.join(" ")); + } + + return url; +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..0e6b85d --- /dev/null +++ b/docs/index.html @@ -0,0 +1,165 @@ + + + + + + + +harp bindings for the Python tobac package • harpTobac + + + + + + + + + + + + +
    +
    + + + + +
    +
    +
    + + + +

    harpTobac is a an interface to the Python package, tobac, for tracking and object based analysis of clouds.

    +

    It currently enables you to pass harp_grid_df data frames to do a basic analysis and tracking of 2d fields. That is, feature detection in 2d, segmentation in 2d and 2d linking of features into tracks.

    +

    Currently no specific functions for visualisation have been written, but the outputs are basic data frames and harp_grid_df data frames that can be easily visualised using ggplot2 and harpVis geoms.

    +
    +

    Installation +

    +

    You can install harpTobac from Github like so:

    +
    +if (!requireNamespace("remotes")) {
    +  install.packages("remotes")
    +}
    +remotes::install_github("harphub/harpTobac")
    +

    Once you have installed harpTobac you will need to install the tobac Python package. This is done using the install_tobac() function. The necessary packages will be installed into a virtualenv called “harp-py”. This is where all Python packages that can be used by harp are installed and run from. If you already have a “harp-py” virtualenv you will be asked if you want to remove it prior to installation. Typically you will answer no to this, otherwise all of your harp Python packages will be removed.

    + +

    You will only need to do the above once, straight after installing harpTobac. Subsequently, when the harpTobac package is attached your session will use the “harp-py” virtualenv.

    +
    +
    +
    + + +
    + + +
    + +
    +

    +

    Site built with pkgdown 2.0.7.

    +
    + +
    +
    + + + + + + + + diff --git a/docs/link.svg b/docs/link.svg new file mode 100644 index 0000000..88ad827 --- /dev/null +++ b/docs/link.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/docs/pkgdown.css b/docs/pkgdown.css new file mode 100644 index 0000000..80ea5b8 --- /dev/null +++ b/docs/pkgdown.css @@ -0,0 +1,384 @@ +/* Sticky footer */ + +/** + * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ + * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css + * + * .Site -> body > .container + * .Site-content -> body > .container .row + * .footer -> footer + * + * Key idea seems to be to ensure that .container and __all its parents__ + * have height set to 100% + * + */ + +html, body { + height: 100%; +} + +body { + position: relative; +} + +body > .container { + display: flex; + height: 100%; + flex-direction: column; +} + +body > .container .row { + flex: 1 0 auto; +} + +footer { + margin-top: 45px; + padding: 35px 0 36px; + border-top: 1px solid #e5e5e5; + color: #666; + display: flex; + flex-shrink: 0; +} +footer p { + margin-bottom: 0; +} +footer div { + flex: 1; +} +footer .pkgdown { + text-align: right; +} +footer p { + margin-bottom: 0; +} + +img.icon { + float: right; +} + +/* Ensure in-page images don't run outside their container */ +.contents img { + max-width: 100%; + height: auto; +} + +/* Fix bug in bootstrap (only seen in firefox) */ +summary { + display: list-item; +} + +/* Typographic tweaking ---------------------------------*/ + +.contents .page-header { + margin-top: calc(-60px + 1em); +} + +dd { + margin-left: 3em; +} + +/* Section anchors ---------------------------------*/ + +a.anchor { + display: none; + margin-left: 5px; + width: 20px; + height: 20px; + + background-image: url(./link.svg); + background-repeat: no-repeat; + background-size: 20px 20px; + background-position: center center; +} + +h1:hover .anchor, +h2:hover .anchor, +h3:hover .anchor, +h4:hover .anchor, +h5:hover .anchor, +h6:hover .anchor { + display: inline-block; +} + +/* Fixes for fixed navbar --------------------------*/ + +.contents h1, .contents h2, .contents h3, .contents h4 { + padding-top: 60px; + margin-top: -40px; +} + +/* Navbar submenu --------------------------*/ + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu>.dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover>.dropdown-menu { + display: block; +} + +.dropdown-submenu>a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} + +.dropdown-submenu:hover>a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left>.dropdown-menu { + left: -100%; + margin-left: 10px; + border-radius: 6px 0 6px 6px; +} + +/* Sidebar --------------------------*/ + +#pkgdown-sidebar { + margin-top: 30px; + position: -webkit-sticky; + position: sticky; + top: 70px; +} + +#pkgdown-sidebar h2 { + font-size: 1.5em; + margin-top: 1em; +} + +#pkgdown-sidebar h2:first-child { + margin-top: 0; +} + +#pkgdown-sidebar .list-unstyled li { + margin-bottom: 0.5em; +} + +/* bootstrap-toc tweaks ------------------------------------------------------*/ + +/* All levels of nav */ + +nav[data-toggle='toc'] .nav > li > a { + padding: 4px 20px 4px 6px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; +} + +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 5px; + color: inherit; + border-left: 1px solid #878787; +} + +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 5px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; + border-left: 2px solid #878787; +} + +/* Nav: second level (shown on .active) */ + +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} + +nav[data-toggle='toc'] .nav .nav > li > a { + padding-left: 16px; + font-size: 1.35rem; +} + +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 15px; +} + +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 15px; + font-weight: 500; + font-size: 1.35rem; +} + +/* orcid ------------------------------------------------------------------- */ + +.orcid { + font-size: 16px; + color: #A6CE39; + /* margins are required by official ORCID trademark and display guidelines */ + margin-left:4px; + margin-right:4px; + vertical-align: middle; +} + +/* Reference index & topics ----------------------------------------------- */ + +.ref-index th {font-weight: normal;} + +.ref-index td {vertical-align: top; min-width: 100px} +.ref-index .icon {width: 40px;} +.ref-index .alias {width: 40%;} +.ref-index-icons .alias {width: calc(40% - 40px);} +.ref-index .title {width: 60%;} + +.ref-arguments th {text-align: right; padding-right: 10px;} +.ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} +.ref-arguments .name {width: 20%;} +.ref-arguments .desc {width: 80%;} + +/* Nice scrolling for wide elements --------------------------------------- */ + +table { + display: block; + overflow: auto; +} + +/* Syntax highlighting ---------------------------------------------------- */ + +pre, code, pre code { + background-color: #f8f8f8; + color: #333; +} +pre, pre code { + white-space: pre-wrap; + word-break: break-all; + overflow-wrap: break-word; +} + +pre { + border: 1px solid #eee; +} + +pre .img, pre .r-plt { + margin: 5px 0; +} + +pre .img img, pre .r-plt img { + background-color: #fff; +} + +code a, pre a { + color: #375f84; +} + +a.sourceLine:hover { + text-decoration: none; +} + +.fl {color: #1514b5;} +.fu {color: #000000;} /* function */ +.ch,.st {color: #036a07;} /* string */ +.kw {color: #264D66;} /* keyword */ +.co {color: #888888;} /* comment */ + +.error {font-weight: bolder;} +.warning {font-weight: bolder;} + +/* Clipboard --------------------------*/ + +.hasCopyButton { + position: relative; +} + +.btn-copy-ex { + position: absolute; + right: 0; + top: 0; + visibility: hidden; +} + +.hasCopyButton:hover button.btn-copy-ex { + visibility: visible; +} + +/* headroom.js ------------------------ */ + +.headroom { + will-change: transform; + transition: transform 200ms linear; +} +.headroom--pinned { + transform: translateY(0%); +} +.headroom--unpinned { + transform: translateY(-100%); +} + +/* mark.js ----------------------------*/ + +mark { + background-color: rgba(255, 255, 51, 0.5); + border-bottom: 2px solid rgba(255, 153, 51, 0.3); + padding: 1px; +} + +/* vertical spacing after htmlwidgets */ +.html-widget { + margin-bottom: 10px; +} + +/* fontawesome ------------------------ */ + +.fab { + font-family: "Font Awesome 5 Brands" !important; +} + +/* don't display links in code chunks when printing */ +/* source: https://stackoverflow.com/a/10781533 */ +@media print { + code a:link:after, code a:visited:after { + content: ""; + } +} + +/* Section anchors --------------------------------- + Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 +*/ + +div.csl-bib-body { } +div.csl-entry { + clear: both; +} +.hanging-indent div.csl-entry { + margin-left:2em; + text-indent:-2em; +} +div.csl-left-margin { + min-width:2em; + float:left; +} +div.csl-right-inline { + margin-left:2em; + padding-left:1em; +} +div.csl-indent { + margin-left: 2em; +} diff --git a/docs/pkgdown.js b/docs/pkgdown.js new file mode 100644 index 0000000..6f0eee4 --- /dev/null +++ b/docs/pkgdown.js @@ -0,0 +1,108 @@ +/* http://gregfranko.com/blog/jquery-best-practices/ */ +(function($) { + $(function() { + + $('.navbar-fixed-top').headroom(); + + $('body').css('padding-top', $('.navbar').height() + 10); + $(window).resize(function(){ + $('body').css('padding-top', $('.navbar').height() + 10); + }); + + $('[data-toggle="tooltip"]').tooltip(); + + var cur_path = paths(location.pathname); + var links = $("#navbar ul li a"); + var max_length = -1; + var pos = -1; + for (var i = 0; i < links.length; i++) { + if (links[i].getAttribute("href") === "#") + continue; + // Ignore external links + if (links[i].host !== location.host) + continue; + + var nav_path = paths(links[i].pathname); + + var length = prefix_length(nav_path, cur_path); + if (length > max_length) { + max_length = length; + pos = i; + } + } + + // Add class to parent
  • , and enclosing
  • if in dropdown + if (pos >= 0) { + var menu_anchor = $(links[pos]); + menu_anchor.parent().addClass("active"); + menu_anchor.closest("li.dropdown").addClass("active"); + } + }); + + function paths(pathname) { + var pieces = pathname.split("/"); + pieces.shift(); // always starts with / + + var end = pieces[pieces.length - 1]; + if (end === "index.html" || end === "") + pieces.pop(); + return(pieces); + } + + // Returns -1 if not found + function prefix_length(needle, haystack) { + if (needle.length > haystack.length) + return(-1); + + // Special case for length-0 haystack, since for loop won't run + if (haystack.length === 0) { + return(needle.length === 0 ? 0 : -1); + } + + for (var i = 0; i < haystack.length; i++) { + if (needle[i] != haystack[i]) + return(i); + } + + return(haystack.length); + } + + /* Clipboard --------------------------*/ + + function changeTooltipMessage(element, msg) { + var tooltipOriginalTitle=element.getAttribute('data-original-title'); + element.setAttribute('data-original-title', msg); + $(element).tooltip('show'); + element.setAttribute('data-original-title', tooltipOriginalTitle); + } + + if(ClipboardJS.isSupported()) { + $(document).ready(function() { + var copyButton = ""; + + $("div.sourceCode").addClass("hasCopyButton"); + + // Insert copy buttons: + $(copyButton).prependTo(".hasCopyButton"); + + // Initialize tooltips: + $('.btn-copy-ex').tooltip({container: 'body'}); + + // Initialize clipboard: + var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { + text: function(trigger) { + return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); + } + }); + + clipboardBtnCopies.on('success', function(e) { + changeTooltipMessage(e.trigger, 'Copied!'); + e.clearSelection(); + }); + + clipboardBtnCopies.on('error', function() { + changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); + }); + }); + } +})(window.jQuery || window.$) diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml new file mode 100644 index 0000000..c087dfa --- /dev/null +++ b/docs/pkgdown.yml @@ -0,0 +1,8 @@ +pandoc: 3.1.1 +pkgdown: 2.0.7 +pkgdown_sha: ~ +articles: + tracking_model_OLR: tracking_model_OLR.html + tracking_seviri_brightness_temp: tracking_seviri_brightness_temp.html +last_built: 2024-09-25T12:10Z + diff --git a/docs/reference/Rplot001.png b/docs/reference/Rplot001.png new file mode 100644 index 0000000..17a3580 Binary files /dev/null and b/docs/reference/Rplot001.png differ diff --git a/docs/reference/detect_features_multithreshold.html b/docs/reference/detect_features_multithreshold.html new file mode 100644 index 0000000..ddf986e --- /dev/null +++ b/docs/reference/detect_features_multithreshold.html @@ -0,0 +1,242 @@ + +harp wrapper for the tobac feature_detection_multithreshold() function — detect_features_multithreshold • harpTobac + + +
    +
    + + + +
    +
    + + +
    +

    This function is used to detect features on a field based on contiguous +regions. The regions are above / below a threshold depending on the value of +the target argument. Note that 3d features are not yet implemented for this +wrapper.

    +
    + +
    +
    detect_features_multithreshold(
    +  field_data,
    +  thresholds,
    +  data_col = "gridded_data",
    +  dttm_col = "valid_dttm",
    +  target = c("max", "min"),
    +  position_threshold = c("centre", "extreme", "weighted_diff", "weighted_abs"),
    +  sigma_threshold = 0.5,
    +  n_erosion_threshold = 0,
    +  n_min_threshold = 0,
    +  min_distance = 0,
    +  feature_number_start = 1,
    +  pbc_flag = c("none", "h_dim1", "h_dim2", "both"),
    +  vertical_coord = NULL,
    +  vertical_axis = NULL,
    +  detect_subset = NULL,
    +  wavelength_filtering = NULL,
    +  dz = NULL,
    +  strict_thresholding = FALSE
    +)
    +
    + +
    +

    Arguments

    +
    field_data
    +

    A harp_grid_df data frame such as one returned by the +harpIO functions +harpIO::read_grid() with data_frame = TRUE, harpIO::read_forecast(), +or harpIO::read_analysis().

    + + +
    thresholds
    +

    Threshold values used to select target regions to track. +The feature detection is inclusive of the threshold value(s), i.e. values +greater/less than or equal are included in the target region. The target +argument controls whether the detection is based on less than or greater +than the threshold(s).

    + + +
    data_col
    +

    <tidy-select> The column in +field_data containing the fields to be used to detect features in. Should +be a <geolist> column. If the named column is not found in field_data, +but field_data contains 1 <geolist> column, that <geolist> column is +used.

    + + +
    dttm_col
    +

    <tidy-select> The column in +field_data containing the date-times to be used for the time dimension. +Can be numeric with units in Unix time (seconds since 1970-01-01 00:00:00), +or a <POSIXt>column. If the named column is not found in field_data, +but field_data contains 1 <POSIXt> column, that <POSIXt> column is +used.

    + + +
    target
    +

    Flag to determine if tracking is targeting minima or maxima in +the data. Should be "max" or "min". Default is "max".

    + + +
    position_threshold
    +

    Flag to choose the method to be used for the +setting the position of the tracked feature. Can be one of "centre", +"extreme", or "weighted_diff". Default is ‘centre’, though "weighted_diff" +is often preferable for atmospheric features.

    + + +
    sigma_threshold
    +

    Standard deviation for initial filtering step. Default +is 0.5.

    + + +
    n_erosion_threshold
    +

    Number of pixels by which to erode the identified +features. Default is 0.

    + + +
    n_min_threshold
    +

    Minimum number of identified contiguous pixels for a +feature to be detected. Default is 0.

    + + +
    min_distance
    +

    Minimum distance between detected features (in metres). +Default is 0.

    + + +
    feature_number_start
    +

    Feature id to start with. Default is 1.

    + + +
    pbc_flag
    +

    Sets whether to use periodic boundaries, and if so in which +directions. "none" means that we do not have periodic boundaries "hdim_1" +means that we are periodic along hdim1, "hdim_2" means that we are periodic +along hdim2 and "both" means that we are periodic along both horizontal +dimensions

    + + +
    vertical_coord
    +

    Name of the vertical coordinate. If NULL, tries to +auto-detect. It looks for the coordinate or the dimension name +corresponding to the string.

    + + +
    vertical_axis
    +

    The vertical axis number of the data. If NULL, uses +vertical_coord to determine axis. This must be >=0.

    + + +
    detect_subset
    +

    Whether to run feature detection on only a subset of the +data. If this is not NULL, it should be a named list and it will subset +the grid that we run feature detection on to the range specified for each +axis specified. The format of this list is: list(axis-number = c(start, end)), where axis-number is the number of the axis to subset, start is +inclusive, and end is exclusive. For example, if your data are oriented as +(time, z, y, x) and you want to only detect on values between z levels 10 +and 29, you would set: list("1" = c(10, 30)). Note that this is not +tested.

    + + +
    wavelength_filtering
    +

    Minimum and maximum wavelength for horizontal +spectral filtering in metres as a 2 element vector. Default is NULL.

    + + +
    dz
    +

    Constant vertical grid spacing (metres). If not specified and +the input is 3D, this function requires that altitude is available in the +features input. If you specify a value here, this function assumes that it +is the constant z spacing between points, even if z_coordinate_name is +specified.

    + + +
    strict_thresholding
    +

    If TRUE, a feature can only be detected if all +previous thresholds have been met. Default is FALSE.

    + +
    +
    +

    Value

    + + +

    A data frame of detected features.

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 0000000..243a0ad --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,107 @@ + +Function reference • harpTobac + + +
    +
    + + + +
    +
    + + + + + + + + + + + + + +
    +

    All functions

    +

    +
    +

    detect_features_multithreshold()

    +

    harp wrapper for the tobac feature_detection_multithreshold() function

    +

    install_tobac()

    +

    Install Tobac

    +

    link_tracks()

    +

    harp wrapper to the tobac function tracking.linking_trackpy().

    +

    segment_2d()

    +

    harp wrapper for tobac segmentation.segmentation_2d() function

    +

    toabc

    +

    Main tobac module

    + + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/install_tobac.html b/docs/reference/install_tobac.html new file mode 100644 index 0000000..d83f04f --- /dev/null +++ b/docs/reference/install_tobac.html @@ -0,0 +1,117 @@ + +Install Tobac — install_tobac • harpTobac + + +
    +
    + + + +
    +
    + + +
    +

    install_tobac() installs the Python modules needed to run Tobac functions. +The packages are installed in a virtualenv, which by default is named +"harp-py". This virtual environment is the default virtual environment in +which all harp related Python modules are installed. If you already have the +"harp-py" virtualenv, you will be asked if you want to remove the virtualenv +prior to installation. Typically you would answer no to this.

    +
    + +
    +
    install_tobac(envname = "harp-py", new_env = identical(envname, "harp-py"))
    +
    + +
    +

    Arguments

    +
    envname
    +

    The virtual environment into which to install the tobac Python +modules. Default is "harp-py".

    + + +
    new_env
    +

    Whether to start from a new environment by removing the +envname if it already exists. The defulat is TRUE if envname already +exists, and you will be prompted if you want to remove the virtualenv +envname.

    + +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/link_tracks.html b/docs/reference/link_tracks.html new file mode 100644 index 0000000..82e1471 --- /dev/null +++ b/docs/reference/link_tracks.html @@ -0,0 +1,270 @@ + +harp wrapper to the tobac function tracking.linking_trackpy(). — link_tracks • harpTobac + + +
    +
    + + + +
    +
    + + +
    +

    harp wrapper to the tobac function tracking.linking_trackpy().

    +
    + +
    +
    link_tracks(
    +  features,
    +  field_data,
    +  dz = NULL,
    +  data_col = "gridded_data",
    +  dttm_col = "valid_dttm",
    +  d_max = NULL,
    +  subnetwork_size = NULL,
    +  v_max = NULL,
    +  memory = 0,
    +  stubs = 1,
    +  time_cell_min = NULL,
    +  order = 1,
    +  extrapolate = 0,
    +  method_linking = c("predict", "random"),
    +  adaptive_step = NULL,
    +  adaptive_stop = NULL,
    +  cell_number_start = 1,
    +  cell_number_unassigned = -1,
    +  vertical_coord = NULL,
    +  min_h1 = NULL,
    +  max_h1 = NULL,
    +  min_h2 = NULL,
    +  max_h2 = NULL,
    +  pbc_flag = c("none", "hdim_1", "hdim_2", "both")
    +)
    +
    + +
    +

    Arguments

    +
    features
    +

    A features data frame as returned by +detect_features_multithreshold() or +segment_2d()

    + + +
    field_data
    +

    A harp_grid_df data frame such as one returned by the +harpIO functions +harpIO::read_grid() with data_frame = TRUE, harpIO::read_forecast(), +or harpIO::read_analysis().

    + + +
    dz
    +

    Constant vertical grid spacing (meters), optional. If not specified +and the input is 3D, this function requires that vertical_coord is +available in the features input. If you specify a value here, this function +assumes that it is the constant z spacing between points, even if +vertical_coord is specified.

    + + +
    data_col
    +

    <tidy-select> The column in +field_data containing the fields to be used to detect features in. Should +be a <geolist> column. If the named column is not found in field_data, +but field_data contains 1 <geolist> column, that <geolist> column is +used.

    + + +
    dttm_col
    +

    <tidy-select> The column in +field_data containing the date-times to be used for the time dimension. +Can be numeric with units in Unix time (seconds since 1970-01-01 00:00:00), +or a <POSIXt>column. If the named column is not found in field_data, +but field_data contains 1 <POSIXt> column, that <POSIXt> column is +used.

    + + +
    d_max
    +

    Maximum search range in metres. Only one of d_max, or v_max can +be set. Default is NULL.

    + + +
    subnetwork_size
    +

    Maximum size of subnetwork for linking. This parameter +should be adjusted when using adaptive search. Usually a lower value is +desired in that case. For a more in depth explanation have look +here. +If NULL, 30 is used for regular search and 15 for adaptive search. +Default is NULL.

    + + +
    v_max
    +

    Speed at which features are allowed to move in m/s. Only one of +d_max or v_max can be set. Default is NULL.

    + + +
    memory
    +

    Number of output timesteps features allowed to vanish for to +still be considered tracked. Default is 0. Warning :: This parameter +should be used with caution, as it can lead to erroneous trajectory +linking, espacially for data with low time resolution.

    + + +
    stubs
    +

    Minimum number of timesteps of a tracked cell to be reported. +Default is 1

    + + +
    time_cell_min
    +

    Minimum length in time that a cell must be tracked for +to be considered a valid cell in seconds. Default is NULL.

    + + +
    order
    +

    Order of polynomial used to extrapolate trajectory into gaps and +on start and end point. Default is 1.

    + + +
    extrapolate
    +

    Number or timesteps to extrapolate trajectories. +Currently unused. Default is 0.

    + + +
    method_linking
    +

    Flag choosing method used for trajectory linking. Can +be "predict" or "random". Default is ‘predict’. Note: the default in +tobac is "random" though they typically encourage users to use ‘predict’.

    + + +
    adaptive_step
    +

    Reduce search range by multiplying it by this factor. +Needs to be used in combination with adaptive_stop. Default is NULL.

    + + +
    adaptive_stop
    +

    If not NULL, when encountering an oversize subnet, retry by progressively reducing search_rangeby multiplying withadaptive_stepuntil the subnet is solvable. If search_range becomes <=adaptive_stop, give up and raise a SubnetOversizeException. Needs to be used in combination with adaptive_step. Default is NULL`.

    + + +
    cell_number_start
    +

    Cell number for first tracked cell. Default is 1.

    + + +
    cell_number_unassigned
    +

    Number to set the unassigned/non-tracked cells +to. Default is -1.

    + + +
    vertical_coord
    +

    Name of the vertical coordinate. The vertical +coordinate used must be metres. If NULL, it tries to auto-detect. It looks for the coordinate or the dimension name corresponding to the string. To use dz, set this to NULL`.

    + + +
    min_h1
    +

    Minimum hdim_1 value, required when pbc_flag is "hdim_1" or +"both".

    + + +
    max_h1
    +

    Maximum hdim_1 value, required when pbc_flag is "hdim_1" or +"both".

    + + +
    min_h2
    +

    Minimum hdim_2 value, required when pbc_flag is "hdim_2" or +"both".

    + + +
    max_h2
    +

    Maximum hdim_2 value, required when pbc_flag is "hdim_2" or +"both".

    + + +
    pbc_flag
    +

    Sets whether to use periodic boundaries, and if so in which +directions. "none" means that we do not have periodic boundaries "hdim_1" +means that we are periodic along hdim1, "hdim_2" means that we are periodic +along hdim2 and "both" means that we are periodic along both horizontal +dimensions

    + +
    +
    +

    Value

    + + +

    Data frame of the linked features, containing the column "cell", with +integers indicating the affiliation of a feature to a specific track, and +the variable "time_cell" with the time, in seconds' the cell has already +existed.

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/segment_2d.html b/docs/reference/segment_2d.html new file mode 100644 index 0000000..a346b1c --- /dev/null +++ b/docs/reference/segment_2d.html @@ -0,0 +1,194 @@ + +harp wrapper for tobac segmentation.segmentation_2d() function — segment_2d • harpTobac + + +
    +
    + + + +
    +
    + + +
    +

    harp wrapper for tobac segmentation.segmentation_2d() function

    +
    + +
    +
    segment_2d(
    +  features,
    +  field_data,
    +  threshold,
    +  data_col = "gridded_data",
    +  dttm_col = "valid_dttm",
    +  target = c("max", "min"),
    +  level = NULL,
    +  method = "watershed",
    +  max_distance = NULL,
    +  pbc_flag = c("none", "h_dim1", "h_dim2", "both"),
    +  seed_3d_flag = c("column", "box"),
    +  statistic = NULL
    +)
    +
    + +
    +

    Arguments

    +
    features
    +

    A features data frame, as returned by +detect_features_multithreshold().

    + + +
    field_data
    +

    A harp_grid_df data frame such as one returned by the +harpIO functions +harpIO::read_grid() with data_frame = TRUE, harpIO::read_forecast(), +or harpIO::read_analysis().

    + + +
    threshold
    +

    Threshold for the watershedding field to be used for the +mask.

    + + +
    data_col
    +

    <tidy-select> The column in +field_data containing the fields to be used to detect features in. Should +be a <geolist> column. If the named column is not found in field_data, +but field_data contains 1 <geolist> column, that <geolist> column is +used.

    + + +
    dttm_col
    +

    <tidy-select> The column in +field_data containing the date-times to be used for the time dimension. +Can be numeric with units in Unix time (seconds since 1970-01-01 00:00:00), +or a <POSIXt>column. If the named column is not found in field_data, +but field_data contains 1 <POSIXt> column, that <POSIXt> column is +used.

    + + +
    target
    +

    Flag to determine if tracking is targeting minima or maxima in +the data. Should be "max" or "min". Default is "max".

    + + +
    level
    +

    Levels at which to seed the cells for the watershedding +algorithm. Default is NULL.

    + + +
    method
    +

    Flag determining the algorithm to use (currently only +"watershed" is implemented).

    + + +
    max_distance
    +

    Maximum distance from a marker allowed to be classified +as belonging to that cell in metres. Default is NULL.

    + + +
    pbc_flag
    +

    Sets whether to use periodic boundaries, and if so in which +directions. "none" means that we do not have periodic boundaries "hdim_1" +means that we are periodic along hdim1, "hdim_2" means that we are periodic +along hdim2 and "both" means that we are periodic along both horizontal +dimensions

    + + +
    seed_3d_flag
    +

    Seed 3D field at feature positions with either the full +column (default) or a box of user-set size.

    + + +
    statistic
    +

    Default is NULL. Parameter to calculate bulk statistics +within feature detection. Named list with callable function(s) to apply +over the region of each detected feature and the name of the statistics to +appear in the feature output data frame. The functions should be the values +and the names of the metric the keys (e.g. list(mean = np.mean)). This +probably doesn't work yet as there needs to be a translation between R and +Python functions here.

    + +
    +
    +

    Value

    + + +

    A named list with:

    • segments: A data frame with a geolist column with 2d fields on the +same domain as the input data with integer values denoting each segment.

    • +
    • features: Feature data frame including the number of cells in the +segmented area of the feature at the time step.

    • +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/toabc.html b/docs/reference/toabc.html new file mode 100644 index 0000000..d0cb22c --- /dev/null +++ b/docs/reference/toabc.html @@ -0,0 +1,109 @@ + +Main tobac module — toabc • harpTobac + + +
    +
    + + + +
    +
    + + +
    +

    Interface to main Tobac module. Provides access to top level functions as +well as sub-modules using $ instead of . as in Python.

    +
    + +
    +
    toabc
    +
    + +
    +

    Format

    +

    Tobac module

    +
    + +
    +

    Examples

    +
    if (FALSE) {
    +library(tobac)
    +
    +tobac$sys$api_version
    +}
    +
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/sitemap.xml b/docs/sitemap.xml new file mode 100644 index 0000000..5659dfc --- /dev/null +++ b/docs/sitemap.xml @@ -0,0 +1,45 @@ + + + + /404.html + + + /LICENSE.html + + + /articles/index.html + + + /articles/tarcking_seviri_brightness_temp.html + + + /articles/tracking_model_OLR.html + + + /articles/tracking_seviri_brightness_temp.html + + + /authors.html + + + /index.html + + + /reference/detect_features_multithreshold.html + + + /reference/index.html + + + /reference/install_tobac.html + + + /reference/link_tracks.html + + + /reference/segment_2d.html + + + /reference/toabc.html + + diff --git a/vignettes/tarcking_seviri_brightness_temp.Rmd b/vignettes/tracking_seviri_brightness_temp.Rmd similarity index 100% rename from vignettes/tarcking_seviri_brightness_temp.Rmd rename to vignettes/tracking_seviri_brightness_temp.Rmd