Added `seems-to-work' elastic montaging. Missing parts are
[trakem2.git] / lineage / generate_reference_SAT_lineage_library.clj
blob2093874e1bcafeea8dc93d298425b39f70ba0253
1 ; Albert Cardona 2009
2 ; Asks for a directory and recursively opens all XML files in it,
3 ; creating a new hidden TrakEM2 project from it,
4 ; and then if it has fiducial points, reads them out
5 ; and reads all lineages from it.
7 (ns lineage.identify
8   (:import (ini.trakem2.analysis Compare)
9            (ini.trakem2 Project ControlWindow)
10            (ini.trakem2.display Line3D Pipe Polyline)
11            (ij.text TextWindow)
12            (ij.io DirectoryChooser)
13            (java.io File FilenameFilter StringWriter)))
15 (def
16   #^{:doc "The lineages to ignore from all open projects"}
17   regex-exclude "(.*unknown.*)|(.*poorly.*)|(.*MB.*)|(.*TR.*)")
19 (defn gather-chains
20   "Collect and calibrate all possible calibrated VectorString chains from all lineages in project"
21   [project]
22   (let [ls (.getRootLayerSet project)
23         cal (.getCalibrationCopy ls)]
24     (map
25       (fn [chain]
26         (.calibrate (.vs chain) cal)
27         chain)
28       (Compare/createPipeChains (.getRootProjectThing project) ls regex-exclude))))
30 (defn gather-mb
31   "Take the mushroom body of the project and store it as two chains,
32   one titled 'peduncle + dorsal lobe' and another 'peduncle + medial lobe'."
33   [project]
34   (let [ls (.getRootLayerSet project)
35         cal (.getCalibrationCopy ls)]
36     (if-let [peduncle (.findChild (.getRootProjectThing project) "peduncle")]
37       (let [medial-lobe (.findChild peduncle "medial lobe")
38             dorsal-lobe (.findChild peduncle "dorsal lobe")
39             c1 (ini.trakem2.analysis.Compare$Chain. (.getObject (first (.findChildrenOfType peduncle "pipe"))))
40             c2 (.duplicate c1)]
41         (.append c1 (.getObject (first (.findChildrenOfType medial-lobe "pipe"))))
42         (.append c2 (.getObject (first (.findChildrenOfType dorsal-lobe "pipe"))))
43         (map
44           (fn [chain title]
45             (set! (.title chain) title)
46             (.calibrate (.vs chain) cal)
47             chain)
48           [c1 c2]
49           ["peduncle + medial lobe" "peduncle + dorsal lobe"]))
50       ; Else empty list
51       [])))
53 (defn gather-fiducials
54   "Extract a table of calibrated fiducial points in project,
55   in the form {<name> [x y z] ...}"
56   [project]
57   (if-let [fids (first (.. project getRootProjectThing (findChildrenOfTypeR "fiducial_points")))]
58     (reduce
59       (fn [m e]
60         (let [t (.getValue e)]
61           (assoc m (.getKey e) [(.x t) (.y t) (.z t)])))
62             {}
63             (Compare/extractPoints fids))
64     nil))
66 (defn gather-xmls
67   "Scan a folder for XML files, recursively."
68   [dir regex-exclude]
69   (reduce
70     (fn [v filename]
71       (if (.isDirectory (File. dir filename))
72         (into v (gather-xmls (str dir \/ filename) regex-exclude))
73         (if (.endsWith (.toLowerCase filename) ".xml")
74           (conj v (str dir \/ filename))
75           v)))
76     []
77     (.list (File. dir)
78          (proxy [FilenameFilter] []
79            (accept [fdir filename]
80              (and (not (.isHidden (File. fdir filename)))
81                   (nil? (re-matches (re-pattern regex-exclude) (str (.getAbsolutePath fdir) \/ filename)))))))))
83 (defn fix-title
84   "Takes a title like 'DALv2 [lineage] #123 FRT42D-BP106'
85   and returns the title without the word in the last set of brackets, like:
86   'DALv2 #123 FRT42D-BP106'"
87   [title]
88   (let [i-last (.lastIndexOf title (int \]))]
89     (if (= -1 i-last)
90       title
91       (let [i-first (.lastIndexOf title (int \[) (dec i-last))]
92         (if (= -1 i-first)
93           title
94           (str (.substring title 0 i-first) (.substring title (inc i-last))))))))
97 (defn gather-SATs
98   "Take a list of chains, each one representing a SAT,
99   and return a table of tables, like:
100   {\"DPLpv\" {:x [...] :y [...] :z [...]}}"
101   [project]
102   (reduce
103     (fn [m chain]
104       (assoc m
105              (fix-title (.getCellTitle chain))
106              {:x (seq (.getPoints (.vs chain) 0))
107               :y (seq (.getPoints (.vs chain) 1))
108               :z (seq (.getPoints (.vs chain) 2))}))
110     {}
111     (into (gather-chains project) (gather-mb project))))
113 (defn generate-SAT-lib
114   "Create the SAT library from a root directory.
115   Will include all XML in any subfolder, recursively."
116   [xmls]
117   (reduce
118     (fn [m xml-path]
119       (let [project (Project/openFSProject xml-path false)
120             fids (gather-fiducials project)]
121         (if (and
122               fids
123               (not (empty? fids)))
124           (let [r (assoc m
125                          (.toString project)
126                          {:source xml-path
127                           :fiducials fids
128                           :SATs (gather-SATs project)})]
129             (.destroy project)
130             r)
131           ; Else, ignore
132           (do
133             (.destroy project)
134             (println "No fiducials found in" xml-path)
135             m))))
136     {}
137     xmls))
139 (defn start
140   "Will ignore any of the xml files in the chosen dir whose absolute file path matches the regex-exclude string."
141   ([regex-exclude]
142     (if-let [dir (.getDirectory (DirectoryChooser. "Choose root dir"))]
143       (start dir regex-exclude)))
144   ([dir regex-exclude]
145     (ControlWindow/setGUIEnabled false)
146     (try
147       (TextWindow. "SAT-lib.clj"
148                    (let [sw (StringWriter.)]
149                      (binding [*out* sw]
150                        (prn (generate-SAT-lib (gather-xmls dir regex-exclude))))
151                        (.toString sw))
152                     400 400)
153       (catch Exception e
154         (.printStackTrace e)))
155     (ControlWindow/setGUIEnabled true)))