Package python :: Module fileio
[hide private]
[frames] | no frames]

Source Code for Module python.fileio

  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 # now for the triggers 42 # for decoding we need the number of triggers 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 # now for the hits 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 # when the end of the file is reached an empty string is returned 97 # so we read a chunk of data and if an empty string is retrieved 98 # return None, otherwise it's safe to decode that as the beginning 99 # of the next event. 100 data = file_handle.read(INT_SIZE) 101 if data == '' : 102 # EOF, so return None 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 # now for the triggers 112 # for decoding we need the number of triggers 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 # now for the hits 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