A high performance Protein Databank parser written in Zig.
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: added new PDB struct for easier use

Ethan Holz (Jan 5, 2024, 1:01 AM -0700) 53a2780b f3be20ae

+60 -11
+9 -11
src/main.zig
··· 8 8 const AtomRecord = @import("records.zig").AtomRecord; 9 9 const RunRecord = @import("records.zig").RunRecord; 10 10 const PDBReader = @import("records.zig").PDBReader; 11 + const PDB = @import("records.zig").PDB; 11 12 12 13 test { 13 14 // this causes 'zig build test' to test any referenced files ··· 60 61 61 62 if (parsedArgs.runs == 1) { 62 63 var bufreader = std.io.bufferedReader(file.reader()); 63 - var atoms = try PDBReader(bufreader.reader(), allocator); 64 - defer atoms.deinit(); 64 + 65 + var pdb = try PDB.init(allocator); 66 + defer pdb.deinit(); 67 + try pdb.read(bufreader.reader()); 68 + 65 69 const writer = std.io.getStdOut().writer(); 66 - for (atoms.items) |*atom| { 67 - if (parsedArgs.json) { 68 - try writer.print("{json}\n", .{atom}); 69 - } else { 70 - try writer.print("{}\n", .{atom}); 71 - } 72 - atom.free(allocator); 73 - } 70 + try writer.print("{}\n", .{pdb}); 74 71 std.os.exit(0); 75 72 } 76 73 ··· 93 90 } 94 91 timer.reset(); 95 92 var bufreader = std.io.bufferedReader(file.reader()); 96 - _ = try PDBReader(bufreader.reader(), arenaAllocator); 93 + var pdb = try PDB.init(arenaAllocator); 94 + try pdb.read(bufreader.reader()); 97 95 const elapsed = timer.read(); 98 96 try times.append(elapsed); 99 97 var runRecord: RunRecord = RunRecord{ .run = i + 1, .time = elapsed, .file = parsedArgs.fileName };
+51
src/records.zig
··· 7 7 const string = []const u8; 8 8 const char = u8; 9 9 10 + pub const PDB = struct { 11 + records: std.ArrayList(Record) = undefined, 12 + allocator: std.mem.Allocator = undefined, 13 + 14 + pub fn init(allocator: std.mem.Allocator) !PDB { 15 + var pdb = PDB{}; 16 + pdb.records = std.ArrayList(Record).init(allocator); 17 + pdb.allocator = allocator; 18 + return pdb; 19 + } 20 + 21 + pub fn deinit(self: *PDB) void { 22 + for (self.records.items) |*record| record.free(self.allocator); 23 + self.records.deinit(); 24 + } 25 + 26 + pub fn read(self: *PDB, reader: anytype) !void { 27 + var buf: [90]u8 = undefined; 28 + var recordNumber: u32 = 0; 29 + const end = std.mem.readInt(u48, "END ", .little); 30 + while (try reader.readUntilDelimiterOrEof(&buf, '\n')) |line| { 31 + if (line.len < 6) continue; 32 + const tag_int = std.mem.readInt(u48, line[0..6], .little); 33 + if (tag_int == end) break; 34 + const tag = std.meta.intToEnum(RecordType, tag_int) catch continue; 35 + if (tag == .endmdl) { 36 + continue; 37 + } 38 + // TODO: Add switch to handle connect records 39 + const record = try Record.parse(line, tag, recordNumber, self.allocator); 40 + recordNumber = record.serial(); 41 + try self.records.append(record); 42 + } 43 + } 44 + 45 + pub fn format( 46 + self: PDB, 47 + comptime fmt: []const u8, 48 + _: std.fmt.FormatOptions, 49 + writer: anytype, 50 + ) !void { 51 + for (self.records.items) |record| { 52 + if (comptime std.mem.eql(u8, fmt, "json")) { 53 + try writer.print("{json}\n", .{record}); 54 + } else { 55 + try writer.print("{}\n", .{record}); 56 + } 57 + } 58 + } 59 + }; 60 + 10 61 /// Reads in a PDB file and converts them to an ArrayList of records 11 62 pub fn PDBReader(reader: anytype, allocator: std.mem.Allocator) !std.ArrayList(Record) { 12 63 var records = std.ArrayList(Record).init(allocator);