Fix for number started xml name
This commit is contained in:
parent
32b9a44a7f
commit
a425d6cb6c
@ -139,7 +139,7 @@ object Communications {
|
|||||||
|
|
||||||
data class DanteMessage(val command: CommandType, val board: Int, val packet: Int, val payload: ByteArray) {
|
data class DanteMessage(val command: CommandType, val board: Int, val packet: Int, val payload: ByteArray) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "${command.name}[$board, $packet]: ${payload.size}"
|
return "${command.name}[$board, $packet] of size ${payload.size}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import java.lang.Math.pow
|
|||||||
import java.net.Socket
|
import java.net.Socket
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.ByteOrder
|
import java.nio.ByteOrder
|
||||||
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
@ -69,7 +70,7 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
*/
|
*/
|
||||||
private data class BoardState(val num: Int, var meta: Meta? = null)
|
private data class BoardState(val num: Int, var meta: Meta? = null)
|
||||||
|
|
||||||
private val boards = (0 until chainLength).map { BoardState(it) }
|
private val boards = (0..chainLength).map { BoardState(it) }
|
||||||
|
|
||||||
|
|
||||||
fun open() {
|
fun open() {
|
||||||
@ -118,16 +119,18 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
|
|
||||||
val socket = Socket(ip, 8000 + port)
|
val socket = Socket(ip, 8000 + port)
|
||||||
|
|
||||||
logger.info("Opened socket {}", socket.inetAddress)
|
logger.info("Opened socket {}", "${socket.inetAddress}:${socket.port}")
|
||||||
|
|
||||||
//Create command queue on port 0
|
//Create command queue on port 0
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
outputJob.cancel()
|
//outputJob.cancel()
|
||||||
output = socket.getOutputStream()
|
output = socket.getOutputStream()
|
||||||
outputJob = launch(context = pool, parent = parentJob) {
|
outputJob = launch(context = pool, parent = parentJob) {
|
||||||
|
while (true) {
|
||||||
val command = sendChannel.receive()
|
val command = sendChannel.receive()
|
||||||
output.write(command)
|
output.write(command)
|
||||||
logger.debug("Sent {}", command.hex)
|
logger.trace("Sent {}", command.hex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +142,11 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
// second check is not executed unless first one is true
|
// second check is not executed unless first one is true
|
||||||
val header = ByteArray(6)
|
val header = ByteArray(6)
|
||||||
stream.read(header)
|
stream.read(header)
|
||||||
val command = Communications.CommandType.values().find { it.byte == header[0] }!!
|
val command = Communications.CommandType.values().find { it.byte == header[0] }
|
||||||
|
?: throw RuntimeException("Unknown command code: ${header[0]}")
|
||||||
val board = header[1]
|
val board = header[1]
|
||||||
val packet = header[2]
|
val packet = header[2]
|
||||||
val length = header[3].positive * 0x100 + header[4].positive * 0x010 + header[5].positive
|
val length = (header[3].positive * 0x100 + header[4].positive * 0x010 + header[5].positive) * 4
|
||||||
val payload = ByteArray(length)
|
val payload = ByteArray(length)
|
||||||
stream.read(payload)
|
stream.read(payload)
|
||||||
handle(Communications.DanteMessage(command, board.positive, packet.positive, payload))
|
handle(Communications.DanteMessage(command, board.positive, packet.positive, payload))
|
||||||
@ -171,7 +175,7 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
* Generate next packet number
|
* Generate next packet number
|
||||||
*/
|
*/
|
||||||
private fun nextPacket(): Int {
|
private fun nextPacket(): Int {
|
||||||
return (packetNumber.incrementAndGet() % 256 - 128).toInt()
|
return (packetNumber.incrementAndGet() % 256).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Long>.asBuffer(): ByteBuffer {
|
private fun List<Long>.asBuffer(): ByteBuffer {
|
||||||
@ -191,9 +195,9 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
private suspend fun writeRegister(board: Int, register: Int, data: List<Long>, mask: Long? = null) {
|
private suspend fun writeRegister(board: Int, register: Int, data: List<Long>, mask: Long? = null) {
|
||||||
//representing data as byte buffer
|
//representing data as byte buffer
|
||||||
val buffer = if (mask != null) {
|
val buffer = if (mask != null) {
|
||||||
val oldData = readRegister(board, register, data.size)
|
val oldData = withTimeout(1000) { readRegister(board, register, data.size) }
|
||||||
//(oldData & not_mask) | (newData & mask);
|
//(oldData & not_mask) | (newData & mask);
|
||||||
(0..data.size).map { (oldData[it] and mask.inv()).or(data[it] and mask) }.asBuffer();
|
(0 until data.size).map { (oldData[it] and mask.inv()).or(data[it] and mask) }.asBuffer();
|
||||||
} else {
|
} else {
|
||||||
data.asBuffer()
|
data.asBuffer()
|
||||||
}
|
}
|
||||||
@ -206,6 +210,7 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun readRegister(board: Int, register: Int, length: Int = 1): List<Long> {
|
private suspend fun readRegister(board: Int, register: Int, length: Int = 1): List<Long> {
|
||||||
|
|
||||||
val packet = nextPacket()
|
val packet = nextPacket()
|
||||||
send(READ, board, packet, register, length = length)
|
send(READ, board, packet, register, length = length)
|
||||||
var message: Communications.DanteMessage? = null
|
var message: Communications.DanteMessage? = null
|
||||||
@ -222,6 +227,10 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
}.map { it.positive }.toList()
|
}.map { it.positive }.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getFirmwareVersion(): Long {
|
||||||
|
return readRegister(0, Communications.Register.FIRMWARE_VERSION.code)[0]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a single DPP parameter
|
* Write a single DPP parameter
|
||||||
* @param register number of parameter register
|
* @param register number of parameter register
|
||||||
@ -242,15 +251,15 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
*/
|
*/
|
||||||
suspend fun configureBoard(board: Int, meta: Meta) {
|
suspend fun configureBoard(board: Int, meta: Meta) {
|
||||||
val gain = meta.getDouble("gain")
|
val gain = meta.getDouble("gain")
|
||||||
val det_thresh = meta.getInt("detection_thresold")
|
val det_thresh = meta.getInt("detection_threshold")
|
||||||
val pileup_thr = meta.getInt("pileup_thresold")
|
val pileup_thr = meta.getInt("pileup_threshold")
|
||||||
val en_fil_peak_time = meta.getInt("energy_filter.peaking_time")
|
val en_fil_peak_time = meta.getInt("energy_filter.peaking_time")
|
||||||
val en_fil_flattop = meta.getInt("energy_filter.flat_top")
|
val en_fil_flattop = meta.getInt("energy_filter.flat_top")
|
||||||
val fast_peak_time = meta.getInt("fast_filter.peaking_time")
|
val fast_peak_time = meta.getInt("fast_filter.peaking_time")
|
||||||
val fast_flattop = meta.getInt("fast_filter.flat_top")
|
val fast_flattop = meta.getInt("fast_filter.flat_top")
|
||||||
val recovery_time = meta.getValue("recovery_time").longValue()
|
val recovery_time = meta.getValue("recovery_time").longValue()
|
||||||
val zero_peak_rate = meta.getInt("zero_peak_rate")
|
val zero_peak_rate = meta.getInt("zero_peak_rate")
|
||||||
val inverted_input = meta.getInt("inverted_input")
|
val inverted_input = meta.getInt("inverted_input", 0)
|
||||||
|
|
||||||
assert(en_fil_peak_time in 1..511)
|
assert(en_fil_peak_time in 1..511)
|
||||||
assert(gain in 0.01..(en_fil_peak_time * 2 - 0.01))
|
assert(gain in 0.01..(en_fil_peak_time * 2 - 0.01))
|
||||||
@ -306,7 +315,9 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
writeDPP(board, 128, 0b100 + inverted_input * (1L shl 24))
|
writeDPP(board, 128, 0b100 + inverted_input * (1L shl 24))
|
||||||
writeDPP(board, 128, 1 + inverted_input * (1L shl 24))
|
writeDPP(board, 128, 1 + inverted_input * (1L shl 24))
|
||||||
|
|
||||||
|
|
||||||
logger.info("Finished {} board configuration", board)
|
logger.info("Finished {} board configuration", board)
|
||||||
|
boards.find { it.num == board }?.meta = meta
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -323,14 +334,14 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
* Clear unused data
|
* Clear unused data
|
||||||
*/
|
*/
|
||||||
private suspend fun clearData() {
|
private suspend fun clearData() {
|
||||||
for (element in dataChannel) {
|
while (!dataChannel.isEmpty) {
|
||||||
logger.warn("Dumping residual data packet {}", element.toString())
|
logger.warn("Dumping residual data packet {}", dataChannel.receive().toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun clearCommunications() {
|
private suspend fun clearCommunications() {
|
||||||
for (element in comChannel) {
|
while (!dataChannel.isEmpty) {
|
||||||
logger.debug("Dumping residual communication packet {}", element.toString())
|
logger.debug("Dumping residual communication packet {}", dataChannel.receive().toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +367,13 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
writeRegister(it.num, ACQUISITION_TIME.code, length.toLong())
|
writeRegister(it.num, ACQUISITION_TIME.code, length.toLong())
|
||||||
writeRegister(it.num, TIME_PER_MAP_POINT.code, statisticsInterval.toLong(), 0x00FFFFFF)
|
writeRegister(it.num, TIME_PER_MAP_POINT.code, statisticsInterval.toLong(), 0x00FFFFFF)
|
||||||
writeRegister(it.num, MAP_POINTS.code, (length.toDouble() / statisticsInterval).toLong(), 0x00FFFFFF)
|
writeRegister(it.num, MAP_POINTS.code, (length.toDouble() / statisticsInterval).toLong(), 0x00FFFFFF)
|
||||||
|
|
||||||
|
if (readRegister(it.num, ACQUISITION_SETTINGS.code)[0] != Communications.AcquisitionMode.LIST_MODE.long) {
|
||||||
|
throw RuntimeException("Set list mode failed")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// logger.info("Waiting for configuration to settle")
|
||||||
|
// delay(500)
|
||||||
writeRegister(0, ACQUISITION_STATUS.code, 0x00000001, 0x00000001)
|
writeRegister(0, ACQUISITION_STATUS.code, 0x00000001, 0x00000001)
|
||||||
|
|
||||||
val start = Instant.now()
|
val start = Instant.now()
|
||||||
@ -364,8 +381,12 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
|
|
||||||
|
|
||||||
val dataCollectorJob = launch(context = pool, parent = parentJob) {
|
val dataCollectorJob = launch(context = pool, parent = parentJob) {
|
||||||
while (true) {
|
while (Duration.between(start, Instant.now()) < Duration.ofMillis(length + 4000L)) {
|
||||||
val packet = dataChannel.receive()
|
val packet = withTimeout(1000) { dataChannel.receive() }
|
||||||
|
if (packet.command != LIST_MODE) {
|
||||||
|
logger.warn("Unexpected packet type: {}", packet.command.name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
val channel = packet.board
|
val channel = packet.board
|
||||||
// get or create new channel block
|
// get or create new channel block
|
||||||
val channelBuilder = builder.channelsBuilderList.find { it.id.toInt() == channel }
|
val channelBuilder = builder.channelsBuilderList.find { it.id.toInt() == channel }
|
||||||
@ -376,7 +397,7 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
it.addBlocksBuilder().also {
|
it.addBlocksBuilder().also {
|
||||||
it.time = (start.epochSecond * 1e9 + start.nano).toLong()
|
it.time = (start.epochSecond * 1e9 + start.nano).toLong()
|
||||||
it.binSize = 8 // tick in nanos
|
it.binSize = 8 // tick in nanos
|
||||||
it.length = length.toLong() * 1000 //block length in nanos
|
it.length = (length * 1e6).toLong() //block length in nanos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,19 +423,15 @@ class DanteClient(val ip: String, chainLength: Int) : AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
writeRegister(0, ACQUISITION_STATUS.code, 0x00000001, 0x00000000)
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel data collection after specific time passed
|
|
||||||
*/
|
|
||||||
val schedulerJob = launch(context = pool, parent = parentJob) {
|
|
||||||
delay(length + 2000L)
|
|
||||||
dataCollectorJob.cancel(CancellationException("Expired"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val meta = buildMeta {
|
val meta = buildMeta {
|
||||||
setNode("dpp", boards.first().meta)
|
boards.first().meta?.let {
|
||||||
|
putNode("dpp", it)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dataCollectorJob.join()
|
dataCollectorJob.join()
|
||||||
return ProtoNumassPoint(builder.build(), meta)
|
return ProtoNumassPoint(builder.build(), meta)
|
||||||
|
@ -16,33 +16,50 @@
|
|||||||
|
|
||||||
package inr.numass.control.dante
|
package inr.numass.control.dante
|
||||||
|
|
||||||
|
import hep.dataforge.context.Context
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import hep.dataforge.fx.plots.FXPlotManager
|
||||||
|
import hep.dataforge.kodex.KMetaBuilder
|
||||||
import hep.dataforge.kodex.buildMeta
|
import hep.dataforge.kodex.buildMeta
|
||||||
|
import hep.dataforge.kodex.configure
|
||||||
|
import hep.dataforge.kodex.nullable
|
||||||
|
import hep.dataforge.plots.data.DataPlot
|
||||||
|
import hep.dataforge.tables.Adapters
|
||||||
|
import inr.numass.data.analyzers.NumassAnalyzer
|
||||||
|
import inr.numass.data.analyzers.SimpleAnalyzer
|
||||||
|
import inr.numass.data.analyzers.withBinning
|
||||||
|
import inr.numass.data.api.NumassBlock
|
||||||
import inr.numass.data.channel
|
import inr.numass.data.channel
|
||||||
import kotlinx.coroutines.experimental.runBlocking
|
import kotlinx.coroutines.experimental.runBlocking
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val client = DanteClient("192.168.111.123", 7)
|
val client = DanteClient("192.168.111.120", 7)
|
||||||
|
client.open()
|
||||||
val meta = buildMeta {
|
val meta = buildMeta {
|
||||||
|
"gain" to 1.0
|
||||||
/*
|
"detection_threshold" to 150
|
||||||
val gain = meta.getDouble("gain")
|
"pileup_threshold" to 1
|
||||||
val det_thresh = meta.getInt("detection_thresold")
|
"energy_filter" to {
|
||||||
val pileup_thr = meta.getInt("pileup_thresold")
|
"peaking_time" to 63
|
||||||
val en_fil_peak_time = meta.getInt("energy_filter.peaking_time")
|
"flat_top" to 2
|
||||||
val en_fil_flattop = meta.getInt("energy_filter.flat_top")
|
}
|
||||||
val fast_peak_time = meta.getInt("fast_filter.peaking_time")
|
"fast_filter" to {
|
||||||
val fast_flattop = meta.getInt("fast_filter.flat_top")
|
"peaking_time" to 4
|
||||||
val recovery_time = meta.getValue("recovery_time").longValue()
|
"flat_top" to 1
|
||||||
val zero_peak_rate = meta.getInt("zero_peak_rate")
|
}
|
||||||
val inverted_input = meta.getInt("inverted_input")
|
"recovery_time" to 100
|
||||||
*/
|
"zero_peak_rate" to 0
|
||||||
}
|
}
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
println("Firmware version: ${client.getFirmwareVersion()}")
|
||||||
|
|
||||||
|
// client.reset()
|
||||||
|
// delay(500)
|
||||||
|
|
||||||
client.configureAll(meta)
|
client.configureAll(meta)
|
||||||
}
|
|
||||||
val point = runBlocking {
|
val point = client.readPoint(10 * 1000)
|
||||||
client.readPoint(10*1000)
|
|
||||||
}
|
|
||||||
println("***META***")
|
println("***META***")
|
||||||
println(point.meta)
|
println(point.meta)
|
||||||
println("***BLOCKS***")
|
println("***BLOCKS***")
|
||||||
@ -50,5 +67,38 @@ fun main(args: Array<String>) {
|
|||||||
println("channel: ${it.channel}")
|
println("channel: ${it.channel}")
|
||||||
println("\tlength: ${it.length}")
|
println("\tlength: ${it.length}")
|
||||||
println("\tevents: ${it.events.count()}")
|
println("\tevents: ${it.events.count()}")
|
||||||
|
it.plotAmplitudeSpectrum(plotName = it.channel.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun NumassBlock.plotAmplitudeSpectrum(plotName: String = "spectrum", frameName: String = "", context: Context = Global, metaAction: KMetaBuilder.() -> Unit = {}) {
|
||||||
|
val meta = buildMeta("meta", metaAction)
|
||||||
|
val plotManager = context.load(FXPlotManager::class)
|
||||||
|
val binning = meta.getInt("binning", 20)
|
||||||
|
val lo = meta.optNumber("window.lo").nullable?.toInt()
|
||||||
|
val up = meta.optNumber("window.up").nullable?.toInt()
|
||||||
|
val data = SimpleAnalyzer().getAmplitudeSpectrum(this, meta.getMetaOrEmpty("spectrum")).withBinning(binning, lo, up)
|
||||||
|
plotManager.display(name = frameName) {
|
||||||
|
val valueAxis = if (meta.getBoolean("normalize", false)) {
|
||||||
|
NumassAnalyzer.COUNT_RATE_KEY
|
||||||
|
} else {
|
||||||
|
NumassAnalyzer.COUNT_KEY
|
||||||
|
}
|
||||||
|
plots.configure {
|
||||||
|
"connectionType" to "step"
|
||||||
|
"thickness" to 2
|
||||||
|
"showLine" to true
|
||||||
|
"showSymbol" to false
|
||||||
|
"showErrors" to false
|
||||||
|
}.setType(DataPlot::class)
|
||||||
|
|
||||||
|
val plot = DataPlot.plot(
|
||||||
|
plotName,
|
||||||
|
Adapters.buildXYAdapter(NumassAnalyzer.CHANNEL_KEY, valueAxis),
|
||||||
|
data
|
||||||
|
)
|
||||||
|
plot.configure(meta)
|
||||||
|
add(plot)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user