Skip to content

Commit

Permalink
[wip] OpenOrganelle demo, super not working yet
Browse files Browse the repository at this point in the history
  • Loading branch information
kephale committed Jun 13, 2023
1 parent 19a6746 commit f4bfc8e
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 0 deletions.
8 changes: 8 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ dependencies {
// implementation(n5.imglib2)
implementation("org.janelia.saalfeldlab:n5")
implementation("org.janelia.saalfeldlab:n5-hdf5")
implementation("org.janelia.saalfeldlab:n5-ij:3.2.4-SNAPSHOT")
implementation("org.janelia.saalfeldlab:n5-imglib2:5.0.0")
implementation("org.janelia.saalfeldlab:n5-viewer_fiji:5.3.0")
//implementation("com.github.saalfeldlab:n5-viewer:ec0b177")
implementation("org.janelia.saalfeldlab:n5-aws-s3")
implementation("org.janelia.saalfeldlab:n5-google-cloud")
implementation("org.janelia.saalfeldlab:n5-blosc")
implementation("org.janelia.saalfeldlab:n5-zarr")
implementation("sc.fiji:spim_data")

implementation(platform(kotlin("bom")))
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/sc/iview/commands/MenuWeights.kt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ object MenuWeights {
const val DEMO_ADVANCED_CREMI = 1.0
const val DEMO_ADVANCED_BDVSLICING = 2.0
const val DEMO_ADVANCED_MESHTEXTURE = 3.0
const val DEMO_ADVANCED_OPENORGANELLE = 4.0
// Help
const val HELP_HELP = 0.0
const val HELP_ABOUT = 200.0
Expand Down
256 changes: 256 additions & 0 deletions src/main/kotlin/sc/iview/commands/demo/advanced/OpenOrganelle.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
package sc.iview.commands.demo.advanced

import graphics.scenery.Origin
import graphics.scenery.utils.extensions.xyz
import graphics.scenery.volumes.Colormap
import graphics.scenery.volumes.TransferFunction
import net.imagej.lut.LUTService
import net.imagej.mesh.Mesh
import net.imagej.mesh.Meshes
import net.imagej.ops.OpService
import net.imglib2.RandomAccessibleInterval
import net.imglib2.cache.img.CachedCellImg
import net.imglib2.roi.labeling.ImgLabeling
import net.imglib2.roi.labeling.LabelRegions
import net.imglib2.type.NativeType
import net.imglib2.type.numeric.ARGBType
import net.imglib2.type.numeric.RealType
import net.imglib2.view.Views
import org.janelia.saalfeldlab.n5.N5DatasetDiscoverer
import org.janelia.saalfeldlab.n5.N5Reader
import org.janelia.saalfeldlab.n5.N5TreeNode
import org.janelia.saalfeldlab.n5.bdv.MultiscaleDatasets
import org.janelia.saalfeldlab.n5.ij.N5Factory
import org.janelia.saalfeldlab.n5.ij.N5Importer
import org.janelia.saalfeldlab.n5.imglib2.N5Utils
import org.janelia.saalfeldlab.n5.metadata.*
import org.janelia.saalfeldlab.n5.ui.DataSelection
import org.joml.Vector3f
import org.joml.Vector4f
import org.scijava.command.Command
import org.scijava.command.CommandService
import org.scijava.log.LogService
import org.scijava.plugin.Menu
import org.scijava.plugin.Parameter
import org.scijava.plugin.Plugin
import org.scijava.ui.UIService
import sc.iview.SciView
import sc.iview.commands.MenuWeights
import sc.iview.commands.demo.basic.VolumeRenderDemo
import sc.iview.process.MeshConverter
import java.io.File
import java.io.IOException
import java.util.*
import java.util.concurrent.Executors


@Plugin(type = Command::class,
label = "OpenOrganelle demo",
menuRoot = "SciView",
menu = [Menu(label = "Demo", weight = MenuWeights.DEMO),
Menu(label = "Advanced", weight = MenuWeights.DEMO_ADVANCED),
Menu(label = "OpenOrganelle Demo", weight = MenuWeights.DEMO_ADVANCED_OPENORGANELLE)])
class OpenOrganelle : Command {
@Parameter
private lateinit var ui: UIService

@Parameter
private lateinit var log: LogService

@Parameter
private lateinit var ops: OpService

@Parameter
private lateinit var sciview: SciView

@Parameter
private lateinit var lut: LUTService

/*
* TODO
*
* https://openorganelle.janelia.org/datasets/jrc_mus-kidney
* s3://janelia-cosem-datasets/jrc_mus-kidney/jrc_mus-kidney.n5
*
*/

internal class DefaultLabelIterator : MutableIterator<Long> {
private var i = 0L
override fun hasNext(): Boolean {
return i < Long.MAX_VALUE
}

override fun next(): Long {
return i++
}

override fun remove() {
throw UnsupportedOperationException()
}
}

/**
* When an object implementing interface `Runnable` is used
* to create a thread, starting the thread causes the object's
* `run` method to be called in that separately executing
* thread.
*
*
* The general contract of the method `run` is that it may
* take any action whatsoever.
*
* @see Thread.run
*/

override fun run() {
val task = sciview.taskManager.newTask("OpenOrganelle", "Loading dataset")

val file = File("s3://janelia-cosem-datasets/jrc_mus-kidney/jrc_mus-kidney.n5")

// Read the EM volume
task.status = "Reading image volume"
//val nai = readMultiscaleN5(file.canonicalPath, "em/fibsem-uint8")
log.info("Start Reading")
val nai = readMultiscaleN5()

log.info("Done Reading")

if (nai == null) {
log.error("Could not read data")
return
}
// val raiVolume = nai.third
// val cursor = Views.iterable(raiVolume).localizingCursor()
// while (cursor.hasNext() && cursor.getIntPosition(2) < 50) {
// cursor.fwd()
// cursor.get().set(0)
// }
//
val colormapVolume = lut.loadLUT(lut.findLUTs().get("Grays.lut"))
// val colormapNeurons = lut.loadLUT(lut.findLUTs().get("Fire.lut"))

// sciview.addVolume(nai) {
// origin = Origin.FrontBottomLeft
// this.spatialOrNull()?.scale = Vector3f(0.08f, 0.08f, 5.0f)
// transferFunction = TransferFunction.ramp(0.3f, 0.1f, 0.1f)
// // min 20, max 180, color map fire
//
// transferFunction.addControlPoint(0.3f, 0.5f)
// transferFunction.addControlPoint(0.8f, 0.01f)
// converterSetups.get(0).setDisplayRange(20.0, 220.0)
// colormap = Colormap.fromColorTable(colormapVolume)
// }

// Read the labels volume
task.status = "Reading labels volume"
val labels = readMultiscaleN5()

task.status = "Creating labeling"
task.completion = 10.0f
// val rai = nai.second
// log.info("Got ${nai.first.size} labels")

// let's extract some neurons here
log.info("Creating labeling ...")

//val labels = (0..(nai.first.keys.maxOrNull()?.toInt() ?: 1)).toList()
// val labeling = ImgLabeling.fromImageAndLabels(rai, labels)
// log.info("Creating regions...")
// val regions = LabelRegions(labeling)
// log.info("Created ${regions.count()} regions")
//
// val largestNeuronLabels = nai.first.entries.sortedByDescending { p -> p.value }.take(50).shuffled().take(10).map { kv -> kv.key }
//
// log.info("Largest neuron labels are ${largestNeuronLabels.joinToString(",")}")
//
// regions.filter { largestNeuronLabels.contains(it.label.toLong() + 1L) }.forEachIndexed { i, region ->
// log.info("Meshing neuron ${i + 1}/${largestNeuronLabels.size} with label ${region.label}...")
// task.status = "Meshing neuron ${i + 1}/${largestNeuronLabels.size}"
//
// // ui.show(region)
// // Generate the mesh with imagej-ops
// val m: Mesh = Meshes.marchingCubes(region);
//
// log.info("Converting neuron ${i + 1}/${largestNeuronLabels.size} to scenery format...")
// // Convert the mesh into a scenery mesh for visualization
// val mesh = MeshConverter.toScenery(m, false, flipWindingOrder = true)
// sciview.addNode(mesh) {
// spatial().scale = Vector3f(0.01f, 0.01f, 0.06f)
// ifMaterial {
// diffuse =
// colormapNeurons.lookupARGB(0.0, 255.0, kotlin.random.Random.nextDouble(0.0, 255.0)).toRGBColor()
// .xyz()
// roughness = 0.0f
// }
// name = "Neuron $i"
// }
// val completion = 10.0f + ((i + 1) / largestNeuronLabels.size.toFloat()) * 90.0f
// task.completion = completion
// }
//
// task.completion = 100.0f
}



fun readMultiscaleN5(n5root: String = "s3://janelia-cosem-datasets/jrc_mus-kidney/jrc_mus-kidney.n5",
multiscaleBaseDataset: String = "/labels/empanada-mito_seg",
scale: Double = 1.0): CachedCellImg<out NativeType<*>, *>? {
// set up the n5 reader

log.info("Opening reader")
var n5: N5Reader = N5Factory().openReader(n5root)
// parse the metadata so bdv knows how to display the scales
val importers = Arrays.asList<N5MetadataParser<*>>(*N5Importer.PARSERS)
val groupParsers = Arrays.asList<N5MetadataParser<*>>(*N5Importer.GROUP_PARSERS)
log.info("Dataset discoverer")
val parsers = N5DatasetDiscoverer(
n5,
Executors.newSingleThreadExecutor(),
importers,
groupParsers
)

log.info("Dataset discoverer done")

// get the particular metadata we care above
var root = parsers.discoverAndParseRecursive("")
val multiscaleMetadata = root.childrenList()[0].childrenList()[0].metadata

var datasetToOpen = multiscaleMetadata.path

log.info("Opening image")

var img = N5Utils.openVolatile(n5, datasetToOpen)

log.info("Image opened")

// run n5 viewer
//N5Viewer.exec(new DataSelection( n5, Collections.singletonList( multiscaleMetadata )));


return img
}


private fun Int.toRGBColor(): Vector4f {
val a = ARGBType.alpha(this) / 255.0f
val r = ARGBType.red(this) / 255.0f
val g = ARGBType.green(this) / 255.0f
val b = ARGBType.blue(this) / 255.0f

return Vector4f(r, g, b, a)
}


companion object {
@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
val sv = SciView.create()
val command = sv.scijavaContext!!.getService(CommandService::class.java)
val argmap = HashMap<String, Any>()
command.run(OpenOrganelle::class.java, true, argmap)
}
}
}

0 comments on commit f4bfc8e

Please sign in to comment.