Advertisement
Guest User

Untitled

a guest
Sep 16th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.97 KB | None | 0 0
  1. package graphics.scenery
  2.  
  3. import cleargl.GLVector
  4. import edu.mines.jtk.sgl.Tuple4
  5. import graphics.scenery.backends.Renderer
  6. import graphics.scenery.controls.TrackedDeviceType
  7. import java.awt.geom.Ellipse2D
  8. //import org.jruby.RubyBoolean
  9. //import org.junit.Test
  10. import java.io.File
  11. import java.lang.IllegalStateException
  12. import java.util.*
  13. import kotlin.collections.ArrayList
  14. import kotlin.collections.HashMap
  15. import kotlin.concurrent.thread
  16. import kotlin.math.cos
  17. import kotlin.math.sin
  18. import kotlin.random.Random
  19.  
  20.  
  21. class TSNEPlot(val fileName: String = "Pancreas_metadata_FACS_TSNE.csv"): Node() {
  22. val laser = Cylinder(0.005f, 0.2f, 20)
  23. var mesh = Mesh()
  24. var textBoardMesh = Mesh()
  25. var positionScaling = 0.2f
  26.  
  27. init {
  28.  
  29. fun simpleCsvReader(pathname: String = "Pancreas_metadata_FACS_TSNE.csv"): Pair<HashMap<String, ArrayList<String>>, ArrayList<ArrayList<Float>>> {
  30. //logger.info("my file name is: $pathname")
  31. val result = ArrayList<ArrayList<Float>>()
  32. val names = ArrayList<String>()
  33. val plate = ArrayList<String>()
  34.  
  35. val csv = File(pathname)
  36. var nline = 0
  37. csv.forEachLine(Charsets.UTF_8) { line ->
  38. if (nline != 0) {
  39. val fields = ArrayList<Float>()
  40. // TODO: triple check this line is correct
  41. var colN = 0
  42. line.split(",").drop(8).forEach {
  43. if (colN == 0) {
  44. plate.add(it.replace("\"", ""))
  45. } else if (colN == 1) {
  46. names.add(it.replace("\"", ""))
  47. } else {
  48. val field = it.toFloat()
  49. fields.add(field)
  50. }
  51. colN += 1
  52.  
  53. }
  54. result.add(fields)
  55. }
  56. nline += 1
  57. }
  58.  
  59. //print("$plate")
  60.  
  61. val metaresult = hashMapOf(
  62. "pancreaticCellMap" to names,
  63. "plateMap" to plate
  64. )
  65.  
  66. return Pair(metaresult, result)
  67. }//basic .csv reader
  68.  
  69.  
  70.  
  71. fun csvReader(pathName: String = "TabulaMuris3Ddata.csv"): Triple<ArrayList<String>, ArrayList<ArrayList<Float>>, ArrayList<ArrayList<Float>>> {
  72. val cellNames = ArrayList<String>()
  73. val geneExpressions = ArrayList<ArrayList<Float>>()
  74. val tsneCoordinates = ArrayList<ArrayList<Float>>()
  75.  
  76. val csv = File(pathName)
  77. var nline = 0
  78. csv.forEachLine(Charsets.UTF_8) {line ->
  79. if(nline != 0) {
  80. val tsneFields = ArrayList<Float>()
  81. val geneFields = ArrayList<Float>()
  82. var colN = 0
  83. line.split(";").drop(1).forEach {
  84. //logger.info("this is my line $line")
  85. if(colN == 0) {
  86. cellNames.add(it.replace("\"", ""))
  87. //logger.info("this should be a cell name: $it")
  88. }
  89. else if(colN in 1..3) {
  90. val itFloatGene = it.toFloat()
  91. geneFields.add(itFloatGene)
  92. }
  93. else if(colN in 4..6) {
  94. val itFloatTsne = it.toFloat()
  95. tsneFields.add(itFloatTsne)
  96. }
  97. colN += 1
  98. }
  99. geneExpressions.add(geneFields)
  100. tsneCoordinates.add(tsneFields)
  101. }
  102. nline += 1
  103. }
  104. return Triple(cellNames, geneExpressions, tsneCoordinates)
  105. }//read in tabula muris data
  106.  
  107. //csv parameters
  108. val (metadataTable, positionTable) = simpleCsvReader("Pancreas_metadata_FACS_TSNE.csv")
  109. val (cellNames, geneExpressions, tsneCoordinates) = csvReader("TabulaMuris3Ddata.csv")
  110. val uniqueCellNames = cellNames.toSet()
  111.  
  112.  
  113. fun getColorMaps(): HashMap<String, HashMap<String, GLVector>> {
  114.  
  115. val tabulaCells = HashMap<String, GLVector>()
  116. for(i in uniqueCellNames){
  117. tabulaCells[i] = graphics.scenery.numerics.Random.randomVectorFromRange(3, 0f, 255f)
  118. logger.info("entry $i in tabulaCells: ${tabulaCells[i]}")
  119. }
  120.  
  121. val pancreaticCellMap = hashMapOf(
  122. "udf" to GLVector(255 / 255f, 98 / 255f, 188 / 255f),
  123. "type B pancreatic cell" to GLVector(232 / 255f, 107 / 255f, 244 / 255f),
  124. "pancreatic stellate cell" to GLVector(149 / 255f, 145 / 255f, 255 / 255f),
  125. "pancreatic PP cell" to GLVector(0 / 255f, 176 / 255f, 246 / 255f),
  126. "pancreatic ductal cell" to GLVector(0 / 255f, 191 / 255f, 196 / 255f),
  127. "pancreatic D cell" to GLVector(0 / 255f, 190 / 255f, 125 / 255f),
  128. "pancreatic acinar cell" to GLVector(57 / 255f, 182 / 255f, 0 / 255f),
  129. "pancreatic A cell" to GLVector(162 / 255f, 165 / 255f, 0 / 255f),
  130. "leukocyte" to GLVector(216 / 255f, 144 / 255f, 0 / 255f),
  131. "endothelial cell" to GLVector(248 / 255f, 118 / 255f, 108 / 255f)
  132. )
  133.  
  134. val plateMap = hashMapOf(
  135. "MAA000574" to GLVector(102 / 255f, 194 / 255f, 165 / 255f),
  136. "MAA000577" to GLVector(252 / 255f, 141 / 255f, 98 / 255f),
  137. "MAA000884" to GLVector(141 / 255f, 160 / 255f, 203 / 255f),
  138. "MAA000910" to GLVector(231 / 255f, 138 / 255f, 195 / 255f),
  139. "MAA001857" to GLVector(166 / 255f, 216 / 255f, 84 / 255f),
  140. "MAA001861" to GLVector(255 / 255f, 217 / 255f, 47 / 255f),
  141. "MAA001862" to GLVector(229 / 255f, 196 / 255f, 148 / 255f),
  142. "MAA001868" to GLVector(179 / 255f, 179 / 255f, 179 / 255f)
  143. )
  144.  
  145. val hashDatabase = hashMapOf(
  146. "pancreaticCellMap" to pancreaticCellMap,
  147. "plateMap" to plateMap,
  148. "tabulaCells" to tabulaCells
  149. )
  150.  
  151. return hashDatabase
  152. }//get color maps
  153.  
  154. fun getShapeMaps(): HashMap<String, Node>{
  155.  
  156. return hashMapOf(
  157. "deltahedra" to Icosphere(0.20f * positionScaling, 0),
  158. "ellipses" to Icosphere(0.20f * positionScaling, 3),
  159. "cubes" to Box(GLVector(0.01f * positionScaling, 0.01f * positionScaling, 0.01f * positionScaling))
  160. )
  161. }//get shape maps
  162.  
  163. // Parameters
  164.  
  165. val colorMaps = getColorMaps()
  166. val defaultColor = "pancreaticCellMap"
  167. val defaultShape = "ellipses"
  168.  
  169.  
  170. val names = metadataTable[defaultColor]
  171. val colorMap = colorMaps[defaultColor]
  172. val tabulaColorMap = colorMaps["tabulaCells"]
  173. if (names == null || colorMap == null || tabulaColorMap == null) {
  174. throw IllegalStateException("names or colorMap not found")
  175. }
  176.  
  177.  
  178.  
  179. val v = getShapeMaps()[defaultShape]
  180. v!!.name = "master sphere"
  181. v.material = ShaderMaterial.fromFiles("DefaultDeferredInstanced.vert", "DefaultDeferred.frag")
  182. v.material.ambient = GLVector(0.1f, 0.0f, 0.0f)
  183. v.material.diffuse = GLVector(0.8f, 0.7f, 0.7f)
  184. v.material.specular = GLVector(0.05f, 0f, 0f)
  185. v.material.metallic = 0.01f
  186. v.material.roughness = 0.5f
  187. v.instancedProperties["ModelMatrix"] = { v.model }
  188. addChild(v)
  189.  
  190. var zipCounter = 0
  191. cellNames.zip(tsneCoordinates) {cell, tsne ->
  192.  
  193. val s = Mesh()
  194. val parsedGeneExpression = geneExpressions[zipCounter]
  195.  
  196. val getShapeMap = getShapeMaps()[defaultShape]
  197. //val s = getShapeMap ?: throw IllegalStateException("s not found")
  198. s.name = cell
  199. s.scale = GLVector(parsedGeneExpression[0]*0.5f, parsedGeneExpression[1]*0.5f, parsedGeneExpression[2]*0.5f)
  200. s.position = GLVector(tsne[0], tsne[1], tsne[2])
  201. s.material.diffuse = tabulaColorMap.getOrDefault(cell, GLVector(1.0f, 0f, 0f))
  202. logger.info("this is the assigned color: ${tabulaColorMap[cell]}")
  203. // s.material.ambient = GLVector(0.1f, 0.0f, 0.0f)
  204. // s.material.specular = GLVector(0.05f, 0f, 0f)
  205. // s.material.metallic = 0.01f
  206. // s.material.roughness = 0.5f
  207. v.instances.add(s)
  208. zipCounter += 1
  209. }
  210.  
  211.  
  212.  
  213.  
  214. val x = Cylinder.betweenPoints(GLVector(-5.00f, 0f, 0f), GLVector(5.00f, 0f, 0f))
  215. x.material.diffuse = GLVector(1.0f, 1.0f, 1.0f)
  216. val y = Cylinder.betweenPoints(GLVector(0f, -5.00f, 0f), GLVector(0f, 5.00f, 0f))
  217. y.material.diffuse = GLVector(1.0f, 1.0f, 1.0f)
  218. val z = Cylinder.betweenPoints(GLVector(0f, 0f, -20.00f), GLVector(0f, 0f, 5.00f))
  219. z.material.diffuse = GLVector(1.0f, 1.0f, 1.0f)
  220.  
  221. // Add objects to the scene
  222.  
  223. addChild(x)
  224. addChild(y)
  225. addChild(z)// Cylinders
  226. addChild(mesh)
  227.  
  228. // Create scene lighting
  229. Light.createLightTetrahedron<PointLight>(spread = 10.0f, radius = 95.0f).forEach {
  230. addChild(it)
  231. }
  232.  
  233. //Add box to scene for sense of bound
  234. val hullbox = Box(GLVector(100.0f, 100.0f, 100.0f), insideNormals = true)
  235. with(hullbox) {
  236. position = GLVector(0.0f, 0.0f, 0.0f)
  237.  
  238. material.ambient = GLVector(0.6f, 0.6f, 0.6f)
  239. material.diffuse = GLVector(0.4f, 0.4f, 0.4f)
  240. material.specular = GLVector(0.0f, 0.0f, 0.0f)
  241. material.cullingMode = Material.CullingMode.Front
  242. }
  243. addChild(hullbox)//hullbox
  244.  
  245.  
  246. laser.material.diffuse = GLVector(5.0f, 0.0f, 0.02f)
  247. laser.material.metallic = 0.0f
  248. laser.material.roughness = 1.0f
  249. laser.rotation.rotateByAngleX(-Math.PI.toFloat()/2.0f)
  250. laser.visible = false//laser
  251.  
  252. //fetch center of mass for each cell type and attach TextBoard with cell type at that location
  253.  
  254. val listOfCells = arrayListOf(
  255. "udf",
  256. "type B pancreatic cell",
  257. "pancreatic stellate cell",
  258. "pancreatic PP cell",
  259. "pancreatic ductal cell",
  260. "pancreatic D cell",
  261. "pancreatic acinar cell",
  262. "pancreatic A cell",
  263. "leukocyte",
  264. "endothelial cell")
  265.  
  266.  
  267. fun fetchCenterOfMass(type: String): GLVector {
  268.  
  269. var additiveMass = FloatArray(3)
  270. var filteredLength = 0f
  271.  
  272. for(i in mesh.children.filter{ it.name == type }) {
  273.  
  274. additiveMass[0] += i.position.toFloatArray()[0]
  275. additiveMass[1] += i.position.toFloatArray()[1]
  276. additiveMass[2] += i.position.toFloatArray()[2]
  277.  
  278. filteredLength += 1
  279. //logger.info("added mass: $additiveMass")
  280. }
  281.  
  282. return GLVector(
  283. additiveMass[0] / filteredLength,
  284. additiveMass[1] / filteredLength,
  285. additiveMass[2] / filteredLength
  286. )
  287. }
  288.  
  289. fun textBoardPositions(): HashMap<String, GLVector> {
  290. val massMap = HashMap<String, GLVector>()
  291. for(i in listOfCells){
  292. massMap[i] = fetchCenterOfMass(i)
  293. //logger.info("center of mass for $i is: ${fetchCenterOfMass(i)}")
  294. }
  295. return massMap
  296. }
  297.  
  298. val massMap = textBoardPositions()
  299. //logger.info("massMap: $massMap")
  300.  
  301. for(i in listOfCells){
  302.  
  303. val t = TextBoard(isBillboard = false)
  304. t.text = i
  305. t.name = i
  306. t.transparent = 0
  307. t.fontColor = GLVector(0.0f, 0.0f, 0.0f)
  308. t.backgroundColor = colorMap[i]!!
  309. t.position = massMap[i]!!//*positionScaling
  310. //logger.info("scaled size: ${t.position}")
  311. t.scale = GLVector(2.0f, 2.0f, 2.0f)*positionScaling
  312. t.opacity = 0.5f
  313. textBoardMesh.addChild(t)
  314. }
  315.  
  316. addChild(textBoardMesh)
  317.  
  318.  
  319.  
  320.  
  321.  
  322. }
  323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement