Starting the new year and hoping the pandemic would be soon over turned out to be an illusion. In many countries Instead of efficient vaccinations we had to face a series of new lockdowns and severe restrictions. New virus variants seem to promise even more of this whilst threatening and interrupting lives. Covid-19, of course, also affected teaching and in February I started taping my annual lectures in Individual-based Forest Ecology and Management as part of our MSc in Forest Ecology and Sustainable Forest Management. Since teaching had to be remote anyway I thought it would be appropriate to put the flipped-classroom teaching mode that I have heard of so much in recent years to a test. This I did and the students could follow my lectures in their own time. I also provided videos of my R tutorials. At regular times I then invited students to Zoom meetings for two hours at a time, so that they could ask questions and we could have a discussion. This went better than I had anticipated, however, the students were quite shy and it took a while to get them talking.
Since methods of individual-based forest management form an important part of Continuous Cover Forestry (CCF; sometimes also termed Near-Natural Forestry), I also had to say a few words on CCF and like last year I was overwhelmed by the positive response of the students. Not only students from outside Sweden were extremely interested in CCF, but also our Swedish MSc students. This is encouraging, since CCF is thought of as an important instrument for mitigating climate change and the Swedish forest industry has so far not much subscribed to alternatives to clearfelling.
Two interesting things came up in the quantitative realm of the lectures. When introducing the aggregation index by Clark and Evans (1954) I remembered that the R spatstat package (Baddeley et al., 2016) offers the function clickppp() which allows the user to determine their own point pattern by mouse clicking. Using this function turned out to be quite a bit of fun, as you can carry out your own little experiments. For example, you can ask your friends and colleagues to try aiming at a random pattern. If carried out correctly, the spatstat function relating to the Clark and Evans index should return a value near 1.
library(spatstat) # Go for your own experiment myDataP <- clickppp(win = owin(c(0, 50), c(0, 50))) # Using spatstat clarkevans(myDataP)
You can first try this yourself and you will most likely discover how hard it is to produce a random point pattern. Although we really try hard to randomly place points, we rarely succeed. You can then go on and other people of different age, gender, cultural background etc. to see, of anyone or any group of people is less biased than you are yourself. This could even become a nice exercise in citizen science similar to the counting of singing-bird species in people’s gardens on particular days of the year. What we currently know about such simple experiments puts a question mark over all technical instructions where we are supposed to pick or place something at random. Obviously it seems that we are not able to do that. And yet, often surveys and other activities actually rely on this randomness.
The other interesting matter related to the idea of a student to model silvicultural systems using spatial statistics. The young lady in question came across the lines in my textbook on page 90 where I discussed the group shelterwood system and mentioned that in uplands often elliptical shapes are preferred for opening the main forest canopy to better take into account the light regime and the snow conditions in such topography. She developed this idea of simulating the locations of trees of the forest stand by using a Poisson point process model (to produce random tree locations again). In a second step an ellipse would be placed in the observation window and all tree locations inside the ellipse would be removed. Here is the code:
library(spatstat) library(plotrix) insideEllipse <- function(ex, ey, rx, ry, xvector, yvector) { return((xvector - ex)^2 / rx^2 + (yvector - ey)^2 / ry^2) } set.seed(round(runif(1, min = 1, max = 10000))) # Ramdom starting point xmax <- 100 # Observation window defined by xmax and ymax ymax <- 100 myLambda <- 0.05 # Point density pattern <- rpoispp(lambda = myLambda, win = owin(c(0, xmax), c(0, ymax)), nsim = 1) # Poisson process myX <- pattern$x # Save x and y in separate vectors myY <- pattern$y ellipseX <- runif(1, min = 0, max = xmax) # Define random ellipse centre ellipseY <- runif(1, min = 0, max = ymax) rx <- 20 # Define semi-major axis ry <- 30 # Define semi-minor axis thin <- insideEllipse(ellipseX, ellipseY, rx, ry, myX, myY) <= 1 # Determine points to delete myX <- myX[!thin] # Retain points not earmarked for deletion myY <- myY[!thin] pattern <- ppp(myX, myY, xrange = c(0, xmax), yrange = c(0, ymax)) # Define new ppp after thinning plot(pattern) # Plot the point pattern draw.ellipse(ellipseX, ellipseY, a = rx, b = ry, angle = c(0), border = "red")
You can run the code several times and will find that both the surrounding point pattern and the ellipses change from run to run. Another extension would be to add a random angle so that the semi-major axis of the ellipse would not run in parallel with one of the axes of the system of coordinates. Such code provides a better understanding of what ellipse cuttings as part of shelterwood systems imply and allow their simulations in growth projection models.
These were nice examples of students actively engaging in the course. I look forward to what we will discover together next year.