aboutsummaryrefslogtreecommitdiff
path: root/src/zebra.h
diff options
context:
space:
mode:
authortlatorre <tlatorre@uchicago.edu>2019-01-15 01:08:54 -0600
committertlatorre <tlatorre@uchicago.edu>2019-01-15 01:08:54 -0600
commit9c910abe7a0359018677a874822d8742d0e616b9 (patch)
tree52dda30fd3c5b0eb78050dee4dec10bdf8557ed7 /src/zebra.h
parent272d793cda5456fb8a69d3e2a407bf24d3600cd4 (diff)
downloadsddm-9c910abe7a0359018677a874822d8742d0e616b9.tar.gz
sddm-9c910abe7a0359018677a874822d8742d0e616b9.tar.bz2
sddm-9c910abe7a0359018677a874822d8742d0e616b9.zip
update zebra library to be able to use links
This commit updates the zebra library files zebra.{c,h} so that it's now possible to traverse the data structure using links! This was originally motivated by wanting to figure out which MC particles were generated from the MCGN bank (from which it's only possible to access the tracks and vertices using structural links). I've also added a new test to test-zebra which checks the consistency of all of the next/up/orig, structural, and reference links in a zebra file.
Diffstat (limited to 'src/zebra.h')
-rw-r--r--src/zebra.h108
1 files changed, 100 insertions, 8 deletions
diff --git a/src/zebra.h b/src/zebra.h
index 2f24939..c05f62d 100644
--- a/src/zebra.h
+++ b/src/zebra.h
@@ -1,3 +1,37 @@
+/* Library for reading ZEBRA files.
+ *
+ * The ZEBRA file format is an old file format used by FORTRAN programs for
+ * memory management and storing data structures. In particular, it's the
+ * default file format used by SNOMAN.
+ *
+ * This library is fairly simple and almost certainly does *not* include all
+ * the details needed to read an arbitrary ZEBRA file. Instead I implemented as
+ * much as was necessary to read in SNOMAN files and fixed bugs along the way.
+ *
+ * Example usage:
+ *
+ * zebraBank b;
+ * zebraFile *z = zebra_open("Muons.zdab")
+ *
+ * while (1) {
+ * rv = read_next_logical_record(z);
+ *
+ * switch (rv) {
+ * case 1:
+ * // EOF
+ * goto end;
+ * case -1:
+ * fprintf(stderr, "error getting logical record: %s\n", zebra_err);
+ * goto err;
+ * }
+ *
+ * zebra_get_bank(z,&b,z->first_bank);
+ *
+ * // etc.
+ * }
+ *
+ */
+
#ifndef ZEBRA_H
#define ZEBRA_H
@@ -5,44 +39,102 @@
#include <stdlib.h> /* for size_t */
#include <stdint.h> /* for uint8_t, etc. */
+/* Maximum number of links in a bank.
+ *
+ * Technically we could malloc() this but that means we would have to free
+ * banks which would be annoying. */
+#define MAX_LINKS 100
+
+/* Global error string when any function returns -1. */
extern char zebra_err[256];
+/* Physical record markers. */
#define ZEBRA_SIG0 0x0123cdefUL
#define ZEBRA_SIG1 0x80708070UL
#define ZEBRA_SIG2 0x4321abcdUL
#define ZEBRA_SIG3 0x80618061UL
+/* Bitmasks for the physical record block size control word. */
#define ZEBRA_BLOCK_SIZE_MASK 0x00ffffffUL
#define ZEBRA_EMERGENCY_STOP 0x80000000UL
#define ZEBRA_END_OF_RUN 0x20000000UL
#define ZEBRA_START_OF_RUN 0x40000000UL
-typedef struct bank {
+typedef struct zebraBank {
+ /* Pointer to the next bank in the chain. */
uint32_t next;
+ /* Pointer to the supporting bank. */
uint32_t up;
+ /* Pointer to the previous bank in the chain (or to the referencing link in
+ * the supporting bank if it's the first). */
uint32_t orig;
+ /* Bank number. From the SNOMAN FAQ:
+ *
+ * "In general, ZEBRA attaches no special significance to the bank number,
+ * and it is perfectly O.K. to change it at any time." */
uint32_t number;
- uint32_t name;
+ /* Hollerith bank ID as an integer. */
+ uint32_t idh;
+ /* Total number of links in the bank.
+ *
+ * Note: In SNOMAN reference links aren't guaranteed to point to the start
+ * of a bank. According to the SNOMAN docs all reference links in SNOMAN
+ * should point to the bank's status word instead of the start of the bank,
+ * but I tried the following and it didn't seem to work:
+ *
+ * zebra_get_bank(z,&b,mctk.links[KMCTK_MCVX-1]-8);
+ *
+ * So, I'm not really sure how reference links work in SNOMAN. */
uint32_t num_links;
+ /* Number of structural links. The order of the links in the bank is:
+ *
+ * structural link 1
+ * structural link 2
+ * ...
+ * structural link num_structural_links
+ * reference link num_structural_links+1
+ * reference link num_structural_links+2
+ * ...
+ * reference link num_links
+ *
+ */
uint32_t num_structural_links;
+ /* Number of data words. */
uint32_t num_data_words;
+ /* Status word. */
uint32_t status;
+ /* Pointer to the bank data in zebraFile->buf. Note that after calling
+ * zebra_read_next_logical_record(), this pointer will no longer point to
+ * the bank data. */
uint32_t *data;
-} bank;
+ /* Reference and structural links. */
+ uint32_t links[MAX_LINKS];
+ /* The Hollerith bank name as a string instead of an integer. This can be
+ * useful when printing error messages or for debugging. */
+ char name[5];
+} zebraBank;
typedef struct zebraFile {
FILE *f;
- size_t offset;
+ /* Size of the current logical record in bytes. */
size_t lr_size;
+ /* Buffer used to read in the zebra file. */
uint8_t *buf;
+ /* Total size of the current buffer. */
size_t buf_size;
+ /* Relocation table. */
+ uint32_t *tab;
+ /* Number of words in the relocation table. */
+ size_t nwtab;
+ /* Link to first bank. */
+ uint32_t first_bank;
+ /* Number of words from the start of the buffer to the first bank word. */
+ uint32_t lr_offset;
} zebraFile;
zebraFile *zebra_open(const char *filename);
-int read_next_physical_record(zebraFile *z);
-int get_bytes(zebraFile *z, size_t size);
-int read_next_logical_record(zebraFile *z);
-int next_bank(zebraFile *z, bank *b);
+int zebra_read_next_logical_record(zebraFile *z);
+int zebra_get_bank(zebraFile *z, zebraBank *b, uint32_t link);
void zebra_close(zebraFile *z);
#endif