Skip to content

Instantly share code, notes, and snippets.

@hanslovsky
Last active March 25, 2020 17:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hanslovsky/03d1b9f4492a32c4f28c7a66e06faa5f to your computer and use it in GitHub Desktop.
Save hanslovsky/03d1b9f4492a32c4f28c7a66e06faa5f to your computer and use it in GitHub Desktop.
script to list all groups and dataset within n5 container
#!/usr/bin/env kscript
@file:MavenRepository("imagej.public", "https://maven.imagej.net/content/groups/public")
@file:DependsOn("org.janelia.saalfeldlab:n5:2.1.0")
@file:DependsOn("info.picocli:picocli:4.2.0")
@file:DependsOn("ch.qos.logback:logback-classic:1.3.0-alpha5")
import java.util.concurrent.Callable
import org.janelia.saalfeldlab.n5.N5FSReader
import picocli.CommandLine
import picocli.CommandLine.Command
import picocli.CommandLine.Option
import picocli.CommandLine.Parameters
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@Command(name = "n5-tree", showDefaultValues = true)
class N5TreeArgs : Callable<Int> {
private val logger = LoggerFactory.getLogger("n5-tree")
@Parameters(index = "0", paramLabel = "CONTAINER", arity = "1")
lateinit var container: String
@Option(names = ["--from", "-f"], paramLabel = "FROM", required = false, description = ["Start from this group or dataset. Defaults to root group `/' if not specified."], defaultValue = "/")
lateinit var from: String
@Option(names = ["--breadth-first"], description = ["Traverse breadth-first (depth first by default)"], defaultValue = "false")
var breadthFirst: Boolean = false
@Option(names = ["--ignore-multiscale-group-children"], description = ["Treat multi-scale groups like datasets (leaves of the tree) and stop traversal. multi-scale groups are groups with an attribute `\"multiScale\": true'"])
var ignoreMultiscaleGroupChildren: Boolean = false
@kotlin.ExperimentalStdlibApi
override fun call(): Int {
val container = N5FSReader(this.container)
if (!container.exists("/")) {
logger.error("Container ${this.container} does not exist!")
return 1
}
val queue = ArrayDeque<String>()
val tree = ArrayList<String>()
queue += from
while (queue.isNotEmpty()) {
val current = if (breadthFirst) queue.removeFirst() else queue.removeLast()
if (container.exists(current)) {
tree += current
val isDataset = container.datasetExists(current)
val ignoreChildren = isDataset || ignoreMultiscaleGroupChildren && container.getAttribute<Boolean?>(current, "multiScale", Boolean::class.java as Class<Boolean?>) == true
if (ignoreChildren)
continue
val children = container.list(current)
children
.sorted()
.let { if (breadthFirst) it else it.reversed() }
.forEach { queue += "${current.trimEnd('/')}/$it" }
}
}
println(tree.joinToString("\n"))
return 0
}
}
val exitCode = CommandLine(N5TreeArgs()).execute(*args)
kotlin.system.exitProcess(exitCode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment