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.
8 (:import (ini.trakem2.analysis Compare)
9 (ini.trakem2 Project ControlWindow)
10 (ini.trakem2.display Line3D Pipe Polyline)
12 (ij.io DirectoryChooser)
13 (java.io File FilenameFilter StringWriter)))
16 #^{:doc "The lineages to ignore from all open projects"}
17 regex-exclude "(.*unknown.*)|(.*poorly.*)|(.*MB.*)|(.*TR.*)")
20 "Collect and calibrate all possible calibrated VectorString chains from all lineages in project"
22 (let [ls (.getRootLayerSet project)
23 cal (.getCalibrationCopy ls)]
26 (.calibrate (.vs chain) cal)
28 (Compare/createPipeChains (.getRootProjectThing project) ls regex-exclude))))
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'."
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"))))
41 (.append c1 (.getObject (first (.findChildrenOfType medial-lobe "pipe"))))
42 (.append c2 (.getObject (first (.findChildrenOfType dorsal-lobe "pipe"))))
45 (set! (.title chain) title)
46 (.calibrate (.vs chain) cal)
49 ["peduncle + medial lobe" "peduncle + dorsal lobe"]))
53 (defn gather-fiducials
54 "Extract a table of calibrated fiducial points in project,
55 in the form {<name> [x y z] ...}"
57 (if-let [fids (first (.. project getRootProjectThing (findChildrenOfTypeR "fiducial_points")))]
60 (let [t (.getValue e)]
61 (assoc m (.getKey e) [(.x t) (.y t) (.z t)])))
63 (Compare/extractPoints fids))
67 "Scan a folder for XML files, recursively."
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))
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)))))))))
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'"
88 (let [i-last (.lastIndexOf title (int \]))]
91 (let [i-first (.lastIndexOf title (int \[) (dec i-last))]
94 (str (.substring title 0 i-first) (.substring title (inc i-last))))))))
98 "Take a list of chains, each one representing a SAT,
99 and return a table of tables, like:
100 {\"DPLpv\" {:x [...] :y [...] :z [...]}}"
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))}))
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."
119 (let [project (Project/openFSProject xml-path false)
120 fids (gather-fiducials project)]
128 :SATs (gather-SATs project)})]
134 (println "No fiducials found in" xml-path)
140 "Will ignore any of the xml files in the chosen dir whose absolute file path matches the regex-exclude string."
142 (if-let [dir (.getDirectory (DirectoryChooser. "Choose root dir"))]
143 (start dir regex-exclude)))
145 (ControlWindow/setGUIEnabled false)
147 (TextWindow. "SAT-lib.clj"
148 (let [sw (StringWriter.)]
150 (prn (generate-SAT-lib (gather-xmls dir regex-exclude))))
154 (.printStackTrace e)))
155 (ControlWindow/setGUIEnabled true)))