`multiply(x,mat)`

where `mat`

is an internally calculated MxM matrix.
Stated another way, the spectra in the output are linear combinations of spectra in
the input `x`

.
In case of ERROR, a message is logged and the original `x`

is returned.```
## S3 method for class 'colorSpec':
calibrate( x, stimulus=NULL, response=NULL, method=NULL )
```

x

a **colorSpec** responder with M spectra.
The

`type`

must be `'responsivity.light'`

or `'responsivity.material'`

.
The wavelength sequence of `x`

must be regular.stimulus

a **colorSpec** object with a single spectrum, with

`type`

`'light'`

or `'material'`

to match `x`

.
The wavelength sequence of `stimulus`

must be equal to that of `x`

.
If `st`

response

an M-vector, or a scalar which is replicated to length M.
All entries in *may be* chosen, see **Details**.

`response`

must be positive.
If `response`

is `NULL`

, then an appropriate default method

an MxM *adaption matrix*.

`method`

can also be `'scaling'`

and it is then set to the MxM identity matrix,
which scales each responsivity spectrum in `x`

independently.
If M=3, `method`

can also be- a
**colorSpec**object equal to`multiply(x,mat)`

where`mat`

is an internally calculated MxM matrix. The`quantity`

and`wavelength`

are preserved. Note that`mat`

is not the same as the the MxM*adaption matrix*. To inspect`mat`

execute`summary`

on the returned object. If`method`

is`'scaling'`

then`mat`

is diagonal and the diagonal entries are the M gain factors needed to achieve the calibration.

`stimulus`

is `NULL`

, it is set to
`illuminantE`

or `neutralMaterial`

to match `x`

.
If `response`

is `NULL`

and the response of `x`

is `electrical`

or `action`

,
then `response`

is set to an M-vector of all 1s.
If `response`

is `NULL`

and the response of `x`

is `neural`

,
then this is an ERROR and the user is prompted to supply a specific `response`

.
If `method`

is `NULL`

and M=3 and the response of `x`

is `neural`

,
then `method`

is set to the 3x3 Bradford matrix.
Otherwise `method`

is set to the MxM identity matrix,
which scales each responsivity spectrum in `x`

independently.`is.regular`

,
`quantity`

,
`wavelength`

,
`colorSpec`

,
`summary`

,
`illuminantE`

,
`neutralMaterial`

,
`product`

# make an art gallery illuminated by illuminant A gallery = product( A.1nm, 'artwork', xyz1931.1nm, wave='auto') # chromatically adapt the output XYZs to D50 white point, using Bradford matrix gallery.D50 = calibrate( gallery, response=officialXYZ('D50') ) gallery.D50 # make a flatbead scanner from illuminant F11 and a Flea2 camera scanner = product( subset(Fs.5nm,'F11'), 'paper', Flea2.RGB, wave='auto') # adjust RGB gain factors so the perfect reflecting diffuser yields RGB=(1,1,1) scanner = calibrate( scanner ) scanner # same flatbead scanner, but this time with some "white headroom" scanner = product( subset(Fs.5nm,'F11'), 'paper', Flea2.RGB, wave='auto' ) scanner = calibrate( scanner, response=0.95 ) scanner