40 lines
1.2 KiB
Nim
40 lines
1.2 KiB
Nim
# Reader/writer for xyz files
|
|
import particle
|
|
import strutils
|
|
import strscans
|
|
import strformat
|
|
import linalg
|
|
|
|
proc parseXyz*(path: string): seq[Particle] =
|
|
let f = readFile(path)
|
|
let lines = f.split("\n")
|
|
var i = 0
|
|
while i <= lines.high():
|
|
# read a single frame
|
|
# read atom count
|
|
let atomCount = parseInt(lines[i])
|
|
inc i
|
|
|
|
# the comment
|
|
let comment = lines[i]
|
|
inc i
|
|
|
|
var x, y, z: float
|
|
var name: string
|
|
# the atoms
|
|
if i + atomCount + 1 >= lines.high(): # tolerate empty line at end
|
|
for j in 0..atomCount-1:
|
|
if not lines[i + j].scanf("$s$w$s$f$s$f$s$f$s", name, x, y, z):
|
|
raise newException(Defect, "Invalid format on line " & $i)
|
|
result.add(newParticle(name, vector(x, y, z), massFromName(name)))
|
|
break
|
|
i += atomCount
|
|
|
|
proc appendXyz*(f: File, parts: seq[Particle], t: float) =
|
|
# f should be open in APPEND mode
|
|
f.writeLine(parts.len()) # atom count
|
|
f.writeLine("t = " & $t) # comment line containing the time
|
|
for atom in parts:
|
|
let pos = atom.pos
|
|
f.writeLine(&"{atom.name} {pos.x} {pos.y} {pos.z}")
|