pixie16.read.list_mode package¶
pixie16.read.list_mode.list_mode_data_reader module¶
Read list mode data
The file provides a python based list mode data parser.
The input can either come from a data stream or from one or several binary files (in case a large binary data set is split across multiple files).
We keep all the data in numpy arrays, whic are either memmaped or pre-allocated, to make data access fast.
- exception pixie16.read.list_mode.list_mode_data_reader.EmptyError¶
Bases:
ExceptionWe reached the end of the last file.
- class pixie16.read.list_mode.list_mode_data_reader.Event(channel: int = -1, crate: int = -1, slot: int = -1, timestamp: float = -1.0, CFD_fraction: int = -1, energy: int = -1, trace: int = -1, CFD_error: int = -1, pileup: int = -1, trace_flag: int = -1, Esum_trailing: int = -1, Esum_leading: int = -1, Esum_gap: int = -1, baseline: float = -1.0, QDCSum0: int = -1, QDCSum1: int = -1, QDCSum2: int = -1, QDCSum3: int = -1, QDCSum4: int = -1, QDCSum5: int = -1, QDCSum6: int = -1, QDCSum7: int = -1, ext_timestamp: float = -1.0, chunk_timestamp: float = -1)¶
Bases:
StructData storage for a single event that has attribute access.
This is similar to a namedtuple, but the msgspec implemenation is faster.
- CFD_error: int¶
- CFD_fraction: int¶
- Esum_gap: int¶
- Esum_leading: int¶
- Esum_trailing: int¶
- QDCSum0: int¶
- QDCSum1: int¶
- QDCSum2: int¶
- QDCSum3: int¶
- QDCSum4: int¶
- QDCSum5: int¶
- QDCSum6: int¶
- QDCSum7: int¶
- baseline: float¶
- channel: int¶
- chunk_timestamp: float¶
- crate: int¶
- energy: int¶
- ext_timestamp: float¶
- pileup: int¶
- slot: int¶
- timestamp: float¶
- to_list()¶
- trace: int¶
- trace_flag: int¶
- class pixie16.read.list_mode.list_mode_data_reader.FileReader(files: Iterable[Path])¶
Bases:
objectRead binary data from multiple files.
Use mmap for fast data access to binary data on disc. The data can be distributed across several files.
This class should be used as a context manager: >>> files = (“file1.bin”, “file2.bin”) >>> with FileReader(files) as r: >>> r.read(100)
or one needs to call self.open_files() and self.close_files() manually.
- advance(size: int)¶
Not needed, since all the data is in the files and we can just advance the file position during read()
- close_files()¶
- open_files()¶
- read(size: int, offset: int = 0) bytes¶
Retrieve the next size bytes from the files and advance the file position.
- Parameters:
size – How many bytes should be returned.
offset – ignored here (used in Streamreader)
- Raises:
EmptyError – When data of the requested size is not available in the data stream.
- exception pixie16.read.list_mode.list_mode_data_reader.LeftoverBytesError¶
Bases:
ExceptionTo be raised if a partial event is left in the byte stream/file.
- class pixie16.read.list_mode.list_mode_data_reader.ListModeDataReader(reader: FileReader | StreamReader)¶
Bases:
object- iterevents()¶
Will raise an exception to exit loop.
- pop_all()¶
- class pixie16.read.list_mode.list_mode_data_reader.StreamReader(initial_buffer_size=25000000)¶
Bases:
objectHandle streamed binary data.
Provides the same interface as FileReader and can be used as a direct replacement.
New data can be added using the put method.
Internally we store the data in a np.array of np.uint32.
We make the array large enough to hold the data and have the buffer grow and shrink as needed.
This is similar to a ring buffer, but we just allocate twice the buffer size memory and then keep track of the left and right position in the buffer and shift the data to the far left every now and then.
- adjust_and_shift_buffer() None¶
Create a new buffer and copy the old buffer to beginning.
This also takes care of changing the size of the buffer
- advance(size: int) None¶
Advance self.left once a full event is read (possible after multiple read statement)
- put(input: numpy.ndarray) None¶
Add data to the buffer.
Also increase/decrease the buffer size as needed.
- read(size: int, offset: int = 0) numpy.ndarray¶
Return size 32-bit words from the buffer as a numpy array.
In the streamreader, there might be an incomplete event at the end of the buffer. However, we have several read statements to read a single event. We cannot advance self.left directly, unless we read a whole event (up to 3 read()). offset is used to read partial data and advance() is used to move self.left once a full event is read.
- pixie16.read.list_mode.list_mode_data_reader.data_rate_from_file(files)¶
Calculate the data rate in MB/s from a list of binary files. Returns a dictionary with the data rate for each second in the data set.
- pixie16.read.list_mode.list_mode_data_reader.data_rate_per_channel_from_file(files)¶
Calculate the data rate in MB/s per channel from a list of binary files. Returns a nested dictionary {channel: {second: MB/s}}.
- pixie16.read.list_mode.list_mode_data_reader.events_from_files_generator(files)¶
Yields events from a list of binary files
- pixie16.read.list_mode.list_mode_data_reader.read_list_mode_data(files, buffer_size=1000000000)¶
Loads a list of binary files into a pandas DataFrame.
Note: the binary files need to be ordered correctly, in case an event is distributed across two files.
- pixie16.read.list_mode.list_mode_data_reader.read_list_mode_data_as_events(files, buffer_size=1000000000, max_size=None)¶
Returns a list of at most max_size events from files.
Note: the binary files need to be ordered correctly, in case an event is distributed across two files.
- pixie16.read.list_mode.list_mode_data_reader.sort_events_by_channel(events, channel_list=None)¶
Sort events by channel.
Takes the output of read_list_mode_data_as_events and sorts them into a dictionary that has the channel number as key and as value a list of events (still including the channel number).
- Parameters:
events – List of events as returned by read_list_mode_data_as_events
channel_list – Optional list of channels to include. This can help to reduce the amount of data.
- pixie16.read.list_mode.list_mode_data_reader.timestamps_and_sizes_from_files_generator(files)¶
Yields (timestamp, event_length_words) for each event in binary files.
- pixie16.read.list_mode.list_mode_data_reader.timestamps_sizes_and_channel_from_files_generator(files)¶
Yields (channel, timestamp, event_length_words) for each event in binary files.
- pixie16.read.list_mode.list_mode_data_reader.to_tuple(obj)¶
- pixie16.read.list_mode.list_mode_data_reader.unpack_energy(data)¶
Extract energy sum fields from 16 bytes (4 32-bit words).
Format: u32 u32 u32 f32 Fields: Esum_trailing, Esum_leading, Esum_gap, baseline
- pixie16.read.list_mode.list_mode_data_reader.unpack_ext_time(data)¶
Extract extended timestamp from 8 bytes (2 32-bit words).
Format: u32 p16 u16 (p16 means 16 padding bits) Fields: Ext_TS_Lo, Ext_TS_Hi
- pixie16.read.list_mode.list_mode_data_reader.unpack_extra_header(data, extra_header_length)¶
Unpack additional header data based on length.
- Parameters:
data – Byte data (from byteswapped numpy array)
extra_header_length – Number of 32-bit words in extra header
- Raises:
KeyError – If extra_header_length is not a valid value (indicates corrupt data)
- pixie16.read.list_mode.list_mode_data_reader.unpack_header(data)¶
Extract header fields from 16 bytes using bitwise operations.
Format: b1u14u5u4u4u4u32u3u13u16b1u15u16 Fields: pileup, Event Length, Header Length, crate, slot, channel,
EVTTIME_LO, CFD trigger source bits, CFD Fractional Time, EVTTIME_HI, trace_flag, Trace Length, energy
Note: Works on little-endian data bytes directly from mmap.
- pixie16.read.list_mode.list_mode_data_reader.unpack_qsums(data)¶
Extract QDC sum fields from 32 bytes (8 32-bit words).
Format: u32 * 8 Fields: QDCSum0-7