# Cooled Thermal Cameras Calibration Manual

This manual describes how to work with the calibration tool (ctdcalib) used to calibrate cooled thermal cameras. The tool is a console app that can be started like: "python3 ctdcalib.py recipe-file work-folder"

The work-folder parameter is a directory on the system where the tool will log store all its logs. The recipe file is actualy calibration procedure that the user desires to execute. The recipe is in python, but has some specific rules that need to be followed in order to write a valid recipe.
By default the tool will print its output on the stdout(console), while also saving it in a file called log.txt in the root of the work-folder.

## Recipe Creation
The recipe is a python script file. It has the following global functions, variables and classes injected in the global scope (no need to load every time). Apart from this -- this is a normal python script and obeys the normal python script rules.

## Global Variables
The tool "injects" these global variables in the recipe's context, so that they are always present whenever a recipe is being executed.

| Name | Variable Purpose | 
| ----- | ---------------- |
| SESSION_DIR | a variable containing the path to the work-dir |

## Global Functions
In addition to the builtin python functions, the following functions are available in the global scope of the recipe:

1. LOG(msg:str)
- definition: Logs something on the console and in the log file
- parameters:
    * msg -- str, the message to be visualized

2. SLEEP(time:float)
- definition: Adds an artificial delay in the recipe execution
- parameters:
    * time -- float, the time to delay in seconds

## Controllable Devices
### Black Body
A device capable of regulating its emiting temperature based on a set absolute or on the ambient surrounding one.

### Constructor
BlackBody(sn:str, threshold:float)
- definition: Connects a black body device
- parameters:
    * sn - str, the serial number of the device, to which to connect to
    * threshold, float, optional parameter, default value is 1, used when blocking to reach target temperature

### Supported functions
* set_abs_temperature(temp:float, block:bool)
    - definition: starts the device in absolute mode, in which an absolute temperature of the emitter is maintained, regardless of the background temperature. This cancels any previous differential temperature command.
    - parameters:
        * temp -  the desired absolute temperature
        * block - bool, optional, by default is False, controls whether the command waits for the target to be reached or completes after assignment
    - returns: None
* set_diff_temperature(temp:float, block:bool)
    - definition: starts the device in differential mode, in which the temperature of the emitter is calculated based on the difference with the background temp. This cancels any previous absolute temperature command.
    - parameters:
        * temp -  the differential temp, in Celcium. If temp=10 and the background temperature is 20, then the emitter temperature target will be 30.
        * block - bool, optional, by default is False, controls whether the command waits for the target to be reached or completes after assignment
    - returns: None
* stop_emitter()
    - definition: exits any started mode and reverts to standby state. In this state the black body does not maintain any specific temperature of the emitter and the emitter will slowly reach the background temp (because it is OFF).
    - parameters: None
    - returns: None
* get_emiter_temperature()
   - definition: gets the current emiter temperature
    - parameters: None
    - returns: float, current temperature in degress Celcium
* get_background_temperature()
    - definition: gets the current background temperature
    - parameters: None
    - returns: float, current temperature in degress Celcium
* get_info()
    - definition: returns status information about the device
    - params: None
    - returns: a dictionary with the following keys
        * serial - str, the serial number of the device,
        * model, str, the model description of the device
        * version, str, fw version, semantic versioning
        * absolute-range - str, temperature range of operation in absolute mode,
        * differential-range, str, temperature range of operation in differential mode,
    
### Bidentifier Mwir
This device is a camera with a single thermal sensor, it requires a network connection. The camera supports a 100 valid NUC slots (0-99). The 100th slot is reserved for using 1pnuc, the 101 slot is reserved for the default buffers. The 1pnuc and default slot are not memory mapped, while the 0-99 nuc range are stored in flash. The device first needs to load them to RAM(done automatically on device startup) to use them and if the user wants to save any changes made to them, they need to be saved to back to flash.

### Constructor
BidentifierMwir(ip:str, username:str, password:str, port:int)

- definition: creates a BidentitifierMwir camera device
- parameters:
    * ip - str,  the network address of the device, accessible from the calibration machine
    * username - str,  login username for ssh connection
    * password - str the password for ssh connection
    * port - int, optional argument, if not specified the port is 22

### Supported functions
* one_point_nuc()
    - definition: creates a 1pnuc from the gain of the currently selected slot, the result is placed in the 1pnuc slot
    - parameters: no parameters
    - returns: None
* one_point_nuc_defocus()
    - definition: creates a 1pnuc from the gain of the currently selected slot, the result is placed in the 1pnuc slot. Before the actual nuc procedure is executed, the camera defocuses, then after the procedure is complete it returns to its previous location
    - parameters: no parameters
    - returns: None
