 
 (defn built-desc->keras-output-dims
   [built-desc]
-  (when (every? #(contains? built-desc %) [:output-channels :output-height :output-width])
+  (when (every? #(% built-desc) [:output-channels :output-height :output-width])
     [(:output-height built-desc) (:output-width built-desc) (:output-channels built-desc)]))
 
 

            [clojure.core.matrix :as m]
            [clojure.core.matrix.macros :refer [c-for]]
            [think.datatype.core :as dtype]
            [clojure.string :as string]))



                                 desc-seq   (mapv vector model-desc built-desc)
                                 by-layer   (associate-layer-outputs desc-seq outputs)]
                             (check-output-dims by-layer))}))))))


(defn reshape-layer-output
  "For outputs that aren't flat, reshape layer weights to use Cortex ordering
  instead of Keras dim ordering."
  [[built-desc data]]
  (when data
   (if-let [keras-dims (built-desc->keras-output-dims built-desc)]
     (do
       (println "Reshaping output for: " (:id built-desc) keras-dims (count data))
       ;;keras: 0 height 1 width 2 n-channels
       ;;cortex: 0 n-channels 1 height 2 width
       (reshape-data data keras-dims [2 0 1]))
     (do
       (println "No reshape required for: " (:id built-desc))
       data))))

(defn load-sidecar-with-outputs
  "Given a sidecar model (as from load-sidecar-model) verify that outputs match
  outputs generated by Keras."
  [weight-desc desc-seq output-file]
  (resource/with-resource-context
    (let [h5-file     (hdf5/open-file output-file)
          outputs     (layer-output-by-id h5-file)
          input-desc  (first weight-desc)
          input-shape (if (:output-width input-desc)
                        [(:output-channels input-desc)
                         (* (:output-height input-desc)
                            (:output-width input-desc))]
                        [(:output-size input-desc)])
          test-data   (-> h5-file hdf5-child-map :test_image hdf5/->clj :data)
          input       (to-core-matrix test-data input-shape)
          verify-seq  (desc/build-and-verify-trained-network weight-desc)
          with-output (associate-layer-outputs desc-seq outputs)
          lyr-outputs (mapv reshape-layer-output with-output)]
      {:model weight-desc
       :input input
       :layer-outputs lyr-outputs})))

(defn load-sidecar-and-verify
  "Loads a Keras model with json-file, h5 weights file, and h5 output generated
  by provided Python export scripts if it passes verification. If it does not,
  throws ex-info with a report containing layers which did not pass verification."
  [model-json-file weights-h5-file output-h5-file]
  (let [model-desc  (-> model-json-file
                        read-model
                        model->simple-description)
        built-desc  (desc/build-full-network-description model-desc)
        desc-seq    (mapv vector model-desc built-desc)
        weight-desc (load-sidecar-model model-json-file weights-h5-file output-h5-file)
        with-output (load-sidecar-with-outputs weight-desc
                                               desc-seq
                                               output-h5-file)
        verified    (compute-verify/verify-model with-output)]
    (if (empty? (:cpu verified))
      (:model with-output)
      (throw (ex-info "Model did not pass verification."
                {:cause  :incorrect-output
                 :report verified})))))
