`xform`

is designed to operate on a variety of data types, especially
objects encapsulating neurons. `xform`

depends on two specialised
downstream functions `xformpoints`

and `xformimage`

.
These are user visible any contain some useful documentation, but should only
be required for expert use; in almost all circumstances, you should use only
`xform`

.

`xform.character`

is designed to work with files on disk.
Presently it is restricted to images, although other datatypes may be
supported in future.

```
xform(x, reg, ...)
# S3 method for default
xform(x, reg, na.action = c("warn", "none", "drop", "error"), ...)
# S3 method for character
xform(x, reg, ...)
# S3 method for list
xform(x, reg, FallBackToAffine = TRUE, na.action = "error", ...)
# S3 method for shape3d
xform(x, reg, FallBackToAffine = TRUE, na.action = "error", ...)
# S3 method for mesh3d
xform(x, reg, FallBackToAffine = TRUE, na.action = "error", ...)
# S3 method for neuron
xform(x, reg, FallBackToAffine = TRUE, na.action = "error", ...)
# S3 method for data.frame
xform(x, reg, subset = NULL, ...)
# S3 method for dotprops
xform(x, reg, FallBackToAffine = TRUE, ...)
# S3 method for neuronlist
xform(
x,
reg,
subset = NULL,
...,
OmitFailures = NA,
VectoriseRegistrations = FALSE,
TransformDFCoords = TRUE
)
```

- x
an object to transform

- reg
A registration defined by a matrix, a function, a

`cmtkreg`

object, or a character vector specifying a path to one or more registrations on disk (see Registrations section).- ...
additional arguments passed to methods and eventually to

`xformpoints`

- na.action
How to handle NAs. NB drop may not work for some classes.

- FallBackToAffine
Whether to use an affine transform when a cmtk warping transformation fails.

- subset
For

`xform.neuronlist`

indices (character/logical/integer) that specify a subset of the members of`x`

to be transformed.- OmitFailures
Whether to omit neurons for which

`FUN`

gives an error. The default value (`NA`

) will result in nlapply stopping with an error message the moment there is an error. For other values, see details.- VectoriseRegistrations
When

`FALSE`

, the default, each element of`reg`

will be applied sequentially to each element of`x`

. When`TRUE`

, it is assumed that there is one element of`reg`

for each element of`x`

.- TransformDFCoords
If the metadata

`data.frame`

attached to`x`

includes columns that look like x,y,z coordinates, transform those as well.

Methods are provided for some specialised S3 classes. Further
methods can of course be constructed for user-defined S3 classes. However
this will probably not be necessary if the `xyzmatrix`

and
``xyzmatrix<-``

generics are suitably overloaded *and* the S3
object inherits from `list`

.

Note that given the behaviour of the `xyzmatrix`

functions, the
`xform.data.frame`

method will transform the x,y,z or X,Y,Z columns of
a data.frame if the data.frame has more than 3 columns, erroring out if no
such unique columns exist.

TODO get this to work for matrices with more than 3 columns by working on xyzmatrix definition.

For the `xform.dotprops`

method, dotprops tangent vectors will
be recalculated from scratch after the points have been transformed (even
though the tangent vectors could in theory be transformed more or less
correctly). When there are multiple transformations, `xform`

will take
care to carry out all transformations before recalculating the vectors.

With `xform.neuronlist`

, if you want to apply a different
registration to each object in the neuronlist `x`

, then you should use
`VectoriseRegistrations=TRUE`

.

When `x`

's attached data.frame contains columns called x,y,z or X,Y,Z
then these are assumed to be coordinates and also transformed when
`TransformDFCoords=TRUE`

(the default). This provides a mechanism for
transforming the soma positions of `neuronlist`

objects containing
`dotprops`

objects (which do not otherwise store the soma position).
Note that if transformation fails, a warning will be issued and the points
will be replaced with `NA`

values.

When `reg`

is a character vector, xform's specialised downstream
functions will check to see if it defines a path to one (or more)
registrations on disk. These can be of two classes

CMTK registrations

`reglist`

objects saved in R's`RDS`

format (see`readRDS`

) which can contain any sequence of registrations supported by nat.

If the path does indeed point to a CMTK registration, this method will hand
off to `xformpoints.cmtkreg`

or `xformimages.cmtkreg`

. In this
case, the character vector may optionally have an attribute, 'swap', a
logical vector of the same length indicating whether the transformation
direction should be swapped. At the moment only CMTK registration files are
supported.

If `reg`

is a character vector of length >=1 defining a sequence of
registration files on disk they should proceed from sample to reference.

Where `reg`

is a function, it should have a signature like
`myfun(x,), ...`

where the `...`

**must** be provided in
order to swallow any arguments passed from higher level functions that are
not relevant to this particular transformation function.

```
if (FALSE) {
kc1=kcs20[[1]]
kc1.default=xform(kc1,function(x,...) x)
stopifnot(isTRUE(all.equal(kc1,kc1.default)))
kc1.5=xform(kc1,function(x,...) x, k=5)
stopifnot(isTRUE(all.equal(kc1.5,kc1.default)))
kc1.20=xform(kc1,function(x,...) x, k=20)
stopifnot(!isTRUE(all.equal(kc1,kc1.20)))
# apply two registrations converting sample->IS2->JFRC2
reg_seq=c("IS2_sample.list", "JFRC2_IS2.list")
xform(kc1, reg_seq)
# apply two registrations, swapping the direction of the second one
# i.e. sample -> IS2 -> FCWB
reg_seq=structure(c("IS2_sample.list", "IS2_FCWB.list"), swap=c(FALSE, TRUE))
xform(kc1, reg_seq)
}
if (FALSE) {
# apply reg1 to Cell07PNs[[1]], reg2 to Cell07PNs[[2]] etc
regs=c(reg1, reg2, reg3)
nx=xform(Cell07PNs[1:3], reg=regs, VectoriseRegistrations=TRUE)
}
```