Introduction
Design
Habitat mask
Costing
Simulation
Spacing
Summary
Options
Troubleshooting
References
Appendices
This Shiny application is an interactive interface to parts of the R package secrdesign (Efford 2025a). General context is provided by the study design chapter of the online SECR book (Efford 2025b).
The application focuses on the effect of detector layout and other design variables on the precision of density estimates, measured by the relative standard error (RSE, aka CV). Vary settings on the Design page to obtain an immediate “rule-of-thumb” approximation to RSE($\hat D$), based on the expected numbers of recaptures and distinct individuals (Efford and Boulanger 2019). The current source code is available from https://GitHub.com/MurrayEfford/secrdesignapp.
The RSE approximation is biased low for some layouts, especially when sample size is small. A correction factor may be applied to adjust the approximation. Refine the approximation by simulating data from the chosen design; this may take a long time. The correction factor is updated automatically from simulation results (see Options to suppress this). Use “Add to summary” to include the current scenario in a spreadsheet for export.
Documentation for secrdesign is available at www.otago.ac.nz/density and in the SECR Book. For example:
secrdesign-manual.pdf (details of each function)
secrdesign-tools.pdf (optimal spacing etc.)
secrdesign-Enrm.pdf (expected sample size)
TIP: on small displays, running your browser in full-screen mode will avoid the need to scroll down (often F11 will get you there; otherwise try the options menu).
TIP: you can run the latest version of secrdesignapp on your own machine directly from GitHub - see the link above.
IMPORTANT NOTE: Maximising precision is only one component of study design. Sampling must also be representative of the population in the region of interest. Linear arrays are unreliable when home ranges are elongated in a common direction (Efford 2019).
ACKNOWLEDGEMENT: Greg Trounson (Department of Mathematics and Statistics, University of Otago) has provided invaluable and continuing help by testing the app and maintaining it on the server.
Use settings on this page to specify a detector layout, population and sampling parameters. The settings are interpreted in various plots and used for calculations shown in the Results window. They are also used for calculations on later pages (Costing, Spacing, Simulation).
\( \renewcommand{\vec}[1]{\mathbf{#1}} \)
| Detector type | multi, proximity, or count |
Options for detector type follow secr (Efford 2025c): “multi” refers to a multi-catch trap; “proximity” to binary proximity detectors, and “count” to detectors that yield integer counts. Counts are assumed to be Poisson-distributed.
The detector layout (‘Array’) may be specified as a rectangular grid or line (via make.grid), read from a file, or as a systematic or random array within a region. Code for generating an array according to the current settings is shown on the Simulation page.
For a rectangular grid the options are:
| rows | number of rows (ny) |
| columns | number of columns (nx) |
| row spacing | metres (spacey) |
| column spacing | metres (spacex) |
| hollow | detectors only on perimeter? |
The secr function make.grid forms a rectangular detector layout. By default, column settings are equal to row settings; to alter this either change the column settings after the row setings, or see Options to uncouple rows and columns. The order of detectors is column-boustrophedonical (make.grid argument ID = “numxb”), so connecting them in sequence gives a plausible route. See ?make.grid for more.
The ‘Suggest spacing’ button finds the spacing with \( \small \mathrm E (n) = \mathrm E ( r ) \) and sets this for the current grid.
For a line the options are simply the number of detectors and the spacing. Lines are implemented with make.grid as for grids. The ‘Suggest spacing’ button finds the spacing with \( \small \mathrm E (n) = \mathrm E ( r ) \) and sets this for the current line.
This uses a text file in the format for secr function read.traps. The file typically should have three columns (trapID, x, y) with no headers. Optional arguments separated by commas may be used to customise input (e.g., skip, which is passed through read.traps to read.table).
A region is a study area within which detectors will be placed either systematically on a square grid or at random. For both systematic and random options the elements may be a single detector or a cluster of detectors (Grid or Line). The region boundary may be provided as either
GIS operations use sf internally (Pebesma 2018).
See Options | Detector array to control the clipping of detector clusters that cross the boundary of the region.
Two algorithms are offered for random placement - a simple random sample of points (SRS) or a balanced spatial sample (GRTS) as described by Stevens and Olsen (2004) and implemented in package spsurvey (Kincaid and Olsen 2018).
A systematic array is specified by the cluster design, the spacing between cluster centres, and the origin. By default the origin is fixed at (+sp/2, +sp/2) relative to the lower left corner of the bounding box of the region, where sp is the array spacing. Alternately the origin may be chosen at random within a square of side sp.
The component clusters (other than single detectors) are defined on the relevant tab (e.g. Grid).
The ‘Lacework’ option (secr \(\ge\) 4.1.1) places detectors along the lines of a square grid. The expected number of detectors is shown in teal. Spacing of the gridlines in secrdesignapp >= 1.6 is a multiple of the spacing along the lines, to eliminate close spacing at intersections. Lacework assumes single detectors.
Detector clusters are rotated by the specified number of degrees (there’s not much to gain from this, but 45 degrees looks nice).
Choosing a random origin or random array results in a set of locations that changes whenever one of the detector options changes. A seed of zero is interpreted as NULL, resulting in a new random number stream each time. For repeatable randomisation, set the random seed to an integer greater than zero.
The latest addition to secrdesignapp is optimization of detector layouts using a genetic algorithm as implemented in the R package kofnGA (Wolters 2015). The criterion may be either the lesser of the expected numbers of individuals or recaptures (min(n,r); Efford and Boulanger 2019, Durbach et al. 2021) or the number detected at two or more detectors (n2; cf Dupont et al. 2021). The ‘min(n,r)’ criterion is the default, and is usually preferred.
The GA method starts with a set of potential detector locations. Usually these lie on a fine grid across the region where detectors might be placed; the grid spacing is controlled by the user. Alternatively, the user may provide a file of potential locations, defined previously using the File tab. Potential locations are shown as grey dots on an interim plot of the region.
Calculation of E($n$) and E($r$) or E($n_2$) uses the secrdesign functions Enrm or En2 and the various parameter settings (D, lambda0, sigma etc.). This requires an ad hoc habitat mask that is computed on the fly by buffering around the region (default external buffer zero; may be positive or negative). The mask mesh dimension nx is taken from the Habitat mask page (default nx = 32; other settings from that page are ignored in GA optimization).
The Optimize button initiates a call to kofnGA. This can take considerable time, and progress is not shown. On completion, the final message from kofnGA with the best value of the objective function (OF) is displayed. This should match the value of min(n,r) or n2 shown in the Results panel, except for differences due to differences between the temporary and final habitat masks. The kofnGA ngen and kofnGA popsize settings control the GA algorithm; defaults are too small for many purposes. With criterion ‘min(n,r)’ it is expected that the optimum will have E($n$) = E($r$); a difference greater than 1.0 is flagged: the result is not optimum and ngen or popsize should be increased.
The optimized detector array is treated like any other input array in downstream computations (Results, Simulate etc.).
| Density | animals per hectare (multiply by 100 for animals per km2) |
| Detection function | HHN hazard halfnormal \( \small \lambda(d) = -\lambda_0 \exp\{-d^2/(2\sigma^2)\} \) |
| HEX hazard negative exponential \( \small \lambda(d) = -\lambda_0 \exp(-d/\sigma) \) | |
| lambda0 | intercept \(\lambda_0\) |
| sigma | spatial scale \(\sigma\) |
Only two detection functions are supported: ‘HHN’ and ‘HEX’. These relate an animal’s hazard of detection at a particular detector on a particular sampling occasion (\(\lambda\)) to the distance \(\small d\) of the detector from its home-range centre. The corresponding probability of detection is \( \small g(d) = 1 - \exp { - \lambda(d)} \).
See the Detectfn plot for the effect of given lambda0 and sigma.
| Occasions | number of sampling occasions (times detectors were checked) |
| Arrays | number of replicate identical arrays (not for Region array) |
| Distribution | distribution of number detected |
A study may be extended by sampling on more occasions. The number of recaptures \(r\) increases indefinitely, but the number of distinct individuals \(n\) levels off.
Setting Arrays > 1 is a useful way to predict the outcome from multiple detector clusters when no region has been specified. Replicating the sampling effort at many independent locations within the same population increases both \(r\) and \(n\). Using multiple clusters (repeated arrays) is also a way to sample a large region. We assume detector clusters are far enough apart that no animal is detected on more than one cluster (array).
The Distribution radio button toggles between two models for the number of detected individuals \(n\). The “Binomial” option corresponds to fixed number \(N\) in the masked area and a binomial point process for the distribution of activity centres. The “Poisson” option corresponds to Poisson \(N\) and a Poisson point process for activity centres. The chosen distribution is used in simulations for both generating data and fitting a model.
The ‘Auto refresh’ box may be unchecked to delay updating until you have fully specified a scenario. This can save a lot of time.
| Simulate | Simulate current scenario with settings on Simulation page |
| Add to summary | Transfer scenario and results to summary table |
| Reset all | Reset all input options to defaults (except file inputs) |
Simulation output is shown on the Simulation page and added to the Summary by default.
Bookmarking was offered in early versions; it has been disabled.
Values in the Results window are updated automatically when the inputs change.
| Expected number of individuals1 | \(n\) |
| Expected number of recaptures1,2 | \(r\) |
| Expected number of movements1,3 | \(m\) |
| Median detectors per 95% home range4 | across region for all non-zero points |
| Overlap coefficient5 | \( k = \sigma \sqrt D / 100 \) |
| Effective sampling area6 | \(a = \int_{R^2} p_\cdot(\vec x) \, d \vec x \) |
| Rule-of-thumb RSE7 | \( 100 . \mathrm{CF} / \sqrt { \mathrm{min} (n,r)} \) |
Many of the Results require integration over possible animal locations. This is approximated by summing pixels in the ‘habitat mask’ defined in Habitat mask. The mask specification is usually not critical, but you may wish to play (e.g., cut nx to 32 for faster refresh).
The relative standard error RSE (aka CV) is a measure of estimator precision. \(\small \mathrm{RSE}(\hat D) = \mathrm{SE} (\hat D) / \hat D \). For a particular design the precision may be predicted approximately from the expected values of \(n\) and \(r\) – this is the “rule-of-thumb” RSE. The approximation is intended for Poisson-distributed \(n\) (see Distribution). Sampling variance is predictably less when \(n\) is binomial; the binomial \(\mathrm{RSE}_B\) for a given Poisson \(\mathrm{RSE}_P\) depends on the effective sampling area \(a\) and total mask area \(A\) as follows $$\mathrm{RSE}_B = \sqrt {\mathrm{RSE}_P^2 - 1 / (DA)}.$$ This adjustment is applied whenever a binomial distribution is selected.
The raw “rule-of-thumb” RSE is further adjusted by a correction factor specified in Options. By default, the correction factor is also updated automatically to match the results from simulations whenever they are run.
The traffic light provides a quick and dirty indication of whether you are on the right track. Click on red or amber lights to see the reason. Thresholds are set in Options. The defaults are
The suitability of these precision thresholds of course depends on the required power, and they are no more than a guide. Estimates from scenarios with RSE>20% may exhibit bias, so it is wise to aim for lower RSE even if you think that precision is sufficient.
Plots update automatically. Any plot may be saved by right-clicking on the image.
A plot of the current detector layout. Coordinates may be viewed or output to a text file with the ‘Save’ link; the code used to generate the array is included in the header. The file is in a format suitable for secr::read.traps. The summary text includes the ratio of the array diameter (grid diagonal) to the diameter of a 95% activity circle (HR95). HR95 is 2 x 2.45 sigma for detectfn = ‘HHN’ and 2 x 4.74 sigma for detectfn = ‘HEX’.
Detection function on the hazard scale
One simulated realisation of a population with the 2-D distribution specified on the Simulation page. The ‘Restrict to mask’ option is available only when a Poisson 2-D distribution is specified.
Contours of the overall detection probability \(p_\cdot(\mathbf x)\) (‘Pxy’ is the label that has been used for this quantity in the Windows application Density). Settings in Options toggle the display between filled and unfilled contour plots, and determine whether contours are labelled. The requested contour levels are 0.1, 0.2, …, 0.9, but higher contours may be missing. Click on the plot to find the value at a point.
Two styles of plot are offered (see Options | Power plot)
Probability of detecting a change in density in a 2-survey comparison as a function of effect size for a given expected \(\small \mathrm{RSE}(\hat D)\). See Efford and Boulanger 2019 for the computation method.
Effect size is the ratio of final density \(\small D_2\) to initial density \(\small D_1\) expressed as a percentage. The alpha level is specified in Options (default \(\small \alpha = 0.05\)).
The curve is initially computed with the approximated RSE from the current design. Use the slider to vary this. Especially, consider adding a safety margin for underestimation of RSE.
It is likely that \(\small \mathrm{RSE}(\hat D)\) will increase as density declines. By default, an adjustment is applied to the final RSE: \(\small \mathrm{RSE}(\hat D_2) = \sqrt {D_1/D_2} \mathrm{RSE}(\hat D_1) \). This may be removed by unticking the ‘Adjust final RSE’ box.
As an alternative to conventional power analysis we can construct intervals for the estimated ratio of densities, given the true ratio and the sampling errors. The interval is the region between the upper and lower curves for a given true population change on the x axis.
The log attempts to capture key messages, warnings and errors that would otherwise be sent to the console and not be seen by the user. Coverage is patchy.
Settings here should be self explanatory. See secr-habitatmasks.pdf for background.
The mask may either be imported from a text file (‘File’) or built by buffering around the detector array from the Design page (‘Build’). The format of the text file is that exported from secr >3.2.1with write.mask (basically two columns, the x- and y-coordinates). The default buffer multiplier for the ‘Build’ option (4) may be inadequate when detectfn = ‘HEX’.
| dots | display mask points as dots rather than filled cells |
| xpd | clip plot and suppress enclosing box |
| show mask edge | use secr::plotMaskEdge to outline mask |
| Travel per km $ | travel from detector to detector within an array |
| Cost per array $ | one-off overheads for each array |
| Cost per detector $ | one-off cost of purchase and installation |
| Cost per detector visit $ | fixed cost per occasion, including set-up occasion |
| Cost per detection $ | handling and lab costs |
Travel distance and per-visit costs are a function of the number of sampling occasions on the Design page. Usually there will also be travel and per-detector costs associated with a start-up visit; this may be excluded by un-ticking the “Include setup occasion” box.
| Type | sequential, manual or sumspacing |
| Return to start |
Travel cost depends on the length of the route taken to check detectors. If the layout lists detectors in the order they are to be visited then the default ‘Sequential’ option applies. However, this may not be the shortest route, especially if the route should return to the starting point.
The ‘Manual’ option allows the user to construct a route ‘on the fly’ by clicking near detectors at the turning points. Click on ‘Define new route…’ to start again.
The ‘SumSpacing’ option determines route length by summing inter-detector distances. This is unreliable if detectors are clustered and spacing is not uniform.
This page optionally simulates the single scenario on the Design page. Simulations may be slow. You must close the application to abort them.
A very approximate algorithm is used to predict the execution time from the product of
with adjustments for the maximisation method (default “none”) and detector type (default “proximity”). If the predicted time exceeds 0.2 minutes a dialogue box allows the user to cancel simulations before they start.
Unfortunately, there is no elegant way to interrupt simulations once they have started. Close your browser window and start again.
Code is provided for users who want to go further. Multiple scenarios may be evaluated by providing vector arguments to make.scenarios.
Maximization method = 'none' by-passes likelihood maximization and evaluates the Hessian (and hence the variance-covariance matrix) at the true values of the parameters. This is a fast way to predict \(\small \mathrm{RSE}(\hat D)\); it is apparently reliable and requires few replicates. Bias is not estimated.
If the ‘Add to summary’ box is ticked then simulation results are added automatically to the Summary table.
| Function to fit model | choose secr.fit(slow), or bypass fitting |
| Maximization method | method used for likelihood maximization by fitting function1 |
| 2-D distribution | `model2D` argument of sim.popn |
| other details | free-form arguments passed in `details` list to sim.popn |
| Replicates | number of replicate simulations2 |
| Cores | number of cores for parallel processing3 |
| Seed | random number seed4 |
parallel::detectCores. run.scenarios) The 2-D (spatial) distribution of simulated activity centres is controlled in sim.popn by the argument model2D. These values are offered in secrdesignapp:
| poisson | random uniform (Poisson) distribution |
| cluster | clustered (Neyman-Scott) distribution controlled by parameters mu (mean number per cluster) and hsigma (SD of bivariate normal within-cluster scatter)1 |
| even2 | systematic grid, each point jittered uniformly within its 'cell' |
sim.popnThe Popn plot on the Design page displays realisations of the 2-D distribution specified on the Simulation page. The effect of varying the 2-D distribution on simulation results will only be apparent if a maximization method is specified (Newton-Raphson or Nelder-Mead).
| Number of replicates | as input |
| Time for simulations | seconds |
| Number of animals (n) | mean and SE over replicates |
| Number of detections (n+r) | mean and SE over replicates |
| Number of moves (m)1 | mean and SE over replicates |
| Simulated \(\small \widehat{\mathrm{RSE}}\) | mean and SE over replicates |
| Empirical RSE2 | Allows for clustered or even 2-D distribution |
| Simulated RB3 | mean and SE over replicates |
NOTE: If the 2-D distribution is not Poisson then the ‘Simulated RSE’ will be misleading because it is the average of the biased estimates of RSE reported when the model is fitted assuming a Poisson distribution. For a non-Poisson 2-D distribution, rely on the ‘Empirical RSE’, noting that this requires maximization of the likelihood as noted above. Empirical RSE will be highly variable between runs unless there are many replicates (a minimum of 20 is suggested).
This page evaluates the effect of detector spacing on precision and total cost. The array geometry is fixed on the Design page. A numerical search is performed for the array spacing that minimises the rule-of-thumb \(\small \mathrm{RSE}(\hat D) \).
The Spacing tab is hidden when the detector array is of the File or Region types. The effect of using multiple detector clusters with a particular geometry may be emulated by setting the Array number.
This code shows how optimalSpacing may be used to evaluate spacings. An internal version is executed when the button is clicked.
| Optimal spacing (relative to sigma) |
| Optimal spacing (absolute) |
| Minimum RSE |
Use the ‘Save’ link to generate an RData file containing the object returned by secrdesign::optimalSpacing. The object is named spacingOutput with class c('optimalSpacing', 'list') for which there is a plot method. Rule-of-thumb results are in component rotRSE and simulation results, if any, are in component simRSE. Use the results in an R session like this:
load("spacing.RData")
str(spacingOutput)
spacingOutput$rotRSE
plot(spacingOutput)
Rule-of-thumb RSE vs relative spacing. The spacing that minimises the rule-of-thumb RSE is shown with a dot.
Expected values of \(n\), \(r\), and \(m\) vs relative spacing (Design).
Costings follow the Costing page. Route length and expected number of detections vary with spacing. The cost components for travel and per-detection will therefore vary if their unit cost is greater than zero.
The table on this page has one column for each scenario; scenarios are added by clicking the ‘Add to summary’ button on the Design page, or automatically from Simulation. Fields from “simfn” onwards will have missing values if no simulation has been performed.
The table may be downloaded as a comma-separated text file or in the RDS format (use readRDS to restore in R). The table is transposed on download so that scenarios become rows.
These should be self-explanatory. Experiment if in doubt.
Here are some known pitfalls
Run secrdesignapp from GitHub on your own machine for the best performance. See https://GitHub.com/MurrayEfford/secrdesignapp. You will need to install R packages secr, secrdesign, shiny and shinyjs.
At least .shp, .dbf and .shx.
This often happens when the boundary file for a large region is uploaded before setting the sigma parameter. With the default settings (Shape = Rounded, sigma = 25 m, nx = 32) there may well be no points in the mask. Fix this by increasing sigma.
This will happen when a rigid boundary is provided in Options | Habitat mask.
This is intended. The coefficient cannot be compared between HHN and HEX models, and the simplest way to prevent misunderstanding was to block for HEX.
A systematic or random array defined with a Region polygon may exclude sites that lie within other polygons (Options | Detector array | Excluded region). How is an exclusion applied to the habitat mask? Unfortunately the secr function make.mask accepts only one polygon input, although this may represent either habitat or non-habitat. To combine habitat (inclusion) and non-habitat (exclusion) polygons you will first need to use GIS software
(e.g., the st_difference function in the R package sf) and save the result as a single sfc_POLYGON object
(e.g., as an .rds file).
library(sf)
setwd('d:/density secr 5.3/secrdesignapp')
region <- sf::read_sf('OVforest.shp')
region <- st_as_sfc(region) # for simplicity
coord <- read.table('excltest.txt') # read boundary coordinates
excluded <- secr::boundarytoSF(coord) # convert to sfc_POLYGON
newpoly <- sf::st_difference (region, excluded)
saveRDS(newpoly, file = 'newpoly.RDS')
The RDS file may then be used in Habitat mask | Mask polygon files.
Borchers, D. L. and Efford, M. G. (2008) Spatially explicit maximum likelihood methods for capture–recapture studies. Biometrics 64, 377–385.
Dupont, G., Royle, J. A., Nawaz, M. A. and Sutherland, C. (2021) Optimal sampling design for spatial capture–recapture. Ecology 102, e03262.
Durbach, I., Borchers, D., Sutherland, C. and Sharma, K. (2021) Fast, flexible alternatives to regular grid designs for spatial capture–recapture. Methods in Ecology and Evolution 12, 298–310. https://doi.org/10.1111/2041-210X.13517
Efford, M. G. (2019) Non-circular home ranges and the estimation of population density. Ecology 100(2), e02580.
Efford, M. G. (2025a) secrdesign: Sampling design for spatially explicit capture–recapture. R package version 2.10.0. https://CRAN.R-project.org/package=secrdesign
Efford, M. G. (2025b) The SECR Book. A handbook of spatially explicit capture–recapture methods. Version 1.0.1. Zenodo 15109938. Latest version online at https://murrayefford.github.io/SECRbook/.
Efford, M. G. (2025c) secr: Spatially explicit capture–recapture models. R package version 5.3.0. https://CRAN.R-project.org/package=secr
Efford, M. G. and Boulanger, J. (2019) Fast evaluation of study designs for spatially explicit capture–recapture. Methods in Ecology and Evolution 10, 1529–1535. https://doi.org/10.1111/2041-210X.13239
Efford, M. G., Dawson, D. K., Jhala, Y. V. and Qureshi, Q. (2016) Density-dependent home-range size revealed by spatially explicit capture–recapture. Ecography 39, 676–688.
Kincaid, T. M. and Olsen, A. R. (2018) spsurvey: Spatial Survey Design and Analysis. R package version 3.4. https://CRAN.R-project.org/package=spsurvey.
Pebesma, E. J. (2018) Simple features for R: standardized support for spatial vector data. The R Journal 10, 439–446. https://doi.org/10.32614/RJ-2018-009
Stevens, D. L. Jr and Olsen, A. R. (2004) Spatially balanced sampling of natural resources. Journal of the American Statistical Association 99, 262–278.
Wolters, M. A. (2015) A genetic algorithm for selection of fixed-size subsets with application to design problems. Journal of Statistical Software, Code Snippets, 68, 1–18. https://doi.org/10.18637/jss.v068.c01