* set_nuc(slot:int, update:bool)
    - definition: use the specified slot as NUC
    - parameters
        * slot - the desired NUC slot, 0-101 is the valid range
        * update - bool, optional - specifies whether to update the image parameters from the nuc table when setting the NUC (like integration time and fps), true if not specified
    - returns: None
* save_nuc(slot:int)
    - definition: save 2pNUC slot from RAM -> FLASH
    - parameters
        * slot - the desired NUC slot, 0-99 is the valid range
    - returns: None
* restore_nuc(slot_int):
    - definition:restore 2pNUC slot from FLASH -> RAM
    - parameters
        * slot - the desired NUC slot, 0-99 is the valid range
    - returns: None
* two_point_nuc_low()
    - definition: performs a 2pnuc-low operation
    - parameters : None
    - returns: None
* two_point_nuc_high()
    - definition: performs a 2pnuc-high operation
    - parameters : None
    - returns: None
* two_point_nuc_calc(save:int)
    - definition: performs a 2pnuc-calc operation, this works correctly if calc_low and calc_high variants have been called beforehand
    - parameters : 
        * save - int, 1 - saves the created nuc on the created slot in FLASH, 0 -  nuc is still created but is only in RAM
    - returns: None
* download_nuc_raw(low_path:str, high_path:str)
    - definition: downloads the raw input parts that were taken by the last "calc low" and "calc high" commands
    - parameters :
        * low_path - path on the filesystem where to save the low raw file
        * high_path - path on the filesystem where to save the high raw file
    - returns: None
* download_raw(path:str)
    - definition: downloads a raw image from the camera
    - parameters :
        * path - path on the filesystem where to save the  raw file
    - returns: None
* download_nbc(path:str)
    - definition: downloads a raw image from the camera, after NUC and BPC
    - parameters :
        * path - path on the filesystem where to save the  raw file
    - returns: None
* download_nuc(path:str, slot:int)
    - definition: downloads a NUC from the specified slot
    - parameters :
        * path - path on the filesystem where to save the NUC file
        * slot - the desired NUC slot, 0-101 is the valid range
    - returns: None
* upload_nuc(path:str, slot:int)
    - definition: downloads a NUC from the specified slot
    - parameters :
        * path - path on the filesystem where to read the NUC file
        * slot - the desired NUC slot, 0-101 is the valid range
    - returns: None
* copy_nuc(src_slot:int, dst_slot:int)
    - definition: copies a NUC from one slot to another (only in RAM)
    - parameters :
        * src_slot - NUC slot to read from, 0-101 is the valid range
        * dst_slot - NUC slot to save to, 0-101 is the valid range
    - returns: None
* set_fov(fov:int)
    - definition: Move the lens to a predefined field-of-view(FOV). This command blocks until the move is complete.
    - parameters:
        * fov - 1 - WFOV, 2 - MFOV, 3 - NFOV, valid range [1-3]
    - returns: None
* get_lens_position()
    - definition: Read the current position of the lens driver
    - parameters: None
    - returns: a dictionary with the following keys
        * zoom - unsigned 16-bit position
        * focus - unsigned 16-bit position
        * temperature - in degrees celcium
        * bit - BIT result byte
        * work-hours - 
        * busy
        * zoom-absolue
        * focus-absolute
* set_zoom_position(pos:int)
    - definition: sets the zoom position of the lens driver
    - parameters: 
        * pos - int, the desired zoom position, unsigned 16-bit
    - returns: None
* set_focus_position(pos:int)
    - definition: sets the focus position of the lens driver
    - parameters: 
        * pos - int, the desired focus position, unsigned 16-bit
    - returns: None
* get_image_processing_status()
    - definition: returns the image processing status of the camera. These are based on configuration + current scene.
    - returns: a dictionary with the following keys
        * tail-rejection-low
        * tail-rejection-high
        * agl-low
        * agl-high
        * histogram-low
        * histogram-high
        * average
        * offset
        * digital-zoom -- float, coefficient from x1 to x8
        * current-nuc -- int, from 0 to 101
        * raw-tail-rejection-low
        * raw-tail-rejection-high
        * raw-max-peak

* get_sensor_id()
    - definition: returns the sensor's id number
    - parameters: 
    - returns: string
* set_integration_time(it:int)
    - definition: sets the camera integration time
    - parameters
        * it - sets the current integration time, in us
    - returns: None
* get_integration_time()
    - definition: gets the current integration time
    - parameters: None
    - returns: int, the integration time in us
* set_fps(fps:int)
    - definition: sets the camera fps
    - parameters
        * fps - sets the current fps
    - returns: None
* get_fps()
    - definition: gets the current fps
    - parameters: None
    - returns: int
* set_digital_zoom(zoom:float)
    - definition: sets the desired digital zoom
    - parameters:
        * zoom - float, range [1-8]
    - returns: int
