From 57b722f74097da7709aec76afaa4ecb289e476d3 Mon Sep 17 00:00:00 2001
From: Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
Date: Wed, 18 Sep 2013 09:53:03 +0200
Subject: Use pco_get/set_framerate instead of delay + exposure

---
 plugins/pco/uca-pco-camera.c | 194 ++++---------------------------------------
 1 file changed, 18 insertions(+), 176 deletions(-)

(limited to 'plugins/pco')

diff --git a/plugins/pco/uca-pco-camera.c b/plugins/pco/uca-pco-camera.c
index 8a58f06..6eedff8 100644
--- a/plugins/pco/uca-pco-camera.c
+++ b/plugins/pco/uca-pco-camera.c
@@ -115,7 +115,6 @@ enum {
     PROP_SENSOR_PIXELRATE,
     PROP_SENSOR_ADCS,
     PROP_SENSOR_MAX_ADCS,
-    PROP_DELAY_TIME,
     PROP_HAS_DOUBLE_IMAGE_MODE,
     PROP_DOUBLE_IMAGE_MODE,
     PROP_OFFSET_MODE,
@@ -194,10 +193,6 @@ struct _UcaPcoCameraPrivate {
     GValueArray *vertical_binnings;
     GValueArray *pixelrates;
 
-    /* The time bases are given as pco time bases (TIMEBASE_NS and so on) */
-    guint16 delay_timebase;
-    guint16 exposure_timebase;
-
     frameindex_t last_frame;
     guint16 active_segment;
     guint num_recorded_images;
@@ -307,64 +302,6 @@ override_maximum_adcs(UcaPcoCameraPrivate *priv)
     spec->maximum = pco_get_maximum_number_of_adcs(priv->pco);
 }
 
-static gdouble
-convert_timebase(guint16 timebase)
-{
-    switch (timebase) {
-        case TIMEBASE_NS:
-            return 1e-9;
-        case TIMEBASE_US:
-            return 1e-6;
-        case TIMEBASE_MS:
-            return 1e-3;
-        default:
-            g_warning("Unknown timebase");
-    }
-    return 1e-3;
-}
-
-static void
-read_timebase(UcaPcoCameraPrivate *priv)
-{
-    pco_get_timebase(priv->pco, &priv->delay_timebase, &priv->exposure_timebase);
-}
-
-static gboolean
-check_timebase (gdouble time, gdouble scale)
-{
-    const gdouble EPSILON = 1e-3;
-    gdouble scaled = time * scale;
-    return scaled >= 1.0 && (scaled - ((int) scaled)) < EPSILON;
-}
-
-static gdouble
-get_suitable_timebase(gdouble time)
-{
-    if (check_timebase (time, 1e3))
-        return TIMEBASE_MS;
-    if (check_timebase (time, 1e6))
-        return TIMEBASE_US;
-    if (check_timebase (time, 1e9))
-        return TIMEBASE_NS;
-    return TIMEBASE_INVALID;
-}
-
-static gdouble
-get_internal_delay (UcaPcoCamera *camera)
-{
-    if (camera->priv->description->type == CAMERATYPE_PCO_DIMAX_STD) {
-        guint sensor_rate;
-        g_object_get (camera, "sensor-pixelrate", &sensor_rate, NULL);
-
-        if (sensor_rate == 55000000.0)
-            return 0.000079;
-        else if (sensor_rate == 62500000.0)
-            return 0.000036;
-    }
-
-    return 0.0;
-}
-
 static int
 fg_callback(frameindex_t frame, struct fg_apc_data *apc)
 {
@@ -691,93 +628,23 @@ uca_pco_camera_set_property(GObject *object, guint property_id, const GValue *va
 
         case PROP_EXPOSURE_TIME:
             {
-                const gdouble time = g_value_get_double(value);
-
-                if (priv->exposure_timebase == TIMEBASE_INVALID)
-                    read_timebase(priv);
-
-                /*
-                 * Lets check if we can express the time in the current time
-                 * base. If not, we need to adjust that.
-                 */
-                guint16 suitable_timebase = get_suitable_timebase(time);
-
-                if (suitable_timebase == TIMEBASE_INVALID) {
-                    g_warning("Cannot set such a small exposure time");
-                }
-                else {
-                    if (suitable_timebase != priv->exposure_timebase) {
-                        priv->exposure_timebase = suitable_timebase;
-                        err = pco_set_timebase(priv->pco, priv->delay_timebase, suitable_timebase);
-                        break;
-                    }
-
-                    gdouble timebase = convert_timebase(suitable_timebase);
-                    guint32 timesteps = time / timebase;
+                uint32_t exposure;
+                uint32_t framerate;
 
-                    err = pco_set_exposure_time(priv->pco, timesteps);
-                }
+                pco_get_framerate (priv->pco, &framerate, &exposure);
+                exposure = (uint32_t) (g_value_get_double (value) * 1000 * 1000 * 1000);
+                pco_set_framerate (priv->pco, framerate, exposure, false);
             }
             break;
 
         case PROP_FRAMES_PER_SECOND:
             {
-                gdouble n_frames_per_second;
-                gdouble exposure_time;
-                gdouble delay;
-
-                /*
-                 * We want to expose n frames in one second, each frame takes
-                 * exposure time + delay time. Thus we have
-                 *
-                 *   1s = n * (t_exp + t_delay) <=> t_exp = 1s/n - t_delay.
-                 */
-                delay = get_internal_delay (UCA_PCO_CAMERA (object));
-                n_frames_per_second = g_value_get_double (value);
-                exposure_time = 1.0 / n_frames_per_second - delay;
+                uint32_t exposure;
+                uint32_t framerate;
 
-                if (exposure_time <= 0.0)
-                    g_warning ("Too many frames per second requested.");
-                else
-                    g_object_set (object, "exposure-time", exposure_time, NULL);
-            }
-            break;
-
-        case PROP_DELAY_TIME:
-            {
-                const gdouble time = g_value_get_double(value);
-
-                if (priv->delay_timebase == TIMEBASE_INVALID)
-                    read_timebase(priv);
-
-                /*
-                 * Lets check if we can express the time in the current time
-                 * base. If not, we need to adjust that.
-                 */
-                guint16 suitable_timebase = get_suitable_timebase(time);
-
-                if (suitable_timebase == TIMEBASE_INVALID) {
-                    if (time == 0.0) {
-                        /*
-                         * If we want to suppress any pre-exposure delays, we
-                         * can set the 0 seconds in whatever time base that is
-                         * currently active.
-                         */
-                        err = pco_set_delay_time(priv->pco, 0);
-                    }
-                    else
-                        g_warning("Cannot set such a small exposure time");
-                }
-                else {
-                    if (suitable_timebase != priv->delay_timebase) {
-                        priv->delay_timebase = suitable_timebase;
-                        err = pco_set_timebase(priv->pco, suitable_timebase, priv->exposure_timebase);
-                    }
-
-                    gdouble timebase = convert_timebase(suitable_timebase);
-                    guint32 timesteps = time / timebase;
-                    err = pco_set_delay_time(priv->pco, timesteps);
-                }
+                pco_get_framerate (priv->pco, &framerate, &exposure);
+                framerate = (uint32_t) (g_value_get_double (value) * 1000);
+                pco_set_framerate (priv->pco, framerate, exposure, true);
             }
             break;
 
@@ -1009,36 +876,21 @@ uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, G
 
         case PROP_EXPOSURE_TIME:
             {
-                uint32_t exposure_time;
-                err = pco_get_exposure_time(priv->pco, &exposure_time);
-
-                if (priv->exposure_timebase == TIMEBASE_INVALID)
-                    read_timebase(priv);
+                uint32_t exposure;
+                uint32_t framerate;
 
-                g_value_set_double(value, convert_timebase(priv->exposure_timebase) * exposure_time);
+                pco_get_framerate (priv->pco, &framerate, &exposure);
+                g_value_set_double (value, exposure / 1000. / 1000. / 1000.);
             }
             break;
 
         case PROP_FRAMES_PER_SECOND:
             {
-                gdouble exposure_time;
-                gdouble delay;
-
-                delay = get_internal_delay (UCA_PCO_CAMERA (object));
-                g_object_get (object, "exposure-time", &exposure_time, NULL);
-                g_value_set_double (value, 1.0 / (exposure_time + delay));
-            }
-            break;
-
-        case PROP_DELAY_TIME:
-            {
-                uint32_t delay_time;
-                err = pco_get_delay_time(priv->pco, &delay_time);
+                uint32_t exposure;
+                uint32_t framerate;
 
-                if (priv->delay_timebase == TIMEBASE_INVALID)
-                    read_timebase(priv);
-
-                g_value_set_double(value, convert_timebase(priv->delay_timebase) * delay_time);
+                pco_get_framerate (priv->pco, &framerate, &exposure);
+                g_value_set_double (value, framerate / 1000.);
             }
             break;
 
@@ -1419,13 +1271,6 @@ uca_pco_camera_class_init(UcaPcoCameraClass *klass)
             UCA_TYPE_PCO_CAMERA_ACQUIRE_MODE, UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO,
             G_PARAM_READWRITE);
 
-    pco_properties[PROP_DELAY_TIME] =
-        g_param_spec_double("delay-time",
-            "Delay time",
-            "Delay before starting actual exposure",
-            0.0, G_MAXDOUBLE, 0.0,
-            G_PARAM_READWRITE);
-
     pco_properties[PROP_NOISE_FILTER] =
         g_param_spec_boolean("noise-filter",
             "Noise filter",
@@ -1604,8 +1449,6 @@ uca_pco_camera_init (UcaPcoCamera *self)
     priv->last_frame = 0;
     priv->grab_buffer = NULL;
     priv->construct_error = NULL;
-    priv->delay_timebase = TIMEBASE_INVALID;
-    priv->exposure_timebase = TIMEBASE_INVALID;
 
     if (!setup_pco_camera (priv))
         return;
@@ -1626,7 +1469,6 @@ uca_pco_camera_init (UcaPcoCamera *self)
     uca_camera_register_unit (camera, "cooling-point-default", UCA_UNIT_DEGREE_CELSIUS);
     uca_camera_register_unit (camera, "sensor-adcs", UCA_UNIT_COUNT);
     uca_camera_register_unit (camera, "sensor-max-adcs", UCA_UNIT_COUNT);
-    uca_camera_register_unit (camera, "delay-time", UCA_UNIT_SECOND);
 }
 
 G_MODULE_EXPORT GType
-- 
cgit v1.2.3