A set of command line tools which hopefully ease the configuration and development of Lima cameras.
TL;DR
From within your favorite python environment, type:
pip install lima-toolbox[all]
The toolbox is composed of a core library and plug-ins for diverse set of cameras.
The core can be installed with:
pip install lima-toolbox
To install support for specific camera(s) use (example):
pip install lima-toolbox[basler,eiger]
At the end you can find a mini-catalog of the available cameras.
PRs which implement new cameras (or improve, or fix existing ones) are most welcome.
Probably the most useful tool is the CLI. You can use it to discover cameras on the network, display information about a specfic camera and even perform acquisitions.
The limatb CLI provides global commands like scan
which are not camera specific.
In addtition, each camera provides its own set of sub-commands. They are accessible
by typing lima <camera> <sub-command>
(ex: lima eiger --host=bl99eiger info
).
Typing limatb --help
will display help. Help is context sensitive, so
typing limatb basler --help
will display help for the basler subset of
commands.
camera toolbox plug-ins which provides scan capability allow you to
discover them by using the scan
command:
$ limatb scan --table-style=box_rounded
Basler:
╭──────────────┬──────────────────────────────┬───────────────────────┬───────────┬────────────┬───────────┬────────╮
│ Class │ Friendly name │ Full name │ Name │ Serial Nb. │ User name │ Vendor │
├──────────────┼──────────────────────────────┼───────────────────────┼───────────┼────────────┼───────────┼────────┤
│ BaslerCamEmu │ Basler Emulation (0815-0000) │ Emulation (0815-0000) │ Emulation │ 0815-0000 │ │ Basler │
├──────────────┼──────────────────────────────┼───────────────────────┼───────────┼────────────┼───────────┼────────┤
│ BaslerCamEmu │ Basler Emulation (0815-0001) │ Emulation (0815-0001) │ Emulation │ 0815-0001 │ │ Basler │
├──────────────┼──────────────────────────────┼───────────────────────┼───────────┼────────────┼───────────┼────────┤
│ BaslerCamEmu │ Basler Emulation (0815-0002) │ Emulation (0815-0002) │ Emulation │ 0815-0002 │ │ Basler │
╰──────────────┴──────────────────────────────┴───────────────────────┴───────────┴────────────┴───────────┴────────╯
Eiger:
╭───────────┬───────────┬─────────────┬──────┬───────╮
│ Host │ Alias(es) │ Address(es) │ Port │ API │
├───────────┼───────────┼─────────────┼──────┼───────┤
│ bl04eiger │ │ 172.95.4.11 │ 8000 │ 1.6.0 │
╰───────────┴───────────┴─────────────┴──────┴───────╯
MythenSLS:
╭────────────┬─────────────┬──────┬────────┬──────────┬──────────┬───────────┬────────────╮
│ Host │ IP │ Port │ Type │ #Modules │ Settings │ Threshold │ Dyn. Range │
├────────────┼─────────────┼──────┼────────┼──────────┼──────────┼───────────┼────────────┤
│ bl04mythen │ 172.95.4.10 │ 1952 │ MYTHEN │ 6 │ STANDARD │ 9071 │ 32 │
╰────────────┴─────────────┴──────┴────────┴──────────┴──────────┴───────────┴────────────╯
Here you can see 3 simulated Basler cameras, an Eiger camera and a Mythen SLS camera are available.
As mentioned above, each camera provides its own set of specific sub-commands.
The sub-commands info
and acquire
are common to all cameras (altough the specific
sub-command options could vary).
The set of options which identify a camera are specific to each camera. For example,
to identify an eiger you must provide the --url=<hostname>
option.
Note that there is nothing enforcing a specific camera to implement any of the common sub-commands. But it is considered good taste if a plugin does it (for the sake of coherency).
A camera plugin may optionally implement the scan
command. It should provide the same
result as the global scan with results restricted to the camera type.
Basic information about a camera can be retrieved with the info
sub-command.
Examples:
$ limatb eiger --url=bl04eiger info
CurrImageType: 10
DefImageType: 10
DetectorImageSize: <3110x3269>
DetectorModel: Dectris Eiger 9M
DetectorType: E-18-0102
InstrumentName: instrument
MaxImageSize: <3110x3269>
PixelSize: (7.5e-05, 7.5e-05)
UserDetectorName: E-18-0102
$ limatb mythensls --url bl04mythen info
CurrImageType 10
DefImageType 10
DetectorImageSize <7680x1>
DetectorModel Mythen-II
DetectorType MythenSLS
InstrumentName instrument
MaxImageSize <7680x1>
PixelSize (1.0, 1.0)
UserDetectorName MythenSLS
Detector type MYTHEN
Serial number 1719109785
Software version 1867412
Status IDLE
Dynamic range 32
Energy threshold 9071
Exposure time 1.0
Number of frames 0
Number of cycles 0
Number of gates 0
Master NO_MASTER
Synchronization NONE
Timing AUTO_TIMING
Delay after triger 0.0
Readout NORMAL_READOUT
Settings STANDARD
External signals ['GATE_OUT_ACTIVE_HIGH', 'TRIGGER_IN_RISING_EDGE', 'OFF',
'OFF']
Aquisitions can be made with the acquire
sub-command.
The common options include -nb-frames
, --exposure-time
, --latency-time
. You
can see the complete list of options with lima <camera> acquire --help
.
Here is an example performing an acquisition on an eiger camera:
You have two options:
Write a PR to this repo with the camera you intend to add. This should always be possible independently of the type of camera you are writing the plug-in for.
Let's say you want to create a plugin for the Simulator camera.
First, create a new file in src/limatb/camera
called simulator.py
.
The lima toolbox CLI uses the click library
to help create a powerful command line interface.
To create a simulator
sub-command you can simply use the lima toolbox camera
decorator (which is a click.group
helper) and write a function that should
return a Lima.Interface
object:
# src/limatb/camera/simulator.py
from limatb.cli import camera
from Lima.Simulator import Camera, Interface
@camera(name='simulator')
def simulator():
camera = Simulator.Camera()
interface = Interface(camera)
return interface
The second and last thing to do is to register the new command in the lima toolbox setup.py like this:
extras_require = {
"simulator": [] # add any extra python dependencies if necessary
}
setup(
...,
entry_points={
"lima.cli.camera": [
...
"Simulator = limatb.camera.simulator:simulator [simulator]"
]
}
)
That's it. Next time you install lima-toolbox there should be a simulator
camera available with the default info
and acquire
sub-commands available
out of the box.
Congratulations! You are now ready to make a PR to this repo with your new camera.
Read further to find how to implement camera options, details about the camera decorator and how to implement your own camera specific sub-commands.
Examples of existing cameras can be found in the src/limatb/camera
directory.
If you need to add any option to the command line to identify or configure your
camera you can do it using click.option
. Here is an example extending the
previous one:
import click
@camera(name='simulator')
@click.option(
'--fill-type',
click.Choice(['gauss', 'diffraction'],
case_sensitive=False),
default='gauss')
def simulator(fill_type):
camera = Simulator.Camera()
interface = Interface(camera)
fill_type = getattr(Lima.Simulator.FrameBuilder, fill_type.capitalize())
frame_getter = camera.getFrameGetter()
frame_getter.setFillType(fill_type)
return interface
The @camera
decorator helper provides a click.group
decorator enhanced with
the info
and acquire
sub-commands by default and the facility that the
returned interface gets inserted into the click context object
ctx.obj['interface']
which can be accessed by any camera sub-commands you
decide to implement.
Here is an example on how to implement a specific sub-command:
@simulator.command("initialize")
@click.pass_context
def initialize(ctx):
# Initialization code here
interface = ctx.obj['interface']
The lima toolbox CLI implements global scan
command which has the purpose
of discovering all the cameras in the system.
To make the specific scan
command of your system visible to the global scan
command you need to register a scan function with the signature:
[async] def scan(timeout: float = None) -> beautifultable.BeautifulTable
and register the entry point in setup.py with:
setup(
...,
entry_points={
"lima.cli.camera.scan": [
...
"Simulator = limatb.camera.simulator:scan [simulator]"
]
}
)
The scan function can have any name you which. You can provide a coroutine
(with async
keyword).
If now you type lima scan
on the command line, it should execute the
scan command of all registered cameras.
Another option, if your camera plugin is installable via a setup.py
, is to apply the
same recipes above, where the only difference resides in implementing the code in your
own python detector package and modifying your setup.py instead.
An example of a project which following this phylosophy is the SLS Mythen.
Feel free to make a PR adding your own camera to this list. They are most welcome!