* get_package_version()
    - definition: returns the FW version of the package, that the device is loaded with
    - parameters: None
    - returns: str, the FW version in semantic version format (X.Y.Z)

* get_temperatures()
    - definition: gets the temperature data from the device
    - parameters: None
    - returns:
        * carrier - float, the temperature in C, from the carrier board
        * lens-driver - float, the temperature in C, from the lens driver
        * sensor-internal - float, the cooled sensor temperature in K, from the sensor board
        * sensor-ambient - float, the sensor's ambient temperature, in C
        * core - float, the core temperature of the carrier board

* set_display_enable(enable:int)
    - definition: set the display's enable functionality (software sleep)
    - parameters: 
        * enable - int, 0 - disabled, everything else is enabled
    - returns: None

* download_table(path:str)
    - definition: download the nuc table of the device
    - parameters: 
        * path - str, path on the system where to save the table
    - returns: None

* download_snapshot(path:str)
    - definition: make and download a snapshot from the device
    - parameters: 
        * path - str, path where to download a snapshot from the device
    - returns: None

* clean_ecc()
    - definition: Cleans the ecc buffers, if used on slot 0-99 cleans every ecc buffer responsible for 0-99. If used on 1pnuc or default slots, cleans only the buffers responsible for them.
    - parameters: None
    - returns: None
    
* set_clock(date:datetime=None)
    - definition: sets the RTC of the camera with the desired date-time
    - parameters: date, the desired datetime to set (uses python standard lib datetime object), if not supplied it takes the current datetime
    - returns: None

### Climate Chamber
This a device can accurately set the temperature itside its enclosure. 

### Constructor
ClimateChamber(ip:str, port:int, threshold:float)
- definition: connects to chamber device that is available through TCP/IP
- parameters: 
    * ip - str, the IP address of the chamber
    * port- str, the port of the control service of the chamber
    * threshold, float, optional, by default is 1, controls the temperature/humidity threshold when starting the chamber

### Supported functions
* start(temp:float, hum:float, block:bool)
    - definition: starts the chamber, maintaining the currently set parameters.
    - parameters:
        * temp - float, in degrees Celcium, the desired temperature
        * hum - float, the humidity from 0 to 100% in relative %
        * block -optional, bool -- denotes if the camera waits for the command to be reached or exits after assignment
    - returns: None

* stop()
    - definition: stops the chamber, making it enter idle mode
    - parameters: None
    - returns: None

* get_status() 
    - definition:gets the current chamber status
    - parameters: None
    - returns: dictionary, with keys "temperature and "humidity"

* get_device_info()
    - definition: gets the device information
    - parameters: None
    - returns: dictionary, with keys "server-version", "serial-number" and "system-type"

### Motor Rail
This is a serially connected device that can accurately position a "thumb" located on a motorized rail. The thumb allows for several other devices to be mounted on it - and thus positioned precisely on the rail.

### Constructor
MotorRail(serial:str)
- definition: the library for working with the MotorRail is a propriatary DLL, so there is no need to specify serial port, serial speed, it autodetects its devices.
- parameters: 
    * serial - serail number of the device that we're connecting to

### Supported functions
* get_pos()
    - definition: gets the current position of the motor rail
    - parameters: None
    - returns: float, the current motor rail position
* set_pos(position:float)
    - definition: sets the desired position of the motor rail. This command will block until the movement is complete.
    - parameters:
        - position: the target position
    - returns: None
* reset_pos()
    - definition: sets the desired position of the motor rail. This command will block until the movement is complete.
    - parameters:
        - position: the target position
    - returns: None
* get_info()
    - definition: gets status information about the motor rail
    - parameters: None
    - returns: a dictionary with the following keys:
        * serial-number - str, the serial number of the device
        * platform-speed - int, the speed settings for the moving motion, 0-SLOW, 1-MEDIUM, 2-FAST
        * calibration-unit - str, the unit in which the motion is calculated
        * min-position - float, minimal allowed position
        * max-position - float, maximum allowed position
        * resolution - float, the resolution of the minimal allowed movement command
* set_platform_speed(speed:int)
    - definition: sets the platform speed of the rail, this is the speed at which the rail moves when completing movement commands
    - parameters:
        * speed - int, this is an ENUM, 0 - SLOW, 1 - Medium, 2 - Fast
    - returns: None

## Mock Devices (Dummy)
These devices have the same methods as their original counterparts but do not connect to actual physical hardware -- they can be used as a substitutes when testing recipe ideas or partial recipe exection.

Example:
```
if test_flag:
    MotorRail = DummyMotorRail

MotorRail mr = MotorRail("1234ASD")
mr.set_pos(1234) # this wont actually move anything
...
```