Direct generation of random events using SimSET Author: Robert Harrison Date: May 2007 Overview To simulate random events directly (as opposed to generating them from singles rates using the Rij = 2SiSj formula) one needs a list of all detected photons ordered by and stamped with their detection times. This is quite different from SimSET’s ‘native’ mode: SimSET generates decays voxel-by-voxel (not in time-order) and when simulating PET always stopped tracking a photon when its annihilation partner wasn’t detected. Furthermore, importance sampling options are not compatible with direct generation of randoms, indeed, the decays and photons all need to have weight 1. The new SimSET randoms software addresses these problems by splitting the simulation into a four-step process: first a list-mode (history) file is created for the detected photons without pruning of unmatched photons; a new program called timesort sorts the list by detection time (using a new field added to the decay record); a new program addrandoms scans this list with a time window adding random events and deleting single events and triple events; the resulting list-mode file is then processed through the binning module. This document describes each of the above steps. Note that this process requires lots of free disk space: simulating a clinically realistic number of events will require hundreds of gigabytes of free disk space. The directory test1user gives an example of how to simulate randoms. The script runPET3d.sh runs all the necessary software. The following descriptions refer to some of the parameter files used by the software. Creating a list-mode file for randoms generation (See PET3d.phgin and PET3d.detparms.) The list-mode file used for randoms generation is the standard list-mode file created by the detector module. The list-mode file name is given in the detector parameters file: STR history_file = "PET3d.dethist" The randoms software only works with the standard history file format, so the line giving custom history parameters should be omitted or set to the empty string: STR history_params_file = "" The run file must also be changed. To support PET tracking both with and without the tracking of unmatched singles, we have added two new options: BOOL simulate_SPECT = false BOOL simulate_PET_coincidences_only = false BOOL simulate_PET_coincidences_plus_singles = true In previous versions setting “simulate_SPECT = false” automatically made the simulation a PET simulation. Now one must specify whether one wants to simulate only those photons that have an annihilation partner (“simulate_PET_coincidences_only = true”, much more efficient when randoms generation is not desired) or all photons including unmatched singles (“simulate_PET_coincidences_plus_singles = true”, necessary when simulating randoms). Exactly one of these three options must be set true in every simulation. The binning parameters file name can be left blank: if filled in, the simulated data will be binned without randoms. STR bin_params_file = "" (A separate run through the binning module after randoms have been added to the listmode data will create the binned data with randoms.) To allow for the generation of photons and events with a uniform weight of 1, we have added an option for SimSET to compute the number of decays to simulate from the activity distribution and scan time. (Previously the user specifed the number of decays, the activity, and the scan time – there was one piece of redundant information, necessitating the use of weights even when importance sampling was not used.) The scan time input has also been changed to a real number – this allows the user to set up very short runs (e.g., 0.01 scan time) to check they have set everything up correctly. In addition, all the importance sampling features must be set to false (simulate_stratification, simulate_forced_detection, and forced_non_absorbtion in the run file and do_forced_interaction in the detector parameters file). Outside of the above changes, the run and detector parameter files can be identical to those used before. The simulation is run as before to create the detected list-mode file: phg PET3d.phgin Sort by detection time (See PET3d.tsparms.) We have created a new program to sort the list mode data by detection time, timesort. It requires only three parameters: # INPUT HISTORY FILE STR history_file = "PET3d.dethist" # SORTED (OUTPUT) HISTORY FILE STR sorted_history_file = "PET3d.dethist.srtd" # BUFFER MEMORY SIZE (IN MEGABYTES) INT buffer_size = 200 The first parameter must give the same file name given for the list-mode file in the detector parameters file. The second is the output file name for the sorted listmode data. The third is the size buffer used for the sub-sorting of the data: 200 megabytes is a good size as long as it doesn’t cause memory problems on your system, e.g., if you only have 500MB RAM you may wish to reduce this to 50. Once the file is created, timesort is run by: timesort –d -r PET3d.tsparms (The “-d” specifies that a detector history file will be used as input. “-r” causes PET3d.dethist to be deleted after the time-sorted file is created – a little cleaning up.) Add random events (See PET3d.randparms.) We have created a new program to add randoms to time-sorted list-mode files, addrandoms. It requires 4 parameters: # detector_type can be # dual-headed or cylindrical ENUM detector_type = cylindrical # STR Time-sorted input history file history_file = "PET3d.dethist.srtd" # Output history file for the new randoms-added data. STR randoms_history_file = "PET3d.randhist" # Coincidence timing window in nanoseconds. REAL coincidence_timing_window_in_ns = 5 The detector type must be dual-headed or cylindrical. (We have not yet passed one of our tests for the dual-headed detector – I am pretty sure that this is a problem in the test definition and not the program, but still have less confidence in that detector.) The second parameter must be the file name for the output from the timesort program. The third parameter is a file name for the output from addrandoms, a list-mode file with randoms added to it (and with all other singles and all triples removed). The fourth parameter gives the desired timing window in nanoseconds. Every detected photon opens a window this long. If exactly one other photon arrives within the window, a true event (if the second photon is from the same decay) or random event (if its from a different decay) is added to the output list-mode file. If two or more other photons arrive within the window, the photons are discarded. addrandoms is run by: addrandoms PET3d.randparms Binning the randoms-added list-mode data (See PET3d.dethistin, PET3d.detrandparms, and PET3d.binparms.) Binning of the randoms-added data uses the same function that has always been used to bin list-mode files. However, there are some new binning options, and one has to make sure to bin the right list-mode file (the one produced by addrandoms). PET3d.dethistin can be a copy of PET3d.phgin, except with a new file name for the detector parameters file and a name for the binning parameters file: STR detector_params_file = "PET3d.detrandparms" STR bin_params_file = "PET3d.binparms" PET3d.detrandparms points to the randoms-added list-mode data: STR history_file = "PET3d.randhist" Otherwise it should be exactly like the detector parameters file (PET3d.detparms). PET3d.binparms has two new parameters, “accept_randoms” and “scatterRandomParam”. To include randoms in the binned data, one must set BOOL accept_randoms = true scatterRandomParam defines a new array of options for binning trues/randoms/scatter. It replaces the parameter “scatterParam”. scatterRandomParam controls how the trues, scatter and randoms get binned. The options are described in the parameter file. The most popular options will probably be: scatterRandomParam = 0, which causes trues, scatter, and randoms to all be binned together (as they are in actual scans); scatterRandomParam = 1, which creates separate bins for trues and scatter (i.e., if the user has selected distance-angle binning, there will be separate distance-angle arrays for true and scatter events); and scatterRandomParam = 6, which creates separate bins for trues, scatter, and randoms.