Created
June 5, 2017 13:47
-
-
Save xomachine/ceeb3505e32859ad9434c64b00c1eb5d to your computer and use it in GitHub Desktop.
Little utility to show rtdb fields of NWChem calculation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from nesm import serializable | |
from streams import Stream, atEnd | |
from tables import Table, initTable, `[]`, `[]=` | |
const cookie* = "hdbm v1.0" | |
serializable: | |
type | |
FileEntry* = object | |
key_size: int32 | |
val_size: int32 | |
active*: bool | |
padding: array[3, byte] | |
key*: string {size: {}.key_size - 1} | |
endkey: byte | |
val*: seq[byte] {size: {}.val_size}# required a feature | |
Header* = tuple | |
cookie: string {size: cookie.len} | |
endcookie: byte | |
type | |
NotADBError* = object of Exception | |
Entry* = object | |
data*: seq[byte] | |
active*: bool | |
HDBM* = Table[string, Entry] | |
proc load*(input: Stream): HDBM = | |
let head = Header.deserialize(input) | |
if head.cookie != cookie: | |
raise newException(NotADBError, "The file is not a database!") | |
result = initTable[string, Entry]() | |
while not input.atEnd: | |
let fentry = FileEntry.deserialize(input) | |
let entry = Entry(data: fentry.val, active: fentry.active) | |
result[fentry.key] = entry | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from strutils import startsWith, `%`, join | |
from sequtils import mapIt | |
from tables import Table | |
from tables import initTable, pairs, rightSize, `[]`, `[]=`, len, contains | |
from nesm import serializable | |
from hdbm import HDBM | |
const info_header = "!rtdb!" | |
const MT_BASE = 1000 | |
serializable: | |
static: | |
type DataType* = enum | |
Undefined | |
Char = MT_BASE | |
Integer | |
LongInteger | |
Float | |
Double | |
LongDouble | |
SPComplex | |
DPComplex | |
LongDPComplex | |
FortByte | |
FortInteger | |
FortLogical | |
FortReal | |
FortDP | |
FortSPComplex | |
FortDPComplex | |
type InfoStruct = object | |
ma_type: uint32 | |
#spacer: array[2, byte] | |
nelements: uint32 | |
date: array[26, char] | |
type | |
UndefinedDataError = object of Exception | |
Element* = object | |
nelements*: Natural | |
kind*: DataType | |
last_changed*: string | |
data: seq[byte] | |
RTDB* = Table[string, Element] | |
proc toRTDB*(hdbm: HDBM): RTDB = | |
result = initTable[string, Element](rightSize(hdbm.len div 2)) | |
for k, v in hdbm.pairs(): | |
if k.startsWith(info_header): | |
#echo "Encountered info section: " & k | |
#echo $v.active | |
let info = InfoStruct.deserialize(v.data) | |
#echo "Data: " & $info | |
let realKey = k[info_header.len..^1] | |
if realKey notin result: | |
result[realKey] = Element(nelements: 0, last_changed: "", | |
kind: Undefined, data: @[]) | |
result[realKey].nelements = info.nelements | |
result[realKey].kind = DataType(info.ma_type) | |
#result[realKey].last_changed = newString(info.date.len) | |
result[realKey].last_changed = $cast[cstring](info.date[0].unsafeAddr) | |
#copyMem(result[realKey].last_changed[0].addr, info.date[0].unsafeAddr, | |
# info.date.len - 1) | |
else: | |
if k notin result: | |
result[k] = Element(nelements: 0, last_changed: "", | |
kind: Undefined, data: @[]) | |
result[k].data = v.data | |
proc getKeyAs*[T](self: RTDB, key: string): seq[T] = | |
let element = self[key] | |
assert((element.data.len == T.sizeof * element.nelements), | |
"Size of data is not equals size of type expected") | |
result = newSeq[T](element.nelements) | |
for i in 0..<element.nelements: | |
copyMem(result[i].addr, element.data[i*T.sizeof].unsafeAddr, T.sizeof) | |
proc stringify[T](a: seq[byte], maxnum: Natural): string = | |
result = "" | |
for i in 0..<maxnum: | |
result.add($(cast[ptr T](a[i*sizeof(T)].unsafeAddr)[]) & ", ") | |
proc `$`*(e: Element): string = | |
let last = min(e.nelements, 5) | |
#assert(e.data.len mod e.nelements == 0, "Kind: $1, len: $2, nelem: $3" % | |
# [$e.kind, $e.data.len, $e.nelements]) | |
if e.nelements == 0: | |
"Empty" | |
else: | |
let esize = e.data.len div e.nelements | |
case e.kind: | |
of Char: | |
$cast[cstring](e.data[0].unsafeAddr) | |
of Double, FortDP, LongDouble: | |
assert(float64.sizeof == esize, "Kind: $1, size: $2" % [$e.kind, $esize]) | |
stringify[float64](e.data, last) | |
of Integer, LongInteger, FortInteger: | |
assert(int64.sizeof == esize, "Kind: $1, size: $2" % [$e.kind, $esize]) | |
stringify[int64](e.data, last) | |
of FortReal, Float: | |
assert(float32.sizeof == esize, "Kind: $1, size: $2" % [$e.kind, $esize]) | |
stringify[float32](e.data, last) | |
of FortLogical: | |
stringify[bool](e.data, last) | |
of FortByte: | |
cast[cstring](e.data[0].unsafeAddr).repr | |
else: | |
"Undefined" | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from hdbm import HDBM, load | |
from rtdb import toRTDB, `$` | |
from tables import pairs | |
from streams import newFileStream | |
let input = newFileStream(stdin) | |
let db = input.load() | |
let nwrtdb = toRTDB(db) | |
for k, v in nwrtdb.pairs: | |
echo("Key: " & k & " Kind: " & $v.kind & " Count: " & $v.nelements & | |
" Data: " & $v & " Last changed: " & v.last_changed) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment