KaliVeda
Toolkit for HIC analysis
|
Generic event mixing algorithm for N-particle correlation studies.
NPart | number of particles to correlate = 2, 3, 4, ... |
ParticleClass | class used to represent particles as passed via iterators to ProcessEvent() |
ParticleInfoStruct | user-provided structure which will be used to store any required information on each particle to be used in the event mixing |
NumBins | number of different event classes to be treated separately in the event mixing |
This class is a generic implementation of the event mixing technique used to estimate the uncorrelated background for \(N\)-particle correlation functions. Events belonging to different user-defined event classes can be treated separately at the same time.
The generic problem adressed here is the construction of \(N\)-particle correlation functions using an event mixing technique. Given events containing \(N\) particle types A, type B, type C, ..., it is assumed the user wants to construct some quantity which can be calculated from the properties of any multiplet of particles (A,B,C,...), using both correlated and uncorrelated (mixed) sets of particles. The algorithm requires the user to provide:
For each analysed event, the function for correlated particles will be called for each multiplet in the event, and then each previous event stored in buffers will be used to generate uncorrelated multiplets for which the corresponding function will be called. The particles of each type of the \(n\) previous events (by default \(n=10\): can be changed with an argument to the class constructor) are kept in memory: decorrelating begins when each buffer is full, after this each new event which is added causes the previous 'oldest' event in the same buffer to be discarded.
The user must define a class/struct which will be used to store any necessary information on each particle in the buffers used in the event mixing. This struct must define a constructor whose single argument is compatible with whatever type of reference to the particles in the event is returned by the iterators provided by the user (this is the same type as the template parameter ParticleType - see ProcessEvent() method below). In the case of events stored in KVEvent (or derived) objects, this class/struct must have a constructor which can be called with a reference to a KVNucleus object (or derived class) and which will extract and store the required information.
Here are some examples:
This could be used for azimuthal correlations, supposing that all is required is the azimuthal angle of each particle.
In experimental cases (i.e. analysing reconstructed data), you probably need to store some information on which detector was hit by the particle, in order to avoid generating uncorrelated pairs which could not exist experimentally. For example:
If more detailed informations on each particle are required, the most simple (but not the most lightweight in terms of memory) way may be to store the informations in a KVNucleus object in your structure. In this case, rather than trying to do a direct 'copy' of the nucleus passed to the constructor (especially when dealing with KVReconstructedNucleus objects), you should use the appropriate 'Set' methods of KVNucleus in order to copy the required characteristics for each nucleus. In this example, we show the minimum required in order to keep all kinematic information (in a given reference frame - not all frames can be copied) on each nucleus:
In all cases, your class/struct needs to have a default constructor, default copy constructor, and default move constructor: just add them as shown:
Once the class/struct for particle info storage is defined, the event mixer can be declared as a member variable of your analysis class, as in this example for 2-body azimuthal correlations calculated for experimental data:
The 4 template parameters are:
The constructor optionally takes an argument defining the buffer depth to use for the mixing (if not given, default value 10 events is used).
In your event by event analysis, you need to call the ProcessEvent() method, providing the required iterators and functions to treat each multiplet of particles, along with the 'bin' number corresponding to the class of the current event (e.g. events could be classed according to total multiplicity into bins of centrality - it is up to you how you sort your events):
The 'iterators' IterA, IterB, etc. are not in fact strictly iterators: they are any expression which can be used on the right-hand side of a range-for loop, i.e. 'X' in the following pseudo-code:
For example, if the particles in your event are stored in a std::vector, X would be a reference to the vector:
KaliVeda provides a wide range of pseudo-iterators for KVEvent to be used in range-for loops, which are commonly used in KVEventSelector analysis classes:
Therefore to use KVEventMixer in a KVEventSelector analysis class, IterA, IterB, ... will probably be one of these pseudo-iterators, as in this (incomplete) example for correlating \(\alpha\)-particles and deuterons:
Finally you have to provide two functions in order to treat each set of correlated and uncorrelated particles. This is conveniently done using lambda functions, but any callable can be used.
Both functions receive as first argument the 'bin' corresponding to the event class (this is the value passed as first argumet to ProcessEvent). For correlated particles, the multiplet of \(N\) correlated particles are passed in a vector:
KVRefVec<T> behaves like a std::vector of references to T
objects: given a vector KVRefVec<T> o;
, o[i]
is a T&
reference.
The correlated function CorFunc will be called for every set of particles (A,B,C,...) generated by coupling all possible combinations of the \(N\) different types of particles in the event. If 2 or more of the particle types are in fact the same, so that two or more particles to correlate may in fact be the same physical particle, it is the user's responsibility to avoid correlating each particle with itself in the given CorFunc (e.g. by comparing the memory address of each particle object).
For uncorrelated particles, we pass to the user's function a reference to a particle in the current event and \(N-1\) references to the other particles taken from previous events in the buffers:
The particles of each type are taken from the buffers of \(N\) previous events; note that in the buffers for different particles, there may be particles of different types from the same event. If you want to avoid using particles from the same event, you could (as in order to avoid particles hitting the same detector in different events) store in the ParticleInfoStruct the event number for each particle, and then check that all buffer particles are from different events in you UnCorFunc function.
Definition at line 200 of file KVEventMixerN.h.
#include <KVEventMixerN.h>
Classes | |
struct | bin_data |
struct | event |
Public Member Functions | |
KVEventMixerN (typename event_buffer::size_type number_of_events_to_mix=10) | |
vector of references to particles from buffers for decorrelation | |
template<typename TreatNCorFunc , typename part_iterator , typename... part_iterator_list> | |
void | decorrelate (int part_index, TreatNCorFunc TreatNCor, part_iterator &iter_part, part_iterator_list... part_iterators) |
template<typename TreatNCorFunc > | |
void | decorrelate (int, TreatNCorFunc) |
template<typename part_iterator , typename... part_iterator_list> | |
void | fill_all_particle_buffers (int part_index, part_iterator &iter_part, part_iterator_list... part_iterators) |
void | fill_all_particle_buffers (int) |
template<typename TreatCorFunc , typename part_iterator , typename... part_iterator_list> | |
void | process_event (int part_index, TreatCorFunc TreatCor, part_iterator &iter_part, part_iterator_list... part_iterators) |
template<typename TreatCorFunc > | |
void | process_event (int, TreatCorFunc TreatCor) |
template<typename TreatCorFunc , typename TreatNCorFunc , typename part_iterator , typename... part_iterator_list> | |
void | ProcessEvent (int bin_number, TreatCorFunc TreatCor, TreatNCorFunc TreatNCor, const part_iterator &iter_part, part_iterator_list... part_iterators) |
template<typename TreatNCorFunc > | |
void | recursive_decorrelation (ParticleClass &part, int part_index, int decor_index, int decor_vec_index, TreatNCorFunc TreatNCor) |
Private Types | |
using | event_buffer = std::deque< event > |
Private Attributes | |
bin_data | bins [NumBins] |
std::array< bool, NPart > | buffer_ready |
std::array< bool, NPart > | can_decorrelate |
KVRefVec< ParticleClass > | correlated_particles {NPart} |
int | current_bin_number |
number of events used for decorrelation (event mixing) | |
event_buffer::size_type | decor_events = 10 |
std::array< bool, NPart > | mult_fixed |
particle multiplicities for event being treated by ProcessEvent | |
std::array< int, NPart > | n_part |
bin number passed in current call to ProcessEvent | |
KVRefVec< ParticleInfoStruct > | uncorrelated_particles {NPart - 1} |
vector of references to particles in current event | |
|
private |
Definition at line 218 of file KVEventMixerN.h.
|
inline |
vector of references to particles from buffers for decorrelation
ParticleInfoStruct | user-provided structure which will be used to store any required information on each particle to be used in the event mixing |
NumBins | number of different event classes to be treated separately in the event mixing [default:1] |
number_of_events_to_mix | number of previous events to store in order to do event mixing [default:10] |
Definition at line 241 of file KVEventMixerN.h.
|
inline |
Definition at line 334 of file KVEventMixerN.h.
|
inline |
Definition at line 330 of file KVEventMixerN.h.
|
inline |
Definition at line 288 of file KVEventMixerN.h.
|
inline |
Definition at line 281 of file KVEventMixerN.h.
|
inline |
Definition at line 256 of file KVEventMixerN.h.
|
inline |
Definition at line 246 of file KVEventMixerN.h.
|
inline |
Definition at line 349 of file KVEventMixerN.h.
|
inline |
Definition at line 309 of file KVEventMixerN.h.
|
private |
Definition at line 222 of file KVEventMixerN.h.
|
private |
Definition at line 229 of file KVEventMixerN.h.
|
private |
Definition at line 230 of file KVEventMixerN.h.
|
private |
Definition at line 232 of file KVEventMixerN.h.
|
private |
number of events used for decorrelation (event mixing)
Definition at line 226 of file KVEventMixerN.h.
|
private |
Definition at line 224 of file KVEventMixerN.h.
|
private |
particle multiplicities for event being treated by ProcessEvent
Definition at line 228 of file KVEventMixerN.h.
|
private |
bin number passed in current call to ProcessEvent
Definition at line 227 of file KVEventMixerN.h.
|
private |
vector of references to particles in current event
Definition at line 233 of file KVEventMixerN.h.