\name{testNM}
\alias{NMs.randomCRW}
\alias{NMs.randomShiftRotation}
\alias{NMs.CRW}
\alias{NMs.randomCs}
\alias{NMs2NMm}
\alias{print.NMm}
\alias{print.NMs}
\alias{testNM}
\title{Null Model Approach for Animal Movement Analysis}
\description{
  The functions \code{NMs.*} allow to define "single null models" (see
  details).  The function \code{NMs2NMm} can be used on an object of
  class \code{"NMs"} to define "multiple null models".  The function
  \code{testNM} can be used to simulate the defined null models.
}
\usage{
NMs.randomCRW(ltraj, rangles = TRUE, rdist = TRUE, fixedStart = TRUE,
              x0 = NULL, rx = NULL, ry = NULL, treatment.func = NULL,
              treatment.par = NULL, constraint.func = NULL,
              constraint.par = NULL, nrep = 999)

NMs.randomShiftRotation(ltraj, rshift = TRUE, rrot = TRUE,
                        rx = NULL, ry = NULL, treatment.func = NULL,
                        treatment.par = NULL, constraint.func = NULL,
                        constraint.par = NULL, nrep = 999)


NMs.CRW(N = 1, nlocs = 100, rho = 0, h = 1, x0 = c(0,0),
        treatment.func = NULL,
        treatment.par = NULL, constraint.func = NULL,
        constraint.par = NULL, nrep = 999)


NMs.randomCs(ltraj, Cs = NULL, rDistCs = TRUE,
             rAngleCs = TRUE,
             rCentroidAngle = TRUE, rCs = TRUE,
             newCs = NULL, newDistances = NULL,
             treatment.func = NULL, treatment.par = NULL,
             constraint.func = NULL, constraint.par = NULL,
             nrep=999)

NMs2NMm(NMs, treatment.func = NULL,
        treatment.par = NULL, constraint.func = NULL,
        constraint.par = NULL, nrep = 999)

\method{print}{NMm}(x, \dots)

\method{print}{NMs}(x, \dots)

testNM(NM, count = TRUE)
}
\arguments{
  \item{ltraj}{an object of class \code{"ltraj"}}
  \item{rangles}{logical.  Whether the turning angles should be
    randomized.}
  \item{rdist}{logical.  Whether the distances between successive
    relocations should be randomized.}
  \item{fixedStart}{logical.  If \code{TRUE}, the first location of the
    randomized trajectories corresponds to \code{x0}.  If \code{FALSE},
    the first location \code{(x, y)} is sampled in the interval
    \code{(rx, ry)}}
  \item{x0}{a vector of length 2 giving the x and y coordinates of the
    first relocations.  If \code{NULL} and \code{fixedStart=TRUE}, the first
    location of the trajectory corresponds to the first location of the
    actual trajectory}
  \item{rx}{a vector of length 2 giving the x
    coordinates of the bounding box where the first location of the
    trajectory should be sampled}
  \item{ry}{a vector of length 2 giving the range (min, max) of the y
    coordinates of the bounding box where the first location of the
    trajectory should be sampled}
  \item{treatment.func}{any function taking two arguments \code{x} and
    \code{par}, where \code{x} is the trajectory generated by the
    function, and par can be any R object (e.g. a list containing the
    parameters needed by the function.  Note that the argument
    \code{par} should be present in the function definition even if it
    is not needed in the function). See details and examples.  If
    \code{NULL}, a function is defined internally that simply returns
    the raw trajectory simulated by the model}
  \item{treatment.par}{the R object that will be passed as
    an argument to the parameter \code{par} of the function
    \code{treatment.func}}
  \item{constraint.func}{any function taking two arguments \code{x} and
    \code{par}, where \code{x} is the trajectory generated by the
    function, and par can be any R object (e.g. a list containing the
    parameters needed by the function).  **This function should
    necessarily return a logical value** (See details and examples).  If
    \code{NULL}, a function is defined internally that always returns
    \code{TRUE}}
  \item{constraint.par}{The R object that will be passed as an argument
    to the parameter \code{par} of the function \code{constraint.func}}
  \item{nrep}{The number of repetitions of the null model}
  \item{rshift}{logical. Whether the trajectory should be shifted over
    the study area.}
  \item{rrot}{logical. Whether the trajectory should be rotated around
    its barycentre.}
  \item{N}{The number of animals to simulate.}
  \item{nlocs}{The number of relocations building up each trajectory}
  \item{rho}{The concentration parameter for wrapped normal distribution
    of turning angles (see \code{?simm.crw})}
  \item{h}{the scaling parameter for the movement length  (see
    \code{?simm.crw})}
  \item{Cs}{a list of vectors of length 2.  Each vector should contain
    the x and y coordinates of the capture sites of the animals in
    \code{ltraj}.  This list should therefore have the same number of
    elements as \code{ltraj}}
  \item{rDistCs}{logical.  Whether the distances between the barycentre
    of the trajectories and the corresponding capture sites should be
    randomized among trajectories}
  \item{rAngleCs}{logical. Whether the angle between the east direction
    and the line connecting the capture site and the barycentre of the
    trajectory should be drawn from an uniform distribution.}
  \item{rCentroidAngle}{logical.  Whether the trajectory should be
    randomly rotated around its barycentre.}
  \item{rCs}{logical. Whether the trajectory should be randomly
    associated to a new capture site.}
  \item{newCs}{a list of vectors of length 2.  Each vector should contain
    the x and y coordinates of new capture sites.  If \code{NULL} and
    \code{rcs=TRUE}, the new capture sites are sampled in \code{cs}}
  \item{newDistances}{a vector of new distances that will be used to
    define the distances between capture sites and centroid of simulated
    trajectories if \code{rDistCs=TRUE}}
  \item{NM,x}{a null model of class \code{"NMs"} or \code{"NMm"}}
  \item{NMs}{a null model of class \code{"NMs"}}
  \item{count}{whether the iterations should be displayed}
  \item{\dots}{additionnal arguments to be passed to or from other methods}
}
\details{

  The null model approach has been considered as a useful approach in
  many fields of ecology to study biological processes.  According to
  Gotelli and Graves (1996), "A null model is a pattern-generating model
  that is based on randomization of ecological data or random sampling
  from a known or imagined distribution. The null model is designed with
  respect to some ecological or evolutionary process of
  interest. Certain elements of the data are held constant, and others
  are allowed to vary stochastically to create new assemblage
  patterns. The randomization is designed to produce a pattern that
  would be expected in the absence of a particular ecological
  mechanism".

  This approach can be very useful to test hypotheses related to animal
  movements.  The package adehabitatLT propose several general null
  models that can be used to test biological hypotheses.  For example,
  imagine that we want to test the hypothesis that no habitat selection
  occurs when the animal moves.  The shape of the trajectory, under this
  hypothesis would be the pure result of changing activity (moving,
  foraging, resting).  Therefore, a possible approach to test whether
  habitat selection actually occurs would be to randomly rotate the
  trajectory around its barycentre and shifting it over the study area.
  The function \code{NMs.randomShiftRotation} can be used to define such
  a model.  It is possible to constrain the randomization by defining a
  "constraint function" (e.g. to keep only the randomized trajectories
  satisfying a given criterion).  It is required to specify a "treatment
  function" (i.e., a function that will be applied to each randomized
  trajectory).  Once the null model has been defined, it is then possible
  to perform the randomizations using the function \code{testNM}. We
  give below the details concerning the available null models, as well
  as the constraint and the treatment functions.

  First, two types of null models can be defined: single (NMs) and
  multiple (NMm) null models.  Consider an object of class
  \code{"ltraj"} containing \code{N} bursts.  With NMs, the treatment
  function will be applied to each randomized burst of relocations. Thus,
  for example, if \code{nrep} repetitions of the null model are
  required, \code{nrep} repetitions of the null models will be carried
  out for each burst separately. The treatment function will be applied
  on each randomized burst.  With NMm, for each repetition, \code{N}
  randomized bursts of relocations are generated.  The treatment is then
  applied, for each repetition, to the whole set of \code{N} randomized
  bursts.  Thus, \code{NMs} are useful to test hypothesis on each
  trajectory separately (e.g. individual habitat selection), whereas
  \code{NMm} are useful to test hypotheses relative to the whole set of
  animals stored in an object of class \code{ltraj} (e.g. interactions
  between animals).  The only current way to define an object of class
  \code{NMm} is to first define an object of class \code{NMs} and then
  use the function \code{NMs2NMm} to indicate the treatment function
  that should be applied on the whole set of trajectories.

  The constraint function should be user-defined. It should return a
  logical value indicating whether the constraint is satisfied.  With
  \code{NMs}, this function should take only two parameters: \code{x}
  and \code{par}.  The argument \code{x} is a data frame with three
  columns describing a trajectory (the X and Y coordinates, and the date
  as a vector of class \code{"POSIXct"}), and the argument \code{par}
  can be any R object required by the constraint function (e.g. if the
  constraint to keep 80\% of the relocations of the randomized
  trajectories within a given habitat type, the parameter \code{par} 
  can be a raster map, or a list of raster maps).  With
  \code{NMm}, this function should also take only the two parameters
  \code{x} and \code{par}.  The argument \code{par} can be any R object
  required by the constraint function.  However, when \code{"NMm"} are
  defined, the argument \code{x} of the constraint function should be an
  object of class \code{"ltraj"}.  If the function \code{NMs2NMm} is
  used to define the object of class \code{"NMm"}, two types of
  constraint can therefore be defined: at the individual level (in the
  function \code{NMs.*}) and for the whole set of animals (in the
  function \code{NMs2NMm}).  In this case, some constraints will be
  satisfied at the individual level, and others at the scale of the
  whole set of animals.  If no constraint function is defined by the
  user, a constraint function always returning \code{TRUE} is
  automatically defined internally.

  The treatment function can be any function defined by the user, but
  should take two arguments \code{x} and \code{par}, identical to those
  passed to the constraint function (i.e., \code{x} should be a data
  frame with three columns for \code{NMs} and an object of class
  \code{"ltraj"} for \code{NMm}. Note that only one treatment function
  can be applied to the randomization: if \code{NMs2NMm} is used to
  define an object of class \code{NMm}, the treatment function defined
  in the function \code{NMs.*} will be ignored, and only the treatment
  function defined in the function \code{NMs2NMm} will be taken into
  account.  If no treatment function is defined by the user, a treatment
  function will be defined internally, simply returning the randomized
  trajectory (i.e. a data.frame with three columns for \code{NMs}, and
  an object of class \code{ltraj} for \code{NMm}).
  
  We now describe the list of available null models:
  
  \code{NMs.CRW}: this model is a purely parametric model. It
  simulates a correlated random walk with specified parameters (see
  \code{?simm.crw} for a complete description of this model).
  
  \code{NMs.randomCRW}: this model also simulates a correlated
  random walk, but the distributions of the turning angles and/or
  distances between successive relocations are derived from the
  trajectories passed as arguments.  It is possible to randomize the
  turning angles, the distances between successive relocations, or
  both (default).
  
  \code{NMs.randomShiftRotation}: this model randomly rotates the
  trajectory around its barycentre and randomly shifts it over the study
  area (but does not change its shape).  The function allows for a
  random rotation, a random shift or both operations (default).
  
  \code{NMs.randomCs}: this model is similar to the previous one:
  it keeps the shape of the trajectory unchanged.  However, it
  randomizes the position of the trajectories with respect to a set of
  capture sites (it can be
  used to take into account the fact that a the home range of a
  sedentary animal captured at a given place is likely to be close to
  this place).  First a
  capture site may be randomly drawn from a list of capture sites
  (either the actual capture sites or a list passed by the user). Then,
  the angle between the east direction and the line connecting the
  capture site of the animal and the barycentre of its trajectory is
  randomly drawn from a uniform distribution.  Then, the distance
  between this barycentre and the capture site is randomly drawn from
  the observed distribution of distances between capture sites and
  trajectory barycentre (or from a set of distances passed as
  argument).  Finally, the trajectory is randomly rotated around its
  barycentre.
}
\value{
  For objects of class \code{"NMs"} a list of \code{N} elements (where
  \code{N} is the number of trajectories in the object of class
  \code{"ltraj"} passed as argument, with each element is a list storing
  the \code{nrep} results of the treatment function applied to each randomized
  trajectory.

  For objects of class \code{"NMm"}, a list of \code{nrep} elements,
  each element storing the result of the treatment function applied to
  each set of \code{N} randomized trajectories.
}
\references{
  Gotelli, N. and Graves, G. (1996) \emph{Null models in
    Ecology}. Smithsonian Institution Press.

  Richard, E., Calenge, C., Said, S., Hamann, J.L. and Gaillard,
  J.M. (2012) Studying spatial interactions between sympatric
  populations of large herbivores: a null model
  approach. \emph{Ecography}, in press.
}
\author{ Clement Calenge \email{clement.calenge@oncfs.gouv.fr} }
\seealso{
  \code{\link{as.ltraj}} for additional information about objects of
  class \code{"ltraj"}
}
\examples{
\dontrun{
########################################
##
## example using NMs.randomShiftRotation

## first load the data:
data(puechcirc)
data(puechabonsp)
map <- puechabonsp$map

## Consider the first animal
## on an elevation map
anim1 <- puechcirc[1]
plot(anim1, spixdf=map[,1])

## We define a very simple treatment function
## for a NMs model: it just plots the randomized trajectory
## over the study area
## As required, the function takes two arguments:
## x is a data.frame storing a randomized trajectory (three
## columns: the x, y coordinates and the date)
## par contains the map of the study area

myfunc <- function(x, par)
{
   par(mar = c(0,0,0,0))
   ## first plot the map
   image(par)

   ## then add the trajectory
   lines(x[,1], x[,2], lwd=2)
}

## Then we define the null model
##
## We define the range of the study area where the trajectory
## will be shifted:
rxy <- apply(coordinates(map),2,range)
rxy

## We define the null model with 9 repetitions
nmo <- NMs.randomShiftRotation(na.omit(anim1), rshift = TRUE, rrot = TRUE,
                               rx = rxy[,1], ry = rxy[,2], treatment.func = myfunc,
                               treatment.par = map, nrep=9)

## Then apply the null model
par(mfrow = c(3,3))
tmp <- testNM(nmo)

## You may try variations, by setting rshift or rrot to FALSE, to see
## the differences

## Note that some of the randomized trajectories are located outside the
## study area, although all barycentres are located within the X and Y
## limits of this study area.
## We may define a constraint function returning TRUE only if all
## relocations are located within the study area

## again, note that the two parameters are x and par
consfun <- function(x, par)
{
   ## first convert x to the class SpatialPointsDataFrame
   coordinates(x) <- x[,1:2]

   ## then use the function over from the package sp
   ## to check whether all points in x are located inside
   ## the study area
   ov <- over(x, geometry(map))
   return(all(!is.na(ov)))  
}

## Now fit again the null model under these constraints:
nmo2 <- NMs.randomShiftRotation(na.omit(anim1), rshift = TRUE, rrot = TRUE,
                                rx = rxy[,1], ry = rxy[,2], treatment.func = myfunc,
                                treatment.par = map,
                                constraint.func = consfun,
                                constraint.par = map, nrep=9)

## Then apply the null model
par(mfrow = c(3,3))
tmp <- testNM(nmo2)

## all the relocations are now inside the study area.


########################################
##
## example using NMs.randomCRW


## We generate correlated random walks with the same starting
## point as the original trajectory, the same turning angle
## distribution, and the same distance between relocation
## distribution. We use the same constraint function as previously
## (all relocations falling within the study area), and we
## use the same treatment function as previously (just plot
## the result).
mo <- NMs.randomCRW(na.omit(anim1), rangles=TRUE, rdist=TRUE,
                    treatment.func = myfunc,
                    treatment.par = map, constraint.func=consfun,
                    constraint.par = map, nrep=9)

par(mfrow = c(3,3))
tmp <- testNM(mo)

## Now, try a different treatment function: e.g. measure
## the distance between the first and last relocation,
## to test whether the animal is performing a return trip
myfunc2 <- function(x, par)
{
    sqrt(sum(unlist(x[1,1:2] - x[nrow(x),1:2])^2))
}

## Now fit again the null model with this new treatment and 499 repetitions:
mo2 <- NMs.randomCRW(na.omit(anim1), rangles=TRUE, rdist=TRUE,
                     treatment.func = myfunc2,
                     treatment.par = map, constraint.func=consfun,
                     constraint.par = map, nrep=499)

## Then apply the null model
suppressWarnings(RNGversion("3.5.0"))
set.seed(298) ## to make the calculation reproducible
rand <- testNM(mo2)

## rand is a list with one element (there is one trajectory in anim1).
length(rand[[1]])

## The first element of rand is a list of length 499 (there are 499
## randomizations).
head(rand[[1]])

## unlist this list:
rand2 <- unlist(rand[[1]])

## calculate the observed average elevation:
obs <- myfunc2(na.omit(anim1)[[1]][,1:3], map)

## and performs a randomization test:
(rt <- as.randtest(rand2, obs, alter="less"))
plot(rt)

## Comparing to a model where the animal is moving randomly, and based
## on the chosen criterion (distance between the first and last
## relocation), we can see that the distance between the first and last
## relocation is rarely observed.  It seems to indicate that the animal
## tends to perform a loop.



########################################
##
## example using NMs2NMm

## Given the previous results, we may try to see if all
## the trajectories in puechcirc are characterized by return
## trips
## We need a NMm approach. Because we have 3 burst in puechcirc
## we need a summary criterion. For example, the mean
## distance between the first and last relocation.

## We program a treatment function: it also takes two arguments, but x
## is now an object of class "ltraj" ! 
## par is needed, but will not be used in the function

myfunm <- function(x, par)
{
   di <- unlist(lapply(x, function(y) {
      sqrt(sum(unlist(y[1,1:2] - y[nrow(y),1:2])^2))
   }))
   return(mean(di))
}

## Now, prepare the NMs object: we do not indicate any treatment
## function (it would not be taken into account when NMs would be
## transformed to NMm).  However, we keep the constraint function
## the simulated trajectories should fall within the study area
mo2s <- NMs.randomCRW(na.omit(puechcirc), constraint.func=consfun,
                      constraint.par = map)

## We convert this object to NMm, and we pass the treatment function
mo2m <- NMs2NMm(mo2s, treatment.func = myfunm, nrep=499)

## and we fit the model
suppressWarnings(RNGversion("3.5.0"))
set.seed(908)
resu <- testNM(mo2m)

## We calculate the observed mean distance between the
## first and last relocation
obs <- myfunm(na.omit(puechcirc))

## and performs a randomization test:
(rt <- as.randtest(unlist(resu), obs, alter="less"))
plot(rt)

## The test is no longer significant


########################################
##
## example using NMs.randomCs

## Consider this sample of 5 capture sites:
cs <- list(c(701184, 3161020), c(700164, 3160473),
           c(698797, 3159908), c(699034, 3158559),
           c(701020, 3159489))
image(map)
lapply(cs, function(x) points(x[1], x[2], pch=16))

## Consider this sample of distances:
dist <- c(100, 200, 150)

## change the treatment function so that the capture sites are showed as
## well. Now, par is a list with two elements: the first one is the map
## and the second one is the list of capture sites

myfunc <- function(x, par)
{
   par(mar = c(0,0,0,0))
   ## first plot the map
   image(par[[1]])

   lapply(par[[2]], function(x) points(x[1], x[2], pch=16))

   ## then add the trajectory
   lines(x[,1], x[,2], lwd=2)
}


## Now define the null model, with the same constraints
## and treatment as before
mod <- NMs.randomCs(na.omit(anim1), newCs=cs, newDistances=dist,
                    treatment.func=myfunc, treatment.par=list(map, cs),
                    constraint.func=consfun, constraint.par=map,
                    nrep=9)

## apply the null model
par(mfrow = c(3,3))
tmp <- testNM(mod)
}


}
\keyword{nonparametric}
\keyword{distribution}
