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

Bird flux #123

Open
ethanplunkett opened this issue Jul 11, 2023 · 12 comments · Fixed by #176
Open

Bird flux #123

ethanplunkett opened this issue Jul 11, 2023 · 12 comments · Fixed by #176
Assignees
Labels
enhancement New feature or request

Comments

@ethanplunkett
Copy link
Contributor

ethanplunkett commented Jul 11, 2023

Currently all our modelling is based on stopping locations. However, with big movements many birds may pass over cells without stopping. To answer the question how many birds pass through a cell (or approximation of one) in a given week we would sum the density of not just the birds that stop or start from that cell but also any birds that, in that week's movement, pass through the cell.

To approximate this we'd first build a n x n x n array where n is n_active() the first dimension is the starting location index, the second dimension is the ending location index, and the third dimensions is touched locations. Cell values would be TRUE if the location indicated by the third dimension is on the path between the first and second dimension. "Touching" would be defined here as the cell center being within 1/2 the cell width of the line. This is equivalent to drawing a circle within each square cell that touches the four sides and seeing if the line touches or crosses through that circle.

We could then, for any given timestep, determine the total density that enters, leaves, or passes through each cell: the bird flux.

We could also calculate a density weighted average vector for all the birds that pass through the cell. I think we'd want to include stationary birds in this calculation too.

@ethanplunkett ethanplunkett added the enhancement New feature or request label Jul 11, 2023
@slager
Copy link
Contributor

slager commented Jul 11, 2023

How would flux estimates work for species where many tracks cross the ocean? For some bird species, ocean crossings and/or non-straight-line migration trajectories are the norm, so being able to calculate fluxes across our grid seems tricky at best.

@dsheldon
Copy link
Contributor

I suggest having a parameter that allows the circle radius (around the center point of the cell) to be different from the grid cell size and then dividing by the length and time units so the measurement has units

birds / km / hr

This matches with the standard "migration traffic rate (MTR)" used in radar analysis. This will help decouple the measurement from the grid dimensions and give a measurement that can be thought of as a pointwise measurement of traffic near a location.

@ethanplunkett
Copy link
Contributor Author

It's dependent on the assumption that migration between stops is linear so will be less accurate when that assumption isn't met but I still think it would be useful.

Good point @slager that birds cross cells that aren't active in our model, output should probably be for all cells in the extent not just active cells, so the logical array"s third dimension would be nrow(bf) x ncol(bf). For efficiency it could be trimmed down to the subset of cells that are crossed with a mask made just for that purpose.

@ethanplunkett
Copy link
Contributor Author

@dsheldon that seems reasonable but requires a total population estimate to convert between density and number of birds. We don't currently have that in the species information.

@dsheldon
Copy link
Contributor

We can keep the numerator in units of fraction of the population, then let users convert if they want to hazard a guess at the total population. This is consistent with radar work, where the density is proportional to the number of birds through difficult-to-estimate constants.

@ethanplunkett
Copy link
Contributor Author

Figure out how to summarize direction too. Perhaps in directional bins, perhaps as a mean and SD.

@ethanplunkett
Copy link
Contributor Author

Use great circle distances and spherical coordinates.

@ethanplunkett ethanplunkett self-assigned this Mar 6, 2024
@ethanplunkett
Copy link
Contributor Author

@dsheldon Do you think we should count arriving birds, departing birds, and birds passing overhead? I see arguments for:

  1. Only count the birds passing overhead as (maybe) this is what Radar is most likely to pick up on.
  2. Count passing overhead and one of the other two as counting both arriving and departing double counts those birds.
  3. Count arriving, departing, and passing overhead as that's the sum total of movement at the given point for the transition.

As I've implemented it the user can input points or if they don't all cells in the BirdFlow raster extent that are active OR fall between active cells are used as the points. Thus with the defaults behavior the points fall on the center of BirdFlow cells. When the user submits arbitrary points (say radar station locations) then it is less clear what (1) and (2) mean, but we could look up the cells that the points fall within and exclude them in the betweenness array.

For now I'm proceeding with (3) but it's easy to change.

@ethanplunkett
Copy link
Contributor Author

Preliminary non-directional flux (maybe "net migration" is a better term for this?):

image

For American Woodcock based on BirdFlowModels::amewoo

@dsheldon
Copy link
Contributor

dsheldon commented Mar 7, 2024

Regarding your previous question: I support counting birds that arrive or depart in addition to passing over, as they would appear airborne in the circle of specified radius.

I would not count birds that start and end in a cell that intersects with the circle, as the mostly likely situation is that those birds are not migrating.

@ethanplunkett ethanplunkett linked a pull request Mar 27, 2024 that will close this issue
@ethanplunkett ethanplunkett reopened this Mar 27, 2024
@ethanplunkett
Copy link
Contributor Author

Note #176 includes non-directional flux only.

@ethanplunkett
Copy link
Contributor Author

ethanplunkett commented Mar 28, 2024

Flux to do:

  • Scale (as discussed above)
  • Improve memory efficiency
    • Create and process lines connecting active cells in batches ~100,000
    • Determine ahead of time which transitions are used in the model based on dynamic mask and sparsification and only create lines for these transitions.
  • Add test that doesn't take forever
    • Use truncated mode
    • Possibly make new super coarse test model
    • Possibly use cached between matrix and test is_between() on a toy example
    • Use sparse model
  • Add directionality
    • Calculate non directional betweeness first, and then only calculate directionality for the small subset that are between.
    • Option 1 for each point - line combo:
      • Snap point to great circle.
      • Calculate initial great circle heading to destination from snapped point
    • Option 2 - for each line
      • Create segments of the great circle
      • calculate heading for each segment.
      • snap points that are "between" (close to line) to the nearest segment and assign it's heading
    • do for upper triangle only, then reverse headings for lower triangle
    • Don't worry about efficiency yet (it's going to be slow and scale poorly) but some optimization strategies:
      • Sparsify models first - this will eliminate a lot of very infrequently used connections that we can skip (see above)
      • C++
      • For the big batch of models with identical extents consider caching and reusing betweeness information.
        • Calculating one large betweenness matrix that covers the common extent and subsetting it for each dynamic mask would work, but due to $O(N^3)$ scaling and the fact that many of the connections would never be used this would probably be worse.
        • Instead we could partially fill out the full extent betweeness array. Use existing values. Calculate new values as needed and add them to the array.
      • All this is a lot of complexity, and is not suited to running species in parallel. So I'm not doing for now.

ethanplunkett added a commit that referenced this issue Mar 29, 2024
- fix memory problem
- add tests
- add radius based scaling
                            #123
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants