Fixed legacy file reading

This commit is contained in:
Alexander Nozik 2021-01-28 11:04:47 +03:00
parent 921f5c9b0a
commit 387b6bbcb4
42 changed files with 377 additions and 5147 deletions

View File

@ -3,11 +3,15 @@ plugins {
} }
allprojects { allprojects {
repositories{
mavenLocal()
}
group = "ru.inr.mass" group = "ru.inr.mass"
version = "0.1.0" version = "0.1.0"
} }
val dataforgeVersion by extra("0.3.0-dev-1") val dataforgeVersion by extra("0.3.0-dev-2")
apiValidation{ apiValidation{
validationDisabled = true validationDisabled = true

View File

@ -40,20 +40,19 @@ public interface NumassSet : Iterable<NumassPoint>, Provider {
return points.iterator() return points.iterator()
} }
override val defaultTarget: String get() = NUMASS_POINT_TARGET
override val defaultTarget: String get() = NUMASS_POINT_PROVIDER_KEY
override fun content(target: String): Map<Name, Any> { override fun content(target: String): Map<Name, Any> {
return if (target == NUMASS_POINT_PROVIDER_KEY) { return if (target == NUMASS_POINT_TARGET) {
points.associateBy { "point[${it.voltage}]".toName() } points.associateBy { "point[${it.voltage}]".toName() }
} else { } else {
super.content(target) super.content(target)
} }
} }
companion object { public companion object {
const val DESCRIPTION_KEY = "info" //public const val DESCRIPTION_KEY = "info"
const val NUMASS_POINT_PROVIDER_KEY = "point" public const val NUMASS_POINT_TARGET: String = "point"
} }
} }

View File

@ -10,10 +10,7 @@ import ru.inr.mass.data.api.NumassPoint
import ru.inr.mass.data.api.NumassSet import ru.inr.mass.data.api.NumassSet
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.*
import kotlin.io.path.div
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.streams.toList import kotlin.streams.toList
@OptIn(ExperimentalPathApi::class) @OptIn(ExperimentalPathApi::class)
@ -35,7 +32,9 @@ public class NumassDirectorySet internal constructor(
} }
override val points: List<NumassPoint> by lazy<List<NumassPoint>> { override val points: List<NumassPoint> by lazy<List<NumassPoint>> {
Files.list(path).filter { it.fileName.startsWith("p") }.map { pointPath -> Files.list(path).filter {
it.fileName.name.startsWith("p")
}.map { pointPath ->
try { try {
context.readNumassFile(pointPath) context.readNumassFile(pointPath)
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -1,139 +0,0 @@
///*
// * Copyright 2018 Alexander Nozik.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package ru.inr.mass.data.proto
//
//import hep.dataforge.io.envelopes.*
//import hep.dataforge.values.Value
//import org.slf4j.LoggerFactory
//import java.io.IOException
//import java.nio.ByteBuffer
//import java.nio.channels.FileChannel
//import java.nio.file.Path
//import java.nio.file.StandardOpenOption
//import java.util.*
//
///**
// * An envelope type for legacy numass tags. Reads legacy tag and writes DF02 tags
// */
//class NumassEnvelopeType : EnvelopeType {
//
// override val code: Int = DefaultEnvelopeType.DEFAULT_ENVELOPE_CODE
//
// override val name: String = "numass"
//
// override fun description(): String = "Numass legacy envelope"
//
// /**
// * Read as legacy
// */
// override fun getReader(properties: Map<String, String>): EnvelopeReader {
// return NumassEnvelopeReader()
// }
//
// /**
// * Write as default
// */
// override fun getWriter(properties: Map<String, String>): EnvelopeWriter {
// return DefaultEnvelopeWriter(this, MetaType.resolve(properties))
// }
//
// class LegacyTag : EnvelopeTag() {
// override val startSequence: ByteArray
// get() = LEGACY_START_SEQUENCE
//
// override val endSequence: ByteArray
// get() = LEGACY_END_SEQUENCE
//
// /**
// * Get the length of tag in bytes. -1 means undefined size in case tag was modified
// *
// * @return
// */
// override val length: Int
// get() = 30
//
// /**
// * Read leagscy version 1 tag without leading tag head
// *
// * @param buffer
// * @return
// * @throws IOException
// */
// override fun readHeader(buffer: ByteBuffer): Map<String, Value> {
// val res = HashMap<String, Value>()
//
// val type = buffer.getInt(2)
// res[Envelope.TYPE_PROPERTY] = Value.of(type)
//
// val metaTypeCode = buffer.getShort(10)
// val metaType = MetaType.resolve(metaTypeCode)
//
// if (metaType != null) {
// res[Envelope.META_TYPE_PROPERTY] = metaType.name.parseValue()
// } else {
// LoggerFactory.getLogger(EnvelopeTag::class.java).warn("Could not resolve meta type. Using default")
// }
//
// val metaLength = Integer.toUnsignedLong(buffer.getInt(14))
// res[Envelope.META_LENGTH_PROPERTY] = Value.of(metaLength)
// val dataLength = Integer.toUnsignedLong(buffer.getInt(22))
// res[Envelope.DATA_LENGTH_PROPERTY] = Value.of(dataLength)
// return res
// }
// }
//
// private class NumassEnvelopeReader : DefaultEnvelopeReader() {
// override fun newTag(): EnvelopeTag {
// return LegacyTag()
// }
// }
//
// companion object {
// val INSTANCE = NumassEnvelopeType()
//
// val LEGACY_START_SEQUENCE = byteArrayOf('#'.toByte(), '!'.toByte())
// val LEGACY_END_SEQUENCE = byteArrayOf('!'.toByte(), '#'.toByte(), '\r'.toByte(), '\n'.toByte())
//
// /**
// * Replacement for standard type infer to include legacy type
// *
// * @param path
// * @return
// */
// fun infer(path: Path): EnvelopeType? {
// return try {
// FileChannel.open(path, StandardOpenOption.READ).use {
// val buffer = it.map(FileChannel.MapMode.READ_ONLY, 0, 6)
// when {
// //TODO use templates from appropriate types
// buffer.get(0) == '#'.toByte() && buffer.get(1) == '!'.toByte() -> INSTANCE
// buffer.get(0) == '#'.toByte() && buffer.get(1) == '!'.toByte() &&
// buffer.get(4) == 'T'.toByte() && buffer.get(5) == 'L'.toByte() -> TaglessEnvelopeType.INSTANCE
// buffer.get(0) == '#'.toByte() && buffer.get(1) == '~'.toByte() -> DefaultEnvelopeType.INSTANCE
// else -> null
// }
// }
// } catch (ex: Exception) {
// LoggerFactory.getLogger(EnvelopeType::class.java).warn("Could not infer envelope type of file {} due to exception: {}", path, ex)
// null
// }
//
// }
//
// }
//
//}

View File

@ -4,14 +4,24 @@ import hep.dataforge.context.AbstractPlugin
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.context.PluginFactory import hep.dataforge.context.PluginFactory
import hep.dataforge.context.PluginTag import hep.dataforge.context.PluginTag
import hep.dataforge.io.EnvelopeFormatFactory
import hep.dataforge.io.IOPlugin import hep.dataforge.io.IOPlugin
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.names.Name
import kotlin.reflect.KClass import kotlin.reflect.KClass
public class NumassProtoPlugin : AbstractPlugin() { public class NumassProtoPlugin : AbstractPlugin() {
public val io: IOPlugin by require(IOPlugin) public val io: IOPlugin by require(IOPlugin)
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
override fun content(target: String): Map<Name, Any> {
return if(target== EnvelopeFormatFactory.ENVELOPE_FORMAT_TYPE){
mapOf(TaggedNumassEnvelopeFormat.name to TaggedNumassEnvelopeFormat)
} else{
super.content(target)
}
}
public companion object : PluginFactory<NumassProtoPlugin> { public companion object : PluginFactory<NumassProtoPlugin> {
override fun invoke(meta: Meta, context: Context): NumassProtoPlugin = NumassProtoPlugin() override fun invoke(meta: Meta, context: Context): NumassProtoPlugin = NumassProtoPlugin()
override val tag: PluginTag = PluginTag("numass-proto", group = "ru.inr.mass") override val tag: PluginTag = PluginTag("numass-proto", group = "ru.inr.mass")

View File

@ -0,0 +1,295 @@
/*
* Copyright 2018 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ru.inr.mass.data.proto
import hep.dataforge.context.Context
import hep.dataforge.io.*
import hep.dataforge.meta.Meta
import hep.dataforge.meta.get
import hep.dataforge.meta.string
import hep.dataforge.names.Name
import hep.dataforge.names.plus
import hep.dataforge.names.toName
import kotlinx.io.*
import java.util.*
/**
* A streaming-friendly envelope format with a short binary tag.
* TODO add description
*/
public class TaggedNumassEnvelopeFormat(private val io: IOPlugin) : EnvelopeFormat {
// private val metaFormat = io.metaFormat(metaFormatKey)
// ?: error("Meta format with key $metaFormatKey could not be resolved in $io")
private fun Tag.toBinary() = Binary(24) {
writeRawString(START_SEQUENCE)
writeRawString("DFNU")
writeShort(metaFormatKey)
writeUInt(metaSize)
writeUInt(dataSize.toUInt())
writeRawString(END_SEQUENCE)
}
override fun writeEnvelope(
output: Output,
envelope: Envelope,
metaFormatFactory: MetaFormatFactory,
formatMeta: Meta,
) {
error("Don't write legacy formats")
// val metaFormat = metaFormatFactory.invoke(formatMeta, io.context)
// val metaBytes = metaFormat.toBinary(envelope.meta)
// val actualSize: ULong = (envelope.data?.size ?: 0).toULong()
// val tag = Tag(metaFormatFactory.key, metaBytes.size.toUInt() + 2u, actualSize)
// output.writeBinary(tag.toBinary())
// output.writeBinary(metaBytes)
// output.writeRawString("\r\n")
// envelope.data?.let {
// output.writeBinary(it)
// }
// output.flush()
}
/**
* Read an envelope from input into memory
*
* @param input an input to read from
* @param formats a collection of meta formats to resolve
*/
override fun readObject(input: Input): Envelope {
val tag = input.readTag()
val metaFormat = io.resolveMetaFormat(tag.metaFormatKey)
?: error("Meta format with key ${tag.metaFormatKey} not found")
val meta: Meta = metaFormat.readObject(input.limit(tag.metaSize.toInt()))
val data = input.readBinary(tag.dataSize.toInt())
return SimpleEnvelope(meta, data)
}
override fun readPartial(input: Input): PartialEnvelope {
val tag = input.readTag()
val metaFormat = if (tag.metaFormatKey == 1.toShort()) {
JsonMetaFormat
} else {
io.resolveMetaFormat(tag.metaFormatKey)
?: error("Meta format with key ${tag.metaFormatKey} not found")
}
val meta: Meta = metaFormat.readObject(input.limit(tag.metaSize.toInt()))
return PartialEnvelope(meta, 30u + tag.metaSize, tag.dataSize)
}
private data class Tag(
val metaFormatKey: Short,
val metaSize: UInt,
val dataSize: ULong,
)
override fun toMeta(): Meta = Meta {
IOFormat.NAME_KEY put name.toString()
}
public companion object : EnvelopeFormatFactory {
private const val START_SEQUENCE = "#!"
private const val END_SEQUENCE = "!#\r\n"
override val name: Name = super.name + "numass"
override fun invoke(meta: Meta, context: Context): EnvelopeFormat {
val io = context.io
val metaFormatName = meta["name"].string?.toName() ?: JsonMetaFormat.name
//Check if appropriate factory exists
io.metaFormatFactories.find { it.name == metaFormatName } ?: error("Meta format could not be resolved")
return TaggedNumassEnvelopeFormat(io)
}
private fun Input.readTag(): Tag {
val start = readRawString(2)
if (start != START_SEQUENCE) error("The input is not an envelope")
val versionString = readRawString(4)
val junk1 = readInt()
val metaFormatKey = readShort()
val junk2 = readShort()
val metaLength = readUInt()
val dataLength: ULong = readULong()
val end = readRawString(4)
if (end != END_SEQUENCE) error("The input is not an envelope")
return Tag(metaFormatKey, metaLength, dataLength)
}
override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? {
return try {
input.preview {
val header = readRawString(30)
if (header.startsWith(START_SEQUENCE) && header.endsWith(END_SEQUENCE)) {
TaggedNumassEnvelopeFormat(io)
} else {
null
}
}
} catch (ex: Exception) {
null
}
}
private val default by lazy { invoke() }
override fun readPartial(input: Input): PartialEnvelope =
default.run { readPartial(input) }
override fun writeEnvelope(
output: Output,
envelope: Envelope,
metaFormatFactory: MetaFormatFactory,
formatMeta: Meta,
): Unit = default.run {
writeEnvelope(
output,
envelope,
metaFormatFactory,
formatMeta
)
}
override fun readObject(input: Input): Envelope = default.readObject(input)
}
}
///**
// * An envelope type for legacy numass tags. Reads legacy tag and writes DF02 tags
// */
//object NumassEnvelopeType : EnvelopeFormatFactory {
//
// override val code: Int = DefaultEnvelopeType.DEFAULT_ENVELOPE_CODE
//
// override val name: String = "numass"
//
// override fun description(): String = "Numass legacy envelope"
//
// /**
// * Read as legacy
// */
// override fun getReader(properties: Map<String, String>): EnvelopeReader {
// return NumassEnvelopeReader()
// }
//
// /**
// * Write as default
// */
// override fun getWriter(properties: Map<String, String>): EnvelopeWriter {
// return DefaultEnvelopeWriter(this, MetaType.resolve(properties))
// }
//
// class LegacyTag : EnvelopeTag() {
// override val startSequence: ByteArray
// get() = LEGACY_START_SEQUENCE
//
// override val endSequence: ByteArray
// get() = LEGACY_END_SEQUENCE
//
// /**
// * Get the length of tag in bytes. -1 means undefined size in case tag was modified
// *
// * @return
// */
// override val length: Int
// get() = 30
//
// /**
// * Read leagscy version 1 tag without leading tag head
// *
// * @param buffer
// * @return
// * @throws IOException
// */
// override fun readHeader(buffer: ByteBuffer): Map<String, Value> {
// val res = HashMap<String, Value>()
//
// val type = buffer.getInt(2)
// res[Envelope.TYPE_PROPERTY] = Value.of(type)
//
// val metaTypeCode = buffer.getShort(10)
// val metaType = MetaType.resolve(metaTypeCode)
//
// if (metaType != null) {
// res[Envelope.META_TYPE_PROPERTY] = metaType.name.parseValue()
// } else {
// LoggerFactory.getLogger(EnvelopeTag::class.java).warn("Could not resolve meta type. Using default")
// }
//
// val metaLength = Integer.toUnsignedLong(buffer.getInt(14))
// res[Envelope.META_LENGTH_PROPERTY] = Value.of(metaLength)
// val dataLength = Integer.toUnsignedLong(buffer.getInt(22))
// res[Envelope.DATA_LENGTH_PROPERTY] = Value.of(dataLength)
// return res
// }
// }
//
// private class NumassEnvelopeReader : DefaultEnvelopeReader() {
// override fun newTag(): EnvelopeTag {
// return LegacyTag()
// }
// }
//
// companion object {
// val INSTANCE = NumassEnvelopeType()
//
// val LEGACY_START_SEQUENCE = byteArrayOf('#'.toByte(), '!'.toByte())
// val LEGACY_END_SEQUENCE = byteArrayOf('!'.toByte(), '#'.toByte(), '\r'.toByte(), '\n'.toByte())
//
// /**
// * Replacement for standard type infer to include legacy type
// *
// * @param path
// * @return
// */
// fun infer(path: Path): EnvelopeType? {
// return try {
// FileChannel.open(path, StandardOpenOption.READ).use {
// val buffer = it.map(FileChannel.MapMode.READ_ONLY, 0, 6)
// when {
// //TODO use templates from appropriate types
// buffer.get(0) == '#'.toByte() && buffer.get(1) == '!'.toByte() -> INSTANCE
// buffer.get(0) == '#'.toByte() && buffer.get(1) == '!'.toByte() &&
// buffer.get(4) == 'T'.toByte() && buffer.get(5) == 'L'.toByte() -> TaglessEnvelopeType.INSTANCE
// buffer.get(0) == '#'.toByte() && buffer.get(1) == '~'.toByte() -> DefaultEnvelopeType.INSTANCE
// else -> null
// }
// }
// } catch (ex: Exception) {
// LoggerFactory.getLogger(EnvelopeType::class.java).warn("Could not infer envelope type of file {} due to exception: {}", path, ex)
// null
// }
//
// }
//
// }
//
//}

View File

@ -0,0 +1,26 @@
package ru.inr.mass.data.proto
import hep.dataforge.context.Context
import hep.dataforge.meta.get
import hep.dataforge.meta.string
import hep.dataforge.meta.value
import hep.dataforge.values.ListValue
import org.junit.jupiter.api.Test
import java.nio.file.Path
import kotlin.test.assertEquals
class TestNumassDirectory {
val context = Context("numass-test") {
plugin(NumassProtoPlugin)
}
@Test
fun testDirectoryRead() {
val dataPath = Path.of("src/test/resources", "testData/set_4")
val testSet = context.readNumassDirectory(dataPath)
assertEquals("2018-04-13T22:01:46", testSet.meta["end_time"].string)
assertEquals(ListValue.EMPTY, testSet.meta["comments"].value)
assertEquals(31, testSet.points.size)
assertEquals("2018-04-13T21:56:09", testSet.points.find { it.index == 22 }?.meta["end_time"].string)
}
}

View File

@ -0,0 +1,31 @@
POINT 10 18700 0
POINT 10 19015 0
POINT 10 19005 0
POINT 10 19000 0
POINT 10 18995 0
POINT 10 18990 0
POINT 10 18700 0
POINT 10 18980 0
POINT 10 18950 0
POINT 10 18900 0
POINT 10 18800 0
POINT 10 18700 0
POINT 10 18600 0
POINT 10 18400 0
POINT 10 18200 0
POINT 10 18000 0
POINT 10 17500 0
POINT 10 17000 0
POINT 10 18700 0
POINT 10 16500 0
POINT 10 16000 0
POINT 10 15500 0
POINT 10 15000 0
POINT 10 14500 0
POINT 10 18700 0
POINT 10 14000 0
POINT 10 13500 0
POINT 10 13000 0
POINT 10 12500 0
POINT 10 12000 0
POINT 10 18700 0