Adding a new camera¶
The policy
directory in the obs_lsst
package contains the files
needed to describe cameras made up of LSST chips. The eventual goal is
to describe the real camera, but for now we also have variants to handle
LATISS data, phosim and imsim simulations (they differ in e.g., the gain and
crosstalk values) and data from various test stands.
Once Butler Gen3 is ready this configuration data will be moved out of the obs package and into the calibration registry, which will allow us to track evolution of the system (including replacing failed rafts – not that that’s going to happen).
The basic strategy is that the SConscript
file in the directory
assembles a suitable camera.yaml
file (e.g. phosim.yaml
) and we put
the appropriate entry in the _mapper
file in the data repository.
To add a new camera (e.g., fooCam
, made up of 9 CCDs in a single
“raft” – call it RXX
for now):
Add a directory
policy/fooCam
Put a file
rafts.yaml
in that directory describing RXX (you can start withpolicy/rafts.yaml
).Put a file
RXX.yaml
in policy/fooCam (you can start withpolicy/lsstCam/R11.yaml
). Note that you can choose an ITL or E2V device. Note that you must provide a serial number for each CCD in the raft as that’s how I know how many CCDs there are in the “raft” (e.g. LATISS has only one)The geometryWithinRaft field may be omitted, in which case offsets default to 0.0 and the yaw entry is not generated. These offsets are interpreted relative to the nominal positions given in cameraHeader.yaml for each type of raft, as adjusted for the centre of the raft; these values are therefore reasonable.
The yaw (rotation in the plane of the detector) is measured in degrees, anticlockwise as shown in cameraGeomUtils.plotFocalPlane (i.e. with
R00
in the bottom left, andR04
in the bottom right)If you want to add a camera-specific set of transformations, put a file
cameraTransforms.yaml
inpolicy/fooCam
. Look at the one inpolicy/cameraTransforms.yaml
for inspiration.If you’re plagued by crosstalk, put a file
ccdData.yaml
inpolicy/fooCam
. Look at the one inpolicy/phosim
for the format – basically a dict crosstalk indexed by the CCD type. There are 256 coefficients (16 amplifiers and 256 == 16^2), and we assume for now that all CCDs from a given vendor are the same (but the fix tobin.src/generateCamera.py
to handle per-CCD coefficients would be easy)Edit
policy/SConscript
to add your new camera “fooCam” to thefor camera in ...
loop. note the magic--path
options – it tells the code to use your data in fooCam to override lsstCam values. This is why there’s no imsim directory and phosim only contains the crosstalk coefficients; they take almost everything frompolicy/`
and`policy/lsstCam`run
scons
in theobs_lsst
directory (orscons -u
in policy)add
fooCam.yaml
topolicy/.gitignore
Create a new file
python/lsst/obs/lsst/fooCam.py
(seelatiss.py
for an example)Add a class
FooCamMapper
to the same file, setting a class-level string_cameraName
to “fooCam”. You also need to specify the metadata translation class to use such asLsstFooCamTranslator
. Look at the example inpython/lsst/obs/lsst/latiss.py
– you’ll see that this overrides some entries inlsstCamMapper.yaml
(in the class data memberyamlFileList
) withlatissMapper.yaml
. If you want to provide your own templates you’ll need to do the same thing, adding a filepolicy/fooCam/fooCamMapper.yaml
The name you provided as
_cameraName
is also used to e.g., provide per-camera configuration files (for exampleconfig/latiss/ingest.py
)Don’t forget to add
FooCamMapper
to__all__
Write a header translator for your instrument. This should be placed in
python/lsst/obs/lsst/translators/fooCam.py
. You can follow the examples from other translators there. Remember to add the new file topython/lsst/obs/lsst/translators/__init__.py
. You can test the translator by runningtranslate_header.py -p lsst.obs.lsst.translators testfile.fits
The translators must define the properties specified and defined by
ObservationInfo
. Pay careful attention to how you decide to definedetector_group
anddetector_name
. You can read your detector IDs out of the camera YAML file once it’s created or hard code them into your translator.exposure_id
anddetector_exposure_id
should be written in such a way that they can be called from the mapper class to allow the values to be determined from dataIds.Add a
FooCamParseTask
topython/lsst/obs/lsst/fooCam.py
. It’ll need to set a class variable_mapperClass = FooCamMapper
and also a class variable_translatorClass = LsstFooCamTranslator
(the same class as used in the mapper). Most of the metadata translations are inherited from the base class so you only need to add translations here if you are adding something non-standard. Don’t forget to addFooCamParseTask
to__all__
Put a
_mapper
file in the root of your repository, containinglsst.obs.lsstCam.fooCam.FooCamMapper
Retarget
config.parse
inconfig/fooCam/ingest.py
toFooCamParseTask
You will probably also want to copy e.g.,
config/latiss/latiss.py
toconfig/fooCam/fooCam.py
and also files such asconfig/latiss/bias.py
– don’t forget to modify them to importfooCam.py
!Add
FooCam.yaml
topolicy/.gitignore
Add test data and associated unit tests following the instructions in Testing the Package.
If these instructions are complete and correct you are good to go. Once you’re happy commit all your changes to a branch git, and push, and make a pull request.
We would ideally like to be able to run the integration tests to include the new camera. To enable this please also add some test data to the testdata_lsst repository, and update the ci_lsst package so that the new instrument is included in the integration test.