         time-stamp (burst-time (:tags image) @state)]
     (annotate-image image event @state time-stamp)))
 
-(defmacro doseq-parallel [seq-exprs & body]
-  `(let [pool# (-> (Runtime/getRuntime) .availableProcessors Executors/newFixedThreadPool)]
-     (println (.getCorePoolSize pool#))
-     (doseq ~seq-exprs
-       (let [body-fn# (cast Runnable (fn []
-                                       ;(println (str (Thread/currentThread)))
-                                       ~@body))]
-         (.submit pool# body-fn#)))
-     (.shutdown pool#)
-     (.awaitTermination pool# 10 TimeUnit/DAYS)))
-
 (defn produce-burst-images
   "Pops images from circular buffer and sends them to output queue."
   [burst-events camera-channel-names timeout-ms out-queue]
   (let [total (* (count burst-events)
                  (count camera-channel-names))
-        camera-index-tag (str (. mmc getCameraDevice) "-CameraChannelIndex")
-        images (map (fn [_] (pop-burst-image timeout-ms)) (range total))]
-    (time
-    (doseq [image images]
+        camera-index-tag (str (. mmc getCameraDevice) "-CameraChannelIndex")]
+    (doseq [_ (range total)]
       (.put out-queue
-            (-> image
-                ;(time)
+            (-> (pop-burst-image timeout-ms)
                 (tag-burst-image burst-events camera-channel-names camera-index-tag)
-                make-TaggedImage)))))
+                make-TaggedImage))))
   (burst-cleanup))
 
 (defn collect-burst-images [event out-queue]


;; startup and shutdown

(defn prepare-state [this]
  (let [default-z-drive (core getFocusDevice)
        default-xy-stage (core getXYStageDevice)
        z (get-z-stage-position default-z-drive)
        xy (get-xy-stage-position default-xy-stage)
        exposure (core getExposure)]
    (swap! (.state this) assoc
             :pause false
             :stop false
             :finished false
             :last-wake-time (jvm-time-ms)
             :last-stage-positions (into {} [[default-z-drive z]
                                             [default-xy-stage xy]])
             :reference-z z
             :start-time (jvm-time-ms)
             :init-auto-shutter (core getAutoShutter)
             :init-exposure exposure
             :init-shutter-state (core getShutterOpen)
             :exposure {(core getCameraDevice) exposure}
             :default-z-drive default-z-drive
             :default-xy-stage default-xy-stage
             :init-z-position z
             :init-system-state (get-system-config-cached)
             :init-continuous-focus (core isContinuousFocusEnabled)
             :init-width (core getImageWidth)
             :init-height (core getImageHeight)
             :binning (core getProperty (core getCameraDevice) "Binning")
             :bit-depth (core getImageBitDepth)
             :pixel-size-um (core getPixelSizeUm)
             :source (core getCameraDevice)
             :pixel-type (get-pixel-type)
      )))

(defn cleanup []
  (try
    (attempt-all
      (log "cleanup")
      ; (do-when #(.update %) (:display @state))
      (state-assoc! :finished true :display nil)
      (when (core isSequenceRunning)
        (core stopSequenceAcquisition))

(def active-slice-sequence (atom nil))

(def pixel-type-depths {"GRAY8" 1 "GRAY16" 2 "RGB32" 4 "RGB64" 8})

(defn throw-exception [msg]
  (throw (Exception. msg)))

;; time

