SHARE
TWEET

Untitled

a guest Sep 16th, 2019 92 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top