; @Dataset(label="VEcad",description="VECad channel") vecad-img
; @Dataset(label="Nuclei",description="Nuclei channel") nuclei-img
; @File(label="Save to ROI filename", style="save") roi-filename
; @OUTPUT ImagePlus segments

(ns lymphatic-junctions.scripts.junction-masks
  (:require [fun.imagej.core :as ij]
            [fun.imagej.img :as img]
            [fun.imagej.conversion :as convert]
            [fun.imagej.imp :as ij1]
            [fun.imagej.segmentation.imp :as ij1seg]
            [fun.imagej.imp.statistics :as ij1stats]
            [fun.imagej.imp.calculator :as ij1calc]
            [fun.imagej.imp.roi :as roi]
            [lymphatic-junctions.utils :as utils]
            [clojure.java.io :as io]
            [lymphatic-junctions.globals :as globals]
            [lymphatic-junctions.rf-core :as rf]
            [fun.imagej.ops :as ops]))

(refer 'user);; Import our parameters from the user namespace, because that is where scijava makes them

;(def vecad-img (ij/open-img "/Users/kharrington/Data/Venkatraman_Lakshmi/Vecadh_Images_for_classification/test_img/C2-MAX-v2_pSRc_4.tif"))
;(def nuclei-img (ij/open-img "/Users/kharrington/Data/Venkatraman_Lakshmi/Vecadh_Images_for_classification/test_img/C1-MAX-v2_pSRc_4.tif"))

(let [forest (utils/read-forest (io/resource globals/default-forest))
      ;segments (ij1/erode (ij1/copy-imp (convert/img->imp (fun.imagej.ops.threshold/isoData vecad-img))))
      segments (ij1/copy-imp (convert/img->imp (fun.imagej.ops.threshold/isoData vecad-img)))
      nuclei (ij1/copy-imp (convert/img->imp (fun.imagej.ops.threshold/isoData nuclei-img)))
      rois (ij1seg/imp-to-rois (ij1calc/imp-subtract segments nuclei)  :min-size 20)
      _ (println "Computing statistics")
      segment-maps (for [^ij.gui.Roi roi rois]
                       (assoc (ij1stats/get-image-statistics (ij1/set-roi segments roi)
                                                    :center-of-mass true :centroid true
                                                    :ellipse true :circularity true :area true
                                                    :major true :minor true :solidity true)
                         :roi roi))
      density-maps (ij1stats/rolling-ball-statistics segment-maps globals/density-radius)
      segment-maps (for [k (range (count segment-maps))]
                     (let [segment-map (nth segment-maps k)
                           density-map (nth density-maps k)]
                       (assoc segment-map
                         :num-neighbors (:num-neighbors density-map)
                         :neighbor-circularity (:circularity density-map)
                         :neighbor-area (:area density-map)
                         :neighbor-perimeter (:perimeter density-map)
                         :neighbor-std-dev (:std-dev density-map)
                         :neighbor-mean (:mean density-map))))
      key-fn :roi-color
      _ (println "Classification")
      result-maps (doall
                    (for [segment-map segment-maps]
                      (let [;nucleus-class (int (key (apply max-key val (rf/classify nuclei-forest (map #(get segment-map %) feature-seq)))))
                            junction-class (int (key (apply max-key val (rf/classify forest (map #(get segment-map %) globals/feature-seq)))))]
                        (assoc segment-map
                          ;:predicted-nucleus-class nucleus-class
                          :predicted-class junction-class
                          :output-prediction junction-class
                          #_(if (= 5 nucleus-class) 5 junction-class)))))
      _ (println "Finalizing")
      result-imp (ij1/show-imp (ij1/set-title (ij1seg/color-code-rois segments result-maps :output-prediction)
                                       (str "PredictedClasses")))
      roi-manager (ij.plugin.frame.RoiManager/getRoiManager)
      ]
     (dotimes [k (count result-maps)]
              (let [segmap (nth result-maps k)]
                (.setName (:roi segmap)
                          (str "roi_" k "_cls_" (:predicted-class segmap))
                          )))

    (doseq [roi rois]
      (.addRoi roi-manager roi))
    (.show roi-manager)

    #_(ij1/update-imp result-imp)

     (intern 'user 'segments result-imp)); Export our variable to the user namespace, because that is where scijava expects them
