1 from event import Event
2 from encoder import encode_unsigned, decode_unsigned
3 from encoder import encode_float, decode_float
4 import sys
5
6 import gzip
7
8 FLOAT_SIZE = 8
9 INT_SIZE = 4
10 LONG_SIZE = 8
11
12 -def write(file_handle, ev):
13 """
14 The write function is responsible for writing an event to a file.
15 @param file_handle: The file_handle is a file object and can be a standard
16 file, a gzip file handle, or anything with a write method really.
17 @param ev: The Event object to be written to the frame. There is some type checking
18 performed since it's critical that the bytestream be consistent and well-defined.
19 """
20 if type(ev.runID) == type(int()) :
21 file_handle.write( encode_unsigned(ev.runID) )
22 else:
23 raise TypeError('runID is not an int')
24
25 if type(ev.year) == type(int()) :
26 file_handle.write( encode_unsigned(ev.year) )
27 else:
28 raise TypeError('year is not an int')
29
30 if type(ev.startTime) == type(long()) or \
31 type(ev.startTime) == type(int()) :
32 file_handle.write( encode_unsigned(long(ev.startTime)) )
33 else:
34 raise TypeError('startTime is not a long')
35
36 if type(ev.eventLength) == type(float()) :
37 file_handle.write( encode_float(ev.eventLength) )
38 else:
39 raise TypeError('eventLength is not a float')
40
41
42
43 file_handle.write( encode_unsigned( long(len(ev.triggers))) )
44 for ttime, tname in ev.triggers :
45 file_handle.write( encode_float(ttime) )
46 file_handle.write( encode_unsigned( int(len(tname)) ) )
47 file_handle.write( tname )
48
49
50 file_handle.write( encode_unsigned( long(len(ev.hits))) )
51 for q,t,x,y,z in ev.hits :
52 file_handle.write( encode_float(q) )
53 file_handle.write( encode_float(t) )
54 file_handle.write( encode_float(x) )
55 file_handle.write( encode_float(y) )
56 file_handle.write( encode_float(z) )
57
58 print ev
59
60 -def read(file_handle):
61 """
62 This function is responsible for reading an event from a file and
63 returning an Event object. The order is assumed to be correct as
64 well as the file type. Otherwise this function will load garbage
65 without warning. Since it's assuming a simple well-defined bytestream
66 there's no way of verifying it's well-formed and uncorrupted. What
67 would be better is a dedicated serialization library that stores
68 type and class information along with the data. This should be the
69 next thing to do. The byte stream is assumed as follows in this order:
70 1. 4 bytes - runID(unsigned int)
71
72 2. 4 bytes - year(unsigned int)
73
74 3. 8 bytes - startTime (long) - Number of tenths of nanoseconds since
75 the beginning of the year.
76
77 4. 8 bytes - eventLength(float) - Units of microseconds.
78
79 5. 4 bytes - (long) - Number of triggers. This is not a member
80 of the Event class, since it's simply the size of the trigger list.
81 For each trigger the byte structure is given as :
82 - 8 bytes - trigger time (float) - Time of the trigger with respect
83 to the start of the event.
84 - 4 bytes - nchar (int) - Number of characters in the trigger name.
85 - nchar * 1 byte - The characters that make up the trigger name.
86
87 6. 8 bytes - nhits (long) - Number of hits in the event. The next set
88 consists of nhits*5*8 bytes (one chunk of 8 bytes for each float of q,t,x,y,z).
89
90 @todo: Make a robust serialization library that stores the type information
91 so that it is more generic and robust. Something closer to boost's
92 serialization library. We won't regret it.
93 """
94 ev = Event()
95
96
97
98
99
100 data = file_handle.read(INT_SIZE)
101 if data == '' :
102
103 return None
104 else :
105 ev.runID = decode_unsigned( data )
106
107 ev.year = decode_unsigned( file_handle.read(INT_SIZE) )
108 ev.startTime = decode_unsigned( file_handle.read(LONG_SIZE) )
109 ev.eventLength = decode_float( file_handle.read(FLOAT_SIZE) )
110
111
112
113 ntriggers = decode_unsigned( file_handle.read( LONG_SIZE ) )
114 for n in range(ntriggers) :
115 ttime = decode_float( file_handle.read( FLOAT_SIZE ) )
116 tname = ""
117 nchar = decode_unsigned( file_handle.read( INT_SIZE ) )
118 for m in range(nchar) :
119 tname += file_handle.read( 1 )
120 ev.triggers.append( (ttime,tname) )
121
122
123 nhits = decode_unsigned( file_handle.read( LONG_SIZE ) )
124 for n in range(nhits) :
125 q = decode_float( file_handle.read( FLOAT_SIZE ) )
126 t = decode_float( file_handle.read( FLOAT_SIZE ) )
127 x = decode_float( file_handle.read( FLOAT_SIZE ) )
128 y = decode_float( file_handle.read( FLOAT_SIZE ) )
129 z = decode_float( file_handle.read( FLOAT_SIZE ) )
130 ev.hits.append( (q,t,x,y,z) )
131
132 return ev
133